diff --git a/CHANGES.md b/CHANGES.md index e293a776dd..5f0a2945de 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +Changes in Element v1.4.7 (2022-03-24) +====================================== + +Bugfixes 🐛 +---------- + - Fix inconsistencies between the arrow visibility and the collapse action on the room sections ([#5616](https://github.com/vector-im/element-android/issues/5616)) + - Fix room list header count flickering + Changes in Element v1.4.6 (2022-03-23) ====================================== @@ -37,6 +45,7 @@ SDK API changes ⚠️ Other changes ------------- + - Refactoring for safer olm and megolm session usage ([#5380](https://github.com/vector-im/element-android/issues/5380)) - Improve headers UI in Rooms/Messages lists ([#4533](https://github.com/vector-im/element-android/issues/4533)) - Number of unread messages on space badge now include number of unread DMs ([#5260](https://github.com/vector-im/element-android/issues/5260)) - Amend spaces menu to be consistent with iOS version ([#5270](https://github.com/vector-im/element-android/issues/5270)) diff --git a/fastlane/metadata/android/en-US/changelogs/40104070.txt b/fastlane/metadata/android/en-US/changelogs/40104070.txt new file mode 100644 index 0000000000..99a3ecfe7b --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Main changes in this version: Various bug fixes and stability improvements. +Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.4.7 \ No newline at end of file diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 2b2c38e22a..a26a709afc 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -31,7 +31,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.4.6\"" + buildConfigField "String", "SDK_VERSION", "\"1.4.7\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" 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 f506b147df..aec358218b 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 @@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.room import androidx.lifecycle.LiveData import androidx.paging.PagedList -import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership @@ -218,9 +217,10 @@ interface RoomService { sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): UpdatableLivePageResult /** - * Retrieve a flow on the number of rooms. + * Return a LiveData on the number of rooms + * @param queryParams parameters to query the room summaries. It can be use to keep only joined rooms, for instance. */ - fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow + fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData /** * TODO Doc diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index 0d78489fbd..1bc98015aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -20,7 +20,6 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Transformations import androidx.paging.PagedList import com.zhuinden.monarchy.Monarchy -import kotlinx.coroutines.flow.Flow import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.RoomService @@ -110,8 +109,8 @@ internal class DefaultRoomService @Inject constructor( return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder) } - override fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow { - return roomSummaryDataSource.getCountFlow(queryParams) + override fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData { + return roomSummaryDataSource.getCountLive(queryParams) } override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount { 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 ea4f102fa5..1925fe8e9f 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 @@ -25,12 +25,7 @@ import androidx.paging.PagedList import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.RealmQuery -import io.realm.kotlin.toFlow import io.realm.kotlin.where -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.map import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter @@ -241,15 +236,14 @@ internal class RoomSummaryDataSource @Inject constructor( } } - fun getCountFlow(queryParams: RoomSummaryQueryParams): Flow = - realmSessionProvider - .withRealm { realm -> roomSummariesQuery(realm, queryParams).findAllAsync() } - .toFlow() - // need to create the flow on a context dispatcher with a thread with attached Looper - .flowOn(coroutineDispatchers.main) - .map { it.size } - .flowOn(coroutineDispatchers.io) - .distinctUntilChanged() + fun getCountLive(queryParams: RoomSummaryQueryParams): LiveData { + val liveRooms = monarchy.findAllManagedWithChanges { + roomSummariesQuery(it, queryParams) + } + return Transformations.map(liveRooms) { + it.realmResults.where().count().toInt() + } + } fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount { var notificationCount: RoomAggregateNotificationCount? = null diff --git a/vector/build.gradle b/vector/build.gradle index aeaad19e02..f58b7d444d 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -18,7 +18,7 @@ ext.versionMinor = 4 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 6 +ext.versionPatch = 7 static def getGitTimestamp() { def cmd = 'git show -s --format=%ct' 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 4265eebe62..67d7a732cc 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 @@ -53,6 +53,7 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA import im.vector.app.features.home.room.list.widget.NotifsFabMenuView import im.vector.app.features.notifications.NotificationDrawerManager import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -148,8 +149,10 @@ class RoomListFragment @Inject constructor( } private fun refreshCollapseStates() { + val sectionsCount = adapterInfosList.count { !it.sectionHeaderAdapter.roomsSectionData.isHidden } roomListViewModel.sections.forEachIndexed { index, roomsSection -> val actualBlock = adapterInfosList[index] + val isRoomSectionCollapsable = sectionsCount > 1 val isRoomSectionExpanded = roomsSection.isExpanded.value.orTrue() if (actualBlock.section.isExpanded && !isRoomSectionExpanded) { // mark controller as collapsed @@ -158,12 +161,18 @@ class RoomListFragment @Inject constructor( // we must expand! actualBlock.contentEpoxyController.setCollapsed(false) } - actualBlock.section = actualBlock.section.copy( - isExpanded = isRoomSectionExpanded - ) - actualBlock.sectionHeaderAdapter.updateSection( - actualBlock.sectionHeaderAdapter.roomsSectionData.copy(isExpanded = isRoomSectionExpanded) - ) + actualBlock.section = actualBlock.section.copy(isExpanded = isRoomSectionExpanded) + actualBlock.sectionHeaderAdapter.updateSection { + it.copy( + isExpanded = isRoomSectionExpanded, + isCollapsable = isRoomSectionCollapsable + ) + } + + if (!isRoomSectionExpanded && !isRoomSectionCollapsable) { + // force expand if the section is not collapsable + roomListViewModel.handle(RoomListAction.ToggleSection(roomsSection)) + } } } @@ -271,13 +280,12 @@ class RoomListFragment @Inject constructor( val concatAdapter = ConcatAdapter() - roomListViewModel.sections.forEach { section -> - val sectionAdapter = SectionHeaderAdapter { - roomListViewModel.handle(RoomListAction.ToggleSection(section)) - }.also { - it.updateSection(SectionHeaderAdapter.RoomsSectionData(section.sectionName)) + roomListViewModel.sections.forEachIndexed { index, section -> + val sectionAdapter = SectionHeaderAdapter(SectionHeaderAdapter.RoomsSectionData(section.sectionName)) { + if (adapterInfosList[index].sectionHeaderAdapter.roomsSectionData.isCollapsable) { + roomListViewModel.handle(RoomListAction.ToggleSection(section)) + } } - val contentAdapter = when { section.livePages != null -> { @@ -285,18 +293,23 @@ class RoomListFragment @Inject constructor( .also { controller -> section.livePages.observe(viewLifecycleOwner) { pl -> controller.submitList(pl) - sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( - isHidden = pl.isEmpty(), - isLoading = false - )) + sectionAdapter.updateSection { + it.copy( + isHidden = pl.isEmpty(), + isLoading = false + ) + } + refreshCollapseStates() checkEmptyState() } observeItemCount(section, sectionAdapter) section.notificationCount.observe(viewLifecycleOwner) { counts -> - sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( - notificationCount = counts.totalCount, - isHighlighted = counts.isHighlight - )) + sectionAdapter.updateSection { + it.copy( + notificationCount = counts.totalCount, + isHighlighted = counts.isHighlight, + ) + } } section.isExpanded.observe(viewLifecycleOwner) { _ -> refreshCollapseStates() @@ -309,10 +322,13 @@ class RoomListFragment @Inject constructor( .also { controller -> section.liveSuggested.observe(viewLifecycleOwner) { info -> controller.setData(info) - sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( - isHidden = info.rooms.isEmpty(), - isLoading = false - )) + sectionAdapter.updateSection { + it.copy( + isHidden = info.rooms.isEmpty(), + isLoading = false + ) + } + refreshCollapseStates() checkEmptyState() } observeItemCount(section, sectionAdapter) @@ -327,17 +343,23 @@ class RoomListFragment @Inject constructor( .also { controller -> section.liveList?.observe(viewLifecycleOwner) { list -> controller.setData(list) - sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( - isHidden = list.isEmpty(), - isLoading = false)) + sectionAdapter.updateSection { + it.copy( + isHidden = list.isEmpty(), + isLoading = false, + ) + } + refreshCollapseStates() checkEmptyState() } observeItemCount(section, sectionAdapter) section.notificationCount.observe(viewLifecycleOwner) { counts -> - sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( - notificationCount = counts.totalCount, - isHighlighted = counts.isHighlight - )) + sectionAdapter.updateSection { + it.copy( + notificationCount = counts.totalCount, + isHighlighted = counts.isHighlight + ) + } } section.isExpanded.observe(viewLifecycleOwner) { _ -> refreshCollapseStates() @@ -384,10 +406,11 @@ class RoomListFragment @Inject constructor( lifecycleScope.launch { section.itemCount .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED) + .filter { it > 0 } .collect { count -> - sectionAdapter.updateSection( - sectionAdapter.roomsSectionData.copy(itemCount = count) - ) + sectionAdapter.updateSection { + it.copy(itemCount = count) + } } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt index ec7915ba34..bd43a83f2c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderGroup.kt @@ -70,22 +70,20 @@ class RoomListSectionBuilderGroup( }, { qpm -> val name = stringProvider.getString(R.string.bottom_action_rooms) - session.getFilteredPagedRoomSummariesLive(qpm) - .let { updatableFilterLivePageResult -> - onUpdatable(updatableFilterLivePageResult) + val updatableFilterLivePageResult = session.getFilteredPagedRoomSummariesLive(qpm) + onUpdatable(updatableFilterLivePageResult) - val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.getRoomCountFlow(updatableFilterLivePageResult.queryParams) } - .distinctUntilChanged() + val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() + .flatMapLatest { session.getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() } + .distinctUntilChanged() - sections.add( - RoomsSection( - sectionName = name, - livePages = updatableFilterLivePageResult.livePagedList, - itemCount = itemCountFlow - ) - ) - } + sections.add( + RoomsSection( + sectionName = name, + livePages = updatableFilterLivePageResult.livePagedList, + itemCount = itemCountFlow + ) + ) } ) } @@ -252,37 +250,33 @@ class RoomListSectionBuilderGroup( @StringRes nameRes: Int, notifyOfLocalEcho: Boolean = false, query: (RoomSummaryQueryParams.Builder) -> Unit) { - withQueryParams( - { query.invoke(it) }, - { roomQueryParams -> - val name = stringProvider.getString(nameRes) - session.getFilteredPagedRoomSummariesLive(roomQueryParams) - .also { - activeSpaceUpdaters.add(it) - }.livePagedList - .let { livePagedList -> - // use it also as a source to update count - livePagedList.asFlow() - .onEach { - sections.find { it.sectionName == name } - ?.notificationCount - ?.postValue(session.getNotificationCountForRooms(roomQueryParams)) - } - .flowOn(Dispatchers.Default) - .launchIn(coroutineScope) + withQueryParams(query) { roomQueryParams -> + val name = stringProvider.getString(nameRes) + session.getFilteredPagedRoomSummariesLive(roomQueryParams) + .also { + activeSpaceUpdaters.add(it) + }.livePagedList + .let { livePagedList -> + // use it also as a source to update count + livePagedList.asFlow() + .onEach { + sections.find { it.sectionName == name } + ?.notificationCount + ?.postValue(session.getNotificationCountForRooms(roomQueryParams)) + } + .flowOn(Dispatchers.Default) + .launchIn(coroutineScope) - sections.add( - RoomsSection( - sectionName = name, - livePages = livePagedList, - notifyOfLocalEcho = notifyOfLocalEcho, - itemCount = session.getRoomCountFlow(roomQueryParams) - ) + sections.add( + RoomsSection( + sectionName = name, + livePages = livePagedList, + notifyOfLocalEcho = notifyOfLocalEcho, + itemCount = session.getRoomCountLive(roomQueryParams).asFlow() ) - } - } - - ) + ) + } + } } private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt index f82dbd43e1..d405bc5b6f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListSectionBuilderSpace.kt @@ -32,6 +32,7 @@ import im.vector.app.features.invite.showInvites import im.vector.app.space import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest @@ -40,6 +41,7 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.update import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter @@ -83,64 +85,10 @@ class RoomListSectionBuilderSpace( } RoomListDisplayMode.FILTERED -> { // Used when searching for rooms - withQueryParams( - { - it.memberships = Membership.activeMemberships() - }, - { qpm -> - val name = stringProvider.getString(R.string.bottom_action_rooms) - session.getFilteredPagedRoomSummariesLive(qpm) - .let { updatableFilterLivePageResult -> - onUpdatable(updatableFilterLivePageResult) - - val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.getRoomCountFlow(updatableFilterLivePageResult.queryParams) } - .distinctUntilChanged() - - sections.add( - RoomsSection( - sectionName = name, - livePages = updatableFilterLivePageResult.livePagedList, - itemCount = itemCountFlow - ) - ) - } - } - ) + buildFilteredSection(sections) } RoomListDisplayMode.NOTIFICATIONS -> { - if (autoAcceptInvites.showInvites()) { - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.invitations_header, - notifyOfLocalEcho = true, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - }, - countRoomAsNotif = true - ) { - it.memberships = listOf(Membership.INVITE) - it.roomCategoryFilter = RoomCategoryFilter.ALL - } - } - - addSection( - sections = sections, - activeSpaceUpdaters = activeSpaceAwareQueries, - nameRes = R.string.bottom_action_rooms, - notifyOfLocalEcho = false, - spaceFilterStrategy = if (onlyOrphansInHome) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL - } else { - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL - } - ) { - it.memberships = listOf(Membership.JOIN) - it.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS - } + buildNotificationsSection(sections, activeSpaceAwareQueries) } } @@ -332,6 +280,68 @@ class RoomListSectionBuilderSpace( } } + private fun buildNotificationsSection(sections: MutableList, + activeSpaceAwareQueries: MutableList) { + if (autoAcceptInvites.showInvites()) { + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.invitations_header, + notifyOfLocalEcho = true, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + }, + countRoomAsNotif = true + ) { + it.memberships = listOf(Membership.INVITE) + it.roomCategoryFilter = RoomCategoryFilter.ALL + } + } + + addSection( + sections = sections, + activeSpaceUpdaters = activeSpaceAwareQueries, + nameRes = R.string.bottom_action_rooms, + notifyOfLocalEcho = false, + spaceFilterStrategy = if (onlyOrphansInHome) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL + } else { + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL + } + ) { + it.memberships = listOf(Membership.JOIN) + it.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS + } + } + + private fun buildFilteredSection(sections: MutableList) { + // Used when searching for rooms + withQueryParams( + { + it.memberships = Membership.activeMemberships() + }, + { qpm -> + val name = stringProvider.getString(R.string.bottom_action_rooms) + val updatableFilterLivePageResult = session.getFilteredPagedRoomSummariesLive(qpm) + onUpdatable(updatableFilterLivePageResult) + + val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() + .flatMapLatest { session.getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() } + .distinctUntilChanged() + + sections.add( + RoomsSection( + sectionName = name, + livePages = updatableFilterLivePageResult.livePagedList, + itemCount = itemCountFlow + ) + ) + } + ) + } + private fun addSection(sections: MutableList, activeSpaceUpdaters: MutableList, @StringRes nameRes: Int, @@ -339,83 +349,82 @@ class RoomListSectionBuilderSpace( spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE, countRoomAsNotif: Boolean = false, query: (RoomSummaryQueryParams.Builder) -> Unit) { - withQueryParams( - { query.invoke(it) }, - { roomQueryParams -> - val name = stringProvider.getString(nameRes) - session.getFilteredPagedRoomSummariesLive( - roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()), - pagedListConfig - ).also { - when (spaceFilterStrategy) { - RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { - activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { - override fun updateForSpaceId(roomId: String?) { - it.queryParams = roomQueryParams.copy( - activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) - ) - } - }) - } - RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { - activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { - override fun updateForSpaceId(roomId: String?) { - if (roomId != null) { - it.queryParams = roomQueryParams.copy( - activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) - ) - } else { - it.queryParams = roomQueryParams.copy( - activeSpaceFilter = ActiveSpaceFilter.None - ) - } - } - }) - } - RoomListViewModel.SpaceFilterStrategy.NONE -> { - // we ignore current space for this one - } + withQueryParams(query) { roomQueryParams -> + val updatedQueryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) + val liveQueryParams = MutableStateFlow(updatedQueryParams) + val itemCountFlow = liveQueryParams + .flatMapLatest { + session.getRoomCountLive(it).asFlow() + } + .flowOn(Dispatchers.Main) + .distinctUntilChanged() + + val name = stringProvider.getString(nameRes) + val filteredPagedRoomSummariesLive = session.getFilteredPagedRoomSummariesLive( + roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()), + pagedListConfig + ) + when (spaceFilterStrategy) { + RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { + activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { + override fun updateForSpaceId(roomId: String?) { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) + ) + liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } } - }.livePagedList - .let { livePagedList -> - // use it also as a source to update count - livePagedList.asFlow() - .onEach { - Timber.v("Thread space list: ${Thread.currentThread()}") - sections.find { it.sectionName == name } - ?.notificationCount - ?.postValue( - if (countRoomAsNotif) { - RoomAggregateNotificationCount(it.size, it.size) - } else { - session.getNotificationCountForRooms( - roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) - ) - } - ) - } - .flowOn(Dispatchers.Default) - .launchIn(viewModelScope) - - val itemCountFlow = livePagedList.asFlow() - .flatMapLatest { - val queryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) - session.getRoomCountFlow(queryParams) - } - .distinctUntilChanged() - - sections.add( - RoomsSection( - sectionName = name, - livePages = livePagedList, - notifyOfLocalEcho = notifyOfLocalEcho, - itemCount = itemCountFlow - ) + }) + } + RoomListViewModel.SpaceFilterStrategy.ALL_IF_SPACE_NULL -> { + activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { + override fun updateForSpaceId(roomId: String?) { + if (roomId != null) { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) + ) + } else { + filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy( + activeSpaceFilter = ActiveSpaceFilter.None ) } + liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams } + } + }) } + RoomListViewModel.SpaceFilterStrategy.NONE -> { + // we ignore current space for this one + } + } - ) + val livePagedList = filteredPagedRoomSummariesLive.livePagedList + // use it also as a source to update count + livePagedList.asFlow() + .onEach { + Timber.v("Thread space list: ${Thread.currentThread()}") + sections.find { it.sectionName == name } + ?.notificationCount + ?.postValue( + if (countRoomAsNotif) { + RoomAggregateNotificationCount(it.size, it.size) + } else { + session.getNotificationCountForRooms( + roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()) + ) + } + ) + } + .flowOn(Dispatchers.Default) + .launchIn(viewModelScope) + + sections.add( + RoomsSection( + sectionName = name, + livePages = livePagedList, + notifyOfLocalEcho = notifyOfLocalEcho, + itemCount = itemCountFlow + ) + ) + } } private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { 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 2e6436d21d..3f1dfebf7b 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 @@ -16,6 +16,7 @@ package im.vector.app.features.home.room.list +import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.content.ContextCompat @@ -28,6 +29,7 @@ import im.vector.app.databinding.ItemRoomCategoryBinding import im.vector.app.features.themes.ThemeUtils class SectionHeaderAdapter constructor( + roomsSectionData: RoomsSectionData, private val onClickAction: ClickListener ) : RecyclerView.Adapter() { @@ -39,14 +41,16 @@ class SectionHeaderAdapter constructor( val isHighlighted: Boolean = false, val isHidden: Boolean = true, // This will be false until real data has been submitted once - val isLoading: Boolean = true + val isLoading: Boolean = true, + val isCollapsable: Boolean = false ) - lateinit var roomsSectionData: RoomsSectionData + var roomsSectionData: RoomsSectionData = roomsSectionData private set - fun updateSection(newRoomsSectionData: RoomsSectionData) { - if (!::roomsSectionData.isInitialized || newRoomsSectionData != roomsSectionData) { + fun updateSection(block: (RoomsSectionData) -> RoomsSectionData) { + val newRoomsSectionData = block(roomsSectionData) + if (roomsSectionData != newRoomsSectionData) { roomsSectionData = newRoomsSectionData notifyDataSetChanged() } @@ -82,11 +86,16 @@ class SectionHeaderAdapter constructor( fun bind(roomsSectionData: RoomsSectionData) { binding.roomCategoryTitleView.text = roomsSectionData.name val tintColor = ThemeUtils.getColor(binding.root.context, R.attr.vctr_content_secondary) - val expandedArrowDrawableRes = if (roomsSectionData.isExpanded) R.drawable.ic_expand_more else R.drawable.ic_expand_less - val expandedArrowDrawable = ContextCompat.getDrawable(binding.root.context, expandedArrowDrawableRes)?.also { - DrawableCompat.setTint(it, tintColor) + val collapsableArrowDrawable: Drawable? = if (roomsSectionData.isCollapsable) { + val expandedArrowDrawableRes = if (roomsSectionData.isExpanded) R.drawable.ic_expand_more else R.drawable.ic_expand_less + ContextCompat.getDrawable(binding.root.context, expandedArrowDrawableRes)?.also { + DrawableCompat.setTint(it, tintColor) + } + } else { + null } - binding.roomCategoryCounterView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null) + binding.root.isClickable = roomsSectionData.isCollapsable + binding.roomCategoryCounterView.setCompoundDrawablesWithIntrinsicBounds(null, null, collapsableArrowDrawable, null) binding.roomCategoryCounterView.text = roomsSectionData.itemCount.takeIf { it > 0 }?.toString().orEmpty() binding.roomCategoryUnreadCounterBadgeView.render(UnreadCounterBadgeView.State(roomsSectionData.notificationCount, roomsSectionData.isHighlighted)) } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index 6659058b4e..64fa3f0eee 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -578,7 +578,7 @@ class OnboardingViewModel @AssistedInject constructor( onDirectLoginError(failure) return } - onSessionCreated(data, isAccountCreated = true) + onSessionCreated(data, isAccountCreated = false) } private fun onDirectLoginError(failure: Throwable) { diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt index 7d99c53f23..318f701985 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomsViewModel.kt @@ -84,7 +84,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( val spaceCountFlow: Flow by lazy { spaceUpdatableLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.getRoomCountFlow(spaceUpdatableLivePageResult.queryParams) } + .flatMapLatest { session.getRoomCountLive(spaceUpdatableLivePageResult.queryParams).asFlow() } .distinctUntilChanged() } @@ -110,7 +110,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( val roomCountFlow: Flow by lazy { roomUpdatableLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.getRoomCountFlow(roomUpdatableLivePageResult.queryParams) } + .flatMapLatest { session.getRoomCountLive(roomUpdatableLivePageResult.queryParams).asFlow() } .distinctUntilChanged() } @@ -136,7 +136,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor( val dmCountFlow: Flow by lazy { dmUpdatableLivePageResult.livePagedList.asFlow() - .flatMapLatest { session.getRoomCountFlow(dmUpdatableLivePageResult.queryParams) } + .flatMapLatest { session.getRoomCountLive(dmUpdatableLivePageResult.queryParams).asFlow() } .distinctUntilChanged() }