Room navigation : more reliable roomInfoFlow method

This commit is contained in:
ganfra 2024-04-10 11:41:06 +02:00
parent 23604e0549
commit fc20b7399a
14 changed files with 75 additions and 74 deletions

View file

@ -44,13 +44,11 @@ import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.inputs import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
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.RoomId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
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.roomlist.RoomListService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
@ -61,7 +59,7 @@ import kotlin.jvm.optionals.getOrNull
class RoomFlowNode @AssistedInject constructor( class RoomFlowNode @AssistedInject constructor(
@Assisted val buildContext: BuildContext, @Assisted val buildContext: BuildContext,
@Assisted plugins: List<Plugin>, @Assisted plugins: List<Plugin>,
private val roomListService: RoomListService, private val client: MatrixClient,
private val roomMembershipObserver: RoomMembershipObserver, private val roomMembershipObserver: RoomMembershipObserver,
private val joinRoomEntryPoint: JoinRoomEntryPoint, private val joinRoomEntryPoint: JoinRoomEntryPoint,
) : BaseFlowNode<RoomFlowNode.NavTarget>( ) : BaseFlowNode<RoomFlowNode.NavTarget>(
@ -92,18 +90,16 @@ class RoomFlowNode @AssistedInject constructor(
override fun onBuilt() { override fun onBuilt() {
super.onBuilt() super.onBuilt()
roomListService.getUserMembershipForRoom( client.getRoomInfoFlow(
inputs.roomId inputs.roomId
).flowOn(Dispatchers.Default) ).onEach { roomInfo ->
.onEach { membership -> Timber.d("Room membership: ${roomInfo.map { it.currentUserMembership }}")
Timber.d("RoomMembership = $membership") if (roomInfo.getOrNull()?.currentUserMembership == CurrentUserMembership.JOINED) {
if (membership.getOrNull() == CurrentUserMembership.JOINED) { backstack.newRoot(NavTarget.JoinedRoom)
backstack.newRoot(NavTarget.JoinedRoom) } else {
} else { backstack.newRoot(NavTarget.JoinRoom)
backstack.newRoot(NavTarget.JoinRoom)
}
} }
.flowOn(Dispatchers.Main) }
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
roomMembershipObserver.updates roomMembershipObserver.updates

View file

@ -30,14 +30,13 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.matrix.api.MatrixClient 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.RoomId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import java.util.Optional import java.util.Optional
import kotlin.jvm.optionals.getOrNull import kotlin.jvm.optionals.getOrNull
class JoinRoomPresenter @AssistedInject constructor( class JoinRoomPresenter @AssistedInject constructor(
@Assisted private val roomId: RoomId, @Assisted private val roomId: RoomId,
private val matrixClient: MatrixClient, private val matrixClient: MatrixClient,
private val roomListService: RoomListService,
private val acceptDeclineInvitePresenter: AcceptDeclineInvitePresenter, private val acceptDeclineInvitePresenter: AcceptDeclineInvitePresenter,
) : Presenter<JoinRoomState> { ) : Presenter<JoinRoomState> {
@ -47,23 +46,24 @@ class JoinRoomPresenter @AssistedInject constructor(
@Composable @Composable
override fun present(): JoinRoomState { override fun present(): JoinRoomState {
val userMembership by roomListService.getUserMembershipForRoom(roomId).collectAsState(initial = Optional.empty()) val mxRoomInfo by matrixClient.getRoomInfoFlow(roomId).collectAsState(initial = Optional.empty())
val joinAuthorisationStatus = joinAuthorisationStatus(userMembership) val joinAuthorisationStatus = joinAuthorisationStatus(mxRoomInfo)
val acceptDeclineInviteState = acceptDeclineInvitePresenter.present() val acceptDeclineInviteState = acceptDeclineInvitePresenter.present()
val roomInfo by produceState<AsyncData<RoomInfo>>(initialValue = AsyncData.Uninitialized, key1 = userMembership) { val roomInfo by produceState<AsyncData<RoomInfo>>(initialValue = AsyncData.Uninitialized, key1 = mxRoomInfo) {
value = when { value = when {
userMembership.isPresent -> { mxRoomInfo.isPresent -> {
val roomInfo = matrixClient.getRoom(roomId)?.use { val roomInfo = mxRoomInfo.get().let {
RoomInfo( RoomInfo(
roomId = it.roomId, roomId = roomId,
roomName = it.displayName, roomName = it.name,
roomAlias = it.alias, roomAlias = it.canonicalAlias,
memberCount = it.activeMemberCount, memberCount = it.activeMembersCount,
isDirect = it.isDirect, isDirect = it.isDirect,
topic = it.topic,
roomAvatarUrl = it.avatarUrl roomAvatarUrl = it.avatarUrl
) )
} }
roomInfo?.let { AsyncData.Success(it) } ?: AsyncData.Failure(Exception("Failed to load room info")) AsyncData.Success(roomInfo)
} }
else -> AsyncData.Uninitialized else -> AsyncData.Uninitialized
} }
@ -103,9 +103,10 @@ class JoinRoomPresenter @AssistedInject constructor(
} }
@Composable @Composable
private fun joinAuthorisationStatus(userMembership: Optional<CurrentUserMembership>): JoinAuthorisationStatus { private fun joinAuthorisationStatus(roomInfo: Optional<MatrixRoomInfo>): JoinAuthorisationStatus {
val userMembership = roomInfo.getOrNull()?.currentUserMembership
return when { return when {
userMembership.getOrNull() == CurrentUserMembership.INVITED -> return JoinAuthorisationStatus.IsInvited userMembership == CurrentUserMembership.INVITED -> return JoinAuthorisationStatus.IsInvited
else -> JoinAuthorisationStatus.Unknown else -> JoinAuthorisationStatus.Unknown
} }
} }

View file

@ -29,15 +29,16 @@ data class JoinRoomState(
val joinAuthorisationStatus: JoinAuthorisationStatus, val joinAuthorisationStatus: JoinAuthorisationStatus,
val acceptDeclineInviteState: AcceptDeclineInviteState, val acceptDeclineInviteState: AcceptDeclineInviteState,
val eventSink: (JoinRoomEvents) -> Unit val eventSink: (JoinRoomEvents) -> Unit
){ ) {
val showMemberCount = roomInfo.dataOrNull()?.memberCount != null val showMemberCount = roomInfo.dataOrNull()?.memberCount != null
} }
data class RoomInfo( data class RoomInfo(
val roomId: RoomId, val roomId: RoomId,
val roomName: String, val roomName: String?,
val roomAlias: String?, val roomAlias: String?,
val memberCount: Long?, val memberCount: Long?,
val topic: String?,
val isDirect: Boolean, val isDirect: Boolean,
val roomAvatarUrl: String?, val roomAvatarUrl: String?,
) { ) {

View file

@ -48,6 +48,7 @@ fun aJoinRoomState(
roomAlias = "#exa:matrix.org", roomAlias = "#exa:matrix.org",
memberCount = null, memberCount = null,
isDirect = false, isDirect = false,
topic = null,
roomAvatarUrl = null roomAvatarUrl = null
) )
), ),

View file

@ -203,7 +203,11 @@ private fun JoinRoomTopBar(
when (asyncRoomInfo) { when (asyncRoomInfo) {
is AsyncData.Success -> { is AsyncData.Success -> {
val roomInfo = asyncRoomInfo.data val roomInfo = asyncRoomInfo.data
RoomAvatarAndNameRow(roomName = roomInfo.roomName, roomAvatar = roomInfo.avatarData(AvatarSize.TimelineRoom)) if(roomInfo.roomName == null){
IconTitlePlaceholdersRowMolecule(iconSize = AvatarSize.TimelineRoom.dp)
}else {
RoomAvatarAndNameRow(roomName = roomInfo.roomName, roomAvatar = roomInfo.avatarData(AvatarSize.TimelineRoom))
}
} }
else -> { else -> {
IconTitlePlaceholdersRowMolecule(iconSize = AvatarSize.TimelineRoom.dp) IconTitlePlaceholdersRowMolecule(iconSize = AvatarSize.TimelineRoom.dp)

View file

@ -40,7 +40,6 @@ object JoinRoomModule {
return JoinRoomPresenter( return JoinRoomPresenter(
roomId = roomId, roomId = roomId,
matrixClient = client, matrixClient = client,
roomListService = roomListService,
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter, acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
) )
} }

View file

@ -60,7 +60,7 @@ class RoomListDataSource @Inject constructor(
fun launchIn(coroutineScope: CoroutineScope) { fun launchIn(coroutineScope: CoroutineScope) {
roomListService roomListService
.allRooms .allRooms
.summaries .filteredSummaries
.onEach { roomSummaries -> .onEach { roomSummaries ->
replaceWith(roomSummaries) replaceWith(roomSummaries)
} }

View file

@ -45,7 +45,7 @@ class RoomListSearchDataSource @Inject constructor(
source = RoomList.Source.All, source = RoomList.Source.All,
) )
val roomSummaries: Flow<PersistentList<RoomListRoomSummary>> = roomList.summaries val roomSummaries: Flow<PersistentList<RoomListRoomSummary>> = roomList.filteredSummaries
.map { roomSummaries -> .map { roomSummaries ->
roomSummaries roomSummaries
.filterIsInstance<RoomSummary.Filled>() .filterIsInstance<RoomSummary.Filled>()

View file

@ -27,7 +27,9 @@ import io.element.android.libraries.matrix.api.notification.NotificationService
import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.pusher.PushersService import io.element.android.libraries.matrix.api.pusher.PushersService
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
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.MatrixRoomInfo
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.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
@ -37,8 +39,10 @@ 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
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import java.io.Closeable import java.io.Closeable
import java.util.Optional
interface MatrixClient : Closeable { interface MatrixClient : Closeable {
val sessionId: SessionId val sessionId: SessionId
@ -89,6 +93,7 @@ interface MatrixClient : Closeable {
suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?> suspend fun getAccountManagementUrl(action: AccountManagementAction?): Result<String?>
suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String> suspend fun uploadMedia(mimeType: String, data: ByteArray, progressCallback: ProgressCallback?): Result<String>
fun roomMembershipObserver(): RoomMembershipObserver fun roomMembershipObserver(): RoomMembershipObserver
fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<MatrixRoomInfo>>
fun isMe(userId: UserId?) = userId == sessionId fun isMe(userId: UserId?) = userId == sessionId
} }

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.api.roomlist package io.element.android.libraries.matrix.api.roomlist
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -32,6 +33,8 @@ interface DynamicRoomList : RoomList {
val loadedPages: StateFlow<Int> val loadedPages: StateFlow<Int>
val pageSize: Int val pageSize: Int
val filteredSummaries: SharedFlow<List<RoomSummary>>
/** /**
* Load more rooms into the list if possible. * Load more rooms into the list if possible.
*/ */

View file

@ -17,15 +17,9 @@
package io.element.android.libraries.matrix.api.roomlist package io.element.android.libraries.matrix.api.roomlist
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import java.util.Optional
/** /**
* Entry point for the room list api. * Entry point for the room list api.
@ -86,10 +80,10 @@ interface RoomListService {
*/ */
val state: StateFlow<State> val state: StateFlow<State>
/** }
* Get a flow of the room summary for a given room id.
*/ fun RoomList.loadedStateFlow(): Flow<RoomList.LoadingState.Loaded> {
fun getUserMembershipForRoom(roomId: RoomId): Flow<Optional<CurrentUserMembership>> return loadingState.filterIsInstance()
} }

View file

@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.pusher.PushersService 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.MatrixRoomInfo
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.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
@ -79,12 +80,15 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.buffer import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -104,8 +108,10 @@ import org.matrix.rustcomponents.sdk.TimelineEventTypeFilter
import org.matrix.rustcomponents.sdk.use import org.matrix.rustcomponents.sdk.use
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.util.Optional
import java.util.concurrent.atomic.AtomicBoolean import java.util.concurrent.atomic.AtomicBoolean
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.INFINITE
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParameters import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParameters
import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset
@ -524,6 +530,22 @@ class RustMatrixClient(
override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver override fun roomMembershipObserver(): RoomMembershipObserver = roomMembershipObserver
override fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<MatrixRoomInfo>> {
return flow {
var room = getRoom(roomId)
if (room == null) {
emit(Optional.empty())
awaitRoom(roomId, INFINITE)
room = getRoom(roomId)
}
room?.use {
room.roomInfoFlow
.map { roomInfo -> Optional.of(roomInfo) }
.collect(this)
}
}.distinctUntilChanged()
}
private suspend fun File.getCacheSize( private suspend fun File.getCacheSize(
includeCryptoDb: Boolean = false, includeCryptoDb: Boolean = false,
): Long = withContext(sessionDispatcher) { ): Long = withContext(sessionDispatcher) {

View file

@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.getAndUpdate import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -92,7 +93,8 @@ internal class RoomListFactory(
innerRoomList?.destroy() innerRoomList?.destroy()
} }
return RustDynamicRoomList( return RustDynamicRoomList(
summaries = filteredSummariesFlow, summaries = summariesFlow,
filteredSummaries = filteredSummariesFlow,
loadingState = loadingStateFlow, loadingState = loadingStateFlow,
currentFilter = currentFilter, currentFilter = currentFilter,
loadedPages = loadedPages, loadedPages = loadedPages,
@ -105,6 +107,7 @@ internal class RoomListFactory(
private class RustDynamicRoomList( private class RustDynamicRoomList(
override val summaries: MutableSharedFlow<List<RoomSummary>>, override val summaries: MutableSharedFlow<List<RoomSummary>>,
override val filteredSummaries: SharedFlow<List<RoomSummary>>,
override val loadingState: MutableStateFlow<RoomList.LoadingState>, override val loadingState: MutableStateFlow<RoomList.LoadingState>,
override val currentFilter: MutableStateFlow<RoomListFilter>, override val currentFilter: MutableStateFlow<RoomListFilter>,
override val loadedPages: MutableStateFlow<Int>, override val loadedPages: MutableStateFlow<Int>,

View file

@ -16,24 +16,16 @@
package io.element.android.libraries.matrix.impl.roomlist package io.element.android.libraries.matrix.impl.roomlist
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.roomlist.DynamicRoomList import io.element.android.libraries.matrix.api.roomlist.DynamicRoomList
import io.element.android.libraries.matrix.api.roomlist.RoomList import io.element.android.libraries.matrix.api.roomlist.RoomList
import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListFilter
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally import io.element.android.libraries.matrix.api.roomlist.loadAllIncrementally
import io.element.android.libraries.matrix.impl.room.map
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
@ -43,9 +35,7 @@ import org.matrix.rustcomponents.sdk.RoomListInput
import org.matrix.rustcomponents.sdk.RoomListRange import org.matrix.rustcomponents.sdk.RoomListRange
import org.matrix.rustcomponents.sdk.RoomListServiceState import org.matrix.rustcomponents.sdk.RoomListServiceState
import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator import org.matrix.rustcomponents.sdk.RoomListServiceSyncIndicator
import org.matrix.rustcomponents.sdk.use
import timber.log.Timber import timber.log.Timber
import java.util.Optional
import org.matrix.rustcomponents.sdk.RoomListService as InnerRustRoomListService import org.matrix.rustcomponents.sdk.RoomListService as InnerRustRoomListService
private const val DEFAULT_PAGE_SIZE = 20 private const val DEFAULT_PAGE_SIZE = 20
@ -122,24 +112,6 @@ internal class RustRoomListService(
} }
.distinctUntilChanged() .distinctUntilChanged()
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, RoomListService.State.Idle) .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, RoomListService.State.Idle)
override fun getUserMembershipForRoom(roomId: RoomId): Flow<Optional<CurrentUserMembership>> {
return combine(
allRooms.loadedStateFlow(),
invites.loadedStateFlow(),
) { _, _ ->
val membership = innerRoomListService.roomOrNull(roomId.value)?.use {
it.roomInfo().use { roomInfo ->
roomInfo.membership.map()
}
}
Optional.ofNullable(membership)
}.distinctUntilChanged()
}
private fun RoomList.loadedStateFlow(): Flow<RoomList.LoadingState.Loaded> {
return loadingState.filterIsInstance()
}
} }
private fun RoomListServiceState.toRoomListState(): RoomListService.State { private fun RoomListServiceState.toRoomListState(): RoomListService.State {