diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt index 0bcf9000e7..b69162b3ce 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RoomFlowNode.kt @@ -18,7 +18,6 @@ package io.element.android.appnav import android.os.Parcelable import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope import com.bumble.appyx.core.composable.Children @@ -83,6 +82,7 @@ class RoomFlowNode @AssistedInject constructor( lifecycle.subscribe( onCreate = { Timber.v("OnCreate") + inputs.room.open() plugins().forEach { it.onFlowCreated(id, inputs.room) } appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId) fetchRoomMembers() @@ -149,18 +149,8 @@ class RoomFlowNode @AssistedInject constructor( data class RoomMemberDetails(val userId: UserId) : NavTarget } - private val timeline = inputs.room.timeline() - @Composable override fun View(modifier: Modifier) { - - DisposableEffect(Unit) { - timeline.initialize() - onDispose { - timeline.dispose() - } - } - Children( navModel = backstack, modifier = modifier, diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/childScopeOf.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/childScopeOf.kt new file mode 100644 index 0000000000..060431fdee --- /dev/null +++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/coroutine/childScopeOf.kt @@ -0,0 +1,33 @@ +/* + * 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.core.coroutine + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineName +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.job +import kotlinx.coroutines.plus + +fun childScopeOf( + parentScope: CoroutineScope, + dispatcher: CoroutineDispatcher, + name: String, +): CoroutineScope = run { + val supervisorJob = SupervisorJob(parent = parentScope.coroutineContext.job) + parentScope + dispatcher + supervisorJob + CoroutineName(name) +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 0ddd75966b..b6f685a775 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -61,6 +61,8 @@ interface MatrixRoom : Closeable { fun timeline(): MatrixTimeline + fun open(): Result + suspend fun userDisplayName(userId: UserId): Result suspend fun userAvatarUrl(userId: UserId): Result diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/MatrixTimeline.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/MatrixTimeline.kt index 4eaf04d775..1f45a0ddac 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/MatrixTimeline.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/MatrixTimeline.kt @@ -28,20 +28,8 @@ interface MatrixTimeline { ) fun paginationState(): StateFlow - fun timelineItems(): Flow> + suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result - fun initialize() - fun dispose() - - /** - * @param message markdown message - */ - suspend fun sendMessage(message: String): Result - - suspend fun editMessage(originalEventId: EventId, message: String): Result - - suspend fun replyMessage(inReplyToEventId: EventId, message: String): Result - suspend fun fetchDetailsForEvent(eventId: EventId): Result } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index e0cf58d3de..b01cca4481 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -19,6 +19,7 @@ package io.element.android.libraries.matrix.impl import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.coroutine.childScopeOf import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId @@ -39,6 +40,7 @@ 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.room.RustMatrixRoom import io.element.android.libraries.matrix.impl.room.RustRoomSummaryDataSource +import io.element.android.libraries.matrix.impl.room.roomOrNull 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.verification.RustSessionVerificationService @@ -47,7 +49,7 @@ import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext @@ -66,7 +68,7 @@ import org.matrix.rustcomponents.sdk.RoomVisibility as RustRoomVisibility class RustMatrixClient constructor( private val client: Client, private val sessionStore: SessionStore, - private val coroutineScope: CoroutineScope, + private val appCoroutineScope: CoroutineScope, private val dispatchers: CoroutineDispatchers, private val baseDirectory: File, private val baseCacheDirectory: File, @@ -75,13 +77,13 @@ class RustMatrixClient constructor( override val sessionId: UserId = UserId(client.userId()) + private val sessionCoroutineScope = childScopeOf(appCoroutineScope, dispatchers.main, "Session-${sessionId}") private val verificationService = RustSessionVerificationService() private val pushersService = RustPushersService( client = client, dispatchers = dispatchers, ) private val notificationService = RustNotificationService(client) - private var slidingSyncUpdateJob: Job? = null private val clientDelegate = object : ClientDelegate { override fun didReceiveAuthError(isSoftLogout: Boolean) { @@ -95,6 +97,7 @@ class RustMatrixClient constructor( private val rustRoomSummaryDataSource: RustRoomSummaryDataSource = RustRoomSummaryDataSource( roomList, + sessionCoroutineScope, dispatchers, ) @@ -104,6 +107,7 @@ class RustMatrixClient constructor( private val rustInvitesDataSource: RustRoomSummaryDataSource = RustRoomSummaryDataSource( roomList, + sessionCoroutineScope, dispatchers, ) @@ -127,14 +131,15 @@ class RustMatrixClient constructor( } override fun getRoom(roomId: RoomId): MatrixRoom? { - val roomListItem = roomList.room(roomId.value) + val roomListItem = roomList.roomOrNull(roomId.value) ?: return null val fullRoom = roomListItem.fullRoom() return RustMatrixRoom( sessionId = sessionId, roomListItem = roomListItem, innerRoom = fullRoom, - coroutineScope = coroutineScope, + sessionCoroutineScope = sessionCoroutineScope, coroutineDispatchers = dispatchers, + systemClock = clock ) } @@ -231,10 +236,8 @@ class RustMatrixClient constructor( } override fun close() { - slidingSyncUpdateJob?.cancel() stopSync() - rustRoomSummaryDataSource.close() - rustInvitesDataSource.close() + sessionCoroutineScope.cancel() client.setDelegate(null) verificationService.destroy() roomList.destroy() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index d599029923..5b7b17dce6 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -52,7 +52,7 @@ import org.matrix.rustcomponents.sdk.AuthenticationService as RustAuthentication class RustMatrixAuthenticationService @Inject constructor( @ApplicationContext private val context: Context, private val baseDirectory: File, - private val coroutineScope: CoroutineScope, + private val appCoroutineScope: CoroutineScope, private val coroutineDispatchers: CoroutineDispatchers, private val sessionStore: SessionStore, private val clock: SystemClock, @@ -179,7 +179,7 @@ class RustMatrixAuthenticationService @Inject constructor( return RustMatrixClient( client = client, sessionStore = sessionStore, - coroutineScope = coroutineScope, + appCoroutineScope = appCoroutineScope, dispatchers = coroutineDispatchers, baseDirectory = baseDirectory, baseCacheDirectory = context.cacheDir, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListFlows.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt similarity index 86% rename from libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListFlows.kt rename to libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt index e9d34e468d..b77bd7fee3 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListFlows.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RoomListExtensions.kt @@ -7,10 +7,12 @@ 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.RoomListItem import org.matrix.rustcomponents.sdk.RoomListState import org.matrix.rustcomponents.sdk.RoomListStateListener import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState import org.matrix.rustcomponents.sdk.SlidingSyncListStateObserver +import timber.log.Timber fun RoomList.stateFlow(): Flow = mxCallbackFlow { @@ -46,3 +48,11 @@ fun RoomList.roomListEntriesUpdateFlow(onInitialList: suspend (List get() = _membersStateFlow private var _membersStateFlow = MutableStateFlow(MatrixRoomMembersState.Unknown) + private val isInit = MutableStateFlow(false) + private val syncUpdateFlow = MutableStateFlow(systemClock.epochMillis()) private val timeline by lazy { RustMatrixTimeline( matrixRoom = this, innerRoom = innerRoom, - roomListItem = roomListItem, - coroutineScope = coroutineScope, + coroutineScope = roomCoroutineScope, coroutineDispatchers = coroutineDispatchers ) } override fun syncUpdateFlow(): Flow { - //TODO branch this somehow... - return emptyFlow() + return syncUpdateFlow } override fun timeline(): MatrixTimeline { return timeline } - override fun close() { - innerRoom.destroy() - roomListItem.destroy() + override fun open(): Result { + if (isInit.value) return Result.failure(IllegalStateException("Listener already registered")) + val settings = RoomSubscription( + requiredState = listOf( + RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""), + RequiredState(key = EventType.STATE_ROOM_TOPIC, value = ""), + RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""), + RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""), + ), + timelineLimit = null + ) + roomListItem.subscribe(settings) + innerRoom.timelineDiffFlow { initialList -> + timeline.postItems(initialList) + }.onEach { + syncUpdateFlow.value = systemClock.epochMillis() + timeline.postDiff(it) + }.launchIn(roomCoroutineScope) + roomCoroutineScope.launch { + fetchMembers() + } + isInit.value = true + return Result.success(Unit) } - override val roomId = RoomId(innerRoom.id()) + override fun close() { + if(isInit.value) { + isInit.value = false + roomCoroutineScope.cancel() + roomListItem.unsubscribe() + innerRoom.destroy() + roomListItem.destroy() + } + } override val name: String? get() { @@ -264,7 +301,7 @@ class RustMatrixRoom( } } - override suspend fun cancelSend(transactionId: String): Result = + override suspend fun cancelSend(transactionId: String): Result = withContext(coroutineDispatchers.io) { runCatching { innerRoom.cancelSend(transactionId) @@ -299,4 +336,10 @@ class RustMatrixRoom( innerRoom.setTopic(topic) } } + + private suspend fun fetchMembers() = withContext(coroutineDispatchers.io) { + runCatching { + innerRoom.fetchMembers() + } + } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt index bf32155db8..9c0ea49dd5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomSummaryDataSource.kt @@ -20,8 +20,6 @@ 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.RoomSummaryDataSource import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.launchIn @@ -33,24 +31,21 @@ import org.matrix.rustcomponents.sdk.RoomListEntriesUpdate import org.matrix.rustcomponents.sdk.RoomListEntry import org.matrix.rustcomponents.sdk.RoomListInput import org.matrix.rustcomponents.sdk.RoomListRange -import org.matrix.rustcomponents.sdk.SlidingSyncListLoadingState import timber.log.Timber -import java.io.Closeable import java.util.UUID internal class RustRoomSummaryDataSource( private val roomList: RoomList, + private val sessionCoroutineScope: CoroutineScope, private val coroutineDispatchers: CoroutineDispatchers, private val roomSummaryDetailsFactory: RoomSummaryDetailsFactory = RoomSummaryDetailsFactory(), -) : RoomSummaryDataSource, Closeable { - - private val coroutineScope = CoroutineScope(SupervisorJob() + coroutineDispatchers.io) +) : RoomSummaryDataSource { private val roomSummaries = MutableStateFlow>(emptyList()) private val loadingState = MutableStateFlow(RoomSummaryDataSource.LoadingState.NotLoaded) fun subscribeIfNeeded() { - coroutineScope.launch { + sessionCoroutineScope.launch { roomList.roomListEntriesUpdateFlow { roomListEntries -> val summaries = roomListEntries.map(::buildSummaryForRoomListEntry) updateRoomSummaries { @@ -64,10 +59,6 @@ internal class RustRoomSummaryDataSource( } } - override fun close() { - coroutineScope.cancel() - } - override fun roomSummaries(): StateFlow> { return roomSummaries } @@ -78,7 +69,7 @@ internal class RustRoomSummaryDataSource( override fun setSlidingSyncRange(range: IntRange) { Timber.v("setVisibleRange=$range") - coroutineScope.launch { + sessionCoroutineScope.launch { val ranges = listOf(RoomListRange(range.first.toUInt(), range.last.toUInt())) roomList.applyInput( RoomListInput.Viewport(ranges) @@ -148,7 +139,8 @@ internal class RustRoomSummaryDataSource( } private fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary { - return roomList.room(identifier).use { roomListItem -> + val roomListItem = roomList.roomOrNull(identifier) ?: return RoomSummary.Empty(identifier) + return roomListItem.use { roomListItem.fullRoom().use { fullRoom -> RoomSummary.Filled( details = roomSummaryDetailsFactory.create(roomListItem, fullRoom) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt index 58a6f75ef1..bd30d826f2 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/MatrixTimelineDiffProcessor.kt @@ -36,7 +36,7 @@ internal class MatrixTimelineDiffProcessor( private val timelineItemFactory: MatrixTimelineItemMapper, ) { - fun onUpdate(diff: TimelineDiff) { + fun postDiff(diff: TimelineDiff) { coroutineScope.launch { updateTimelineItems { applyDiff(diff) @@ -122,4 +122,5 @@ internal class MatrixTimelineDiffProcessor( private fun TimelineItem.asMatrixTimelineItem(): MatrixTimelineItem { return timelineItemFactory.map(this) } + } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt index 36044e8c11..dcb518bf98 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustMatrixTimeline.kt @@ -21,40 +21,30 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.MatrixTimeline import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem -import io.element.android.libraries.matrix.api.timeline.item.event.EventType import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEventContentMapper import io.element.android.libraries.matrix.impl.timeline.item.virtual.VirtualTimelineItemMapper -import io.element.android.libraries.matrix.impl.util.TaskHandleBag import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.sample -import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.PaginationOptions -import org.matrix.rustcomponents.sdk.RequiredState import org.matrix.rustcomponents.sdk.Room -import org.matrix.rustcomponents.sdk.RoomListItem -import org.matrix.rustcomponents.sdk.RoomSubscription +import org.matrix.rustcomponents.sdk.TimelineDiff +import org.matrix.rustcomponents.sdk.TimelineItem import timber.log.Timber -import java.util.concurrent.atomic.AtomicBoolean class RustMatrixTimeline( + coroutineScope: CoroutineScope, private val matrixRoom: MatrixRoom, private val innerRoom: Room, - private val roomListItem: RoomListItem, - private val coroutineScope: CoroutineScope, private val coroutineDispatchers: CoroutineDispatchers, ) : MatrixTimeline { - private val isInit = AtomicBoolean(false) - private val timelineItems: MutableStateFlow> = MutableStateFlow(emptyList()) @@ -81,7 +71,6 @@ class RustMatrixTimeline( timelineItemFactory = timelineItemFactory, ) - private val listenerTokens = TaskHandleBag() override fun paginationState(): StateFlow { return paginationState } @@ -91,38 +80,12 @@ class RustMatrixTimeline( return timelineItems.sample(50) } - override fun initialize() { - Timber.v("Init timeline for room ${matrixRoom.roomId}") - coroutineScope.launch { - subscribeAndAddListener(this) - .onSuccess { - isInit.set(true) - } - .onFailure { - Timber.e("Failed adding timeline listener on room with identifier: ${matrixRoom.roomId})") - } - } + internal fun postItems(items: List) { + timelineItems.value = items.map(timelineItemFactory::map) } - override fun dispose() { - Timber.v("Dispose timeline for room ${matrixRoom.roomId}") - listenerTokens.dispose() - isInit.set(false) - } - - /** - * @param message markdown message - */ - override suspend fun sendMessage(message: String): Result { - return matrixRoom.sendMessage(message) - } - - override suspend fun editMessage(originalEventId: EventId, message: String): Result { - return matrixRoom.editMessage(originalEventId, message = message) - } - - override suspend fun replyMessage(inReplyToEventId: EventId, message: String): Result { - return matrixRoom.replyMessage(inReplyToEventId, message) + internal fun postDiff(timelineDiff: TimelineDiff) { + timelineDiffProcessor.postDiff(timelineDiff) } override suspend fun fetchDetailsForEvent(eventId: EventId): Result = withContext(coroutineDispatchers.io) { @@ -134,9 +97,6 @@ class RustMatrixTimeline( override suspend fun paginateBackwards(requestSize: Int, untilNumberOfItems: Int): Result = withContext(coroutineDispatchers.io) { runCatching { Timber.v("Start back paginating for room ${matrixRoom.roomId} ") - if (!isInit.get()) { - throw IllegalStateException("Timeline is not init yet") - } val paginationOptions = PaginationOptions.UntilNumItems( eventLimit = requestSize.toUShort(), items = untilNumberOfItems.toUShort(), @@ -149,30 +109,4 @@ class RustMatrixTimeline( Timber.v("Success back paginating for room ${matrixRoom.roomId}") } } - - private fun subscribeAndAddListener(coroutineScope: CoroutineScope): Result { - return runCatching { - val settings = RoomSubscription( - requiredState = listOf( - RequiredState(key = EventType.STATE_ROOM_CANONICAL_ALIAS, value = ""), - RequiredState(key = EventType.STATE_ROOM_TOPIC, value = ""), - RequiredState(key = EventType.STATE_ROOM_JOIN_RULES, value = ""), - RequiredState(key = EventType.STATE_ROOM_POWER_LEVELS, value = ""), - ), - timelineLimit = null - ) - roomListItem.subscribe(settings) - innerRoom.timelineDiffFlow { initialList -> - timelineItems.value = initialList.map(timelineItemFactory::map) - }.onEach { - timelineDiffProcessor.onUpdate(it) - }.launchIn(coroutineScope) - } - } - - private suspend fun fetchMembers() = withContext(coroutineDispatchers.io) { - runCatching { - innerRoom.fetchMembers() - } - } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeMatrixTimeline.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeMatrixTimeline.kt index 696a778df2..5adc8b8404 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeMatrixTimeline.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeMatrixTimeline.kt @@ -71,18 +71,6 @@ class FakeMatrixTimeline( isInitialized = false } - override suspend fun sendMessage(message: String): Result { - return Result.success(Unit) - } - - override suspend fun editMessage(originalEventId: EventId, message: String): Result { - return Result.success(Unit) - } - - override suspend fun replyMessage(inReplyToEventId: EventId, message: String): Result { - return Result.success(Unit) - } - override suspend fun fetchDetailsForEvent(eventId: EventId): Result { return Result.success(Unit) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index 62602a475b..39a655f06c 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -42,7 +42,7 @@ class MainActivity : ComponentActivity() { RustMatrixAuthenticationService( context = applicationContext, baseDirectory = baseDirectory, - coroutineScope = Singleton.appScope, + appCoroutineScope = Singleton.appScope, coroutineDispatchers = Singleton.coroutineDispatchers, sessionStore = InMemorySessionStore(), clock = DefaultSystemClock()