RoomList: make the main room list working (WIP)
This commit is contained in:
parent
ec9f0e2869
commit
39fcb1bb80
10 changed files with 146 additions and 328 deletions
|
|
@ -19,6 +19,15 @@ package io.element.android.libraries.matrix.api.room
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
interface RoomSummaryDataSource {
|
interface RoomSummaryDataSource {
|
||||||
|
|
||||||
|
enum class LoadingState {
|
||||||
|
NotLoaded,
|
||||||
|
PreLoaded,
|
||||||
|
PartiallyLoaded,
|
||||||
|
FullyLoaded,
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadingState(): StateFlow<LoadingState>
|
||||||
fun roomSummaries(): StateFlow<List<RoomSummary>>
|
fun roomSummaries(): StateFlow<List<RoomSummary>>
|
||||||
fun setSlidingSyncRange(range: IntRange)
|
fun setSlidingSyncRange(range: IntRange)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import io.element.android.libraries.matrix.api.pusher.PushersService
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||||
import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource
|
import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventType
|
|
||||||
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
|
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
|
||||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||||
|
|
@ -40,7 +39,6 @@ import io.element.android.libraries.matrix.impl.notification.RustNotificationSer
|
||||||
import io.element.android.libraries.matrix.impl.pushers.RustPushersService
|
import io.element.android.libraries.matrix.impl.pushers.RustPushersService
|
||||||
import io.element.android.libraries.matrix.impl.room.RustMatrixRoom
|
import io.element.android.libraries.matrix.impl.room.RustMatrixRoom
|
||||||
import io.element.android.libraries.matrix.impl.room.RustRoomSummaryDataSource
|
import io.element.android.libraries.matrix.impl.room.RustRoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.impl.sync.SlidingSyncObserverProxy
|
|
||||||
import io.element.android.libraries.matrix.impl.usersearch.UserProfileMapper
|
import io.element.android.libraries.matrix.impl.usersearch.UserProfileMapper
|
||||||
import io.element.android.libraries.matrix.impl.usersearch.UserSearchResultMapper
|
import io.element.android.libraries.matrix.impl.usersearch.UserSearchResultMapper
|
||||||
import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService
|
import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService
|
||||||
|
|
@ -50,21 +48,12 @@ import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.launchIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
import org.matrix.rustcomponents.sdk.Client
|
import org.matrix.rustcomponents.sdk.Client
|
||||||
import org.matrix.rustcomponents.sdk.ClientDelegate
|
import org.matrix.rustcomponents.sdk.ClientDelegate
|
||||||
import org.matrix.rustcomponents.sdk.RequiredState
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncList
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListBuilder
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListOnceBuilt
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRequestListFilters
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncSelectiveModeBuilder
|
|
||||||
import org.matrix.rustcomponents.sdk.TaskHandle
|
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||||
import org.matrix.rustcomponents.sdk.use
|
import org.matrix.rustcomponents.sdk.use
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -101,75 +90,11 @@ class RustMatrixClient constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val visibleRoomsSlidingSyncFilters = SlidingSyncRequestListFilters(
|
private val roomList = client.roomList()
|
||||||
isDm = null,
|
|
||||||
spaces = emptyList(),
|
|
||||||
isEncrypted = null,
|
|
||||||
isInvite = false,
|
|
||||||
isTombstoned = false,
|
|
||||||
roomTypes = emptyList(),
|
|
||||||
notRoomTypes = listOf("m.space"),
|
|
||||||
roomNameLike = null,
|
|
||||||
tags = emptyList(),
|
|
||||||
notTags = emptyList()
|
|
||||||
)
|
|
||||||
|
|
||||||
private val visibleRoomsSlidingSyncList = MutableSharedFlow<SlidingSyncList>(replay = 1)
|
|
||||||
private val visibleRoomsSlidingSyncListBuilder = SlidingSyncListBuilder("CurrentlyVisibleRooms")
|
|
||||||
.timelineLimit(limit = 1u)
|
|
||||||
.requiredState(
|
|
||||||
requiredState = listOf(
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_AVATAR, value = ""),
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_ENCRYPTION, value = ""),
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.filters(visibleRoomsSlidingSyncFilters)
|
|
||||||
.syncModeSelective(SlidingSyncSelectiveModeBuilder().addRange(0u, 20u))
|
|
||||||
.onceBuilt(object : SlidingSyncListOnceBuilt {
|
|
||||||
override fun updateList(list: SlidingSyncList): SlidingSyncList {
|
|
||||||
visibleRoomsSlidingSyncList.tryEmit(list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
private val invitesSlidingSyncFilters = visibleRoomsSlidingSyncFilters.copy(isInvite = true)
|
|
||||||
|
|
||||||
private val invitesSlidingSyncList = MutableSharedFlow<SlidingSyncList>(replay = 1)
|
|
||||||
private val invitesSlidingSyncListBuilder = SlidingSyncListBuilder("CurrentInvites")
|
|
||||||
.timelineLimit(limit = 1u)
|
|
||||||
.requiredState(
|
|
||||||
requiredState = listOf(
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_AVATAR, value = ""),
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_ENCRYPTION, value = ""),
|
|
||||||
RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.filters(invitesSlidingSyncFilters)
|
|
||||||
.syncModeSelective(SlidingSyncSelectiveModeBuilder().addRange(0u, 20u))
|
|
||||||
.onceBuilt(object : SlidingSyncListOnceBuilt {
|
|
||||||
override fun updateList(list: SlidingSyncList): SlidingSyncList {
|
|
||||||
invitesSlidingSyncList.tryEmit(list)
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
private val slidingSync = client
|
|
||||||
.slidingSync("ElementX")
|
|
||||||
// .homeserver("https://slidingsync.lab.matrix.org")
|
|
||||||
.withCommonExtensions()
|
|
||||||
.addList(visibleRoomsSlidingSyncListBuilder)
|
|
||||||
.addList(invitesSlidingSyncListBuilder)
|
|
||||||
.use {
|
|
||||||
it.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
private val slidingSyncObserverProxy = SlidingSyncObserverProxy(coroutineScope)
|
|
||||||
private val rustRoomSummaryDataSource: RustRoomSummaryDataSource =
|
private val rustRoomSummaryDataSource: RustRoomSummaryDataSource =
|
||||||
RustRoomSummaryDataSource(
|
RustRoomSummaryDataSource(
|
||||||
slidingSyncObserverProxy.updateSummaryFlow,
|
roomList,
|
||||||
slidingSync,
|
|
||||||
visibleRoomsSlidingSyncList,
|
|
||||||
dispatchers,
|
dispatchers,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -178,9 +103,7 @@ class RustMatrixClient constructor(
|
||||||
|
|
||||||
private val rustInvitesDataSource: RustRoomSummaryDataSource =
|
private val rustInvitesDataSource: RustRoomSummaryDataSource =
|
||||||
RustRoomSummaryDataSource(
|
RustRoomSummaryDataSource(
|
||||||
slidingSyncObserverProxy.updateSummaryFlow,
|
roomList,
|
||||||
slidingSync,
|
|
||||||
invitesSlidingSyncList,
|
|
||||||
dispatchers,
|
dispatchers,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -199,25 +122,19 @@ class RustMatrixClient constructor(
|
||||||
|
|
||||||
init {
|
init {
|
||||||
client.setDelegate(clientDelegate)
|
client.setDelegate(clientDelegate)
|
||||||
rustRoomSummaryDataSource.init()
|
rustRoomSummaryDataSource.subscribeIfNeeded()
|
||||||
rustInvitesDataSource.init()
|
//rustInvitesDataSource.init()
|
||||||
slidingSync.setObserver(slidingSyncObserverProxy)
|
|
||||||
slidingSyncUpdateJob = slidingSyncObserverProxy.updateSummaryFlow
|
|
||||||
.onEach { onSlidingSyncUpdate() }
|
|
||||||
.launchIn(coroutineScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getRoom(roomId: RoomId): MatrixRoom? {
|
override fun getRoom(roomId: RoomId): MatrixRoom? {
|
||||||
val slidingSyncRoom = slidingSync.getRoom(roomId.value) ?: return null
|
val roomListItem = roomList.room(roomId.value)
|
||||||
val fullRoom = slidingSyncRoom.fullRoom() ?: return null
|
val fullRoom = roomListItem.fullRoom()
|
||||||
return RustMatrixRoom(
|
return RustMatrixRoom(
|
||||||
sessionId = sessionId,
|
sessionId = sessionId,
|
||||||
slidingSyncUpdateFlow = slidingSyncObserverProxy.updateSummaryFlow,
|
roomListItem = roomListItem,
|
||||||
slidingSyncRoom = slidingSyncRoom,
|
|
||||||
innerRoom = fullRoom,
|
innerRoom = fullRoom,
|
||||||
coroutineScope = coroutineScope,
|
coroutineScope = coroutineScope,
|
||||||
coroutineDispatchers = dispatchers,
|
coroutineDispatchers = dispatchers,
|
||||||
clock = clock,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,9 +178,11 @@ class RustMatrixClient constructor(
|
||||||
|
|
||||||
// Wait to receive the room back from the sync
|
// Wait to receive the room back from the sync
|
||||||
withTimeout(30_000L) {
|
withTimeout(30_000L) {
|
||||||
slidingSyncObserverProxy.updateSummaryFlow.filter { roomId.value in it.rooms }.first()
|
roomSummaryDataSource.roomSummaries()
|
||||||
|
.filter { roomSummaries ->
|
||||||
|
roomSummaries.map { it.identifier() }.contains(roomId.value)
|
||||||
|
}.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
roomId
|
roomId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -301,7 +220,7 @@ class RustMatrixClient constructor(
|
||||||
|
|
||||||
override fun startSync() {
|
override fun startSync() {
|
||||||
if (isSyncing.compareAndSet(false, true)) {
|
if (isSyncing.compareAndSet(false, true)) {
|
||||||
slidingSyncObserverToken = slidingSync.sync()
|
slidingSyncObserverToken = roomList.sync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,16 +233,11 @@ class RustMatrixClient constructor(
|
||||||
override fun close() {
|
override fun close() {
|
||||||
slidingSyncUpdateJob?.cancel()
|
slidingSyncUpdateJob?.cancel()
|
||||||
stopSync()
|
stopSync()
|
||||||
slidingSync.setObserver(null)
|
|
||||||
rustRoomSummaryDataSource.close()
|
rustRoomSummaryDataSource.close()
|
||||||
rustInvitesDataSource.close()
|
rustInvitesDataSource.close()
|
||||||
client.setDelegate(null)
|
client.setDelegate(null)
|
||||||
visibleRoomsSlidingSyncListBuilder.destroy()
|
|
||||||
invitesSlidingSyncListBuilder.destroy()
|
|
||||||
visibleRoomsSlidingSyncList.resetReplayCache()
|
|
||||||
invitesSlidingSyncList.resetReplayCache()
|
|
||||||
slidingSync.destroy()
|
|
||||||
verificationService.destroy()
|
verificationService.destroy()
|
||||||
|
roomList.destroy()
|
||||||
client.destroy()
|
client.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package io.element.android.libraries.matrix.impl.room
|
||||||
|
|
||||||
|
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
||||||
|
import kotlinx.coroutines.channels.trySendBlocking
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
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.RoomListState
|
||||||
|
import org.matrix.rustcomponents.sdk.RoomListStateListener
|
||||||
|
import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState
|
||||||
|
import org.matrix.rustcomponents.sdk.SlidingSyncListStateObserver
|
||||||
|
|
||||||
|
fun RoomList.stateFlow(): Flow<RoomListState> =
|
||||||
|
mxCallbackFlow {
|
||||||
|
val listener = object : RoomListStateListener {
|
||||||
|
override fun onUpdate(state: RoomListState) {
|
||||||
|
trySendBlocking(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RoomList.loadingStateFlow(): Flow<SlidingSyncListLoadingState> =
|
||||||
|
mxCallbackFlow {
|
||||||
|
val listener = object : SlidingSyncListStateObserver {
|
||||||
|
override fun didReceiveUpdate(newState: SlidingSyncListLoadingState) {
|
||||||
|
trySendBlocking(newState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = entriesLoadingState(listener)
|
||||||
|
send(result.entriesLoadingState)
|
||||||
|
result.entriesLoadingStateStream
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List<RoomListEntry>) -> Unit): Flow<RoomListEntriesUpdate> =
|
||||||
|
mxCallbackFlow {
|
||||||
|
val listener = object : RoomListEntriesListener {
|
||||||
|
override fun onUpdate(roomEntriesUpdate: RoomListEntriesUpdate) {
|
||||||
|
trySendBlocking(roomEntriesUpdate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = entries(listener)
|
||||||
|
onInitialList(result.entries)
|
||||||
|
result.entriesStream
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -20,27 +20,24 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.room.RoomSummaryDetails
|
import io.element.android.libraries.matrix.api.room.RoomSummaryDetails
|
||||||
import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory
|
import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory
|
||||||
import org.matrix.rustcomponents.sdk.Room
|
import org.matrix.rustcomponents.sdk.Room
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
import org.matrix.rustcomponents.sdk.RoomListItem
|
||||||
|
|
||||||
class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) {
|
class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory()) {
|
||||||
|
|
||||||
fun create(slidingSyncRoom: SlidingSyncRoom, room: Room?): RoomSummaryDetails {
|
fun create(roomListItem: RoomListItem, room: Room?): RoomSummaryDetails {
|
||||||
val latestRoomMessage = slidingSyncRoom.latestRoomMessage()?.use {
|
val latestRoomMessage = roomListItem.latestEvent()?.use {
|
||||||
roomMessageFactory.create(it)
|
roomMessageFactory.create(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return RoomSummaryDetails(
|
return RoomSummaryDetails(
|
||||||
roomId = RoomId(slidingSyncRoom.roomId()),
|
roomId = RoomId(roomListItem.id()),
|
||||||
name = slidingSyncRoom.name() ?: slidingSyncRoom.roomId(),
|
name = roomListItem.name() ?: roomListItem.id(),
|
||||||
canonicalAlias = room?.canonicalAlias(),
|
canonicalAlias = room?.canonicalAlias(),
|
||||||
isDirect = room?.isDirect() ?: false,
|
isDirect = room?.isDirect() ?: false,
|
||||||
avatarURLString = room?.avatarUrl(),
|
avatarURLString = room?.avatarUrl(),
|
||||||
unreadNotificationCount = slidingSyncRoom.unreadNotifications().use { it.notificationCount().toInt() },
|
unreadNotificationCount = roomListItem.unreadNotifications().use { it.notificationCount().toInt() },
|
||||||
lastMessage = latestRoomMessage,
|
lastMessage = latestRoomMessage,
|
||||||
lastMessageTimestamp = latestRoomMessage?.originServerTs,
|
lastMessageTimestamp = latestRoomMessage?.originServerTs,
|
||||||
inviter = room?.inviter()?.let(RoomMemberMapper::map),
|
inviter = room?.inviter()?.let(RoomMemberMapper::map),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,30 +34,28 @@ import io.element.android.libraries.matrix.impl.media.map
|
||||||
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
|
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
|
||||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onStart
|
import kotlinx.coroutines.flow.onStart
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.rustcomponents.sdk.Room
|
import org.matrix.rustcomponents.sdk.Room
|
||||||
|
import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate
|
||||||
|
import org.matrix.rustcomponents.sdk.RoomListItem
|
||||||
import org.matrix.rustcomponents.sdk.RoomMember
|
import org.matrix.rustcomponents.sdk.RoomMember
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
|
||||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
|
||||||
import org.matrix.rustcomponents.sdk.genTransactionId
|
import org.matrix.rustcomponents.sdk.genTransactionId
|
||||||
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
|
import org.matrix.rustcomponents.sdk.messageEventContentFromMarkdown
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class RustMatrixRoom(
|
class RustMatrixRoom(
|
||||||
override val sessionId: SessionId,
|
override val sessionId: SessionId,
|
||||||
private val slidingSyncUpdateFlow: Flow<UpdateSummary>,
|
private val roomListItem: RoomListItem,
|
||||||
private val slidingSyncRoom: SlidingSyncRoom,
|
|
||||||
private val innerRoom: Room,
|
private val innerRoom: Room,
|
||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
private val clock: SystemClock,
|
|
||||||
) : MatrixRoom {
|
) : MatrixRoom {
|
||||||
|
|
||||||
override val membersStateFlow: StateFlow<MatrixRoomMembersState>
|
override val membersStateFlow: StateFlow<MatrixRoomMembersState>
|
||||||
|
|
@ -69,21 +67,15 @@ class RustMatrixRoom(
|
||||||
RustMatrixTimeline(
|
RustMatrixTimeline(
|
||||||
matrixRoom = this,
|
matrixRoom = this,
|
||||||
innerRoom = innerRoom,
|
innerRoom = innerRoom,
|
||||||
slidingSyncRoom = slidingSyncRoom,
|
roomListItem = roomListItem,
|
||||||
coroutineScope = coroutineScope,
|
coroutineScope = coroutineScope,
|
||||||
coroutineDispatchers = coroutineDispatchers
|
coroutineDispatchers = coroutineDispatchers
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun syncUpdateFlow(): Flow<Long> {
|
override fun syncUpdateFlow(): Flow<Long> {
|
||||||
return slidingSyncUpdateFlow
|
//TODO branch this somehow...
|
||||||
.filter {
|
return emptyFlow()
|
||||||
it.rooms.contains(roomId.value)
|
|
||||||
}
|
|
||||||
.map {
|
|
||||||
clock.epochMillis()
|
|
||||||
}
|
|
||||||
.onStart { emit(clock.epochMillis()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun timeline(): MatrixTimeline {
|
override fun timeline(): MatrixTimeline {
|
||||||
|
|
@ -92,14 +84,14 @@ class RustMatrixRoom(
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
innerRoom.destroy()
|
innerRoom.destroy()
|
||||||
slidingSyncRoom.destroy()
|
roomListItem.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val roomId = RoomId(innerRoom.id())
|
override val roomId = RoomId(innerRoom.id())
|
||||||
|
|
||||||
override val name: String?
|
override val name: String?
|
||||||
get() {
|
get() {
|
||||||
return slidingSyncRoom.name()
|
return roomListItem.name()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val bestName: String
|
override val bestName: String
|
||||||
|
|
|
||||||
|
|
@ -19,36 +19,27 @@ package io.element.android.libraries.matrix.impl.room
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.matrix.api.room.RoomSummary
|
import io.element.android.libraries.matrix.api.room.RoomSummary
|
||||||
import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource
|
import io.element.android.libraries.matrix.api.room.RoomSummaryDataSource
|
||||||
import io.element.android.libraries.matrix.impl.sync.roomListDiff
|
|
||||||
import io.element.android.libraries.matrix.impl.sync.state
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import kotlinx.coroutines.withContext
|
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.RoomListEntry
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSync
|
import org.matrix.rustcomponents.sdk.RoomListInput
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncList
|
import org.matrix.rustcomponents.sdk.RoomListRange
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListRoomsListDiff
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncSelectiveModeBuilder
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState
|
import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState
|
||||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
internal class RustRoomSummaryDataSource(
|
internal class RustRoomSummaryDataSource(
|
||||||
private val slidingSyncUpdateFlow: Flow<UpdateSummary>,
|
private val roomList: RoomList,
|
||||||
private val slidingSync: SlidingSync,
|
|
||||||
private val slidingSyncListFlow: Flow<SlidingSyncList>,
|
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
private val roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(),
|
private val roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(),
|
||||||
) : RoomSummaryDataSource, Closeable {
|
) : RoomSummaryDataSource, Closeable {
|
||||||
|
|
@ -56,39 +47,24 @@ internal class RustRoomSummaryDataSource(
|
||||||
private val coroutineScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.io)
|
private val coroutineScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.io)
|
||||||
|
|
||||||
private val roomSummaries = MutableStateFlow<List<RoomSummary>>(emptyList())
|
private val roomSummaries = MutableStateFlow<List<RoomSummary>>(emptyList())
|
||||||
private val state = MutableStateFlow(SlidingSyncListLoadingState.NOT_LOADED)
|
private val loadingState = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded)
|
||||||
|
|
||||||
fun init() {
|
fun subscribeIfNeeded() {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
val slidingSyncList = slidingSyncListFlow.first()
|
roomList.roomListEntriesUpdateFlow { roomListEntries ->
|
||||||
val summaries = slidingSyncList.currentRoomList().map(::buildSummaryForRoomListEntry)
|
val summaries = roomListEntries.map(::buildSummaryForRoomListEntry)
|
||||||
updateRoomSummaries {
|
updateRoomSummaries {
|
||||||
addAll(summaries)
|
addAll(summaries)
|
||||||
}
|
|
||||||
|
|
||||||
slidingSyncList.roomListDiff(this)
|
|
||||||
.onEach { diffs ->
|
|
||||||
updateRoomSummaries {
|
|
||||||
applyDiff(diffs)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.launchIn(this)
|
}.onEach {
|
||||||
|
updateRoomSummaries {
|
||||||
slidingSyncList.state(this)
|
applyUpdate(it)
|
||||||
.onEach { slidingSyncState ->
|
}
|
||||||
Timber.v("New sliding sync state: $slidingSyncState")
|
}.launchIn(this)
|
||||||
state.value = slidingSyncState
|
|
||||||
}.launchIn(this)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
slidingSyncUpdateFlow
|
|
||||||
.onEach {
|
|
||||||
didReceiveSyncUpdate(it)
|
|
||||||
}.launchIn(coroutineScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
runBlocking { slidingSyncListFlow.firstOrNull() }?.close()
|
|
||||||
coroutineScope.cancel()
|
coroutineScope.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,77 +72,64 @@ internal class RustRoomSummaryDataSource(
|
||||||
return roomSummaries
|
return roomSummaries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loadingState(): StateFlow<RoomSummaryDataSource.LoadingState> {
|
||||||
|
return loadingState
|
||||||
|
}
|
||||||
|
|
||||||
override fun setSlidingSyncRange(range: IntRange) {
|
override fun setSlidingSyncRange(range: IntRange) {
|
||||||
Timber.v("setVisibleRange=$range")
|
Timber.v("setVisibleRange=$range")
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
val slidingSyncMode = SlidingSyncSelectiveModeBuilder()
|
val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt()))
|
||||||
.addRange(range.first.toUInt(), range.last.toUInt())
|
roomList.applyInput(
|
||||||
slidingSyncListFlow.first().setSyncMode(slidingSyncMode)
|
RoomListInput.Viewport(ranges)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun didReceiveSyncUpdate(summary: UpdateSummary) {
|
private fun MutableList<RoomSummary>.applyUpdate(update: RoomListEntriesUpdate) {
|
||||||
Timber.v("UpdateRooms with identifiers: ${summary.rooms}")
|
|
||||||
if (state.value != SlidingSyncListLoadingState.FULLY_LOADED) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
updateRoomSummaries {
|
|
||||||
for (identifier in summary.rooms) {
|
|
||||||
val index = indexOfFirst { it.identifier() == identifier }
|
|
||||||
if (index == -1) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
val updatedRoomSummary = buildRoomSummaryForIdentifier(identifier)
|
|
||||||
set(index, updatedRoomSummary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableList<RoomSummary>.applyDiff(diff: SlidingSyncListRoomsListDiff) {
|
|
||||||
fun MutableList<RoomSummary>.fillUntil(untilIndex: Int) {
|
fun MutableList<RoomSummary>.fillUntil(untilIndex: Int) {
|
||||||
repeat((size - 1 until untilIndex).count()) {
|
repeat((size - 1 until untilIndex).count()) {
|
||||||
add(buildEmptyRoomSummary())
|
add(buildEmptyRoomSummary())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Timber.v("ApplyDiff: $diff for list with size: $size")
|
when (update) {
|
||||||
when (diff) {
|
is RoomListEntriesUpdate.Append -> {
|
||||||
is SlidingSyncListRoomsListDiff.Append -> {
|
val roomSummaries = update.values.map {
|
||||||
val roomSummaries = diff.values.map {
|
|
||||||
buildSummaryForRoomListEntry(it)
|
buildSummaryForRoomListEntry(it)
|
||||||
}
|
}
|
||||||
addAll(roomSummaries)
|
addAll(roomSummaries)
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.PushBack -> {
|
is RoomListEntriesUpdate.PushBack -> {
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(update.value)
|
||||||
add(roomSummary)
|
add(roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.PushFront -> {
|
is RoomListEntriesUpdate.PushFront -> {
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(update.value)
|
||||||
add(0, roomSummary)
|
add(0, roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.Set -> {
|
is RoomListEntriesUpdate.Set -> {
|
||||||
fillUntil(diff.index.toInt())
|
fillUntil(update.index.toInt())
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(update.value)
|
||||||
set(diff.index.toInt(), roomSummary)
|
set(update.index.toInt(), roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.Insert -> {
|
is RoomListEntriesUpdate.Insert -> {
|
||||||
val roomSummary = buildSummaryForRoomListEntry(diff.value)
|
val roomSummary = buildSummaryForRoomListEntry(update.value)
|
||||||
add(diff.index.toInt(), roomSummary)
|
add(update.index.toInt(), roomSummary)
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.Remove -> {
|
is RoomListEntriesUpdate.Remove -> {
|
||||||
removeAt(diff.index.toInt())
|
removeAt(update.index.toInt())
|
||||||
}
|
}
|
||||||
is SlidingSyncListRoomsListDiff.Reset -> {
|
is RoomListEntriesUpdate.Reset -> {
|
||||||
clear()
|
clear()
|
||||||
addAll(diff.values.map { buildSummaryForRoomListEntry(it) })
|
addAll(update.values.map { buildSummaryForRoomListEntry(it) })
|
||||||
}
|
}
|
||||||
SlidingSyncListRoomsListDiff.PopBack -> {
|
RoomListEntriesUpdate.PopBack -> {
|
||||||
removeFirstOrNull()
|
removeFirstOrNull()
|
||||||
}
|
}
|
||||||
SlidingSyncListRoomsListDiff.PopFront -> {
|
RoomListEntriesUpdate.PopFront -> {
|
||||||
removeLastOrNull()
|
removeLastOrNull()
|
||||||
}
|
}
|
||||||
SlidingSyncListRoomsListDiff.Clear -> {
|
RoomListEntriesUpdate.Clear -> {
|
||||||
clear()
|
clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -185,14 +148,13 @@ internal class RustRoomSummaryDataSource(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary {
|
private fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary {
|
||||||
val slidingSyncRoom = slidingSync.getRoom(identifier) ?: return RoomSummary.Empty(identifier)
|
return roomList.room(identifier).use { roomListItem ->
|
||||||
val fullRoom = slidingSyncRoom.fullRoom()
|
roomListItem.fullRoom().use { fullRoom ->
|
||||||
val roomSummary = RoomSummary.Filled(
|
RoomSummary.Filled(
|
||||||
details = roomSummaryDetailsFactory.create(slidingSyncRoom, fullRoom)
|
details = roomSummaryDetailsFactory.create(roomListItem, fullRoom)
|
||||||
)
|
)
|
||||||
fullRoom?.destroy()
|
}
|
||||||
slidingSyncRoom.destroy()
|
}
|
||||||
return roomSummary
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateRoomSummaries(block: MutableList<RoomSummary>.() -> Unit) =
|
private suspend fun updateRoomSummaries(block: MutableList<RoomSummary>.() -> Unit) =
|
||||||
|
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.impl.sync
|
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncList
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListRoomListObserver
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListRoomsCountObserver
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListRoomsListDiff
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncListStateObserver
|
|
||||||
|
|
||||||
fun SlidingSyncList.roomListDiff(scope: CoroutineScope): Flow<SlidingSyncListRoomsListDiff> =
|
|
||||||
mxCallbackFlow {
|
|
||||||
val observer = object : SlidingSyncListRoomListObserver {
|
|
||||||
override fun didReceiveUpdate(diff: SlidingSyncListRoomsListDiff) {
|
|
||||||
scope.launch {
|
|
||||||
send(diff)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observeRoomList(observer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SlidingSyncList.state(scope: CoroutineScope): Flow<SlidingSyncListLoadingState> = mxCallbackFlow {
|
|
||||||
val observer = object : SlidingSyncListStateObserver {
|
|
||||||
override fun didReceiveUpdate(newState: SlidingSyncListLoadingState) {
|
|
||||||
scope.launch {
|
|
||||||
send(newState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observeState(observer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SlidingSyncList.roomsCount(scope: CoroutineScope): Flow<UInt> = mxCallbackFlow {
|
|
||||||
val observer = object : SlidingSyncListRoomsCountObserver {
|
|
||||||
override fun didReceiveUpdate(count: UInt) {
|
|
||||||
scope.launch {
|
|
||||||
send(count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observeRoomsCount(observer)
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2022 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.element.android.libraries.matrix.impl.sync
|
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncObserver
|
|
||||||
import org.matrix.rustcomponents.sdk.UpdateSummary
|
|
||||||
|
|
||||||
// Sounds like a reasonable buffer size before it suspends emitting new items.
|
|
||||||
private const val BUFFER_SIZE = 64
|
|
||||||
|
|
||||||
class SlidingSyncObserverProxy(
|
|
||||||
private val coroutineScope: CoroutineScope,
|
|
||||||
) : SlidingSyncObserver {
|
|
||||||
|
|
||||||
private val updateSummaryMutableFlow =
|
|
||||||
MutableSharedFlow<UpdateSummary>(extraBufferCapacity = BUFFER_SIZE)
|
|
||||||
val updateSummaryFlow: SharedFlow<UpdateSummary> = updateSummaryMutableFlow.asSharedFlow()
|
|
||||||
|
|
||||||
override fun didReceiveSyncUpdate(summary: UpdateSummary) {
|
|
||||||
coroutineScope.launch {
|
|
||||||
updateSummaryMutableFlow.emit(summary)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -37,10 +37,10 @@ internal class MatrixTimelineDiffProcessor(
|
||||||
private val timelineItemFactory: MatrixTimelineItemMapper,
|
private val timelineItemFactory: MatrixTimelineItemMapper,
|
||||||
) : TimelineListener {
|
) : TimelineListener {
|
||||||
|
|
||||||
override fun onUpdate(update: TimelineDiff) {
|
override fun onUpdate(diff: TimelineDiff) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
updateTimelineItems {
|
updateTimelineItems {
|
||||||
applyDiff(update)
|
applyDiff(diff)
|
||||||
}
|
}
|
||||||
when (val firstItem = timelineItems.value.firstOrNull()) {
|
when (val firstItem = timelineItems.value.firstOrNull()) {
|
||||||
is MatrixTimelineItem.Virtual -> updateBackPaginationState(firstItem.virtual)
|
is MatrixTimelineItem.Virtual -> updateBackPaginationState(firstItem.virtual)
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ import kotlinx.coroutines.withContext
|
||||||
import org.matrix.rustcomponents.sdk.PaginationOptions
|
import org.matrix.rustcomponents.sdk.PaginationOptions
|
||||||
import org.matrix.rustcomponents.sdk.RequiredState
|
import org.matrix.rustcomponents.sdk.RequiredState
|
||||||
import org.matrix.rustcomponents.sdk.Room
|
import org.matrix.rustcomponents.sdk.Room
|
||||||
|
import org.matrix.rustcomponents.sdk.RoomListItem
|
||||||
import org.matrix.rustcomponents.sdk.RoomSubscription
|
import org.matrix.rustcomponents.sdk.RoomSubscription
|
||||||
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
import org.matrix.rustcomponents.sdk.SlidingSyncRoom
|
||||||
import org.matrix.rustcomponents.sdk.TimelineItem
|
import org.matrix.rustcomponents.sdk.TimelineItem
|
||||||
|
|
@ -48,7 +49,7 @@ import java.util.concurrent.atomic.AtomicBoolean
|
||||||
class RustMatrixTimeline(
|
class RustMatrixTimeline(
|
||||||
private val matrixRoom: MatrixRoom,
|
private val matrixRoom: MatrixRoom,
|
||||||
private val innerRoom: Room,
|
private val innerRoom: Room,
|
||||||
private val slidingSyncRoom: SlidingSyncRoom,
|
private val roomListItem: RoomListItem,
|
||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
) : MatrixTimeline {
|
) : MatrixTimeline {
|
||||||
|
|
@ -166,12 +167,12 @@ class RustMatrixTimeline(
|
||||||
),
|
),
|
||||||
timelineLimit = null
|
timelineLimit = null
|
||||||
)
|
)
|
||||||
slidingSyncRoom.subscribeToRoom(settings)
|
roomListItem.subscribe(settings)
|
||||||
val result = slidingSyncRoom.addTimelineListener(timelineListener)
|
val result = innerRoom.addTimelineListener(timelineListener)
|
||||||
launch {
|
launch {
|
||||||
fetchMembers()
|
fetchMembers()
|
||||||
}
|
}
|
||||||
listenerTokens += result.taskHandle
|
listenerTokens += result.itemsStream
|
||||||
result.items
|
result.items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue