mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-28 00:39:01 +03:00
(DRAFT) Room counter flow
This commit is contained in:
parent
eb38c9d835
commit
c7dae341c0
9 changed files with 68 additions and 0 deletions
matrix-sdk-android
vector/src/main/java/im/vector/app/features/home/room/list
|
@ -73,6 +73,9 @@ android {
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "11"
|
jvmTarget = "11"
|
||||||
|
freeCompilerArgs += [
|
||||||
|
"-Xopt-in=kotlin.RequiresOptIn"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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
|
||||||
|
@ -216,6 +217,11 @@ interface RoomService {
|
||||||
pagedListConfig: PagedList.Config = defaultPagedListConfig,
|
pagedListConfig: PagedList.Config = defaultPagedListConfig,
|
||||||
sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): UpdatableLivePageResult
|
sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): UpdatableLivePageResult
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a flow on the the number of rooms.
|
||||||
|
*/
|
||||||
|
fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Doc
|
* TODO Doc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,6 +20,7 @@ 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
|
||||||
|
@ -109,6 +110,10 @@ internal class DefaultRoomService @Inject constructor(
|
||||||
return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder)
|
return roomSummaryDataSource.getUpdatablePagedRoomSummariesLive(queryParams, pagedListConfig, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getRoomCountFlow(queryParams: RoomSummaryQueryParams): Flow<Int> {
|
||||||
|
return roomSummaryDataSource.getCountFlow(queryParams)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
override fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
||||||
return roomSummaryDataSource.getNotificationCountForRooms(queryParams)
|
return roomSummaryDataSource.getNotificationCountForRooms(queryParams)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,12 @@ 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.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.ActiveSpaceFilter
|
||||||
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||||
import org.matrix.android.sdk.api.query.isNormalized
|
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.session.space.SpaceSummaryQueryParams
|
||||||
import org.matrix.android.sdk.api.util.Optional
|
import org.matrix.android.sdk.api.util.Optional
|
||||||
import org.matrix.android.sdk.api.util.toOptional
|
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.mapper.RoomSummaryMapper
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||||
|
@ -55,6 +61,7 @@ import javax.inject.Inject
|
||||||
|
|
||||||
internal class RoomSummaryDataSource @Inject constructor(
|
internal class RoomSummaryDataSource @Inject constructor(
|
||||||
@SessionDatabase private val monarchy: Monarchy,
|
@SessionDatabase private val monarchy: Monarchy,
|
||||||
|
private val realmSessionProvider: RealmSessionProvider,
|
||||||
private val roomSummaryMapper: RoomSummaryMapper,
|
private val roomSummaryMapper: RoomSummaryMapper,
|
||||||
private val queryStringValueProcessor: QueryStringValueProcessor
|
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 {
|
fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
||||||
var notificationCount: RoomAggregateNotificationCount? = null
|
var notificationCount: RoomAggregateNotificationCount? = null
|
||||||
monarchy.doWithRealm { realm ->
|
monarchy.doWithRealm { realm ->
|
||||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||||
import im.vector.app.core.epoxy.onClick
|
import im.vector.app.core.epoxy.onClick
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
|
||||||
|
// TODO check where it is used in the project
|
||||||
@EpoxyModelClass(layout = R.layout.item_room_category)
|
@EpoxyModelClass(layout = R.layout.item_room_category)
|
||||||
abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
||||||
|
|
||||||
|
|
|
@ -287,6 +287,12 @@ class RoomListFragment @Inject constructor(
|
||||||
))
|
))
|
||||||
checkEmptyState()
|
checkEmptyState()
|
||||||
}
|
}
|
||||||
|
// TODO use flow if possible ?
|
||||||
|
section.itemCount.observe(viewLifecycleOwner) { count ->
|
||||||
|
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||||
|
itemCount = count
|
||||||
|
))
|
||||||
|
}
|
||||||
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
||||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||||
notificationCount = counts.totalCount,
|
notificationCount = counts.totalCount,
|
||||||
|
@ -326,6 +332,12 @@ class RoomListFragment @Inject constructor(
|
||||||
isLoading = false))
|
isLoading = false))
|
||||||
checkEmptyState()
|
checkEmptyState()
|
||||||
}
|
}
|
||||||
|
// TODO use flow instead ?
|
||||||
|
section.itemCount.observe(viewLifecycleOwner) { count ->
|
||||||
|
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||||
|
itemCount = count
|
||||||
|
))
|
||||||
|
}
|
||||||
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
section.notificationCount.observe(viewLifecycleOwner) { counts ->
|
||||||
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
sectionAdapter.updateSection(sectionAdapter.roomsSectionData.copy(
|
||||||
notificationCount = counts.totalCount,
|
notificationCount = counts.totalCount,
|
||||||
|
|
|
@ -242,6 +242,7 @@ class RoomListSectionBuilderGroup(
|
||||||
@StringRes nameRes: Int,
|
@StringRes nameRes: Int,
|
||||||
notifyOfLocalEcho: Boolean = false,
|
notifyOfLocalEcho: Boolean = false,
|
||||||
query: (RoomSummaryQueryParams.Builder) -> Unit) {
|
query: (RoomSummaryQueryParams.Builder) -> Unit) {
|
||||||
|
// TODO check when this class is used: difference with RoomListSectionBuilderSpace ?
|
||||||
withQueryParams(
|
withQueryParams(
|
||||||
{ query.invoke(it) },
|
{ query.invoke(it) },
|
||||||
{ roomQueryParams ->
|
{ roomQueryParams ->
|
||||||
|
@ -251,6 +252,7 @@ class RoomListSectionBuilderGroup(
|
||||||
activeSpaceUpdaters.add(it)
|
activeSpaceUpdaters.add(it)
|
||||||
}.livePagedList
|
}.livePagedList
|
||||||
.let { livePagedList ->
|
.let { livePagedList ->
|
||||||
|
// TODO should we improve this ?
|
||||||
// use it also as a source to update count
|
// use it also as a source to update count
|
||||||
livePagedList.asFlow()
|
livePagedList.asFlow()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
|
|
@ -374,6 +374,7 @@ class RoomListSectionBuilderSpace(
|
||||||
// use it also as a source to update count
|
// use it also as a source to update count
|
||||||
livePagedList.asFlow()
|
livePagedList.asFlow()
|
||||||
.onEach {
|
.onEach {
|
||||||
|
// TODO should we improve this ?
|
||||||
Timber.v("Thread space list: ${Thread.currentThread()}")
|
Timber.v("Thread space list: ${Thread.currentThread()}")
|
||||||
sections.find { it.sectionName == name }
|
sections.find { it.sectionName == name }
|
||||||
?.notificationCount
|
?.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,9 +26,12 @@ data class RoomsSection(
|
||||||
val sectionName: String,
|
val sectionName: String,
|
||||||
// can be a paged list or a regular list
|
// can be a paged list or a regular list
|
||||||
val livePages: LiveData<PagedList<RoomSummary>>? = null,
|
val livePages: LiveData<PagedList<RoomSummary>>? = null,
|
||||||
|
// TODO liveList is not used : can we delete ?
|
||||||
val liveList: LiveData<List<RoomSummary>>? = null,
|
val liveList: LiveData<List<RoomSummary>>? = null,
|
||||||
val liveSuggested: LiveData<SuggestedRoomInfo>? = null,
|
val liveSuggested: LiveData<SuggestedRoomInfo>? = null,
|
||||||
val isExpanded: MutableLiveData<Boolean> = MutableLiveData(true),
|
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 notificationCount: MutableLiveData<RoomAggregateNotificationCount> = MutableLiveData(RoomAggregateNotificationCount(0, 0)),
|
||||||
val notifyOfLocalEcho: Boolean = false
|
val notifyOfLocalEcho: Boolean = false
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue