Skip to content

misc (matrix) : use innerClient.subscribeToRoomInfo sdk method #4838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.getRoomInfoFlow
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.alias.ResolvedRoomAlias
Expand Down Expand Up @@ -124,7 +122,7 @@ class RoomFlowNode @AssistedInject constructor(
}

private fun subscribeToRoomInfoFlow(roomId: RoomId, serverNames: List<String>) {
val roomInfoFlow = client.getRoomInfoFlow(roomIdOrAlias = roomId.toRoomIdOrAlias())
val roomInfoFlow = client.getRoomInfoFlow(roomId)
val isSpaceFlow = roomInfoFlow.map { it.getOrNull()?.isSpace.orFalse() }.distinctUntilChanged()
val currentMembershipFlow = roomInfoFlow.map { it.getOrNull()?.currentUserMembership }.distinctUntilChanged()
combine(currentMembershipFlow, isSpaceFlow) { membership, isSpace ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@ import io.element.android.libraries.core.meta.BuildMeta
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.RoomIdOrAlias
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.exception.ClientException
import io.element.android.libraries.matrix.api.exception.ErrorKind
import io.element.android.libraries.matrix.api.getRoomInfoFlow
import io.element.android.libraries.matrix.api.room.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.RoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember
Expand Down Expand Up @@ -88,7 +86,7 @@ class JoinRoomPresenter @AssistedInject constructor(
val coroutineScope = rememberCoroutineScope()
var retryCount by remember { mutableIntStateOf(0) }
val roomInfo by remember {
matrixClient.getRoomInfoFlow(roomId.toRoomIdOrAlias())
matrixClient.getRoomInfoFlow(roomId)
}.collectAsState(initial = Optional.empty())
val joinAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val knockAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.room.aRoomInfo
import io.element.android.libraries.matrix.test.room.aRoomMember
import io.element.android.libraries.matrix.test.room.aRoomPreview
import io.element.android.libraries.matrix.test.room.aRoomPreviewInfo
import io.element.android.libraries.matrix.test.room.aRoomSummary
import io.element.android.libraries.matrix.test.room.join.FakeJoinRoom
import io.element.android.libraries.matrix.ui.model.InviteSender
import io.element.android.libraries.matrix.ui.model.toInviteSender
Expand Down Expand Up @@ -88,12 +88,12 @@ class JoinRoomPresenterTest {

@Test
fun `present - when room is joined then content state is filled with his data`() = runTest {
val roomSummary = aRoomSummary()
val roomInfo = aRoomInfo()
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ -> Result.failure(AN_EXCEPTION) },
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand All @@ -104,58 +104,58 @@ class JoinRoomPresenterTest {
awaitItem().also { state ->
val contentState = state.contentState as ContentState.Loaded
assertThat(contentState.roomId).isEqualTo(A_ROOM_ID)
assertThat(contentState.name).isEqualTo(roomSummary.info.name)
assertThat(contentState.topic).isEqualTo(roomSummary.info.topic)
assertThat(contentState.alias).isEqualTo(roomSummary.info.canonicalAlias)
assertThat(contentState.numberOfMembers).isEqualTo(roomSummary.info.joinedMembersCount)
assertThat(contentState.isDm).isEqualTo(roomSummary.info.isDirect)
assertThat(contentState.roomAvatarUrl).isEqualTo(roomSummary.info.avatarUrl)
assertThat(contentState.name).isEqualTo(roomInfo.name)
assertThat(contentState.topic).isEqualTo(roomInfo.topic)
assertThat(contentState.alias).isEqualTo(roomInfo.canonicalAlias)
assertThat(contentState.numberOfMembers).isEqualTo(roomInfo.joinedMembersCount)
assertThat(contentState.isDm).isEqualTo(roomInfo.isDirect)
assertThat(contentState.roomAvatarUrl).isEqualTo(roomInfo.avatarUrl)
}
}
}

@Test
fun `present - when room is invited then join authorization is equal to invited`() = runTest {
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.INVITED)
val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.INVITED)
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ -> Result.failure(AN_EXCEPTION) },
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val seenInvitesStore = InMemorySeenInvitesStore()
val presenter = createJoinRoomPresenter(
matrixClient = matrixClient,
seenInvitesStore = seenInvitesStore,
)
val inviteData = roomSummary.info.toInviteData()
val inviteData = roomInfo.toInviteData()
assertThat(seenInvitesStore.seenRoomIds().first()).isEmpty()
presenter.test {
skipItems(2)
awaitItem().also { state ->
assertThat(state.joinAuthorisationStatus).isEqualTo(JoinAuthorisationStatus.IsInvited(inviteData, null))
}
// Check that the roomId is stored in the seen invites store
assertThat(seenInvitesStore.seenRoomIds().first()).containsExactly(roomSummary.roomId)
assertThat(seenInvitesStore.seenRoomIds().first()).containsExactly(roomInfo.id)
}
}

@Test
fun `present - when room is invited then join authorization is equal to invited, an inviter is provided`() = runTest {
val inviter = aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob")
val expectedInviteSender = inviter.toInviteSender()
val roomSummary = aRoomSummary(
val roomInfo = aRoomInfo(
currentUserMembership = CurrentUserMembership.INVITED,
joinedMembersCount = 5,
inviter = inviter,
)
val inviteData = roomSummary.info.toInviteData()
val inviteData = roomInfo.toInviteData()
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ -> Result.failure(AN_EXCEPTION) },
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand All @@ -172,7 +172,7 @@ class JoinRoomPresenterTest {

@Test
fun `present - when room is invited read the number of member from the room preview`() = runTest {
val roomSummary = aRoomSummary(
val roomInfo = aRoomInfo(
currentUserMembership = CurrentUserMembership.INVITED,
// It seems that the SDK does not provide this value.
joinedMembersCount = 0,
Expand All @@ -188,8 +188,8 @@ class JoinRoomPresenterTest {
)
},
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand All @@ -209,13 +209,13 @@ class JoinRoomPresenterTest {
val acceptDeclinePresenter = Presenter {
anAcceptDeclineInviteState(eventSink = eventSinkRecorder)
}
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.INVITED)
val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.INVITED)
val matrixClient = FakeMatrixClient().apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val inviteData = roomSummary.info.toInviteData()
val inviteData = roomInfo.toInviteData()
val presenter = createJoinRoomPresenter(
matrixClient = matrixClient,
acceptDeclineInvitePresenter = acceptDeclinePresenter
Expand Down Expand Up @@ -324,7 +324,7 @@ class JoinRoomPresenterTest {

@Test
fun `present - when room is banned, then join authorization is equal to IsBanned`() = runTest {
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.BANNED, joinRule = JoinRule.Public)
val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.BANNED, joinRule = JoinRule.Public)
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ ->
Result.success(
Expand All @@ -346,8 +346,8 @@ class JoinRoomPresenterTest {
)
}
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand All @@ -369,12 +369,12 @@ class JoinRoomPresenterTest {

@Test
fun `present - when room is left and public then join authorization is equal to canJoin`() = runTest {
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.LEFT, joinRule = JoinRule.Public)
val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.LEFT, joinRule = JoinRule.Public)
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ -> Result.failure(AN_EXCEPTION) },
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand All @@ -390,12 +390,12 @@ class JoinRoomPresenterTest {

@Test
fun `present - when room is left and join rule null then join authorization is equal to Unknown`() = runTest {
val roomSummary = aRoomSummary(currentUserMembership = CurrentUserMembership.LEFT, joinRule = null)
val roomInfo = aRoomInfo(currentUserMembership = CurrentUserMembership.LEFT, joinRule = null)
val matrixClient = FakeMatrixClient(
getNotJoinedRoomResult = { _, _ -> Result.failure(AN_EXCEPTION) },
).apply {
getRoomSummaryFlowLambda = { _ ->
flowOf(Optional.of(roomSummary))
getRoomInfoFlowLambda = { _ ->
flowOf(Optional.of(roomInfo))
}
}
val presenter = createJoinRoomPresenter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
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.RoomSummary
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncService
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
Expand All @@ -41,8 +40,6 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import java.util.Optional

interface MatrixClient {
Expand All @@ -65,9 +62,9 @@ interface MatrixClient {
suspend fun setDisplayName(displayName: String): Result<Unit>
suspend fun uploadAvatar(mimeType: String, data: ByteArray): Result<Unit>
suspend fun removeAvatar(): Result<Unit>
suspend fun joinRoom(roomId: RoomId): Result<RoomSummary?>
suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>): Result<RoomSummary?>
suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List<String>): Result<RoomSummary?>
suspend fun joinRoom(roomId: RoomId): Result<RoomInfo?>
suspend fun joinRoomByIdOrAlias(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>): Result<RoomInfo?>
suspend fun knockRoom(roomIdOrAlias: RoomIdOrAlias, message: String, serverNames: List<String>): Result<RoomInfo?>
fun syncService(): SyncService
fun sessionVerificationService(): SessionVerificationService
fun pushersService(): PushersService
Expand Down Expand Up @@ -99,11 +96,11 @@ interface MatrixClient {
fun roomMembershipObserver(): RoomMembershipObserver

/**
* Get a room summary flow for a given room ID or alias.
* The flow will emit a new value whenever the room summary is updated.
* Get a room info flow for a given room ID.
* The flow will emit a new value whenever the room info is updated.
* The flow will emit Optional.empty item if the room is not found.
*/
fun getRoomSummaryFlow(roomIdOrAlias: RoomIdOrAlias): Flow<Optional<RoomSummary>>
fun getRoomInfoFlow(roomId: RoomId): Flow<Optional<RoomInfo>>

fun isMe(userId: UserId?) = userId == sessionId

Expand Down Expand Up @@ -169,17 +166,6 @@ interface MatrixClient {
suspend fun canReportRoom(): Boolean
}

/**
* Get a room info flow for a given room ID or alias.
* The flow will emit a new value whenever the room info is updated.
* The flow will emit Optional.empty item if the room is not found.
*/
fun MatrixClient.getRoomInfoFlow(roomIdOrAlias: RoomIdOrAlias): Flow<Optional<RoomInfo>> {
return getRoomSummaryFlow(roomIdOrAlias)
.map { roomSummary -> roomSummary.map { it.info } }
.distinctUntilChanged()
}

/**
* Returns a room alias from a room alias name, or null if the name is not valid.
* @param name the room alias name ie. the local part of the room alias.
Expand Down
Loading
Loading