RoomList: avoid to many recompositions
This commit is contained in:
parent
485b38efad
commit
fcf7e8d7f1
8 changed files with 88 additions and 41 deletions
|
|
@ -1,6 +1,5 @@
|
|||
package io.element.android.x.matrix
|
||||
|
||||
import android.util.Log
|
||||
import io.element.android.x.core.data.CoroutineDispatchers
|
||||
import io.element.android.x.matrix.core.UserId
|
||||
import io.element.android.x.matrix.room.RoomSummaryDataSource
|
||||
|
|
@ -33,13 +32,13 @@ class MatrixClient internal constructor(
|
|||
|
||||
private val slidingSyncObserver = object : SlidingSyncObserver {
|
||||
override fun didReceiveSyncUpdate(summary: UpdateSummary) {
|
||||
Timber.v("didReceiveSyncUpdate=$summary")
|
||||
Timber.v("didReceiveSyncUpdate=$summary on Thread: ${Thread.currentThread()}")
|
||||
roomSummaryDataSource.updateRoomsWithIdentifiers(summary.rooms)
|
||||
}
|
||||
}
|
||||
|
||||
private val slidingSyncView = SlidingSyncViewBuilder()
|
||||
.timelineLimit(limit = 10u)
|
||||
.timelineLimit(limit = 1u)
|
||||
.requiredState(requiredState = listOf(RequiredState(key = "m.room.avatar", value = "")))
|
||||
.name(name = "HomeScreenView")
|
||||
.syncMode(mode = SlidingSyncMode.FULL_SYNC)
|
||||
|
|
@ -65,6 +64,7 @@ class MatrixClient internal constructor(
|
|||
}
|
||||
|
||||
fun stopSync() {
|
||||
roomSummaryDataSource.stopSync()
|
||||
slidingSync.setObserver(null)
|
||||
slidingSyncObserverToken?.cancel()
|
||||
}
|
||||
|
|
@ -73,6 +73,7 @@ class MatrixClient internal constructor(
|
|||
|
||||
override fun close() {
|
||||
stopSync()
|
||||
roomSummaryDataSource.close()
|
||||
client.setDelegate(null)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package io.element.android.x.matrix.room
|
|||
|
||||
import io.element.android.x.matrix.core.RoomId
|
||||
|
||||
|
||||
sealed interface RoomSummary {
|
||||
data class Empty(val identifier: String) : RoomSummary
|
||||
data class Filled(val details: RoomSummaryDetails) : RoomSummary
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ import io.element.android.x.matrix.core.RoomId
|
|||
import io.element.android.x.matrix.room.message.RoomMessageFactory
|
||||
import io.element.android.x.matrix.sync.roomListDiff
|
||||
import io.element.android.x.matrix.sync.state
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.flow.*
|
||||
import org.matrix.rustcomponents.sdk.*
|
||||
import timber.log.Timber
|
||||
import java.io.Closeable
|
||||
import java.util.*
|
||||
|
||||
interface RoomSummaryDataSource {
|
||||
|
|
@ -24,7 +24,7 @@ internal class RustRoomSummaryDataSource(
|
|||
private val slidingSyncView: SlidingSyncView,
|
||||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory(),
|
||||
) : RoomSummaryDataSource {
|
||||
) : RoomSummaryDataSource, Closeable {
|
||||
|
||||
private val coroutineScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.io)
|
||||
|
||||
|
|
@ -33,6 +33,7 @@ internal class RustRoomSummaryDataSource(
|
|||
|
||||
init {
|
||||
slidingSyncView.roomListDiff()
|
||||
.buffer(50)
|
||||
.onEach { diff ->
|
||||
updateRoomSummaries {
|
||||
applyDiff(diff)
|
||||
|
|
@ -40,32 +41,43 @@ internal class RustRoomSummaryDataSource(
|
|||
}.launchIn(coroutineScope)
|
||||
|
||||
slidingSyncView.state()
|
||||
.onEach { newRoomState ->
|
||||
state.value = newRoomState
|
||||
.onEach { slidingSyncState ->
|
||||
Timber.v("New sliding sync state: $slidingSyncState")
|
||||
state.value = slidingSyncState
|
||||
}.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
fun stopSync() {
|
||||
coroutineScope.coroutineContext.cancelChildren()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
coroutineScope.cancel()
|
||||
}
|
||||
|
||||
override fun roomSummaries(): Flow<List<RoomSummary>> {
|
||||
return roomSummaries
|
||||
return roomSummaries.sample(100)
|
||||
}
|
||||
|
||||
internal fun updateRoomsWithIdentifiers(identifiers: List<String>) {
|
||||
Timber.v("UpdateRooms with identifiers: $identifiers")
|
||||
if (state.value != SlidingSyncState.LIVE) {
|
||||
return
|
||||
}
|
||||
val roomSummaryList = roomSummaries.value.toMutableList()
|
||||
for (identifier in identifiers) {
|
||||
val index = roomSummaryList.indexOfFirst { it.identifier() == identifier }
|
||||
if (index == -1) {
|
||||
continue
|
||||
updateRoomSummaries {
|
||||
for (identifier in identifiers) {
|
||||
val index = indexOfFirst { it.identifier() == identifier }
|
||||
if (index == -1) {
|
||||
continue
|
||||
}
|
||||
val updatedRoomSummary = buildRoomSummaryForIdentifier(identifier)
|
||||
set(index, updatedRoomSummary)
|
||||
}
|
||||
val updatedRoomSummary = buildRoomSummaryForIdentifier(identifier)
|
||||
roomSummaryList[index] = updatedRoomSummary
|
||||
}
|
||||
roomSummaries.value = roomSummaryList
|
||||
}
|
||||
|
||||
private fun MutableList<RoomSummary>.applyDiff(diff: SlidingSyncViewRoomsListDiff) {
|
||||
Timber.v("ApplyDiff: $diff")
|
||||
if (diff.isInvalidation()) {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue