mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-06 00:02:48 +02:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d589758b7b | ||
|
9bf54a3750 | ||
|
e01c5049f6 | ||
|
f5d2ba39f4 | ||
|
9ec684f438 | ||
|
60ecfd4fc2 | ||
|
8bcc2f5b0c | ||
|
04b136e3e4 | ||
|
87438085c6 | ||
|
81aa42a8e8 | ||
|
3c73ccce7b | ||
|
1ef1bd81bc | ||
|
a97d3eae7e | ||
|
a362d5427d | ||
|
745382cdfa | ||
|
70e5698082 | ||
|
866a5a7e3a | ||
|
1a0bd3f31e | ||
|
c2d2afbe72 | ||
|
4ef0bc9052 |
17
CHANGES.md
17
CHANGES.md
@@ -1,3 +1,19 @@
|
||||
Changes in Element v1.4.8 (2022-03-28)
|
||||
======================================
|
||||
|
||||
Other changes
|
||||
-------------
|
||||
- Moving live location sharing permission to debug only builds whilst it is WIP ([#5636](https://github.com/vector-im/element-android/issues/5636))
|
||||
|
||||
|
||||
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 +53,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))
|
||||
|
2
fastlane/metadata/android/en-US/changelogs/40104070.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/40104070.txt
Normal 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
|
2
fastlane/metadata/android/en-US/changelogs/40104080.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/40104080.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Main changes in this version: Thread timeline are now live and faster. Various bug fixes and stability improvements.
|
||||
Full changelog: https://github.com/vector-im/element-android/releases
|
@@ -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.8\""
|
||||
|
||||
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
|
||||
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""
|
||||
|
@@ -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<Int>
|
||||
fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int>
|
||||
|
||||
/**
|
||||
* TODO Doc
|
||||
|
@@ -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<Int> {
|
||||
return roomSummaryDataSource.getCountFlow(queryParams)
|
||||
override fun getRoomCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int> {
|
||||
return roomSummaryDataSource.getCountLive(queryParams)
|
||||
}
|
||||
|
||||
override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
||||
|
@@ -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<Int> =
|
||||
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<Int> {
|
||||
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
|
||||
|
@@ -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 = 8
|
||||
|
||||
static def getGitTimestamp() {
|
||||
def cmd = 'git show -s --format=%ct'
|
||||
|
@@ -2,6 +2,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="im.vector.app">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
|
||||
<application>
|
||||
<activity android:name=".features.debug.TestLinkifyActivity" />
|
||||
<activity android:name=".features.debug.DebugPermissionActivity" />
|
||||
|
@@ -45,7 +45,8 @@
|
||||
<!-- Location Sharing -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<!-- Debug only whilst live location sharing is WIP -->
|
||||
<!--<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />-->
|
||||
|
||||
<!-- Jitsi SDK is now API23+ -->
|
||||
<uses-sdk tools:overrideLibrary="org.jitsi.meet.sdk,com.oney.WebRTCModule,com.learnium.RNDeviceInfo,com.reactnativecommunity.asyncstorage,com.ocetnik.timer,com.calendarevents,com.reactnativecommunity.netinfo,com.kevinresol.react_native_default_preference,com.rnimmersive,com.corbt.keepawake,com.BV.LinearGradient,com.horcrux.svg,com.oblador.performance,com.reactnativecommunity.slider,com.brentvatne.react" />
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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<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>,
|
||||
activeSpaceUpdaters: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>,
|
||||
@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) {
|
||||
|
@@ -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<SectionHeaderAdapter.VH>() {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
@@ -578,7 +578,7 @@ class OnboardingViewModel @AssistedInject constructor(
|
||||
onDirectLoginError(failure)
|
||||
return
|
||||
}
|
||||
onSessionCreated(data, isAccountCreated = true)
|
||||
onSessionCreated(data, isAccountCreated = false)
|
||||
}
|
||||
|
||||
private fun onDirectLoginError(failure: Throwable) {
|
||||
|
@@ -84,7 +84,7 @@ class SpaceAddRoomsViewModel @AssistedInject constructor(
|
||||
|
||||
val spaceCountFlow: Flow<Int> 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<Int> 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<Int> by lazy {
|
||||
dmUpdatableLivePageResult.livePagedList.asFlow()
|
||||
.flatMapLatest { session.getRoomCountFlow(dmUpdatableLivePageResult.queryParams) }
|
||||
.flatMapLatest { session.getRoomCountLive(dmUpdatableLivePageResult.queryParams).asFlow() }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user