Merge branch 'hotfix/1.4.7' into main

This commit is contained in:
ganfra 2022-03-24 19:33:44 +01:00
commit 9ec684f438
13 changed files with 278 additions and 239 deletions

View File

@ -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) Changes in Element v1.4.6 (2022-03-23)
====================================== ======================================
@ -37,6 +45,7 @@ SDK API changes ⚠️
Other 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)) - 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)) - 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)) - Amend spaces menu to be consistent with iOS version ([#5270](https://github.com/vector-im/element-android/issues/5270))

View File

@ -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

View File

@ -31,7 +31,7 @@ android {
// that the app's state is completely cleared between tests. // that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true' 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", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""

View File

@ -18,7 +18,6 @@ package org.matrix.android.sdk.api.session.room
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.paging.PagedList 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.events.model.Event
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState 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.Membership
@ -218,9 +217,10 @@ interface RoomService {
sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): UpdatableLivePageResult 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<Int> fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int>
/** /**
* TODO Doc * TODO Doc

View File

@ -20,7 +20,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations import androidx.lifecycle.Transformations
import androidx.paging.PagedList import androidx.paging.PagedList
import com.zhuinden.monarchy.Monarchy 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.events.model.Event
import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.RoomService import org.matrix.android.sdk.api.session.room.RoomService
@ -110,8 +109,8 @@ internal class DefaultRoomService @Inject constructor(
return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder) return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder)
} }
override fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> { override fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int> {
return roomSummaryDataSource.getCountFlow(queryParams) return roomSummaryDataSource.getCountLive(queryParams)
} }
override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount { override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {

View File

@ -25,12 +25,7 @@ import androidx.paging.PagedList
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
import io.realm.Realm import io.realm.Realm
import io.realm.RealmQuery import io.realm.RealmQuery
import io.realm.kotlin.toFlow
import io.realm.kotlin.where 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.MatrixCoroutineDispatchers
import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.ActiveSpaceFilter
import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter
@ -241,15 +236,14 @@ internal class RoomSummaryDataSource @Inject constructor(
} }
} }
fun getCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> = fun getCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int> {
realmSessionProvider val liveRooms = monarchy.findAllManagedWithChanges {
.withRealm { realm -> roomSummariesQuery(realm, queryParams).findAllAsync() } roomSummariesQuery(it, queryParams)
.toFlow() }
// need to create the flow on a context dispatcher with a thread with attached Looper return Transformations.map(liveRooms) {
.flowOn(coroutineDispatchers.main) it.realmResults.where().count().toInt()
.map { it.size } }
.flowOn(coroutineDispatchers.io) }
.distinctUntilChanged()
fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount { fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
var notificationCount: RoomAggregateNotificationCount? = null var notificationCount: RoomAggregateNotificationCount? = null

View File

@ -18,7 +18,7 @@ ext.versionMinor = 4
// Note: even values are reserved for regular release, odd values for hotfix release. // 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 // When creating a hotfix, you should decrease the value, since the current value
// is the value for the next regular release. // is the value for the next regular release.
ext.versionPatch = 6 ext.versionPatch = 7
static def getGitTimestamp() { static def getGitTimestamp() {
def cmd = 'git show -s --format=%ct' def cmd = 'git show -s --format=%ct'

View File

@ -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.home.room.list.widget.NotifsFabMenuView
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -148,8 +149,10 @@ class RoomListFragment @Inject constructor(
} }
private fun refreshCollapseStates() { private fun refreshCollapseStates() {
val sectionsCount = adapterInfosList.count { !it.sectionHeaderAdapter.roomsSectionData.isHidden }
roomListViewModel.sections.forEachIndexed { index, roomsSection -> roomListViewModel.sections.forEachIndexed { index, roomsSection ->
val actualBlock = adapterInfosList[index] val actualBlock = adapterInfosList[index]
val isRoomSectionCollapsable = sectionsCount > 1
val isRoomSectionExpanded = roomsSection.isExpanded.value.orTrue() val isRoomSectionExpanded = roomsSection.isExpanded.value.orTrue()
if (actualBlock.section.isExpanded && !isRoomSectionExpanded) { if (actualBlock.section.isExpanded && !isRoomSectionExpanded) {
// mark controller as collapsed // mark controller as collapsed
@ -158,13 +161,19 @@ class RoomListFragment @Inject constructor(
// we must expand! // we must expand!
actualBlock.contentEpoxyController.setCollapsed(false) actualBlock.contentEpoxyController.setCollapsed(false)
} }
actualBlock.section = actualBlock.section.copy( actualBlock.section = actualBlock.section.copy(isExpanded = isRoomSectionExpanded)
isExpanded = isRoomSectionExpanded actualBlock.sectionHeaderAdapter.updateSection {
) it.copy(
actualBlock.sectionHeaderAdapter.updateSection( isExpanded = isRoomSectionExpanded,
actualBlock.sectionHeaderAdapter.roomsSectionData.copy(isExpanded = isRoomSectionExpanded) isCollapsable = isRoomSectionCollapsable
) )
} }
if (!isRoomSectionExpanded && !isRoomSectionCollapsable) {
// force expand if the section is not collapsable
roomListViewModel.handle(RoomListAction.ToggleSection(roomsSection))
}
}
} }
override fun showFailure(throwable: Throwable) { override fun showFailure(throwable: Throwable) {
@ -271,13 +280,12 @@ class RoomListFragment @Inject constructor(
val concatAdapter = ConcatAdapter() val concatAdapter = ConcatAdapter()
roomListViewModel.sections.forEach { section -> roomListViewModel.sections.forEachIndexed { index, section ->
val sectionAdapter = SectionHeaderAdapter { val sectionAdapter = SectionHeaderAdapter(SectionHeaderAdapter.RoomsSectionData(section.sectionName)) {
if (adapterInfosList[index].sectionHeaderAdapter.roomsSectionData.isCollapsable) {
roomListViewModel.handle(RoomListAction.ToggleSection(section)) roomListViewModel.handle(RoomListAction.ToggleSection(section))
}.also {
it.updateSection(SectionHeaderAdapter.RoomsSectionData(section.sectionName))
} }
}
val contentAdapter = val contentAdapter =
when { when {
section.livePages != null -> { section.livePages != null -> {
@ -285,18 +293,23 @@ class RoomListFragment @Inject constructor(
.also { controller -> .also { controller ->
section.livePages.observe(viewLifecycleOwner) { pl -> section.livePages.observe(viewLifecycleOwner) { pl ->
controller.submitList(pl) controller.submitList(pl)
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( sectionAdapter.updateSection {
it.copy(
isHidden = pl.isEmpty(), isHidden = pl.isEmpty(),
isLoading = false isLoading = false
)) )
}
refreshCollapseStates()
checkEmptyState() checkEmptyState()
} }
observeItemCount(section, sectionAdapter) observeItemCount(section, sectionAdapter)
section.notificationCount.observe(viewLifecycleOwner) { counts -> section.notificationCount.observe(viewLifecycleOwner) { counts ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( sectionAdapter.updateSection {
it.copy(
notificationCount = counts.totalCount, notificationCount = counts.totalCount,
isHighlighted = counts.isHighlight isHighlighted = counts.isHighlight,
)) )
}
} }
section.isExpanded.observe(viewLifecycleOwner) { _ -> section.isExpanded.observe(viewLifecycleOwner) { _ ->
refreshCollapseStates() refreshCollapseStates()
@ -309,10 +322,13 @@ class RoomListFragment @Inject constructor(
.also { controller -> .also { controller ->
section.liveSuggested.observe(viewLifecycleOwner) { info -> section.liveSuggested.observe(viewLifecycleOwner) { info ->
controller.setData(info) controller.setData(info)
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( sectionAdapter.updateSection {
it.copy(
isHidden = info.rooms.isEmpty(), isHidden = info.rooms.isEmpty(),
isLoading = false isLoading = false
)) )
}
refreshCollapseStates()
checkEmptyState() checkEmptyState()
} }
observeItemCount(section, sectionAdapter) observeItemCount(section, sectionAdapter)
@ -327,17 +343,23 @@ class RoomListFragment @Inject constructor(
.also { controller -> .also { controller ->
section.liveList?.observe(viewLifecycleOwner) { list -> section.liveList?.observe(viewLifecycleOwner) { list ->
controller.setData(list) controller.setData(list)
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( sectionAdapter.updateSection {
it.copy(
isHidden = list.isEmpty(), isHidden = list.isEmpty(),
isLoading = false)) isLoading = false,
)
}
refreshCollapseStates()
checkEmptyState() checkEmptyState()
} }
observeItemCount(section, sectionAdapter) observeItemCount(section, sectionAdapter)
section.notificationCount.observe(viewLifecycleOwner) { counts -> section.notificationCount.observe(viewLifecycleOwner) { counts ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy( sectionAdapter.updateSection {
it.copy(
notificationCount = counts.totalCount, notificationCount = counts.totalCount,
isHighlighted = counts.isHighlight isHighlighted = counts.isHighlight
)) )
}
} }
section.isExpanded.observe(viewLifecycleOwner) { _ -> section.isExpanded.observe(viewLifecycleOwner) { _ ->
refreshCollapseStates() refreshCollapseStates()
@ -384,10 +406,11 @@ class RoomListFragment @Inject constructor(
lifecycleScope.launch { lifecycleScope.launch {
section.itemCount section.itemCount
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED) .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.filter { it > 0 }
.collect { count -> .collect { count ->
sectionAdapter.updateSection( sectionAdapter.updateSection {
sectionAdapter.roomsSectionData.copy(itemCount = count) it.copy(itemCount = count)
) }
} }
} }
} }

View File

@ -70,12 +70,11 @@ class RoomListSectionBuilderGroup(
}, },
{ qpm -> { qpm ->
val name = stringProvider.getString(R.string.bottom_action_rooms) val name = stringProvider.getString(R.string.bottom_action_rooms)
session.getFilteredPagedRoomSummariesLive(qpm) val updatableFilterLivePageResult = session.getFilteredPagedRoomSummariesLive(qpm)
.let { updatableFilterLivePageResult ->
onUpdatable(updatableFilterLivePageResult) onUpdatable(updatableFilterLivePageResult)
val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow() val itemCountFlow = updatableFilterLivePageResult.livePagedList.asFlow()
.flatMapLatest { session.getRoomCountFlow(updatableFilterLivePageResult.queryParams) } .flatMapLatest { session.getRoomCountLive(updatableFilterLivePageResult.queryParams).asFlow() }
.distinctUntilChanged() .distinctUntilChanged()
sections.add( sections.add(
@ -86,7 +85,6 @@ class RoomListSectionBuilderGroup(
) )
) )
} }
}
) )
} }
RoomListDisplayMode.NOTIFICATIONS -> { RoomListDisplayMode.NOTIFICATIONS -> {
@ -252,9 +250,7 @@ class RoomListSectionBuilderGroup(
@StringRes nameRes: Int, @StringRes nameRes: Int,
notifyOfLocalEcho: Boolean = false, notifyOfLocalEcho: Boolean = false,
query: (RoomSummaryQueryParams.Builder) -> Unit) { query: (RoomSummaryQueryParams.Builder) -> Unit) {
withQueryParams( withQueryParams(query) { roomQueryParams ->
{ query.invoke(it) },
{ roomQueryParams ->
val name = stringProvider.getString(nameRes) val name = stringProvider.getString(nameRes)
session.getFilteredPagedRoomSummariesLive(roomQueryParams) session.getFilteredPagedRoomSummariesLive(roomQueryParams)
.also { .also {
@ -276,13 +272,11 @@ class RoomListSectionBuilderGroup(
sectionName = name, sectionName = name,
livePages = livePagedList, livePages = livePagedList,
notifyOfLocalEcho = notifyOfLocalEcho, notifyOfLocalEcho = notifyOfLocalEcho,
itemCount = session.getRoomCountFlow(roomQueryParams) itemCount = session.getRoomCountLive(roomQueryParams).asFlow()
) )
) )
} }
} }
)
} }
private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) {

View File

@ -32,6 +32,7 @@ import im.vector.app.features.invite.showInvites
import im.vector.app.space import im.vector.app.space
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest
@ -40,6 +41,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.ActiveSpaceFilter
import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter
@ -83,64 +85,10 @@ class RoomListSectionBuilderSpace(
} }
RoomListDisplayMode.FILTERED -> { RoomListDisplayMode.FILTERED -> {
// Used when searching for rooms // Used when searching for rooms
withQueryParams( buildFilteredSection(sections)
{
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
)
)
}
}
)
} }
RoomListDisplayMode.NOTIFICATIONS -> { RoomListDisplayMode.NOTIFICATIONS -> {
if (autoAcceptInvites.showInvites()) { buildNotificationsSection(sections, activeSpaceAwareQueries)
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
}
} }
} }
@ -332,6 +280,68 @@ class RoomListSectionBuilderSpace(
} }
} }
private fun buildNotificationsSection(sections: MutableList<RoomsSection>,
activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
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<RoomsSection>) {
// 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<RoomsSection>, private fun addSection(sections: MutableList<RoomsSection>,
activeSpaceUpdaters: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>, activeSpaceUpdaters: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>,
@StringRes nameRes: Int, @StringRes nameRes: Int,
@ -339,21 +349,29 @@ class RoomListSectionBuilderSpace(
spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE, spaceFilterStrategy: RoomListViewModel.SpaceFilterStrategy = RoomListViewModel.SpaceFilterStrategy.NONE,
countRoomAsNotif: Boolean = false, countRoomAsNotif: Boolean = false,
query: (RoomSummaryQueryParams.Builder) -> Unit) { query: (RoomSummaryQueryParams.Builder) -> Unit) {
withQueryParams( withQueryParams(query) { roomQueryParams ->
{ query.invoke(it) }, val updatedQueryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId())
{ roomQueryParams -> val liveQueryParams = MutableStateFlow(updatedQueryParams)
val itemCountFlow = liveQueryParams
.flatMapLatest {
session.getRoomCountLive(it).asFlow()
}
.flowOn(Dispatchers.Main)
.distinctUntilChanged()
val name = stringProvider.getString(nameRes) val name = stringProvider.getString(nameRes)
session.getFilteredPagedRoomSummariesLive( val filteredPagedRoomSummariesLive = session.getFilteredPagedRoomSummariesLive(
roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()), roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId()),
pagedListConfig pagedListConfig
).also { )
when (spaceFilterStrategy) { when (spaceFilterStrategy) {
RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> { RoomListViewModel.SpaceFilterStrategy.ORPHANS_IF_SPACE_NULL -> {
activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater {
override fun updateForSpaceId(roomId: String?) { override fun updateForSpaceId(roomId: String?) {
it.queryParams = roomQueryParams.copy( filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy(
activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId)
) )
liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams }
} }
}) })
} }
@ -361,14 +379,15 @@ class RoomListSectionBuilderSpace(
activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater { activeSpaceUpdaters.add(object : RoomListViewModel.ActiveSpaceQueryUpdater {
override fun updateForSpaceId(roomId: String?) { override fun updateForSpaceId(roomId: String?) {
if (roomId != null) { if (roomId != null) {
it.queryParams = roomQueryParams.copy( filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy(
activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId) activeSpaceFilter = ActiveSpaceFilter.ActiveSpace(roomId)
) )
} else { } else {
it.queryParams = roomQueryParams.copy( filteredPagedRoomSummariesLive.queryParams = roomQueryParams.copy(
activeSpaceFilter = ActiveSpaceFilter.None activeSpaceFilter = ActiveSpaceFilter.None
) )
} }
liveQueryParams.update { filteredPagedRoomSummariesLive.queryParams }
} }
}) })
} }
@ -376,8 +395,8 @@ class RoomListSectionBuilderSpace(
// we ignore current space for this one // we ignore current space for this one
} }
} }
}.livePagedList
.let { livePagedList -> val livePagedList = filteredPagedRoomSummariesLive.livePagedList
// use it also as a source to update count // use it also as a source to update count
livePagedList.asFlow() livePagedList.asFlow()
.onEach { .onEach {
@ -397,13 +416,6 @@ class RoomListSectionBuilderSpace(
.flowOn(Dispatchers.Default) .flowOn(Dispatchers.Default)
.launchIn(viewModelScope) .launchIn(viewModelScope)
val itemCountFlow = livePagedList.asFlow()
.flatMapLatest {
val queryParams = roomQueryParams.process(spaceFilterStrategy, appStateHandler.safeActiveSpaceId())
session.getRoomCountFlow(queryParams)
}
.distinctUntilChanged()
sections.add( sections.add(
RoomsSection( RoomsSection(
sectionName = name, sectionName = name,
@ -415,9 +427,6 @@ class RoomListSectionBuilderSpace(
} }
} }
)
}
private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) { private fun withQueryParams(builder: (RoomSummaryQueryParams.Builder) -> Unit, block: (RoomSummaryQueryParams) -> Unit) {
RoomSummaryQueryParams.Builder() RoomSummaryQueryParams.Builder()
.apply { builder.invoke(this) } .apply { builder.invoke(this) }

View File

@ -16,6 +16,7 @@
package im.vector.app.features.home.room.list package im.vector.app.features.home.room.list
import android.graphics.drawable.Drawable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -28,6 +29,7 @@ import im.vector.app.databinding.ItemRoomCategoryBinding
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
class SectionHeaderAdapter constructor( class SectionHeaderAdapter constructor(
roomsSectionData: RoomsSectionData,
private val onClickAction: ClickListener private val onClickAction: ClickListener
) : RecyclerView.Adapter<SectionHeaderAdapter.VH>() { ) : RecyclerView.Adapter<SectionHeaderAdapter.VH>() {
@ -39,14 +41,16 @@ class SectionHeaderAdapter constructor(
val isHighlighted: Boolean = false, val isHighlighted: Boolean = false,
val isHidden: Boolean = true, val isHidden: Boolean = true,
// This will be false until real data has been submitted once // 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 private set
fun updateSection(newRoomsSectionData: RoomsSectionData) { fun updateSection(block: (RoomsSectionData) -> RoomsSectionData) {
if (!::roomsSectionData.isInitialized || newRoomsSectionData != roomsSectionData) { val newRoomsSectionData = block(roomsSectionData)
if (roomsSectionData != newRoomsSectionData) {
roomsSectionData = newRoomsSectionData roomsSectionData = newRoomsSectionData
notifyDataSetChanged() notifyDataSetChanged()
} }
@ -82,11 +86,16 @@ class SectionHeaderAdapter constructor(
fun bind(roomsSectionData: RoomsSectionData) { fun bind(roomsSectionData: RoomsSectionData) {
binding.roomCategoryTitleView.text = roomsSectionData.name binding.roomCategoryTitleView.text = roomsSectionData.name
val tintColor = ThemeUtils.getColor(binding.root.context, R.attr.vctr_content_secondary) val tintColor = ThemeUtils.getColor(binding.root.context, R.attr.vctr_content_secondary)
val collapsableArrowDrawable: Drawable? = if (roomsSectionData.isCollapsable) {
val expandedArrowDrawableRes = if (roomsSectionData.isExpanded) R.drawable.ic_expand_more else R.drawable.ic_expand_less 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 { ContextCompat.getDrawable(binding.root.context, expandedArrowDrawableRes)?.also {
DrawableCompat.setTint(it, tintColor) DrawableCompat.setTint(it, tintColor)
} }
binding.roomCategoryCounterView.setCompoundDrawablesWithIntrinsicBounds(null, null, expandedArrowDrawable, null) } else {
null
}
binding.root.isClickable = roomsSectionData.isCollapsable
binding.roomCategoryCounterView.setCompoundDrawablesWithIntrinsicBounds(null, null, collapsableArrowDrawable, null)
binding.roomCategoryCounterView.text = roomsSectionData.itemCount.takeIf { it > 0 }?.toString().orEmpty() binding.roomCategoryCounterView.text = roomsSectionData.itemCount.takeIf { it > 0 }?.toString().orEmpty()
binding.roomCategoryUnreadCounterBadgeView.render(UnreadCounterBadgeView.State(roomsSectionData.notificationCount, roomsSectionData.isHighlighted)) binding.roomCategoryUnreadCounterBadgeView.render(UnreadCounterBadgeView.State(roomsSectionData.notificationCount, roomsSectionData.isHighlighted))
} }

View File

@ -578,7 +578,7 @@ class OnboardingViewModel @AssistedInject constructor(
onDirectLoginError(failure) onDirectLoginError(failure)
return return
} }
onSessionCreated(data, isAccountCreated = true) onSessionCreated(data, isAccountCreated = false)
} }
private fun onDirectLoginError(failure: Throwable) { private fun onDirectLoginError(failure: Throwable) {

View File

@ -84,7 +84,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor(
val spaceCountFlow: Flow<Int> by lazy { val spaceCountFlow: Flow<Int> by lazy {
spaceUpdatableLivePageResult.livePagedList.asFlow() spaceUpdatableLivePageResult.livePagedList.asFlow()
.flatMapLatest { session.getRoomCountFlow(spaceUpdatableLivePageResult.queryParams) } .flatMapLatest { session.getRoomCountLive(spaceUpdatableLivePageResult.queryParams).asFlow() }
.distinctUntilChanged() .distinctUntilChanged()
} }
@ -110,7 +110,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor(
val roomCountFlow: Flow<Int> by lazy { val roomCountFlow: Flow<Int> by lazy {
roomUpdatableLivePageResult.livePagedList.asFlow() roomUpdatableLivePageResult.livePagedList.asFlow()
.flatMapLatest { session.getRoomCountFlow(roomUpdatableLivePageResult.queryParams) } .flatMapLatest { session.getRoomCountLive(roomUpdatableLivePageResult.queryParams).asFlow() }
.distinctUntilChanged() .distinctUntilChanged()
} }
@ -136,7 +136,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor(
val dmCountFlow: Flow<Int> by lazy { val dmCountFlow: Flow<Int> by lazy {
dmUpdatableLivePageResult.livePagedList.asFlow() dmUpdatableLivePageResult.livePagedList.asFlow()
.flatMapLatest { session.getRoomCountFlow(dmUpdatableLivePageResult.queryParams) } .flatMapLatest { session.getRoomCountLive(dmUpdatableLivePageResult.queryParams).asFlow() }
.distinctUntilChanged() .distinctUntilChanged()
} }