(DRAFT) Room counter flow

This commit is contained in:
Maxime Naturel 2022-02-07 09:55:24 +01:00
parent eb38c9d835
commit c7dae341c0
9 changed files with 68 additions and 0 deletions

View file

@ -73,6 +73,9 @@ android {
kotlinOptions {
jvmTarget = "11"
freeCompilerArgs += [
"-Xopt-in=kotlin.RequiresOptIn"
]
}
sourceSets {

View file

@ -18,6 +18,7 @@ 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
@ -216,6 +217,11 @@ interface RoomService {
pagedListConfig: PagedList.Config = defaultPagedListConfig,
sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): UpdatableLivePageResult
/**
* Retrieve a flow on the the number of rooms.
*/
fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int>
/**
* TODO Doc
*/

View file

@ -20,6 +20,7 @@ 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
@ -109,6 +110,10 @@ internal class DefaultRoomService @Inject constructor(
return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder)
}
override fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> {
return roomSummaryDataSource.getCountFlow(queryParams)
}
override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
return roomSummaryDataSource.getNotificationCountForRooms(queryParams)
}

View file

@ -25,7 +25,12 @@ 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.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import org.matrix.android.sdk.api.query.ActiveSpaceFilter
import org.matrix.android.sdk.api.query.RoomCategoryFilter
import org.matrix.android.sdk.api.query.isNormalized
@ -42,6 +47,7 @@ import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotification
import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.internal.database.RealmSessionProvider
import org.matrix.android.sdk.internal.database.mapper.RoomSummaryMapper
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
@ -55,6 +61,7 @@ import javax.inject.Inject
internal class RoomSummaryDataSource @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
private val realmSessionProvider: RealmSessionProvider,
private val roomSummaryMapper: RoomSummaryMapper,
private val queryStringValueProcessor: QueryStringValueProcessor
) {
@ -230,6 +237,28 @@ 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()
.map { it.size }
.flowOn(Dispatchers.IO)
// TODO should we improve how we update notification count with flow ??
fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
var notificationCount: RoomAggregateNotificationCount? = null
monarchy.doWithRealm { realm ->

View file

@ -29,6 +29,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.features.themes.ThemeUtils
// TODO check where it is used in the project
@EpoxyModelClass(layout = R.layout.item_room_category)
abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {

View file

@ -287,6 +287,12 @@ class RoomListFragment @Inject constructor(
))
checkEmptyState()
}
// TODO use flow if possible ?
section.itemCount.observe(viewLifecycleOwner) { count ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
itemCount = count
))
}
section.notificationCount.observe(viewLifecycleOwner) { counts ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
notificationCount = counts.totalCount,
@ -326,6 +332,12 @@ class RoomListFragment @Inject constructor(
isLoading = false))
checkEmptyState()
}
// TODO use flow instead ?
section.itemCount.observe(viewLifecycleOwner) { count ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
itemCount = count
))
}
section.notificationCount.observe(viewLifecycleOwner) { counts ->
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
notificationCount = counts.totalCount,

View file

@ -242,6 +242,7 @@ 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 ->
@ -251,6 +252,7 @@ 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 {

View file

@ -374,6 +374,7 @@ 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
@ -398,6 +399,12 @@ class RoomListSectionBuilderSpace(
)
)
}
// 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)
}
)

View file

@ -26,9 +26,12 @@ data class RoomsSection(
val sectionName: String,
// can be a paged list or a regular list
val livePages: LiveData<PagedList<RoomSummary>>? = null,
// TODO liveList is not used : can we delete ?
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 notificationCount: MutableLiveData<RoomAggregateNotificationCount> = MutableLiveData(RoomAggregateNotificationCount(0, 0)),
val notifyOfLocalEcho: Boolean = false
)