RoomList: change a bit the api of RoomSummaryDataSource

This commit is contained in:
ganfra
2023-06-22 12:34:07 +02:00
parent 6446f2f6a7
commit 8ce65b4429
12 changed files with 78 additions and 92 deletions

View File

@@ -49,8 +49,8 @@ class InviteListPresenter @Inject constructor(
@Composable
override fun present(): InviteListState {
val invites by client
.invitesDataSource
.roomSummaries()
.roomSummaryDataSource
.inviteList()
.collectAsState()
var seenInvites by remember { mutableStateOf<Set<RoomId>>(emptySet()) }

View File

@@ -43,8 +43,8 @@ class DefaultInviteStateDataSource @Inject constructor(
@Composable
override fun inviteState(): InvitesState {
val invites by client
.invitesDataSource
.roomSummaries()
.roomSummaryDataSource
.inviteList()
.collectAsState()
val seenInvites by seenInvitesStore

View File

@@ -77,7 +77,7 @@ class RoomListPresenter @Inject constructor(
var filter by rememberSaveable { mutableStateOf("") }
val roomSummaries by client
.roomSummaryDataSource
.roomSummaries()
.roomList()
.collectAsState()
val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus)
@@ -177,7 +177,7 @@ class RoomListPresenter @Inject constructor(
// Safe to give bigger size than room list
val extendedRangeEnd = range.last + midExtendedRangeSize
val extendedRange = IntRange(extendedRangeStart, extendedRangeEnd)
client.roomSummaryDataSource.setSlidingSyncRange(extendedRange)
client.roomSummaryDataSource.updateRoomListVisibleRange(extendedRange)
}
private suspend fun mapRoomSummaries(

View File

@@ -35,7 +35,6 @@ import java.io.Closeable
interface MatrixClient : Closeable {
val sessionId: SessionId
val roomSummaryDataSource: RoomSummaryDataSource
val invitesDataSource: RoomSummaryDataSource
val mediaLoader: MatrixMediaLoader
fun getRoom(roomId: RoomId): MatrixRoom?
fun findDM(userId: UserId): MatrixRoom?

View File

@@ -28,6 +28,7 @@ interface RoomSummaryDataSource {
}
fun loadingState(): StateFlow<LoadingState>
fun roomSummaries(): StateFlow<List<RoomSummary>>
fun setSlidingSyncRange(range: IntRange)
fun roomList(): StateFlow<List<RoomSummary>>
fun inviteList(): StateFlow<List<RoomSummary>>
fun updateRoomListVisibleRange(range: IntRange)
}

View File

@@ -93,28 +93,18 @@ class RustMatrixClient constructor(
}
}
private val roomList = client.roomList()
private val roomListService = client.roomList()
private val rustRoomSummaryDataSource: RustRoomSummaryDataSource =
RustRoomSummaryDataSource(
roomList,
sessionCoroutineScope,
dispatchers,
roomListService = roomListService,
sessionCoroutineScope = sessionCoroutineScope,
coroutineDispatchers = dispatchers,
)
override val roomSummaryDataSource: RoomSummaryDataSource
get() = rustRoomSummaryDataSource
private val rustInvitesDataSource: RustRoomSummaryDataSource =
RustRoomSummaryDataSource(
roomList,
sessionCoroutineScope,
dispatchers,
)
override val invitesDataSource: RoomSummaryDataSource
get() = rustInvitesDataSource
private val rustMediaLoader = RustMediaLoader(baseCacheDirectory, dispatchers, client)
override val mediaLoader: MatrixMediaLoader
get() = rustMediaLoader
@@ -123,17 +113,16 @@ class RustMatrixClient constructor(
init {
client.setDelegate(clientDelegate)
rustRoomSummaryDataSource.subscribeIfNeeded()
roomList.stateFlow()
rustRoomSummaryDataSource.init()
roomListService.stateFlow()
.onEach {
Timber.v("onRoomList state change: $it")
}
.launchIn(sessionCoroutineScope)
//rustInvitesDataSource.init()
}
override fun getRoom(roomId: RoomId): MatrixRoom? {
val roomListItem = roomList.roomOrNull(roomId.value) ?: return null
val roomListItem = roomListService.roomOrNull(roomId.value) ?: return null
val fullRoom = roomListItem.fullRoom()
return RustMatrixRoom(
sessionId = sessionId,
@@ -185,7 +174,7 @@ class RustMatrixClient constructor(
// Wait to receive the room back from the sync
withTimeout(30_000L) {
roomSummaryDataSource.roomSummaries()
roomSummaryDataSource.roomList()
.filter { roomSummaries ->
roomSummaries.map { it.identifier() }.contains(roomId.value)
}.first()
@@ -226,14 +215,14 @@ class RustMatrixClient constructor(
override fun notificationService(): NotificationService = notificationService
override fun startSync() {
if (!roomList.isSyncing()) {
roomList.sync()
if (!roomListService.isSyncing()) {
roomListService.sync()
}
}
override fun stopSync() {
if (roomList.isSyncing()) {
roomList.stopSync()
if (roomListService.isSyncing()) {
roomListService.stopSync()
}
}
@@ -242,7 +231,7 @@ class RustMatrixClient constructor(
sessionCoroutineScope.cancel()
client.setDelegate(null)
verificationService.destroy()
roomList.destroy()
roomListService.destroy()
client.destroy()
}

View File

@@ -7,6 +7,7 @@ import org.matrix.rustcomponents.sdk.RoomList
import org.matrix.rustcomponents.sdk.RoomListEntriesListener
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListEntry
import org.matrix.rustcomponents.sdk.RoomListInterface
import org.matrix.rustcomponents.sdk.RoomListItem
import org.matrix.rustcomponents.sdk.RoomListState
import org.matrix.rustcomponents.sdk.RoomListStateListener
@@ -14,7 +15,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState
import org.matrix.rustcomponents.sdk.SlidingSyncListStateObserver
import timber.log.Timber
fun RoomList.stateFlow(): Flow<RoomListState> =
fun RoomListInterface.stateFlow(): Flow<RoomListState> =
mxCallbackFlow {
val listener = object : RoomListStateListener {
override fun onUpdate(state: RoomListState) {
@@ -24,7 +25,7 @@ fun RoomList.stateFlow(): Flow<RoomListState> =
state(listener)
}
fun RoomList.loadingStateFlow(): Flow<SlidingSyncListLoadingState> =
fun RoomListInterface.loadingStateFlow(): Flow<SlidingSyncListLoadingState> =
mxCallbackFlow {
val listener = object : SlidingSyncListStateObserver {
override fun didReceiveUpdate(newState: SlidingSyncListLoadingState) {
@@ -36,7 +37,7 @@ fun RoomList.loadingStateFlow(): Flow<SlidingSyncListLoadingState> =
result.entriesLoadingStateStream
}
fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List<RoomListEntry>) -> Unit): Flow<RoomListEntriesUpdate> =
fun RoomListInterface.roomListEntriesUpdateFlow(onInitialList: suspend (List<RoomListEntry>) -> Unit): Flow<RoomListEntriesUpdate> =
mxCallbackFlow {
val listener = object : RoomListEntriesListener {
override fun onUpdate(roomEntriesUpdate: RoomListEntriesUpdate) {
@@ -48,7 +49,7 @@ fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List<RoomListEntr
result.entriesStream
}
fun RoomList.roomOrNull(roomId: String): RoomListItem? {
fun RoomListInterface.roomOrNull(roomId: String): RoomListItem? {
return try {
room(roomId)
} catch (failure: Throwable) {

View File

@@ -81,7 +81,7 @@ class RustMatrixRoom(
RustMatrixTimeline(
matrixRoom = this,
innerRoom = innerRoom,
coroutineScope = roomCoroutineScope,
roomCoroutineScope = roomCoroutineScope,
coroutineDispatchers = coroutineDispatchers
)
}

View File

@@ -22,108 +22,111 @@ import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.RoomList
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
import org.matrix.rustcomponents.sdk.RoomListEntry
import org.matrix.rustcomponents.sdk.RoomListException
import org.matrix.rustcomponents.sdk.RoomListInput
import org.matrix.rustcomponents.sdk.RoomListInterface
import org.matrix.rustcomponents.sdk.RoomListRange
import timber.log.Timber
import java.util.UUID
internal class RustRoomSummaryDataSource(
private val roomList: RoomList,
private val roomListService: RoomListInterface,
private val sessionCoroutineScope: CoroutineScope,
private val coroutineDispatchers: CoroutineDispatchers,
private val roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(),
) : RoomSummaryDataSource {
private val roomSummaries = MutableStateFlow<List<RoomSummary>>(emptyList())
private val roomList = MutableStateFlow<List<RoomSummary>>(emptyList())
private val inviteList = MutableStateFlow<List<RoomSummary>>(emptyList())
private val loadingState = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded)
fun subscribeIfNeeded() {
sessionCoroutineScope.launch {
roomList.roomListEntriesUpdateFlow { roomListEntries ->
val summaries = roomListEntries.map(::buildSummaryForRoomListEntry)
updateRoomSummaries {
addAll(summaries)
}
}.onEach {
updateRoomSummaries {
applyUpdate(it)
fun init() {
sessionCoroutineScope.launch(coroutineDispatchers.computation) {
roomListService.roomListEntriesUpdateFlow { roomListEntries ->
roomList.value = roomListEntries.map(::buildSummaryForRoomListEntry)
}.onEach { update ->
roomList.getAndUpdate {
it.applyUpdate(update)
}
}.launchIn(this)
}
}
override fun roomSummaries(): StateFlow<List<RoomSummary>> {
return roomSummaries
override fun roomList(): StateFlow<List<RoomSummary>> {
return roomList
}
override fun inviteList(): StateFlow<List<RoomSummary>> {
return inviteList
}
override fun loadingState(): StateFlow<RoomSummaryDataSource.LoadingState> {
return loadingState
}
override fun setSlidingSyncRange(range: IntRange) {
override fun updateRoomListVisibleRange(range: IntRange) {
Timber.v("setVisibleRange=$range")
sessionCoroutineScope.launch {
val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt()))
roomList.applyInput(
RoomListInput.Viewport(ranges)
)
try {
val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt()))
roomListService.applyInput(
RoomListInput.Viewport(ranges)
)
} catch (exception: RoomListException) {
Timber.e(exception, "Failed updating visible range")
}
}
}
private fun MutableList<RoomSummary>.applyUpdate(update: RoomListEntriesUpdate) {
fun MutableList<RoomSummary>.fillUntil(untilIndex: Int) {
repeat((size - 1 until untilIndex).count()) {
add(buildEmptyRoomSummary())
}
}
private fun List<RoomSummary>.applyUpdate(update: RoomListEntriesUpdate): List<RoomSummary> {
val newList = toMutableList()
when (update) {
is RoomListEntriesUpdate.Append -> {
val roomSummaries = update.values.map {
buildSummaryForRoomListEntry(it)
}
addAll(roomSummaries)
newList.addAll(roomSummaries)
}
is RoomListEntriesUpdate.PushBack -> {
val roomSummary = buildSummaryForRoomListEntry(update.value)
add(roomSummary)
newList.add(roomSummary)
}
is RoomListEntriesUpdate.PushFront -> {
val roomSummary = buildSummaryForRoomListEntry(update.value)
add(0, roomSummary)
newList.add(0, roomSummary)
}
is RoomListEntriesUpdate.Set -> {
fillUntil(update.index.toInt())
val roomSummary = buildSummaryForRoomListEntry(update.value)
set(update.index.toInt(), roomSummary)
newList[update.index.toInt()] = roomSummary
}
is RoomListEntriesUpdate.Insert -> {
val roomSummary = buildSummaryForRoomListEntry(update.value)
add(update.index.toInt(), roomSummary)
newList.add(update.index.toInt(), roomSummary)
}
is RoomListEntriesUpdate.Remove -> {
removeAt(update.index.toInt())
newList.removeAt(update.index.toInt())
}
is RoomListEntriesUpdate.Reset -> {
clear()
addAll(update.values.map { buildSummaryForRoomListEntry(it) })
newList.clear()
newList.addAll(update.values.map { buildSummaryForRoomListEntry(it) })
}
RoomListEntriesUpdate.PopBack -> {
removeFirstOrNull()
newList.removeFirstOrNull()
}
RoomListEntriesUpdate.PopFront -> {
removeLastOrNull()
newList.removeLastOrNull()
}
RoomListEntriesUpdate.Clear -> {
clear()
newList.clear()
}
}
return newList
}
private fun buildSummaryForRoomListEntry(entry: RoomListEntry): RoomSummary {
@@ -139,7 +142,7 @@ internal class RustRoomSummaryDataSource(
}
private fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary {
val roomListItem = roomList.roomOrNull(identifier) ?: return RoomSummary.Empty(identifier)
val roomListItem = roomListService.roomOrNull(identifier) ?: return RoomSummary.Empty(identifier)
return roomListItem.use {
roomListItem.fullRoom().use { fullRoom ->
RoomSummary.Filled(
@@ -148,11 +151,4 @@ internal class RustRoomSummaryDataSource(
}
}
}
private suspend fun updateRoomSummaries(block: MutableList<RoomSummary>.() -> Unit) =
withContext(coroutineDispatchers.diffUpdateDispatcher) {
val mutableRoomSummaries = roomSummaries.value.toMutableList()
block(mutableRoomSummaries)
roomSummaries.value = mutableRoomSummaries
}
}

View File

@@ -26,7 +26,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem
class MatrixTimelineItemMapper(
private val fetchDetailsForEvent: suspend (EventId) -> Result<Unit>,
private val coroutineScope: CoroutineScope,
private val roomCoroutineScope: CoroutineScope,
private val virtualTimelineItemMapper: VirtualTimelineItemMapper = VirtualTimelineItemMapper(),
private val eventTimelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(),
) {
@@ -51,7 +51,7 @@ class MatrixTimelineItemMapper(
return MatrixTimelineItem.Other
}
private fun fetchEventDetails(eventId: EventId) = coroutineScope.launch {
private fun fetchEventDetails(eventId: EventId) = roomCoroutineScope.launch {
fetchDetailsForEvent(eventId)
}
}

View File

@@ -39,7 +39,7 @@ import org.matrix.rustcomponents.sdk.TimelineItem
import timber.log.Timber
class RustMatrixTimeline(
coroutineScope: CoroutineScope,
roomCoroutineScope: CoroutineScope,
private val matrixRoom: MatrixRoom,
private val innerRoom: Room,
private val coroutineDispatchers: CoroutineDispatchers,
@@ -54,7 +54,7 @@ class RustMatrixTimeline(
private val timelineItemFactory = MatrixTimelineItemMapper(
fetchDetailsForEvent = this::fetchDetailsForEvent,
coroutineScope = coroutineScope,
roomCoroutineScope = roomCoroutineScope,
virtualTimelineItemMapper = VirtualTimelineItemMapper(),
eventTimelineItemMapper = EventTimelineItemMapper(
contentMapper = TimelineEventContentMapper(
@@ -66,7 +66,7 @@ class RustMatrixTimeline(
private val timelineDiffProcessor = MatrixTimelineDiffProcessor(
paginationState = paginationState,
timelineItems = timelineItems,
coroutineScope = coroutineScope,
coroutineScope = roomCoroutineScope,
diffDispatcher = coroutineDispatchers.diffUpdateDispatcher,
timelineItemFactory = timelineItemFactory,
)

View File

@@ -29,14 +29,14 @@ class FakeRoomSummaryDataSource : RoomSummaryDataSource {
roomSummariesFlow.emit(roomSummaries)
}
override fun roomSummaries(): StateFlow<List<RoomSummary>> {
override fun roomList(): StateFlow<List<RoomSummary>> {
return roomSummariesFlow
}
var latestSlidingSyncRange: IntRange? = null
private set
override fun setSlidingSyncRange(range: IntRange) {
override fun updateRoomListVisibleRange(range: IntRange) {
latestSlidingSyncRange = range
}
}