From b9f73c6cc3056706fda07a586a8ce39c1c129d4c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 1 Apr 2021 18:19:05 +0200 Subject: [PATCH] BMA's cleanup --- .../sdk/api/query/RoomCategoryFilter.kt | 24 ++++ .../sdk/api/session/room/RoomService.kt | 39 +++--- .../session/room/RoomSummaryQueryParams.kt | 8 +- .../summary/RoomAggregateNotificationCount.kt | 5 +- .../SessionRealmConfigurationFactory.kt | 1 - .../database/model/RoomSummaryEntity.kt | 19 ++- .../room/summary/RoomSummaryDataSource.kt | 27 ++-- .../room/summary/RoomSummaryUpdater.kt | 3 - .../java/im/vector/app/AppStateHandler.kt | 7 +- .../app/core/platform/VectorBaseFragment.kt | 2 + .../app/features/home/HomeDetailViewModel.kt | 30 ++-- .../app/features/home/ShortcutsHandler.kt | 15 +- .../features/home/room/list/RoomListAction.kt | 2 +- .../home/room/list/RoomListFragment.kt | 98 ++++++------- .../home/room/list/RoomListViewModel.kt | 129 ++++++++---------- .../room/list/RoomSummaryPagedController.kt | 45 +++--- .../features/home/room/list/RoomsSection.kt | 31 +++++ .../home/room/list/SectionHeaderAdapter.kt | 24 ++-- 18 files changed, 266 insertions(+), 243 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/RoomCategoryFilter.kt create mode 100644 vector/src/main/java/im/vector/app/features/home/room/list/RoomsSection.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/RoomCategoryFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/RoomCategoryFilter.kt new file mode 100644 index 0000000000..c8ccc4c8a3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/query/RoomCategoryFilter.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.api.query + +enum class RoomCategoryFilter { + ONLY_DM, + ONLY_ROOMS, + ONLY_WITH_NOTIFICATIONS, + ALL +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index 819ba054ea..8c833644ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -181,25 +181,28 @@ interface RoomService { */ fun peekRoom(roomIdOrAlias: String, callback: MatrixCallback) - fun getPagedRoomSummariesLive( - queryParams: RoomSummaryQueryParams, - pagedListConfig: PagedList.Config = PagedList.Config.Builder() - .setPageSize(10) - .setInitialLoadSizeHint(20) - .setEnablePlaceholders(false) - .setPrefetchDistance(10) - .build() - ): LiveData> + /** + * TODO Doc + */ + fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config = defaultPagedListConfig): LiveData> + /** + * TODO Doc + */ + fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config = defaultPagedListConfig): UpdatableFilterLivePageResult + + /** + * TODO Doc + */ fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount - fun getFilteredPagedRoomSummariesLive( - queryParams: RoomSummaryQueryParams, - pagedListConfig: PagedList.Config = PagedList.Config.Builder() - .setPageSize(10) - .setInitialLoadSizeHint(20) - .setEnablePlaceholders(false) - .setPrefetchDistance(10) - .build() - ): UpdatableFilterLivePageResult + private val defaultPagedListConfig + get() = PagedList.Config.Builder() + .setPageSize(10) + .setInitialLoadSizeHint(20) + .setEnablePlaceholders(false) + .setPrefetchDistance(10) + .build() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt index e0862f229a..7e04ebb5f2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomSummaryQueryParams.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.api.session.room import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomTagQueryFilter import org.matrix.android.sdk.api.session.room.model.Membership @@ -24,13 +25,6 @@ fun roomSummaryQueryParams(init: (RoomSummaryQueryParams.Builder.() -> Unit) = { return RoomSummaryQueryParams.Builder().apply(init).build() } -enum class RoomCategoryFilter { - ONLY_DM, - ONLY_ROOMS, - ONLY_WITH_NOTIFICATIONS, - ALL -} - /** * This class can be used to filter room summaries to use with: * [org.matrix.android.sdk.api.session.room.Room] and [org.matrix.android.sdk.api.session.room.RoomService] diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomAggregateNotificationCount.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomAggregateNotificationCount.kt index 0c581508b8..066178b1ec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomAggregateNotificationCount.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomAggregateNotificationCount.kt @@ -20,7 +20,6 @@ data class RoomAggregateNotificationCount( val notificationCount: Int, val highlightCount: Int ) { - fun totalCount() = notificationCount + highlightCount - - fun isHighlight() = highlightCount > 0 + val totalCount = notificationCount + highlightCount + val isHighlight = highlightCount > 0 } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt index 770ef46080..244fe3432a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/SessionRealmConfigurationFactory.kt @@ -72,7 +72,6 @@ internal class SessionRealmConfigurationFactory @Inject constructor( .allowWritesOnUiThread(true) .modules(SessionRealmModule()) .schemaVersion(RealmSessionStoreMigration.SESSION_STORE_SCHEMA_VERSION) -// .deleteRealmIfMigrationNeeded() .migration(migration) .build() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt index 6007ae504a..669074ffd2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt @@ -106,7 +106,7 @@ internal open class RoomSummaryEntity( private var tags: RealmList = RealmList() - fun tags(): RealmList = tags + fun tags(): List = tags fun updateTags(newTags: List>) { val toDelete = mutableListOf() @@ -118,9 +118,9 @@ internal open class RoomSummaryEntity( existingTag.tagOrder = updatedTag.second } } - toDelete.onEach { it.deleteFromRealm() } + toDelete.forEach { it.deleteFromRealm() } newTags.forEach { newTag -> - if (tags.indexOfFirst { it.tagName == newTag.first } == -1) { + if (tags.all { it.tagName != newTag.first }) { // we must add it tags.add( RoomTagEntity(newTag.first, newTag.second) @@ -128,9 +128,9 @@ internal open class RoomSummaryEntity( } } - isFavourite = newTags.indexOfFirst { it.first == RoomTag.ROOM_TAG_FAVOURITE } != -1 - isLowPriority = newTags.indexOfFirst { it.first == RoomTag.ROOM_TAG_LOW_PRIORITY } != -1 - isServerNotice = newTags.indexOfFirst { it.first == RoomTag.ROOM_TAG_SERVER_NOTICE } != -1 + isFavourite = newTags.any { it.first == RoomTag.ROOM_TAG_FAVOURITE } + isLowPriority = newTags.any { it.first == RoomTag.ROOM_TAG_LOW_PRIORITY } + isServerNotice = newTags.any { it.first == RoomTag.ROOM_TAG_SERVER_NOTICE } } @Index @@ -170,18 +170,15 @@ internal open class RoomSummaryEntity( fun updateAliases(newAliases: List) { // only update underlying field if there is a diff - if (newAliases.toSet() != aliases.toSet()) { - Timber.w("VAL: aliases updated") + if (newAliases.distinct().sorted() != aliases.distinct().sorted()) { aliases.clear() aliases.addAll(newAliases) + flatAliases = newAliases.joinToString(separator = "|", prefix = "|") } } // this is required for querying var flatAliases: String = "" - set(value) { - if (value != field) field = value - } var isEncrypted: Boolean = false set(value) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 02ecce6afa..dd3fbe04b2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -24,7 +24,7 @@ import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.RealmQuery import io.realm.Sort -import org.matrix.android.sdk.api.session.room.RoomCategoryFilter +import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableFilterLivePageResult import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -104,7 +104,8 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat .sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX) } - fun getSortedPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config): LiveData> { + fun getSortedPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config): LiveData> { val realmDataSourceFactory = monarchy.createDataSourceFactory { realm -> roomSummariesQuery(realm, queryParams) .sort(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Sort.DESCENDING) @@ -112,12 +113,14 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat val dataSourceFactory = realmDataSourceFactory.map { roomSummaryMapper.map(it) } - return monarchy.findAllPagedWithChanges(realmDataSourceFactory, + return monarchy.findAllPagedWithChanges( + realmDataSourceFactory, LivePagedListBuilder(dataSourceFactory, pagedListConfig) ) } - fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, pagedListConfig: PagedList.Config): UpdatableFilterLivePageResult { + fun getFilteredPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, + pagedListConfig: PagedList.Config): UpdatableFilterLivePageResult { val realmDataSourceFactory = monarchy.createDataSourceFactory { realm -> roomSummariesQuery(realm, queryParams) .sort(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Sort.DESCENDING) @@ -126,13 +129,13 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat roomSummaryMapper.map(it) } - val mapped = monarchy.findAllPagedWithChanges(realmDataSourceFactory, + val mapped = monarchy.findAllPagedWithChanges( + realmDataSourceFactory, LivePagedListBuilder(dataSourceFactory, pagedListConfig) ) return object : UpdatableFilterLivePageResult { - override val livePagedList: LiveData> - get() = mapped + override val livePagedList: LiveData> = mapped override fun updateQuery(queryParams: RoomSummaryQueryParams) { realmDataSourceFactory.updateQuery { @@ -167,10 +170,10 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat queryParams.roomCategoryFilter?.let { when (it) { - RoomCategoryFilter.ONLY_DM -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, true) - RoomCategoryFilter.ONLY_ROOMS -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, false) + RoomCategoryFilter.ONLY_DM -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, true) + RoomCategoryFilter.ONLY_ROOMS -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, false) RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS -> query.greaterThan(RoomSummaryEntityFields.NOTIFICATION_COUNT, 0) - RoomCategoryFilter.ALL -> { + RoomCategoryFilter.ALL -> { // nop } } @@ -182,8 +185,8 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat it.isLowPriority?.let { lp -> query.equalTo(RoomSummaryEntityFields.IS_LOW_PRIORITY, lp) } - it.isServerNotice?.let { lp -> - query.equalTo(RoomSummaryEntityFields.IS_SERVER_NOTICE, lp) + it.isServerNotice?.let { sn -> + query.equalTo(RoomSummaryEntityFields.IS_SERVER_NOTICE, sn) } } return query diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 69e1332dab..f254c44fda 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -117,10 +117,7 @@ internal class RoomSummaryUpdater @Inject constructor( val roomAliases = ContentMapper.map(lastAliasesEvent?.content).toModel()?.aliases .orEmpty() -// roomSummaryEntity.aliases.clear() -// roomSummaryEntity.aliases.addAll(roomAliases) roomSummaryEntity.updateAliases(roomAliases) - roomSummaryEntity.flatAliases = roomAliases.joinToString(separator = "|", prefix = "|") roomSummaryEntity.isEncrypted = encryptionEvent != null roomSummaryEntity.encryptionEventTs = encryptionEvent?.originServerTs diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index 81d1fdb636..b3b18d4adc 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -19,8 +19,6 @@ package im.vector.app import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent -import im.vector.app.features.grouplist.SelectedGroupDataSource -import im.vector.app.features.home.room.list.ChronologicalRoomComparator import io.reactivex.disposables.CompositeDisposable import javax.inject.Inject import javax.inject.Singleton @@ -29,11 +27,10 @@ import javax.inject.Singleton * This class handles the global app state. * It requires to be added to ProcessLifecycleOwner.get().lifecycle */ +// TODO Keep this class for now, will maybe be used fro Space @Singleton class AppStateHandler @Inject constructor( - private val sessionDataSource: ActiveSessionDataSource, - private val selectedGroupDataSource: SelectedGroupDataSource, - private val chronologicalRoomComparator: ChronologicalRoomComparator) : LifecycleObserver { +) : LifecycleObserver { private val compositeDisposable = CompositeDisposable() diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index e3a3b7b29c..258517aa39 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -127,6 +127,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScre Timber.i("onResume Fragment ${javaClass.simpleName}") } + @CallSuper override fun onPause() { super.onPause() Timber.i("onPause Fragment ${javaClass.simpleName}") @@ -154,6 +155,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScre super.onDestroyView() } + @CallSuper override fun onDestroy() { Timber.i("onDestroy Fragment ${javaClass.simpleName}") uiDisposables.dispose() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 8a73b2e0f9..c87b19f0e6 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -31,8 +31,8 @@ import im.vector.app.features.grouplist.SelectedGroupDataSource import im.vector.app.features.ui.UiStateRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.RoomCategoryFilter import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.internal.util.awaitCallback @@ -82,7 +82,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho override fun handle(action: HomeDetailAction) { when (action) { is HomeDetailAction.SwitchDisplayMode -> handleSwitchDisplayMode(action) - HomeDetailAction.MarkAllRoomsRead -> handleMarkAllRoomsRead() + HomeDetailAction.MarkAllRoomsRead -> handleMarkAllRoomsRead() } } @@ -103,12 +103,11 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho viewModelScope.launch(Dispatchers.Default) { val roomIds = session.getRoomSummaries( roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS + memberships = listOf(Membership.JOIN) + roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS } - ).map { - it.roomId - } + ) + .map { it.roomId } try { awaitCallback { session.markAllAsRead(roomIds, it) @@ -146,7 +145,8 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho roomSummaryQueryParams { memberships = Membership.activeMemberships() } - ).asObservable() + ) + .asObservable() .throttleFirst(300, TimeUnit.MILLISECONDS) .subscribe { val dmInvites = session.getRoomSummaries( @@ -179,13 +179,13 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho setState { copy( - notificationCountCatchup = dmRooms.totalCount() + otherRooms.totalCount() + roomsInvite + dmInvites, - notificationHighlightCatchup = dmRooms.isHighlight() || otherRooms.isHighlight(), - notificationCountPeople = dmRooms.totalCount() + dmInvites, - notificationHighlightPeople = dmRooms.isHighlight() || dmInvites > 0, - notificationCountRooms = otherRooms.totalCount() + roomsInvite, - notificationHighlightRooms = otherRooms.isHighlight() || roomsInvite > 0, - hasUnreadMessages = dmRooms.totalCount() + otherRooms.totalCount() > 0 + notificationCountCatchup = dmRooms.totalCount + otherRooms.totalCount + roomsInvite + dmInvites, + notificationHighlightCatchup = dmRooms.isHighlight || otherRooms.isHighlight, + notificationCountPeople = dmRooms.totalCount + dmInvites, + notificationHighlightPeople = dmRooms.isHighlight || dmInvites > 0, + notificationCountRooms = otherRooms.totalCount + roomsInvite, + notificationHighlightRooms = otherRooms.isHighlight || roomsInvite > 0, + hasUnreadMessages = dmRooms.totalCount + otherRooms.totalCount > 0 ) } } diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 99cc56bd99..00ec8b43f9 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -40,13 +40,17 @@ class ShortcutsHandler @Inject constructor( fun observeRoomsAndBuildShortcuts(): Disposable { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) { // No op - return Observable.empty().subscribe() + return Disposables.empty() } - return activeSessionHolder.getSafeActiveSession()?.getPagedRoomSummariesLive(roomSummaryQueryParams { - this.memberships = listOf(Membership.JOIN) - this.roomTagQueryFilter = RoomTagQueryFilter(isFavorite = true, null, null) - })?.asObservable() + return activeSessionHolder.getSafeActiveSession() + ?.getPagedRoomSummariesLive( + roomSummaryQueryParams { + memberships = listOf(Membership.JOIN) + roomTagQueryFilter = RoomTagQueryFilter(isFavorite = true, null, null) + } + ) + ?.asObservable() ?.subscribe { rooms -> val shortcuts = rooms .take(n = 4) // Android only allows us to create 4 shortcuts @@ -55,7 +59,6 @@ class ShortcutsHandler @Inject constructor( ShortcutManagerCompat.removeAllDynamicShortcuts(context) ShortcutManagerCompat.addDynamicShortcuts(context, shortcuts) } - ?: Disposables.empty() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListAction.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListAction.kt index a5c071680d..883efb2e60 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListAction.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.room.notification.RoomNotificationStat sealed class RoomListAction : VectorViewModelAction { data class SelectRoom(val roomSummary: RoomSummary) : RoomListAction() - data class ToggleSection(val section: RoomListViewModel.RoomsSection) : RoomListAction() + data class ToggleSection(val section: RoomsSection) : RoomListAction() data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListAction() data class RejectInvitation(val roomSummary: RoomSummary) : RoomListAction() data class FilterWith(val filter: String) : RoomListAction() diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index 8323c3b155..8e837e85c6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -95,7 +95,7 @@ class RoomListFragment @Inject constructor( ) private val adapterInfosList = mutableListOf() - private var concatAdapter: ConcatAdapter? = null + private val concatAdapter = ConcatAdapter() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -104,10 +104,10 @@ class RoomListFragment @Inject constructor( sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) roomListViewModel.observeViewEvents { when (it) { - is RoomListViewEvents.Loading -> showLoading(it.message) - is RoomListViewEvents.Failure -> showFailure(it.throwable) + is RoomListViewEvents.Loading -> showLoading(it.message) + is RoomListViewEvents.Failure -> showFailure(it.throwable) is RoomListViewEvents.SelectRoom -> handleSelectRoom(it) - is RoomListViewEvents.Done -> Unit + is RoomListViewEvents.Done -> Unit }.exhaustive } @@ -134,10 +134,10 @@ class RoomListFragment @Inject constructor( val isRoomSectionExpanded = roomsSection.isExpanded.value.orTrue() if (actualBlock.section.isExpanded && !isRoomSectionExpanded) { // we have to remove the content adapter - concatAdapter?.removeAdapter(actualBlock.contentAdapter.adapter) + concatAdapter.removeAdapter(actualBlock.contentAdapter.adapter) } else if (!actualBlock.section.isExpanded && isRoomSectionExpanded) { // we must add it back! - concatAdapter?.addAdapter(contentInsertIndex, actualBlock.contentAdapter.adapter) + concatAdapter.addAdapter(contentInsertIndex, actualBlock.contentAdapter.adapter) } contentInsertIndex = if (isRoomSectionExpanded) { contentInsertIndex + 2 @@ -148,7 +148,7 @@ class RoomListFragment @Inject constructor( isExpanded = isRoomSectionExpanded ) actualBlock.headerHeaderAdapter.updateSection( - actualBlock.headerHeaderAdapter.section.copy(isExpanded = isRoomSectionExpanded) + actualBlock.headerHeaderAdapter.roomsSectionData.copy(isExpanded = isRoomSectionExpanded) ) } } @@ -160,16 +160,10 @@ class RoomListFragment @Inject constructor( override fun onDestroyView() { adapterInfosList.onEach { it.contentAdapter.removeModelBuildListener(modelBuildListener) } adapterInfosList.clear() -// roomController.removeModelBuildListener(modelBuildListener) modelBuildListener = null views.roomListView.cleanup() -// controllers.onEach { -// it.listener = null -// // concatAdapter.removeAdapter(it.adapter) -// } -// controllers.clear() -// roomController.listener = null -// favRoomController.listener = null + footerController.listener = null + // TODO Cleanup listener on the ConcatAdapter's adapters? stateRestorer.clear() views.createChatFabMenu.listener = null super.onDestroyView() @@ -182,8 +176,8 @@ class RoomListFragment @Inject constructor( private fun setupCreateRoomButton() { when (roomListParams.displayMode) { RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.isVisible = true - RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.isVisible = true - RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.isVisible = true + RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.isVisible = true + RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.isVisible = true else -> Unit // No button in this mode } @@ -238,40 +232,35 @@ class RoomListFragment @Inject constructor( stateRestorer = LayoutManagerStateRestorer(layoutManager).register() views.roomListView.layoutManager = layoutManager views.roomListView.itemAnimator = RoomListAnimator() -// views.roomListView.setRecycledViewPool(sharedViewPool) layoutManager.recycleChildrenOnDetach = true modelBuildListener = OnModelBuildFinishedListener { it.dispatchTo(stateRestorer) } - val concatAdapter = ConcatAdapter() -// val hasOnlyOneSection = roomListViewModel.sections.size == 1 roomListViewModel.sections.forEach { section -> - val sectionAdapter = SectionHeaderAdapter { roomListViewModel.handle(RoomListAction.ToggleSection(section)) }.also { - it.updateSection(SectionHeaderAdapter.SectionViewModel( - section.sectionName - )) + it.updateSection(SectionHeaderAdapter.RoomsSectionData(section.sectionName)) } - val contentAdapter = pagedControllerFactory.createRoomSummaryPagedController().also { - section.livePages.observe(viewLifecycleOwner) { pl -> - it.submitList(pl) - sectionAdapter.updateSection(sectionAdapter.section.copy(isHidden = pl.isEmpty())) - checkEmptyState() - } - section.notificationCount.observe(viewLifecycleOwner) { counts -> - sectionAdapter.updateSection(sectionAdapter.section.copy( - notificationCount = counts.totalCount(), - isHighlighted = counts.isHighlight() - )) - } - section.isExpanded.observe(viewLifecycleOwner) { _ -> - refreshCollapseStates() - } - it.listener = this - } + val contentAdapter = pagedControllerFactory.createRoomSummaryPagedController() + .also { controller -> + section.livePages.observe(viewLifecycleOwner) { pl -> + controller.submitList(pl) + sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(isHidden = pl.isEmpty())) + checkEmptyState() + } + section.notificationCount.observe(viewLifecycleOwner) { counts -> + sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( + notificationCount = counts.totalCount, + isHighlighted = counts.isHighlight + )) + } + section.isExpanded.observe(viewLifecycleOwner) { _ -> + refreshCollapseStates() + } + controller.listener = this + } adapterInfosList.add( SectionAdapterInfo( SectionKey( @@ -288,10 +277,9 @@ class RoomListFragment @Inject constructor( } // Add the footer controller - this.footerController.listener = this + footerController.listener = this concatAdapter.addAdapter(footerController.adapter) - this.concatAdapter = concatAdapter views.roomListView.adapter = concatAdapter } @@ -299,8 +287,8 @@ class RoomListFragment @Inject constructor( if (isAdded) { when (roomListParams.displayMode) { RoomListDisplayMode.NOTIFICATIONS -> views.createChatFabMenu.show() - RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.show() - RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.show() + RoomListDisplayMode.PEOPLE -> views.createChatRoomButton.show() + RoomListDisplayMode.ROOMS -> views.createGroupRoomButton.show() else -> Unit } } @@ -308,28 +296,28 @@ class RoomListFragment @Inject constructor( private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) { when (quickAction) { - is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> { + is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> { roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY)) } - is RoomListQuickActionsSharedAction.NotificationsAll -> { + is RoomListQuickActionsSharedAction.NotificationsAll -> { roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES)) } is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> { roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY)) } - is RoomListQuickActionsSharedAction.NotificationsMute -> { + is RoomListQuickActionsSharedAction.NotificationsMute -> { roomListViewModel.handle(RoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE)) } - is RoomListQuickActionsSharedAction.Settings -> { + is RoomListQuickActionsSharedAction.Settings -> { navigator.openRoomProfile(requireActivity(), quickAction.roomId) } - is RoomListQuickActionsSharedAction.Favorite -> { + is RoomListQuickActionsSharedAction.Favorite -> { roomListViewModel.handle(RoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_FAVOURITE)) } - is RoomListQuickActionsSharedAction.LowPriority -> { + is RoomListQuickActionsSharedAction.LowPriority -> { roomListViewModel.handle(RoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY)) } - is RoomListQuickActionsSharedAction.Leave -> { + is RoomListQuickActionsSharedAction.Leave -> { promptLeaveRoom(quickAction.roomId) } }.exhaustive @@ -364,7 +352,7 @@ class RoomListFragment @Inject constructor( } private fun checkEmptyState() { - val hasNoRoom = adapterInfosList.all { it.headerHeaderAdapter.section.isHidden } + val hasNoRoom = adapterInfosList.all { it.headerHeaderAdapter.roomsSectionData.isHidden } if (hasNoRoom) { val emptyState = when (roomListParams.displayMode) { RoomListDisplayMode.NOTIFICATIONS -> { @@ -373,14 +361,14 @@ class RoomListFragment @Inject constructor( image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_noun_party_popper), message = getString(R.string.room_list_catchup_empty_body)) } - RoomListDisplayMode.PEOPLE -> + RoomListDisplayMode.PEOPLE -> StateView.State.Empty( title = getString(R.string.room_list_people_empty_title), image = ContextCompat.getDrawable(requireContext(), R.drawable.empty_state_dm), isBigImage = true, message = getString(R.string.room_list_people_empty_body) ) - RoomListDisplayMode.ROOMS -> + RoomListDisplayMode.ROOMS -> StateView.State.Empty( title = getString(R.string.room_list_rooms_empty_title), image = ContextCompat.getDrawable(requireContext(), R.drawable.empty_state_room), diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt index 2a214e6e90..423a950591 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListViewModel.kt @@ -17,10 +17,7 @@ package im.vector.app.features.home.room.list import androidx.annotation.StringRes -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope -import androidx.paging.PagedList import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext @@ -34,27 +31,26 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomTagQueryFilter import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.room.RoomCategoryFilter import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableFilterLivePageResult import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.session.room.state.isPublic -import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.rx.asObservable import org.matrix.android.sdk.rx.rx import timber.log.Timber import javax.inject.Inject -class RoomListViewModel @Inject constructor(initialState: RoomListViewState, - private val session: Session, - private val stringProvider: StringProvider) - : VectorViewModel(initialState) { +class RoomListViewModel @Inject constructor( + initialState: RoomListViewState, + private val session: Session, + private val stringProvider: StringProvider +) : VectorViewModel(initialState) { interface Factory { fun create(initialState: RoomListViewState): RoomListViewModel @@ -84,19 +80,9 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } } - data class RoomsSection( - val sectionName: String, - val livePages: LiveData>, - val isExpanded: MutableLiveData = MutableLiveData(true), - val notificationCount: MutableLiveData = - MutableLiveData(RoomAggregateNotificationCount(0, 0)), - val notifyOfLocalEcho: Boolean = false - ) - val sections: List by lazy { val sections = mutableListOf() if (initialState.displayMode == RoomListDisplayMode.PEOPLE) { - addSection(sections, R.string.invitations_header, true) { it.memberships = listOf(Membership.INVITE) it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM @@ -113,7 +99,6 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, it.roomCategoryFilter = RoomCategoryFilter.ONLY_DM } } else if (initialState.displayMode == RoomListDisplayMode.ROOMS) { - addSection(sections, R.string.invitations_header, true) { it.memberships = listOf(Membership.INVITE) it.roomCategoryFilter = RoomCategoryFilter.ONLY_ROOMS @@ -143,18 +128,20 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, it.roomTagQueryFilter = RoomTagQueryFilter(null, null, true) } } else if (initialState.displayMode == RoomListDisplayMode.FILTERED) { - withQueryParams({ - it.memberships = Membership.activeMemberships() - }) { qpm -> - val name = stringProvider.getString(R.string.bottom_action_rooms) - session.getFilteredPagedRoomSummariesLive(qpm) - .let { livePagedList -> - updatableQuery = livePagedList - sections.add(RoomsSection(name, livePagedList.livePagedList)) - } - } + withQueryParams( + { + it.memberships = Membership.activeMemberships() + }, + { qpm -> + val name = stringProvider.getString(R.string.bottom_action_rooms) + session.getFilteredPagedRoomSummariesLive(qpm) + .let { updatableFilterLivePageResult -> + updatableQuery = updatableFilterLivePageResult + sections.add(RoomsSection(name, updatableFilterLivePageResult.livePagedList)) + } + } + ) } else if (initialState.displayMode == RoomListDisplayMode.NOTIFICATIONS) { - addSection(sections, R.string.invitations_header, true) { it.memberships = listOf(Membership.INVITE) it.roomCategoryFilter = RoomCategoryFilter.ALL @@ -171,14 +158,14 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, override fun handle(action: RoomListAction) { when (action) { - is RoomListAction.SelectRoom -> handleSelectRoom(action) - is RoomListAction.AcceptInvitation -> handleAcceptInvitation(action) - is RoomListAction.RejectInvitation -> handleRejectInvitation(action) - is RoomListAction.FilterWith -> handleFilter(action) - is RoomListAction.LeaveRoom -> handleLeaveRoom(action) + is RoomListAction.SelectRoom -> handleSelectRoom(action) + is RoomListAction.AcceptInvitation -> handleAcceptInvitation(action) + is RoomListAction.RejectInvitation -> handleRejectInvitation(action) + is RoomListAction.FilterWith -> handleFilter(action) + is RoomListAction.LeaveRoom -> handleLeaveRoom(action) is RoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action) - is RoomListAction.ToggleTag -> handleToggleTag(action) - is RoomListAction.ToggleSection -> handleToggleSection(action.section) + is RoomListAction.ToggleTag -> handleToggleTag(action) + is RoomListAction.ToggleSection -> handleToggleSection(action.section) }.exhaustive } @@ -186,40 +173,41 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, @StringRes nameRes: Int, notifyOfLocalEcho: Boolean = false, query: (RoomSummaryQueryParams.Builder) -> Unit) { - withQueryParams({ - query.invoke(it) - }) { roomQueryParams -> + withQueryParams( + { query.invoke(it) }, + { roomQueryParams -> - val name = stringProvider.getString(nameRes) - session.getPagedRoomSummariesLive(roomQueryParams) - .let { livePagedList -> + val name = stringProvider.getString(nameRes) + session.getPagedRoomSummariesLive(roomQueryParams) + .let { livePagedList -> - // use it also as a source to update count - livePagedList.asObservable() - .observeOn(Schedulers.computation()) - .subscribe { - sections.find { it.sectionName == name } - ?.notificationCount - ?.postValue(session.getNotificationCountForRooms(roomQueryParams)) - }.disposeOnClear() + // use it also as a source to update count + livePagedList.asObservable() + .observeOn(Schedulers.computation()) + .subscribe { + sections.find { it.sectionName == name } + ?.notificationCount + ?.postValue(session.getNotificationCountForRooms(roomQueryParams)) + } + .disposeOnClear() - sections.add( - RoomsSection( - sectionName = name, - livePages = livePagedList, - notifyOfLocalEcho = notifyOfLocalEcho + sections.add( + RoomsSection( + sectionName = name, + livePages = livePagedList, + notifyOfLocalEcho = notifyOfLocalEcho + ) ) - ) - } - } + } + } + ) } private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { - RoomSummaryQueryParams.Builder().apply { - builder.invoke(this) - }.build().let { - block(it) - } + RoomSummaryQueryParams.Builder() + .apply { builder.invoke(this) } + .build() + .let { block(it) } } fun isPublicRoom(roomId: String): Boolean { @@ -233,10 +221,13 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } private fun handleToggleSection(roomSection: RoomsSection) { + roomSection.isExpanded.postValue(!roomSection.isExpanded.value.orFalse()) + /* TODO Cleanup if it is working sections.find { it.sectionName == roomSection.sectionName } ?.let { section -> section.isExpanded.postValue(!section.isExpanded.value.orFalse()) } + */ } private fun handleFilter(action: RoomListAction.FilterWith) { @@ -247,8 +238,8 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } updatableQuery?.updateQuery( roomSummaryQueryParams { - this.memberships = Membership.activeMemberships() - this.displayName = QueryStringValue.Contains(action.filter, QueryStringValue.Case.INSENSITIVE) + memberships = Membership.activeMemberships() + displayName = QueryStringValue.Contains(action.filter, QueryStringValue.Case.INSENSITIVE) } ) } @@ -351,7 +342,7 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, private fun String.otherTag(): String? { return when (this) { - RoomTag.ROOM_TAG_FAVOURITE -> RoomTag.ROOM_TAG_LOW_PRIORITY + RoomTag.ROOM_TAG_FAVOURITE -> RoomTag.ROOM_TAG_LOW_PRIORITY RoomTag.ROOM_TAG_LOW_PRIORITY -> RoomTag.ROOM_TAG_FAVOURITE else -> null } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt index 38137e0033..20386d739a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryPagedController.kt @@ -23,16 +23,19 @@ import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject -class RoomSummaryPagedControllerFactory @Inject constructor(private val roomSummaryItemFactory: RoomSummaryItemFactory) { +class RoomSummaryPagedControllerFactory @Inject constructor( + private val roomSummaryItemFactory: RoomSummaryItemFactory +) { fun createRoomSummaryPagedController(): RoomSummaryPagedController { return RoomSummaryPagedController(roomSummaryItemFactory) } } -class RoomSummaryPagedController constructor(private val roomSummaryItemFactory: RoomSummaryItemFactory) - : PagedListEpoxyController( -// Important it must match the PageList builder notify Looper +class RoomSummaryPagedController( + private val roomSummaryItemFactory: RoomSummaryItemFactory +) : PagedListEpoxyController( + // Important it must match the PageList builder notify Looper modelBuildingHandler = createUIHandler() ) { @@ -46,28 +49,20 @@ class RoomSummaryPagedController constructor(private val roomSummaryItemFactory: } override fun buildItemModel(currentPosition: Int, item: RoomSummary?): EpoxyModel<*> { - val unwrappedItem = item // for place holder if enabled - ?: return roomSummaryItemFactory.createRoomItem( - RoomSummary( - roomId = "null_item_pos_$currentPosition", - name = "", - encryptionEventTs = null, - isEncrypted = false, - typingUsers = emptyList() - ), emptySet(), null, null) + item ?: return roomSummaryItemFactory.createRoomItem( + roomSummary = RoomSummary( + roomId = "null_item_pos_$currentPosition", + name = "", + encryptionEventTs = null, + isEncrypted = false, + typingUsers = emptyList() + ), + selectedRoomIds = emptySet(), + onClick = null, + onLongClick = null + ) -// GenericItem_().apply { id("null_item_pos_$currentPosition") } - - return roomSummaryItemFactory.create(unwrappedItem, roomChangeMembershipStates ?: emptyMap(), emptySet(), listener) + return roomSummaryItemFactory.create(item, roomChangeMembershipStates.orEmpty(), emptySet(), listener) } - -// override fun onModelBound(holder: EpoxyViewHolder, boundModel: EpoxyModel<*>, position: Int, previouslyBoundModel: EpoxyModel<*>?) { -// Timber.w("VAL: Will load around $position") -// super.onModelBound(holder, boundModel, position, previouslyBoundModel) -// } -// fun onRoomLongClicked() { -// userPreferencesProvider.neverShowLongClickOnRoomHelpAgain() -// requestModelBuild() -// } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomsSection.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomsSection.kt new file mode 100644 index 0000000000..71b7169814 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomsSection.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 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.home.room.list + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.paging.PagedList +import org.matrix.android.sdk.api.session.room.model.RoomSummary +import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount + +data class RoomsSection( + val sectionName: String, + val livePages: LiveData>, + val isExpanded: MutableLiveData = MutableLiveData(true), + val notificationCount: MutableLiveData = MutableLiveData(RoomAggregateNotificationCount(0, 0)), + val notifyOfLocalEcho: Boolean = false +) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/SectionHeaderAdapter.kt b/vector/src/main/java/im/vector/app/features/home/room/list/SectionHeaderAdapter.kt index b137947ef7..f9c5766821 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/SectionHeaderAdapter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/SectionHeaderAdapter.kt @@ -30,7 +30,7 @@ class SectionHeaderAdapter constructor( private val onClickAction: (() -> Unit) ) : RecyclerView.Adapter() { - data class SectionViewModel( + data class RoomsSectionData( val name: String, val isExpanded: Boolean = true, val notificationCount: Int = 0, @@ -38,12 +38,12 @@ class SectionHeaderAdapter constructor( val isHidden: Boolean = true ) - lateinit var section: SectionViewModel + lateinit var roomsSectionData: RoomsSectionData private set - fun updateSection(newSection: SectionViewModel) { - if (!::section.isInitialized || newSection != section) { - section = newSection + fun updateSection(newRoomsSectionData: RoomsSectionData) { + if (!::roomsSectionData.isInitialized || newRoomsSectionData != roomsSectionData) { + roomsSectionData = newRoomsSectionData notifyDataSetChanged() } } @@ -52,7 +52,7 @@ class SectionHeaderAdapter constructor( setHasStableIds(true) } - override fun getItemId(position: Int) = section.hashCode().toLong() + override fun getItemId(position: Int) = roomsSectionData.hashCode().toLong() override fun getItemViewType(position: Int) = R.layout.item_room_category @@ -61,10 +61,10 @@ class SectionHeaderAdapter constructor( } override fun onBindViewHolder(holder: VH, position: Int) { - holder.bind(section) + holder.bind(roomsSectionData) } - override fun getItemCount(): Int = if (section.isHidden) 0 else 1 + override fun getItemCount(): Int = if (roomsSectionData.isHidden) 0 else 1 class VH constructor( private val binding: ItemRoomCategoryBinding, @@ -77,14 +77,14 @@ class SectionHeaderAdapter constructor( })) } - fun bind(section: SectionViewModel) { - binding.roomCategoryTitleView.text = section.name + fun bind(roomsSectionData: RoomsSectionData) { + binding.roomCategoryTitleView.text = roomsSectionData.name val tintColor = ThemeUtils.getColor(binding.root.context, R.attr.riotx_text_secondary) - val expandedArrowDrawableRes = if (section.isExpanded) R.drawable.ic_expand_more_white else R.drawable.ic_expand_less_white + val expandedArrowDrawableRes = if (roomsSectionData.isExpanded) R.drawable.ic_expand_more_white else R.drawable.ic_expand_less_white val expandedArrowDrawable = ContextCompat.getDrawable(binding.root.context, expandedArrowDrawableRes)?.also { DrawableCompat.setTint(it, tintColor) } - binding.roomCategoryUnreadCounterBadgeView.render(UnreadCounterBadgeView.State(section.notificationCount, section.isHighlighted)) + binding.roomCategoryUnreadCounterBadgeView.render(UnreadCounterBadgeView.State(roomsSectionData.notificationCount, roomsSectionData.isHighlighted)) binding.roomCategoryTitleView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null) }