Using flow to show items counter
This commit is contained in:
parent
c7dae341c0
commit
0aaa650ac3
|
@ -58,6 +58,7 @@ ext.libs = [
|
|||
'lifecycleCommon' : "androidx.lifecycle:lifecycle-common:$lifecycle",
|
||||
'lifecycleLivedata' : "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle",
|
||||
'lifecycleProcess' : "androidx.lifecycle:lifecycle-process:$lifecycle",
|
||||
'lifecycleRuntimeKtx' : "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle",
|
||||
'datastore' : "androidx.datastore:datastore:1.0.0",
|
||||
'datastorepreferences' : "androidx.datastore:datastore-preferences:1.0.0",
|
||||
'pagingRuntimeKtx' : "androidx.paging:paging-runtime-ktx:2.1.2",
|
||||
|
@ -141,4 +142,4 @@ ext.libs = [
|
|||
'timberJunitRule' : "net.lachlanmckee:timber-junit-rule:1.0.1",
|
||||
'junit' : "junit:junit:4.13.2"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
|
@ -73,9 +73,6 @@ android {
|
|||
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
freeCompilerArgs += [
|
||||
"-Xopt-in=kotlin.RequiresOptIn"
|
||||
]
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
|
|
@ -29,8 +29,10 @@ import io.realm.kotlin.toFlow
|
|||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
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
|
||||
import org.matrix.android.sdk.api.query.isNormalized
|
||||
|
@ -63,7 +65,8 @@ internal class RoomSummaryDataSource @Inject constructor(
|
|||
@SessionDatabase private val monarchy: Monarchy,
|
||||
private val realmSessionProvider: RealmSessionProvider,
|
||||
private val roomSummaryMapper: RoomSummaryMapper,
|
||||
private val queryStringValueProcessor: QueryStringValueProcessor
|
||||
private val queryStringValueProcessor: QueryStringValueProcessor,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers
|
||||
) {
|
||||
|
||||
fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
|
||||
|
@ -237,28 +240,16 @@ internal class RoomSummaryDataSource @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
// @OptIn(ExperimentalCoroutinesApi::class)
|
||||
// fun getCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> = callbackFlow {
|
||||
// val realmResult = realmSessionProvider.withRealm { realm ->
|
||||
// roomSummariesQuery(realm, queryParams).findAllAsync()
|
||||
// }
|
||||
// val changeListener = RealmChangeListener<RealmResults<RoomSummaryEntity>> {
|
||||
// trySendBlocking(it.size)
|
||||
// .onFailure { throwable -> Timber.e(throwable) }
|
||||
// }
|
||||
// realmResult.addChangeListener(changeListener)
|
||||
// awaitClose { realmResult.removeChangeListener(changeListener) }
|
||||
// }
|
||||
|
||||
fun getCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> =
|
||||
// TODO handle properly threads and dispatchers otherwise use livedata of monarchy
|
||||
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(Dispatchers.IO)
|
||||
.flowOn(coroutineDispatchers.io)
|
||||
.distinctUntilChanged()
|
||||
|
||||
// TODO should we improve how we update notification count with flow ??
|
||||
fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
||||
var notificationCount: RoomAggregateNotificationCount? = null
|
||||
monarchy.doWithRealm { realm ->
|
||||
|
|
|
@ -355,6 +355,7 @@ dependencies {
|
|||
// Lifecycle
|
||||
implementation libs.androidx.lifecycleLivedata
|
||||
implementation libs.androidx.lifecycleProcess
|
||||
implementation libs.androidx.lifecycleRuntimeKtx
|
||||
|
||||
implementation libs.androidx.datastore
|
||||
implementation libs.androidx.datastorepreferences
|
||||
|
|
|
@ -23,6 +23,8 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.flowWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.ConcatAdapter
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -50,8 +52,10 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
|||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
|
||||
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.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.matrix.android.sdk.api.extensions.orTrue
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
|
@ -287,11 +291,14 @@ class RoomListFragment @Inject constructor(
|
|||
))
|
||||
checkEmptyState()
|
||||
}
|
||||
// TODO use flow if possible ?
|
||||
section.itemCount.observe(viewLifecycleOwner) { count ->
|
||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||
itemCount = count
|
||||
))
|
||||
lifecycleScope.launch {
|
||||
section.itemCount
|
||||
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
|
||||
.collect { count ->
|
||||
sectionAdapter.updateSection(
|
||||
sectionAdapter.roomsSectionData.copy(itemCount = count)
|
||||
)
|
||||
}
|
||||
}
|
||||
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||
|
@ -332,11 +339,14 @@ class RoomListFragment @Inject constructor(
|
|||
isLoading = false))
|
||||
checkEmptyState()
|
||||
}
|
||||
// TODO use flow instead ?
|
||||
section.itemCount.observe(viewLifecycleOwner) { count ->
|
||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||
itemCount = count
|
||||
))
|
||||
lifecycleScope.launch {
|
||||
section.itemCount
|
||||
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
|
||||
.collect { count ->
|
||||
sectionAdapter.updateSection(
|
||||
sectionAdapter.roomsSectionData.copy(itemCount = count)
|
||||
)
|
||||
}
|
||||
}
|
||||
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||
|
|
|
@ -68,11 +68,18 @@ class RoomListSectionBuilderGroup(
|
|||
it.memberships = Membership.activeMemberships()
|
||||
},
|
||||
{ qpm ->
|
||||
// TODO find a way to show the filtered rooms count ?
|
||||
val name = stringProvider.getString(R.string.bottom_action_rooms)
|
||||
session.getFilteredPagedRoomSummariesLive(qpm)
|
||||
.let { updatableFilterLivePageResult ->
|
||||
onUpdatable(updatableFilterLivePageResult)
|
||||
sections.add(RoomsSection(name, updatableFilterLivePageResult.livePagedList))
|
||||
sections.add(
|
||||
RoomsSection(
|
||||
sectionName = name,
|
||||
livePages = updatableFilterLivePageResult.livePagedList,
|
||||
itemCount = session.getRoomCountFlow(qpm)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -242,7 +249,6 @@ class RoomListSectionBuilderGroup(
|
|||
@StringRes nameRes: Int,
|
||||
notifyOfLocalEcho: Boolean = false,
|
||||
query: (RoomSummaryQueryParams.Builder) -> Unit) {
|
||||
// TODO check when this class is used: difference with RoomListSectionBuilderSpace ?
|
||||
withQueryParams(
|
||||
{ query.invoke(it) },
|
||||
{ roomQueryParams ->
|
||||
|
@ -252,7 +258,6 @@ class RoomListSectionBuilderGroup(
|
|||
activeSpaceUpdaters.add(it)
|
||||
}.livePagedList
|
||||
.let { livePagedList ->
|
||||
// TODO should we improve this ?
|
||||
// use it also as a source to update count
|
||||
livePagedList.asFlow()
|
||||
.onEach {
|
||||
|
@ -267,7 +272,8 @@ class RoomListSectionBuilderGroup(
|
|||
RoomsSection(
|
||||
sectionName = name,
|
||||
livePages = livePagedList,
|
||||
notifyOfLocalEcho = notifyOfLocalEcho
|
||||
notifyOfLocalEcho = notifyOfLocalEcho,
|
||||
itemCount = session.getRoomCountFlow(roomQueryParams)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import kotlinx.coroutines.flow.flatMapLatest
|
|||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
|
||||
|
@ -87,11 +88,18 @@ class RoomListSectionBuilderSpace(
|
|||
it.memberships = Membership.activeMemberships()
|
||||
},
|
||||
{ qpm ->
|
||||
// TODO find a way to show the filtered rooms count ?
|
||||
val name = stringProvider.getString(R.string.bottom_action_rooms)
|
||||
session.getFilteredPagedRoomSummariesLive(qpm)
|
||||
.let { updatableFilterLivePageResult ->
|
||||
onUpdatable(updatableFilterLivePageResult)
|
||||
sections.add(RoomsSection(name, updatableFilterLivePageResult.livePagedList))
|
||||
sections.add(
|
||||
RoomsSection(
|
||||
sectionName = name,
|
||||
livePages = updatableFilterLivePageResult.livePagedList,
|
||||
itemCount = session.getRoomCountFlow(qpm)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -261,7 +269,8 @@ class RoomListSectionBuilderSpace(
|
|||
RoomsSection(
|
||||
sectionName = stringProvider.getString(R.string.suggested_header),
|
||||
liveSuggested = liveSuggestedRooms,
|
||||
notifyOfLocalEcho = false
|
||||
notifyOfLocalEcho = false,
|
||||
itemCount = suggestedRoomsFlow.map { suggestions -> suggestions.size }
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -374,7 +383,6 @@ class RoomListSectionBuilderSpace(
|
|||
// use it also as a source to update count
|
||||
livePagedList.asFlow()
|
||||
.onEach {
|
||||
// TODO should we improve this ?
|
||||
Timber.v("Thread space list: ${Thread.currentThread()}")
|
||||
sections.find { it.sectionName == name }
|
||||
?.notificationCount
|
||||
|
@ -395,16 +403,11 @@ class RoomListSectionBuilderSpace(
|
|||
RoomsSection(
|
||||
sectionName = name,
|
||||
livePages = livePagedList,
|
||||
notifyOfLocalEcho = notifyOfLocalEcho
|
||||
notifyOfLocalEcho = notifyOfLocalEcho,
|
||||
itemCount = session.getRoomCountFlow(roomQueryParams)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// TODO extract into a dedicated private method
|
||||
session.getRoomCountFlow(roomQueryParams)
|
||||
.onEach { count -> sections.find { section -> section.sectionName == name }?.itemCount?.postValue(count) }
|
||||
.flowOn(Dispatchers.Default)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
)
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.home.room.list
|
|||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.paging.PagedList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
|
||||
|
||||
|
@ -30,8 +31,7 @@ data class RoomsSection(
|
|||
val liveList: LiveData<List<RoomSummary>>? = null,
|
||||
val liveSuggested: LiveData<SuggestedRoomInfo>? = null,
|
||||
val isExpanded: MutableLiveData<Boolean> = MutableLiveData(true),
|
||||
// TODO expose a Flow<Int> instead ?
|
||||
val itemCount: MutableLiveData<Int> = MutableLiveData(0),
|
||||
val itemCount: Flow<Int>,
|
||||
val notificationCount: MutableLiveData<RoomAggregateNotificationCount> = MutableLiveData(RoomAggregateNotificationCount(0, 0)),
|
||||
val notifyOfLocalEcho: Boolean = false
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue