Room navigation : more reliable roomInfoFlow method
This commit is contained in:
parent
23604e0549
commit
fc20b7399a
14 changed files with 75 additions and 74 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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?,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ object JoinRoomModule {
|
||||||
return JoinRoomPresenter(
|
return JoinRoomPresenter(
|
||||||
roomId = roomId,
|
roomId = roomId,
|
||||||
matrixClient = client,
|
matrixClient = client,
|
||||||
roomListService = roomListService,
|
|
||||||
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
|
acceptDeclineInvitePresenter = acceptDeclineInvitePresenter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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>,
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue