feature (room upgrade) : start rendering SuccessorRoom and PredecessorRoom banners in timeline
This commit is contained in:
parent
76e1ec05ba
commit
7b75a52ca2
24 changed files with 255 additions and 89 deletions
|
|
@ -39,7 +39,7 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
|||
|
||||
@Composable
|
||||
fun ComposerAlertMolecule(
|
||||
avatar: AvatarData,
|
||||
avatar: AvatarData?,
|
||||
content: AnnotatedString,
|
||||
onSubmitClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -71,9 +71,9 @@ fun ComposerAlertMolecule(
|
|||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Avatar(
|
||||
avatarData = avatar,
|
||||
)
|
||||
if(avatar != null) {
|
||||
Avatar(avatarData = avatar)
|
||||
}
|
||||
Text(
|
||||
text = content,
|
||||
modifier = Modifier.weight(1f),
|
||||
|
|
@ -101,7 +101,7 @@ fun ComposerAlertMolecule(
|
|||
@Composable
|
||||
internal fun ComposerAlertMoleculePreview(@PreviewParameter(BooleanProvider::class) isCritical: Boolean) = ElementPreview {
|
||||
ComposerAlertMolecule(
|
||||
avatar = anAvatarData(size = AvatarSize.ComposerAlert),
|
||||
avatar = null,
|
||||
content = "Alice’s verified identity has changed. Learn more".toAnnotatedString(),
|
||||
isCritical = isCritical,
|
||||
onSubmitClick = {},
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.api.core.SessionId
|
|||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
|
||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -55,6 +56,8 @@ interface BaseRoom : Closeable {
|
|||
*/
|
||||
fun info(): RoomInfo = roomInfoFlow.value
|
||||
|
||||
fun predecessorRoom(): PredecessorRoom?
|
||||
|
||||
/**
|
||||
* A one-to-one is a room with exactly 2 members.
|
||||
* See [the Matrix spec](https://spec.matrix.org/latest/client-server-api/#default-underride-rules).
|
||||
|
|
@ -234,7 +237,6 @@ interface BaseRoom : Closeable {
|
|||
* @param reason - The reason the room is being reported.
|
||||
*/
|
||||
suspend fun reportRoom(reason: String?): Result<Unit>
|
||||
|
||||
/**
|
||||
* Destroy the room and release all resources associated to it.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.api.room.tombstone
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
/**
|
||||
*
|
||||
* When a room A is tombstoned, it is replaced by a room B. The room A is the
|
||||
* predecessor of B, and B is the successor of A. This type holds information
|
||||
* about the predecessor room.
|
||||
*
|
||||
* A room is tombstoned if it has received a m.room.tombstone state event.
|
||||
*
|
||||
*/
|
||||
data class PredecessorRoom(
|
||||
/**
|
||||
* The ID of the replaced room.
|
||||
*/
|
||||
val roomId: RoomId,
|
||||
/**
|
||||
* The event ID of the last known event in the predecessor room.
|
||||
*/
|
||||
val lastEventId: EventId,
|
||||
)
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.api.room
|
||||
package io.element.android.libraries.matrix.api.room.tombstone
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
||||
|
|
@ -14,11 +14,12 @@ import io.element.android.libraries.matrix.api.core.UserId
|
|||
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.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.room.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.impl.room.history.map
|
||||
import io.element.android.libraries.matrix.impl.room.join.map
|
||||
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
|
||||
import io.element.android.libraries.matrix.impl.room.tombstone.map
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentMap
|
||||
|
|
@ -88,11 +89,6 @@ fun RustRoomNotificationMode.map(): RoomNotificationMode = when (this) {
|
|||
RustRoomNotificationMode.MUTE -> RoomNotificationMode.MUTE
|
||||
}
|
||||
|
||||
fun RustSuccessorRoom.map(): SuccessorRoom = SuccessorRoom(
|
||||
roomId = RoomId(roomId),
|
||||
reason = reason,
|
||||
)
|
||||
|
||||
/**
|
||||
* Map a RoomHero to a MatrixUser. There is not need to create a RoomHero type on the application side.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@ import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
|||
import io.element.android.libraries.matrix.api.room.StateEventType
|
||||
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
|
||||
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
|
||||
import io.element.android.libraries.matrix.api.timeline.ReceiptType
|
||||
import io.element.android.libraries.matrix.impl.room.draft.into
|
||||
import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher
|
||||
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
|
||||
import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsMapper
|
||||
import io.element.android.libraries.matrix.impl.room.tombstone.map
|
||||
import io.element.android.libraries.matrix.impl.roomdirectory.map
|
||||
import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType
|
||||
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
||||
|
|
@ -78,6 +80,10 @@ class RustBaseRoom(
|
|||
})
|
||||
}.stateIn(roomCoroutineScope, started = SharingStarted.Lazily, initialValue = initialRoomInfo)
|
||||
|
||||
override fun predecessorRoom(): PredecessorRoom? {
|
||||
return innerRoom.predecessorRoom()?.map()
|
||||
}
|
||||
|
||||
override suspend fun subscribeToSync() = roomSyncSubscriber.subscribe(roomId)
|
||||
|
||||
override suspend fun updateMembers() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.impl.room.tombstone
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
|
||||
import org.matrix.rustcomponents.sdk.PredecessorRoom as RustPredecessorRoom
|
||||
|
||||
fun RustPredecessorRoom.map(): PredecessorRoom {
|
||||
return PredecessorRoom(
|
||||
roomId = RoomId(roomId),
|
||||
lastEventId = EventId(lastEventId),
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.impl.room.tombstone
|
||||
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import org.matrix.rustcomponents.sdk.SuccessorRoom as RustSuccessorRoom
|
||||
|
||||
fun RustSuccessorRoom.map(): SuccessorRoom {
|
||||
return SuccessorRoom(
|
||||
roomId = RoomId(roomId),
|
||||
reason = reason
|
||||
)
|
||||
}
|
||||
|
|
@ -27,6 +27,11 @@ import org.matrix.rustcomponents.sdk.RoomListService
|
|||
import kotlin.coroutines.CoroutineContext
|
||||
import org.matrix.rustcomponents.sdk.RoomList as InnerRoomList
|
||||
|
||||
private val ROOM_LIST_RUST_FILTERS = listOf(
|
||||
RoomListEntriesDynamicFilterKind.NonLeft,
|
||||
RoomListEntriesDynamicFilterKind.DeduplicateVersions
|
||||
)
|
||||
|
||||
internal class RoomListFactory(
|
||||
private val innerRoomListService: RoomListService,
|
||||
private val sessionCoroutineScope: CoroutineScope,
|
||||
|
|
@ -55,11 +60,11 @@ internal class RoomListFactory(
|
|||
|
||||
coroutineScope.launch(coroutineContext) {
|
||||
innerRoomList = innerProvider()
|
||||
innerRoomList?.let { innerRoomList ->
|
||||
innerRoomList.let { innerRoomList ->
|
||||
innerRoomList.entriesFlow(
|
||||
pageSize = pageSize,
|
||||
roomListDynamicEvents = dynamicEvents,
|
||||
initialFilterKind = RoomListEntriesDynamicFilterKind.NonLeft
|
||||
initialFilterKind = RoomListEntriesDynamicFilterKind.All(ROOM_LIST_RUST_FILTERS),
|
||||
).onEach { update ->
|
||||
processor.postUpdate(update)
|
||||
}.launchIn(this)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ 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
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.room.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ 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
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.room.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom
|
||||
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||
import io.element.android.libraries.matrix.api.room.message.RoomMessage
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue