diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 99f6a254b8..e5ebce0c11 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -32,13 +32,11 @@ import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorPreferences -import kotlinx.coroutines.Dispatchers +import im.vector.app.features.spaces.notification.GetNotificationCountForSpacesUseCase import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.sample import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.QueryStringValue @@ -48,12 +46,9 @@ import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getUserOrDefault -import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams -import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.api.session.space.SpaceOrderUtils import org.matrix.android.sdk.api.session.space.model.SpaceOrderContent import org.matrix.android.sdk.api.session.space.model.TopLevelSpaceComparator @@ -67,6 +62,7 @@ class SpaceListViewModel @AssistedInject constructor( private val vectorPreferences: VectorPreferences, private val autoAcceptInvites: AutoAcceptInvites, private val analyticsTracker: AnalyticsTracker, + private val getNotificationCountForSpacesUseCase: GetNotificationCountForSpacesUseCase, ) : VectorViewModel(initialState) { @AssistedFactory @@ -92,39 +88,14 @@ class SpaceListViewModel @AssistedInject constructor( copy(selectedSpace = selectedSpaceOption.orNull()) } - // XXX there should be a way to refactor this and share it - session.roomService().getPagedRoomSummariesLive( - roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.spaceFilter = roomsInSpaceFilter() - }, sortOrder = RoomSortOrder.NONE - ).asFlow() - .sample(300) - .onEach { - val inviteCount = if (autoAcceptInvites.hideInvites) { - 0 - } else { - session.roomService().getRoomSummaries( - roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } - ).size - } - val totalCount = session.roomService().getNotificationCountForRooms( - roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.spaceFilter = roomsInSpaceFilter() - } - ) - val counts = RoomAggregateNotificationCount( - totalCount.notificationCount + inviteCount, - totalCount.highlightCount + inviteCount - ) + getNotificationCountForSpacesUseCase.execute(roomsInSpaceFilter()) + .onEach { counts -> setState { copy( homeAggregateCount = counts ) } } - .flowOn(Dispatchers.Default) .launchIn(viewModelScope) } diff --git a/vector/src/main/java/im/vector/app/features/spaces/notification/GetNotificationCountForSpacesUseCase.kt b/vector/src/main/java/im/vector/app/features/spaces/notification/GetNotificationCountForSpacesUseCase.kt new file mode 100644 index 0000000000..5f79619c92 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/spaces/notification/GetNotificationCountForSpacesUseCase.kt @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.spaces.notification + +import androidx.lifecycle.asFlow +import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.features.invite.AutoAcceptInvites +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.mapLatest +import kotlinx.coroutines.flow.sample +import org.matrix.android.sdk.api.query.SpaceFilter +import org.matrix.android.sdk.api.session.room.RoomSortOrder +import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount +import javax.inject.Inject + +// TODO add unit tests +class GetNotificationCountForSpacesUseCase @Inject constructor( + private val activeSessionHolder: ActiveSessionHolder, + private val autoAcceptInvites: AutoAcceptInvites, +) { + + fun execute(spaceFilter: SpaceFilter): Flow { + val session = activeSessionHolder.getSafeActiveSession() + + val spaceQueryParams = roomSummaryQueryParams { + this.memberships = listOf(Membership.JOIN) + this.spaceFilter = spaceFilter + } + return session + ?.roomService() + ?.getPagedRoomSummariesLive(queryParams = spaceQueryParams, sortOrder = RoomSortOrder.NONE) + ?.asFlow() + ?.sample(300) + ?.mapLatest { + val inviteCount = if (autoAcceptInvites.hideInvites) { + 0 + } else { + session.roomService().getRoomSummaries( + roomSummaryQueryParams { this.memberships = listOf(Membership.INVITE) } + ).size + } + val totalCount = session.roomService().getNotificationCountForRooms(spaceQueryParams) + RoomAggregateNotificationCount( + notificationCount = totalCount.notificationCount + inviteCount, + highlightCount = totalCount.highlightCount + inviteCount, + ) + } + ?.flowOn(Dispatchers.Default) + ?: emptyFlow() + } +}