diff --git a/.idea/dictionaries/shared.xml b/.idea/dictionaries/shared.xml
index dc5f8f7504..abe4b190df 100644
--- a/.idea/dictionaries/shared.xml
+++ b/.idea/dictionaries/shared.xml
@@ -8,6 +8,8 @@
onboarding
placeables
showkase
+ snackbar
+ swipeable
textfields
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d2d648f145..c77fba93e1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -44,14 +44,14 @@
-
-
+
-
+
diff --git a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
index ba8fe290e2..ec3259fb7c 100644
--- a/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
+++ b/app/src/main/kotlin/io/element/android/x/ElementXApplication.kt
@@ -18,8 +18,8 @@ package io.element.android.x
import android.app.Application
import androidx.startup.AppInitializer
-import io.element.android.x.di.AppComponent
import io.element.android.libraries.di.DaggerComponentOwner
+import io.element.android.x.di.AppComponent
import io.element.android.x.di.DaggerAppComponent
import io.element.android.x.info.logApplicationInfo
import io.element.android.x.initializer.CrashInitializer
diff --git a/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt b/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt
index e777b08906..88a86b9467 100644
--- a/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt
+++ b/app/src/main/kotlin/io/element/android/x/intent/IntentProviderImpl.kt
@@ -35,14 +35,21 @@ class IntentProviderImpl @Inject constructor(
@ApplicationContext private val context: Context,
private val deepLinkCreator: DeepLinkCreator,
) : IntentProvider {
- override fun getViewIntent(
+ override fun getViewRoomIntent(
sessionId: SessionId,
roomId: RoomId?,
threadId: ThreadId?,
): Intent {
return Intent(context, MainActivity::class.java).apply {
action = Intent.ACTION_VIEW
- data = deepLinkCreator.create(sessionId, roomId, threadId).toUri()
+ data = deepLinkCreator.room(sessionId, roomId, threadId).toUri()
+ }
+ }
+
+ override fun getInviteListIntent(sessionId: SessionId): Intent {
+ return Intent(context, MainActivity::class.java).apply {
+ action = Intent.ACTION_VIEW
+ data = deepLinkCreator.inviteList(sessionId).toUri()
}
}
}
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt
index 9411ceb4a5..bc73efde71 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt
@@ -18,9 +18,7 @@ package io.element.android.appnav
import android.os.Parcelable
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -30,7 +28,6 @@ import com.bumble.appyx.core.composable.Children
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
-import com.bumble.appyx.core.node.node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack
@@ -58,6 +55,7 @@ import io.element.android.libraries.architecture.animation.rememberDefaultTransi
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.inputs
+import io.element.android.libraries.deeplink.DeeplinkData
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient
@@ -65,6 +63,7 @@ import io.element.android.libraries.matrix.api.core.MAIN_SPACE
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.sync.SyncState
import io.element.android.libraries.matrix.ui.di.MatrixUIBindings
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.appnavstate.api.AppNavigationStateService
import kotlinx.coroutines.CoroutineScope
@@ -89,6 +88,7 @@ class LoggedInFlowNode @AssistedInject constructor(
private val analyticsService: AnalyticsService,
private val coroutineScope: CoroutineScope,
private val networkMonitor: NetworkMonitor,
+ private val notificationDrawerManager: NotificationDrawerManager,
snackbarDispatcher: SnackbarDispatcher,
) : BackstackNode(
backstack = BackStack(
@@ -139,7 +139,6 @@ class LoggedInFlowNode @AssistedInject constructor(
observeAnalyticsState()
lifecycle.subscribe(
onCreate = {
- syncService.startSync()
plugins().forEach { it.onFlowCreated(id, inputs.matrixClient) }
val imageLoaderFactory = bindings().loggedInImageLoaderFactory()
Coil.setImageLoader(imageLoaderFactory)
@@ -341,4 +340,13 @@ class LoggedInFlowNode @AssistedInject constructor(
PermanentChild(navTarget = NavTarget.Permanent)
}
}
+
+ internal suspend fun attachRoom(deeplinkData: DeeplinkData.Room) {
+ backstack.push(NavTarget.Room(deeplinkData.roomId))
+ }
+
+ internal suspend fun attachInviteList(deeplinkData: DeeplinkData.InviteList) {
+ notificationDrawerManager.clearMembershipNotificationForSession(deeplinkData.sessionId)
+ backstack.push(NavTarget.InviteList)
+ }
}
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt
index 12e54b2ea5..8803d574d9 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt
@@ -253,13 +253,10 @@ class RootFlowNode @AssistedInject constructor(
Timber.d("Navigating to $deeplinkData")
attachSession(deeplinkData.sessionId)
.apply {
- val roomId = deeplinkData.roomId
- if (roomId == null) {
- // In case room is not provided, ensure the app navigate back to the room list
- attachRoot()
- } else {
- attachRoom(roomId)
- // TODO .attachThread(deeplinkData.threadId)
+ when (deeplinkData) {
+ is DeeplinkData.Root -> attachRoot()
+ is DeeplinkData.Room -> attachRoom(deeplinkData)
+ is DeeplinkData.InviteList -> attachInviteList(deeplinkData)
}
}
}
diff --git a/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt b/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt
index b567395c1e..6a3d8ff9dd 100644
--- a/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt
+++ b/appnav/src/main/kotlin/io/element/android/appnav/intent/IntentResolver.kt
@@ -21,6 +21,8 @@ import io.element.android.features.login.api.oidc.OidcAction
import io.element.android.features.login.api.oidc.OidcIntentResolver
import io.element.android.libraries.deeplink.DeeplinkData
import io.element.android.libraries.deeplink.DeeplinkParser
+import io.element.android.libraries.matrix.api.core.RoomId
+import io.element.android.libraries.matrix.api.core.SessionId
import timber.log.Timber
import javax.inject.Inject
diff --git a/build.gradle.kts b/build.gradle.kts
index 6e7e32a927..b5d082b8ce 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -59,7 +59,7 @@ allprojects {
config = files("$rootDir/tools/detekt/detekt.yml")
}
dependencies {
- detektPlugins("io.nlopez.compose.rules:detekt:0.1.11")
+ detektPlugins("io.nlopez.compose.rules:detekt:0.1.12")
}
// KtLint
@@ -247,6 +247,7 @@ koverMerged {
excludes += "io.element.android.features.messages.impl.media.local.LocalMediaViewState"
excludes += "io.element.android.features.location.impl.map.MapState"
excludes += "io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*"
+ excludes += "io.element.android.libraries.designsystem.swipe.SwipeableActionsState*"
}
bound {
minValue = 90
diff --git a/changelog.d/821.bugfix b/changelog.d/821.bugfix
new file mode 100644
index 0000000000..da8118e2e0
--- /dev/null
+++ b/changelog.d/821.bugfix
@@ -0,0 +1 @@
+Truncate and ellipsize long reactions
\ No newline at end of file
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
index 9ba9a314e9..dbc7019db4 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleView.kt
@@ -38,10 +38,10 @@ import io.element.android.features.createroom.impl.userlist.UserListState
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalLayoutApi::class)
@@ -92,7 +92,7 @@ fun AddPeopleViewTopBar(
onBackPressed: () -> Unit = {},
onNextPressed: () -> Unit = {},
) {
- CenterAlignedTopAppBar(
+ TopAppBar(
modifier = modifier,
title = {
Text(
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
index 2df5c97dad..09d1560cd2 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
@@ -57,10 +57,10 @@ import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
import io.element.android.libraries.matrix.ui.components.SelectedUsersList
@@ -181,7 +181,7 @@ fun ConfigureRoomToolbar(
onBackPressed: () -> Unit = {},
onNextPressed: () -> Unit = {},
) {
- CenterAlignedTopAppBar(
+ TopAppBar(
modifier = modifier,
title = {
Text(
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
index fe23a9b7ff..3c778bd5eb 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
@@ -48,11 +48,11 @@ import io.element.android.libraries.designsystem.components.ProgressDialog
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.libraries.designsystem.R as DrawableR
@@ -133,7 +133,7 @@ fun CreateRoomRootViewTopBar(
modifier: Modifier = Modifier,
onClosePressed: () -> Unit = {},
) {
- CenterAlignedTopAppBar(
+ TopAppBar(
modifier = modifier,
title = {
Text(
@@ -142,7 +142,7 @@ fun CreateRoomRootViewTopBar(
fontWeight = FontWeight.SemiBold,
)
},
- actions = {
+ navigationIcon = {
IconButton(onClick = onClosePressed) {
Icon(
imageVector = Icons.Default.Close,
diff --git a/features/invitelist/impl/build.gradle.kts b/features/invitelist/impl/build.gradle.kts
index 6ff90d676d..3f8f1a44ed 100644
--- a/features/invitelist/impl/build.gradle.kts
+++ b/features/invitelist/impl/build.gradle.kts
@@ -43,6 +43,7 @@ dependencies {
implementation(projects.libraries.designsystem)
implementation(projects.libraries.uiStrings)
implementation(projects.services.analytics.api)
+ implementation(projects.libraries.push.api)
testImplementation(libs.test.junit)
testImplementation(libs.coroutines.test)
@@ -50,6 +51,7 @@ dependencies {
testImplementation(libs.test.truth)
testImplementation(libs.test.turbine)
testImplementation(projects.libraries.matrix.test)
+ testImplementation(projects.libraries.push.test)
testImplementation(projects.features.invitelist.test)
testImplementation(projects.features.analytics.test)
diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
index a87b2b0ebd..735b4a79a2 100644
--- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
+++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
@@ -37,6 +37,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomSummary
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
import io.element.android.services.analytics.api.AnalyticsService
import io.element.android.services.analytics.api.extensions.toAnalyticsJoinedRoom
import kotlinx.collections.immutable.toPersistentList
@@ -49,6 +50,7 @@ class InviteListPresenter @Inject constructor(
private val client: MatrixClient,
private val store: SeenInvitesStore,
private val analyticsService: AnalyticsService,
+ private val notificationDrawerManager: NotificationDrawerManager,
) : Presenter {
@Composable
@@ -138,6 +140,7 @@ class InviteListPresenter @Inject constructor(
suspend {
client.getRoom(roomId)?.use {
it.acceptInvitation().getOrThrow()
+ notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId)
analyticsService.capture(it.toAnalyticsJoinedRoom(JoinedRoom.Trigger.Invite))
}
roomId
@@ -148,7 +151,9 @@ class InviteListPresenter @Inject constructor(
suspend {
client.getRoom(roomId)?.use {
it.rejectInvitation().getOrThrow()
- } ?: Unit
+ notificationDrawerManager.clearMembershipNotificationForRoom(client.sessionId, roomId)
+ }
+ Unit
}.runCatchingUpdatingState(declinedAction)
}
diff --git a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
index e179ed3878..503e7ad0d7 100644
--- a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
+++ b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
@@ -21,10 +21,12 @@ import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth
import io.element.android.features.analytics.test.FakeAnalyticsService
+import io.element.android.features.invitelist.api.SeenInvitesStore
import io.element.android.features.invitelist.test.FakeSeenInvitesStore
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
+import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipState
@@ -39,6 +41,9 @@ import io.element.android.libraries.matrix.test.A_USER_NAME
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
import io.element.android.libraries.matrix.test.room.FakeRoomSummaryDataSource
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
+import io.element.android.libraries.push.test.notifications.FakeNotificationDrawerManager
+import io.element.android.services.analytics.api.AnalyticsService
import kotlinx.coroutines.test.runTest
import org.junit.Test
@@ -47,12 +52,8 @@ class InviteListPresenterTests {
@Test
fun `present - starts empty, adds invites when received`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource()
- val presenter = InviteListPresenter(
- FakeMatrixClient(
- roomSummaryDataSource = roomSummaryDataSource,
- ),
- FakeSeenInvitesStore(),
- FakeAnalyticsService(),
+ val presenter = createPresenter(
+ FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -72,12 +73,8 @@ class InviteListPresenterTests {
@Test
fun `present - uses user ID and avatar for direct invites`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withDirectChatInvitation()
- val presenter = InviteListPresenter(
- FakeMatrixClient(
- roomSummaryDataSource = roomSummaryDataSource,
- ),
- FakeSeenInvitesStore(),
- FakeAnalyticsService(),
+ val presenter = createPresenter(
+ FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -102,12 +99,8 @@ class InviteListPresenterTests {
@Test
fun `present - includes sender details for room invites`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
- val presenter = InviteListPresenter(
- FakeMatrixClient(
- roomSummaryDataSource = roomSummaryDataSource,
- ),
- FakeSeenInvitesStore(),
- FakeAnalyticsService(),
+ val presenter = createPresenter(
+ FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -136,6 +129,7 @@ class InviteListPresenterTests {
),
FakeSeenInvitesStore(),
FakeAnalyticsService(),
+ FakeNotificationDrawerManager()
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -155,12 +149,8 @@ class InviteListPresenterTests {
@Test
fun `present - shows confirm dialog for declining room invites`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
- val presenter = InviteListPresenter(
- FakeMatrixClient(
- roomSummaryDataSource = roomSummaryDataSource,
- ),
- FakeSeenInvitesStore(),
- FakeAnalyticsService(),
+ val presenter = createPresenter(
+ FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -180,12 +170,8 @@ class InviteListPresenterTests {
@Test
fun `present - hides confirm dialog when cancelling`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
- val presenter = InviteListPresenter(
- FakeMatrixClient(
- roomSummaryDataSource = roomSummaryDataSource,
- ),
- FakeSeenInvitesStore(),
- FakeAnalyticsService(),
+ val presenter = createPresenter(
+ FakeMatrixClient(roomSummaryDataSource = roomSummaryDataSource)
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -205,11 +191,12 @@ class InviteListPresenterTests {
@Test
fun `present - declines invite after confirming`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
+ val fakeNotificationDrawerManager = FakeNotificationDrawerManager()
val client = FakeMatrixClient(
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client = client, notificationDrawerManager = fakeNotificationDrawerManager)
client.givenGetRoomResult(A_ROOM_ID, room)
moleculeFlow(RecompositionClock.Immediate) {
@@ -225,6 +212,7 @@ class InviteListPresenterTests {
skipItems(2)
Truth.assertThat(room.isInviteRejected).isTrue()
+ Truth.assertThat(fakeNotificationDrawerManager.getClearMembershipNotificationForRoomCount(client.sessionId, A_ROOM_ID)).isEqualTo(1)
}
}
@@ -235,7 +223,7 @@ class InviteListPresenterTests {
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client)
val ex = Throwable("Ruh roh!")
room.givenRejectInviteResult(Result.failure(ex))
client.givenGetRoomResult(A_ROOM_ID, room)
@@ -266,7 +254,7 @@ class InviteListPresenterTests {
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client)
val ex = Throwable("Ruh roh!")
room.givenRejectInviteResult(Result.failure(ex))
client.givenGetRoomResult(A_ROOM_ID, room)
@@ -294,11 +282,12 @@ class InviteListPresenterTests {
@Test
fun `present - accepts invites and sets state on success`() = runTest {
val roomSummaryDataSource = FakeRoomSummaryDataSource().withRoomInvitation()
+ val fakeNotificationDrawerManager = FakeNotificationDrawerManager()
val client = FakeMatrixClient(
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client = client, notificationDrawerManager = fakeNotificationDrawerManager)
client.givenGetRoomResult(A_ROOM_ID, room)
moleculeFlow(RecompositionClock.Immediate) {
@@ -311,6 +300,7 @@ class InviteListPresenterTests {
Truth.assertThat(room.isInviteAccepted).isTrue()
Truth.assertThat(newState.acceptedAction).isEqualTo(Async.Success(A_ROOM_ID))
+ Truth.assertThat(fakeNotificationDrawerManager.getClearMembershipNotificationForRoomCount(client.sessionId, A_ROOM_ID)).isEqualTo(1)
}
}
@@ -321,7 +311,7 @@ class InviteListPresenterTests {
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client)
val ex = Throwable("Ruh roh!")
room.givenAcceptInviteResult(Result.failure(ex))
client.givenGetRoomResult(A_ROOM_ID, room)
@@ -346,7 +336,7 @@ class InviteListPresenterTests {
roomSummaryDataSource = roomSummaryDataSource,
)
val room = FakeMatrixRoom()
- val presenter = InviteListPresenter(client, FakeSeenInvitesStore(), FakeAnalyticsService())
+ val presenter = createPresenter(client)
val ex = Throwable("Ruh roh!")
room.givenAcceptInviteResult(Result.failure(ex))
client.givenGetRoomResult(A_ROOM_ID, room)
@@ -376,6 +366,7 @@ class InviteListPresenterTests {
),
store,
FakeAnalyticsService(),
+ FakeNotificationDrawerManager()
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -413,6 +404,7 @@ class InviteListPresenterTests {
),
store,
FakeAnalyticsService(),
+ FakeNotificationDrawerManager()
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
@@ -500,4 +492,16 @@ class InviteListPresenterTests {
unreadNotificationCount = 0,
)
)
+
+ private fun createPresenter(
+ client: MatrixClient,
+ seenInvitesStore: SeenInvitesStore = FakeSeenInvitesStore(),
+ fakeAnalyticsService: AnalyticsService = FakeAnalyticsService(),
+ notificationDrawerManager: NotificationDrawerManager = FakeNotificationDrawerManager()
+ ) = InviteListPresenter(
+ client,
+ seenInvitesStore,
+ fakeAnalyticsService,
+ notificationDrawerManager
+ )
}
diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt
index 0bb741e7a8..3d09c36604 100644
--- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt
+++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/StaticMapView.kt
@@ -29,7 +29,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImagePainter
@@ -38,8 +37,8 @@ import coil.request.ImageRequest
import io.element.android.features.location.api.internal.AttributionPlacement
import io.element.android.features.location.api.internal.StaticMapPlaceholder
import io.element.android.features.location.api.internal.buildStaticMapsApiUrl
-import io.element.android.libraries.designsystem.preview.ElementPreviewDark
-import io.element.android.libraries.designsystem.preview.ElementPreviewLight
+import io.element.android.libraries.designsystem.preview.DayNightPreviews
+import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.text.toDp
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.theme.ElementTheme
@@ -127,18 +126,9 @@ fun StaticMapView(
}
}
-@Preview
+@DayNightPreviews
@Composable
-fun StaticMapViewLightPreview() =
- ElementPreviewLight { ContentToPreview() }
-
-@Preview
-@Composable
-fun StaticMapViewDarkPreview() =
- ElementPreviewDark { ContentToPreview() }
-
-@Composable
-private fun ContentToPreview() {
+fun StaticMapViewPreview() = ElementPreview {
StaticMapView(
lat = 0.0,
lon = 0.0,
diff --git a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt
index a1e060c870..7ef31c326f 100644
--- a/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt
+++ b/features/location/api/src/main/kotlin/io/element/android/features/location/api/internal/StaticMapPlaceholder.kt
@@ -29,13 +29,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import io.element.android.features.location.api.R
-import io.element.android.libraries.designsystem.preview.ElementPreviewDark
-import io.element.android.libraries.designsystem.preview.ElementPreviewLight
+import io.element.android.libraries.designsystem.preview.DayNightPreviews
+import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
@@ -83,22 +82,13 @@ internal fun StaticMapPlaceholder(
}
}
-@Preview
+@DayNightPreviews
@Composable
-fun StaticMapPlaceholderLightPreview(
+fun StaticMapPlaceholderPreview(
@PreviewParameter(BooleanParameterProvider::class) values: Boolean
-) = ElementPreviewLight { ContentToPreview(values) }
-
-@Preview
-@Composable
-fun StaticMapPlaceholderDarkPreview(
- @PreviewParameter(BooleanParameterProvider::class) values: Boolean
-) = ElementPreviewDark { ContentToPreview(values) }
-
-@Composable
-private fun ContentToPreview(showProgress: Boolean) {
+) = ElementPreview {
StaticMapPlaceholder(
- showProgress = showProgress,
+ showProgress = values,
contentDescription = null,
modifier = Modifier.size(400.dp),
onLoadMapClick = {},
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/SendLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/SendLocationView.kt
index ba9c8ce47f..e6ad508091 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/SendLocationView.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/SendLocationView.kt
@@ -48,9 +48,9 @@ import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.libraries.designsystem.R as DesignSystemR
@@ -91,7 +91,7 @@ fun SendLocationView(
sheetDragHandle = {},
sheetSwipeEnabled = false,
topBar = {
- CenterAlignedTopAppBar(
+ TopAppBar(
title = {
Text(
text = stringResource(CommonStrings.screen_share_location_title),
diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt
index 25aa7fbfad..c0b5bf0b80 100644
--- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt
+++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/show/ShowLocationView.kt
@@ -39,11 +39,11 @@ import io.element.android.features.location.impl.map.rememberMapState
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.theme.compound.generated.TypographyTokens
import io.element.android.libraries.ui.strings.CommonStrings
@@ -61,7 +61,7 @@ fun ShowLocationView(
Scaffold(modifier,
topBar = {
- CenterAlignedTopAppBar(
+ TopAppBar(
title = {
Text(
text = stringResource(CommonStrings.screen_view_location_title),
diff --git a/features/login/impl/src/main/res/values-cs/translations.xml b/features/login/impl/src/main/res/values-cs/translations.xml
index bb67aed9d7..55bc53e143 100644
--- a/features/login/impl/src/main/res/values-cs/translations.xml
+++ b/features/login/impl/src/main/res/values-cs/translations.xml
@@ -42,5 +42,6 @@ Díky za trpělivost!"
"Vyberte svůj server"
"Heslo"
"Pokračovat"
+ "Matrix je otevřená síť pro bezpečnou a decentralizovanou komunikaci."
"Uživatelské jméno"
diff --git a/features/login/impl/src/main/res/values-de/translations.xml b/features/login/impl/src/main/res/values-de/translations.xml
index 0ffd103acc..efc7c0cf3c 100644
--- a/features/login/impl/src/main/res/values-de/translations.xml
+++ b/features/login/impl/src/main/res/values-de/translations.xml
@@ -42,5 +42,6 @@ Vielen Dank für deine Geduld!"
"Wählen deinen Server"
"Passwort"
"Weiter"
+ "Matrix ist ein offenes Netzwerk für sichere, dezentrale Kommunikation"
"Benutzername"
diff --git a/features/login/impl/src/main/res/values-ro/translations.xml b/features/login/impl/src/main/res/values-ro/translations.xml
index 123ab99dd6..c2dcadb6ad 100644
--- a/features/login/impl/src/main/res/values-ro/translations.xml
+++ b/features/login/impl/src/main/res/values-ro/translations.xml
@@ -42,5 +42,6 @@ Vă mulțumim pentru răbdare!"
"Selectați serverul"
"Parola"
"Continuați"
+ "Matrix este o rețea deschisă pentru o comunicare sigură și descentralizată."
"Utilizator"
diff --git a/features/login/impl/src/main/res/values-sk/translations.xml b/features/login/impl/src/main/res/values-sk/translations.xml
index 3c1e49f732..2cdaf596e1 100644
--- a/features/login/impl/src/main/res/values-sk/translations.xml
+++ b/features/login/impl/src/main/res/values-sk/translations.xml
@@ -42,5 +42,6 @@
"Vyberte svoj server"
"Heslo"
"Pokračovať"
+ "Matrix je otvorená sieť pre bezpečnú a decentralizovanú komunikáciu."
"Používateľské meno"
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt
index 5c96847715..32897ffc32 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt
@@ -54,7 +54,6 @@ import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogDefaults
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.theme.components.RadioButton
import io.element.android.libraries.designsystem.theme.components.Scaffold
@@ -62,6 +61,7 @@ import io.element.android.libraries.designsystem.theme.components.SearchBar
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.designsystem.theme.roomListRoomMessage
import io.element.android.libraries.designsystem.theme.roomListRoomName
import io.element.android.libraries.matrix.api.core.RoomId
@@ -111,7 +111,7 @@ fun ForwardMessagesView(
Scaffold(
modifier = modifier,
topBar = {
- CenterAlignedTopAppBar(
+ TopAppBar(
title = { Text(stringResource(CommonStrings.common_forward_message), style = ElementTextStyles.Bold.callout) },
navigationIcon = {
BackButton(onClick = { onBackButton(state) })
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
index 325ece7f14..1006319c87 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
@@ -50,10 +50,10 @@ import io.element.android.libraries.designsystem.components.button.ButtonWithPro
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.OutlinedTextField
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@@ -83,7 +83,7 @@ fun ReportMessageView(
Scaffold(
topBar = {
- CenterAlignedTopAppBar(
+ TopAppBar(
title = {
Text(
stringResource(CommonStrings.action_report_content),
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt
index 7aef36af20..1b6eadaa55 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/MessagesReactionButton.kt
@@ -44,6 +44,7 @@ import androidx.compose.ui.unit.sp
import io.element.android.features.messages.impl.R
import io.element.android.features.messages.impl.timeline.model.AggregatedReaction
import io.element.android.features.messages.impl.timeline.model.AggregatedReactionProvider
+import io.element.android.features.messages.impl.timeline.model.aTimelineItemReactions
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.preview.DayNightPreviews
import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -132,7 +133,7 @@ private fun IconContent(
)
@Composable
-fun ReactionContent(
+private fun ReactionContent(
reaction: AggregatedReaction,
modifier: Modifier = Modifier,
) = Row(
@@ -140,7 +141,7 @@ fun ReactionContent(
modifier = modifier,
) {
Text(
- text = reaction.key,
+ text = reaction.displayKey,
fontSize = 15.sp, lineHeight = reactionEmojiLineHeight
)
if (reaction.count > 1) {
@@ -148,7 +149,7 @@ fun ReactionContent(
Text(
text = reaction.count.toString(),
color = if (reaction.isHighlighted) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.secondary,
- fontSize = 14.sp
+ fontSize = 14.sp,
)
}
}
@@ -174,6 +175,12 @@ internal fun MessagesReactionExtraButtonsPreview() = ElementPreview {
content = MessagesReactionsButtonContent.Text("12 more"),
onClick = {}
)
+ MessagesReactionButton(
+ content = MessagesReactionsButtonContent.Reaction(aTimelineItemReactions().reactions.first().copy(
+ key = "A very long reaction with many characters that should be truncated"
+ )),
+ onClick = {}
+ )
}
}
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt
index d4b0f80e3e..7f18ad2fdf 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-@file:OptIn(ExperimentalMaterial3Api::class)
-
package io.element.android.features.messages.impl.timeline.components
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -28,6 +28,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.absoluteOffset
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
@@ -35,26 +36,25 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.DismissDirection
-import androidx.compose.material3.DismissState
-import androidx.compose.material3.DismissValue
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.SwipeToDismiss
-import androidx.compose.material3.rememberDismissState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
@@ -66,6 +66,7 @@ import io.element.android.features.messages.impl.timeline.aTimelineItemReactions
import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView
import io.element.android.features.messages.impl.timeline.components.event.toExtraPadding
import io.element.android.features.messages.impl.timeline.model.TimelineItem
+import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
import io.element.android.features.messages.impl.timeline.model.bubble.BubbleState
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
@@ -78,6 +79,9 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
+import io.element.android.libraries.designsystem.swipe.SwipeableActionsState
+import io.element.android.libraries.designsystem.swipe.rememberSwipeableActionsState
+import io.element.android.libraries.designsystem.text.toPx
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.UserId
@@ -93,7 +97,10 @@ import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
+import kotlinx.coroutines.launch
import org.jsoup.Jsoup
+import kotlin.math.abs
+import kotlin.math.roundToInt
@Composable
fun TimelineItemEventRow(
@@ -110,6 +117,7 @@ fun TimelineItemEventRow(
onSwipeToReply: () -> Unit,
modifier: Modifier = Modifier
) {
+ val coroutineScope = rememberCoroutineScope()
val interactionSource = remember { MutableInteractionSource() }
fun onUserDataClicked() {
@@ -121,56 +129,88 @@ fun TimelineItemEventRow(
inReplyToClick(inReplyToEventId)
}
- if (canReply) {
- val dismissState = rememberDismissState(
- confirmValueChange = {
- if (it == DismissValue.DismissedToEnd) {
- onSwipeToReply()
+ Column(modifier = modifier.fillMaxWidth()) {
+ if (event.groupPosition.isNew()) {
+ Spacer(modifier = Modifier.height(16.dp))
+ } else {
+ Spacer(modifier = Modifier.height(2.dp))
+ }
+ if (canReply) {
+ val state: SwipeableActionsState = rememberSwipeableActionsState()
+ val offset = state.offset.value
+ val swipeThresholdPx = 40.dp.toPx()
+ val thresholdCrossed = abs(offset) > swipeThresholdPx
+ SwipeSensitivity(3f) {
+ Box(Modifier.fillMaxWidth()) {
+ Row(modifier = Modifier.matchParentSize()) {
+ ReplySwipeIndicator({ offset / 120 })
+ }
+ TimelineItemEventRowContent(
+ modifier = Modifier
+ .absoluteOffset { IntOffset(x = offset.roundToInt(), y = 0) }
+ .draggable(
+ orientation = Orientation.Horizontal,
+ enabled = !state.isResettingOnRelease,
+ onDragStopped = {
+ coroutineScope.launch {
+ if (thresholdCrossed) {
+ onSwipeToReply()
+ }
+ state.resetOffset()
+ }
+ },
+ state = state.draggableState,
+ ),
+ event = event,
+ isHighlighted = isHighlighted,
+ interactionSource = interactionSource,
+ onClick = onClick,
+ onLongClick = onLongClick,
+ onTimestampClicked = onTimestampClicked,
+ inReplyToClicked = ::inReplyToClicked,
+ onUserDataClicked = ::onUserDataClicked,
+ onReactionClicked = { emoji -> onReactionClick(emoji, event) },
+ onMoreReactionsClicked = { onMoreReactionsClick(event) },
+ )
}
- // Do not dismiss the message, return false!
- false
}
- )
- SwipeToDismiss(
- state = dismissState,
- background = {
- ReplySwipeIndicator({ dismissState.toSwipeProgress() })
- },
- directions = setOf(DismissDirection.StartToEnd),
- dismissContent = {
- TimelineItemEventRowContent(
- event = event,
- isHighlighted = isHighlighted,
- interactionSource = interactionSource,
- onClick = onClick,
- onLongClick = onLongClick,
- onTimestampClicked = onTimestampClicked,
- inReplyToClicked = ::inReplyToClicked,
- onUserDataClicked = ::onUserDataClicked,
- onReactionClicked = { emoji -> onReactionClick(emoji, event) },
- onMoreReactionsClicked = { onMoreReactionsClick(event) },
- )
- }
- )
- } else {
- TimelineItemEventRowContent(
- event = event,
- isHighlighted = isHighlighted,
- interactionSource = interactionSource,
- onClick = onClick,
- onLongClick = onLongClick,
- onTimestampClicked = onTimestampClicked,
- inReplyToClicked = ::inReplyToClicked,
- onUserDataClicked = ::onUserDataClicked,
- onReactionClicked = { emoji -> onReactionClick(emoji, event) },
- onMoreReactionsClicked = { onMoreReactionsClick(event) },
- )
+ } else {
+ TimelineItemEventRowContent(
+ event = event,
+ isHighlighted = isHighlighted,
+ interactionSource = interactionSource,
+ onClick = onClick,
+ onLongClick = onLongClick,
+ onTimestampClicked = onTimestampClicked,
+ inReplyToClicked = ::inReplyToClicked,
+ onUserDataClicked = ::onUserDataClicked,
+ onReactionClicked = { emoji -> onReactionClick(emoji, event) },
+ onMoreReactionsClicked = { onMoreReactionsClick(event) },
+ )
+ }
}
- // This is assuming that we are in a ColumnScope, but this is OK, for both Preview and real usage.
- if (event.groupPosition.isNew()) {
- Spacer(modifier = modifier.height(16.dp))
- } else {
- Spacer(modifier = modifier.height(2.dp))
+}
+
+/**
+ * Impact ViewConfiguration.touchSlop by [sensitivityFactor].
+ * Inspired from https://issuetracker.google.com/u/1/issues/269627294.
+ * @param sensitivityFactor the factor to multiply the touchSlop by. The highest value, the more the user will
+ * have to drag to start the drag.
+ * @param content the content to display.
+ */
+@Composable
+fun SwipeSensitivity(
+ sensitivityFactor: Float,
+ content: @Composable () -> Unit,
+) {
+ val current = LocalViewConfiguration.current
+ CompositionLocalProvider(
+ LocalViewConfiguration provides object : ViewConfiguration by current {
+ override val touchSlop: Float
+ get() = current.touchSlop * sensitivityFactor
+ }
+ ) {
+ content()
}
}
@@ -266,14 +306,6 @@ private fun TimelineItemEventRowContent(
}
}
-private fun DismissState.toSwipeProgress(): Float {
- return when (targetValue) {
- DismissValue.Default -> 0f
- DismissValue.DismissedToEnd -> progress * 3
- DismissValue.DismissedToStart -> progress * 3
- }
-}
-
@Composable
private fun MessageSenderInformation(
sender: String,
@@ -544,6 +576,7 @@ private fun ContentToPreview() {
body = "A long text which will be displayed on several lines and" +
" hopefully can be manually adjusted to test different behaviors."
),
+ groupPosition = TimelineItemGroupPosition.First,
),
isHighlighted = false,
canReply = true,
@@ -562,6 +595,7 @@ private fun ContentToPreview() {
content = aTimelineItemImageContent().copy(
aspectRatio = 5f
),
+ groupPosition = TimelineItemGroupPosition.Last,
),
isHighlighted = false,
canReply = true,
@@ -606,7 +640,8 @@ private fun ContentToPreviewWithReply() {
body = "A long text which will be displayed on several lines and" +
" hopefully can be manually adjusted to test different behaviors."
),
- inReplyTo = aInReplyToReady(replyContent)
+ inReplyTo = aInReplyToReady(replyContent),
+ groupPosition = TimelineItemGroupPosition.First,
),
isHighlighted = false,
canReply = true,
@@ -625,7 +660,8 @@ private fun ContentToPreviewWithReply() {
content = aTimelineItemImageContent().copy(
aspectRatio = 5f
),
- inReplyTo = aInReplyToReady(replyContent)
+ inReplyTo = aInReplyToReady(replyContent),
+ groupPosition = TimelineItemGroupPosition.Last,
),
isHighlighted = false,
canReply = true,
@@ -699,7 +735,6 @@ private fun ContentTimestampToPreview(event: TimelineItem.Event) {
}
}
-
@Preview
@Composable
internal fun TimelineItemEventRowWithManyReactionsLightPreview() =
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/AggregatedReaction.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/AggregatedReaction.kt
index d25cc98a1d..ba13896c06 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/AggregatedReaction.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/AggregatedReaction.kt
@@ -16,8 +16,18 @@
package io.element.android.features.messages.impl.timeline.model
+import io.element.android.libraries.core.extensions.ellipsize
+
/**
- * @property key the reaction key (e.g. "👍")
+ * Length at which we ellipsize a reaction key for display
+ *
+ * Reactions can be free text, so we need to limit the length
+ * displayed on screen.
+ */
+private const val MAX_DISPLAY_CHARS = 16
+
+/**
+ * @property key the full reaction key (e.g. "👍", "YES!")
* @property count the number of users who reacted with this key
* @property isHighlighted true if the reaction has (also) been sent by the current user.
*/
@@ -25,4 +35,14 @@ data class AggregatedReaction(
val key: String,
val count: Int,
val isHighlighted: Boolean = false
-)
+) {
+
+ /**
+ * The key to be displayed on screen.
+ *
+ * See [MAX_DISPLAY_CHARS].
+ */
+ val displayKey: String by lazy {
+ key.ellipsize(MAX_DISPLAY_CHARS)
+ }
+}
diff --git a/features/messages/impl/src/main/res/values-de/translations.xml b/features/messages/impl/src/main/res/values-de/translations.xml
index a7dec0a6d4..1486e35726 100644
--- a/features/messages/impl/src/main/res/values-de/translations.xml
+++ b/features/messages/impl/src/main/res/values-de/translations.xml
@@ -10,11 +10,14 @@
"Anhang"
"Foto- & Video-Bibliothek"
"Standort"
+ "Der Nachrichtenverlauf ist in diesem Raum derzeit nicht verfügbar"
"Benutzerdetails konnten nicht abgerufen werden"
"Möchtest du sie wieder einladen?"
"Du bist allein in diesem Chat"
"Nachricht kopiert"
"Du bist keine Berechtigung, um in diesem Raum zu posten"
+ "Weniger anzeigen"
+ "Mehr anzeigen"
"Erneut senden"
"Ihre Nachricht konnte nicht gesendet werden"
"Fehler bei der Verarbeitung von Medien zum Hochladen, bitte versuchen Sie es erneut."
diff --git a/features/messages/impl/src/main/res/values-sk/translations.xml b/features/messages/impl/src/main/res/values-sk/translations.xml
index bfefe641d7..fcd8c0ca82 100644
--- a/features/messages/impl/src/main/res/values-sk/translations.xml
+++ b/features/messages/impl/src/main/res/values-sk/translations.xml
@@ -11,11 +11,14 @@
"Príloha"
"Knižnica fotografií a videí"
"Poloha"
+ "História správ v tejto miestnosti nie je momentálne k dispozícii"
"Nepodarilo sa získať údaje o používateľovi"
"Chceli by ste ich pozvať späť?"
"V tomto rozhovore ste sami"
"Správa skopírovaná"
"Nemáte povolenie uverejňovať príspevky v tejto miestnosti"
+ "Zobraziť menej"
+ "Zobraziť viac"
"Odoslať znova"
"Vašu správu sa nepodarilo odoslať"
"Nepodarilo sa spracovať médiá na odoslanie, skúste to prosím znova."
diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml
index b669766ede..03ac9ea46b 100644
--- a/features/messages/impl/src/main/res/values/localazy.xml
+++ b/features/messages/impl/src/main/res/values/localazy.xml
@@ -4,11 +4,9 @@
- "%1$d room change"
- "%1$d room changes"
- "Show less"
- "%1$d more"
- "Add emoji"
"Camera"
"Take photo"
"Record a video"
@@ -25,6 +23,8 @@
"Show more"
"Send again"
"Your message failed to send"
+ "Add emoji"
+ "Show less"
"Failed processing media to upload, please try again."
"Remove"
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/model/AggregatedReactionTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/model/AggregatedReactionTest.kt
new file mode 100644
index 0000000000..0e1ccbd003
--- /dev/null
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/model/AggregatedReactionTest.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.features.messages.timeline.model
+
+import io.element.android.features.messages.impl.timeline.model.AggregatedReaction
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class AggregatedReactionTest {
+ @Test
+ fun `reaction display key is shortened`() {
+ val reaction = AggregatedReaction(
+ key = "1234567890123456790",
+ count = 1,
+ isHighlighted = false
+ )
+
+ assertEquals("1234567890123456…", reaction.displayKey)
+ }
+}
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt
index 7afa2a67da..66ff62ee2b 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt
@@ -28,6 +28,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.features.logout.api.LogoutPreferencePresenter
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.meta.BuildType
+import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
+import io.element.android.libraries.designsystem.utils.collectSnackbarMessageAsState
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.api.user.getCurrentUser
@@ -43,6 +45,7 @@ class PreferencesRootPresenter @Inject constructor(
private val sessionVerificationService: SessionVerificationService,
private val buildType: BuildType,
private val versionFormatter: VersionFormatter,
+ private val snackbarDispatcher: SnackbarDispatcher,
) : Presenter {
@Composable
@@ -54,6 +57,8 @@ class PreferencesRootPresenter @Inject constructor(
initialLoad(matrixUser)
}
+ val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
+
// Session verification status (unknown, not verified, verified)
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
val sessionIsNotVerified by remember {
@@ -67,7 +72,8 @@ class PreferencesRootPresenter @Inject constructor(
myUser = matrixUser.value,
version = versionFormatter.get(),
showCompleteVerification = sessionIsNotVerified,
- showDeveloperSettings = showDeveloperSettings
+ showDeveloperSettings = showDeveloperSettings,
+ snackbarMessage = snackbarMessage,
)
}
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt
index 8760550fd0..2b0963c53c 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootState.kt
@@ -17,6 +17,7 @@
package io.element.android.features.preferences.impl.root
import io.element.android.features.logout.api.LogoutPreferenceState
+import io.element.android.libraries.designsystem.utils.SnackbarMessage
import io.element.android.libraries.matrix.api.user.MatrixUser
data class PreferencesRootState(
@@ -24,5 +25,6 @@ data class PreferencesRootState(
val myUser: MatrixUser?,
val version: String,
val showCompleteVerification: Boolean,
- val showDeveloperSettings: Boolean
+ val showDeveloperSettings: Boolean,
+ val snackbarMessage: SnackbarMessage?,
)
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
index 4f9626bcbd..9dbd54ffff 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
@@ -17,11 +17,14 @@
package io.element.android.features.preferences.impl.root
import io.element.android.features.logout.api.aLogoutPreferenceState
+import io.element.android.libraries.designsystem.utils.SnackbarMessage
+import io.element.android.libraries.ui.strings.CommonStrings
fun aPreferencesRootState() = PreferencesRootState(
logoutState = aLogoutPreferenceState(),
myUser = null,
version = "Version 1.1 (1)",
showCompleteVerification = true,
- showDeveloperSettings = true
+ showDeveloperSettings = true,
+ snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
)
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt
index f1e6e7de61..01d790f8b9 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt
@@ -24,6 +24,8 @@ import androidx.compose.material.icons.outlined.DeveloperMode
import androidx.compose.material.icons.outlined.Help
import androidx.compose.material.icons.outlined.InsertChart
import androidx.compose.material.icons.outlined.VerifiedUser
+import androidx.compose.material3.Snackbar
+import androidx.compose.material3.SnackbarHost
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -39,6 +41,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.theme.components.Text
+import io.element.android.libraries.designsystem.utils.rememberSnackbarHostState
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.MatrixUserProvider
import io.element.android.libraries.theme.ElementTheme
@@ -55,11 +58,20 @@ fun PreferencesRootView(
onOpenDeveloperSettings: () -> Unit,
modifier: Modifier = Modifier,
) {
+ val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage)
+
// Include pref from other modules
PreferenceView(
modifier = modifier,
onBackPressed = onBackPressed,
- title = stringResource(id = CommonStrings.common_settings)
+ title = stringResource(id = CommonStrings.common_settings),
+ snackbarHost = {
+ SnackbarHost(snackbarHostState) { data ->
+ Snackbar(
+ snackbarData = data,
+ )
+ }
+ }
) {
UserPreferences(state.myUser)
if (state.showCompleteVerification) {
diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
index 58931e25d7..f3cf23599f 100644
--- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
+++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
@@ -23,6 +23,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.logout.impl.DefaultLogoutPreferencePresenter
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.core.meta.BuildType
+import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.AN_AVATAR_URL
import io.element.android.libraries.matrix.test.A_USER_NAME
@@ -41,7 +42,8 @@ class PreferencesRootPresenterTest {
matrixClient,
FakeSessionVerificationService(),
BuildType.DEBUG,
- FakeVersionFormatter()
+ FakeVersionFormatter(),
+ SnackbarDispatcher(),
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt
index 2c70e66ff6..4ef482ffe9 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt
@@ -22,7 +22,7 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import io.element.android.features.leaveroom.api.LeaveRoomEvent
import io.element.android.features.leaveroom.api.LeaveRoomPresenter
@@ -55,14 +55,14 @@ class RoomDetailsPresenter @Inject constructor(
val canEditTopic by getCanSendStateEvent(membersState, StateEventType.ROOM_TOPIC)
val dmMember by room.getDirectRoomMember(membersState)
val roomMemberDetailsPresenter = roomMemberDetailsPresenter(dmMember)
- val roomType = getRoomType(dmMember)
+ val roomType by getRoomType(dmMember)
- val topicState = remember(canEditTopic, room.topic) {
+ val topicState = remember(canEditTopic, room.topic, roomType) {
val topic = room.topic
when {
!topic.isNullOrBlank() -> RoomTopicState.ExistingTopic(topic)
- canEditTopic -> RoomTopicState.CanAddTopic
+ canEditTopic && roomType is RoomDetailsType.Room -> RoomTopicState.CanAddTopic
else -> RoomTopicState.Hidden
}
}
@@ -85,8 +85,8 @@ class RoomDetailsPresenter @Inject constructor(
memberCount = room.joinedMemberCount,
isEncrypted = room.isEncrypted,
canInvite = canInvite,
- canEdit = canEditAvatar || canEditName || canEditTopic,
- roomType = roomType.value,
+ canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room,
+ roomType = roomType,
roomMemberDetailsState = roomMemberDetailsState,
leaveRoomState = leaveRoomState,
eventSink = ::handleEvents,
@@ -112,20 +112,12 @@ class RoomDetailsPresenter @Inject constructor(
}
@Composable
- private fun getCanInvite(membersState: MatrixRoomMembersState): State {
- val canInvite = remember(membersState) { mutableStateOf(false) }
- LaunchedEffect(membersState) {
- canInvite.value = room.canInvite().getOrElse { false }
- }
- return canInvite
+ private fun getCanInvite(membersState: MatrixRoomMembersState) = produceState(false, membersState) {
+ value = room.canInvite().getOrElse { false }
}
@Composable
- private fun getCanSendStateEvent(membersState: MatrixRoomMembersState, type: StateEventType): State {
- val canSendEvent = remember(membersState) { mutableStateOf(false) }
- LaunchedEffect(membersState) {
- canSendEvent.value = room.canSendStateEvent(type).getOrElse { false }
- }
- return canSendEvent
+ private fun getCanSendStateEvent(membersState: MatrixRoomMembersState, type: StateEventType) = produceState(false, membersState) {
+ value = room.canSendStateEvent(type).getOrElse { false }
}
}
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
index aa98bb75b7..845eb7bc93 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
@@ -68,11 +68,11 @@ import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
import io.element.android.libraries.matrix.ui.components.UnsavedAvatar
import io.element.android.libraries.ui.strings.CommonStrings
@@ -102,7 +102,7 @@ fun RoomDetailsEditView(
Scaffold(
modifier = modifier.clearFocusOnTap(focusManager),
topBar = {
- CenterAlignedTopAppBar(
+ TopAppBar(
title = {
Text(
text = stringResource(id = R.string.screen_room_details_edit_room_title),
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt
index 9d5939a8f5..f7782284cc 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersView.kt
@@ -39,13 +39,13 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.SearchBar
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.components.CheckableUnresolvedUserRow
import io.element.android.libraries.matrix.ui.components.CheckableUserRow
@@ -117,7 +117,7 @@ fun RoomInviteMembersTopBar(
onBackPressed: () -> Unit = {},
onSendPressed: () -> Unit = {},
) {
- CenterAlignedTopAppBar(
+ TopAppBar(
modifier = modifier,
title = {
Text(
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
index 5a45fe9685..2f7845cb1c 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
@@ -49,13 +49,13 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
-import io.element.android.libraries.designsystem.theme.components.CenterAlignedTopAppBar
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
import io.element.android.libraries.designsystem.theme.components.Scaffold
import io.element.android.libraries.designsystem.theme.components.SearchBar
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
+import io.element.android.libraries.designsystem.theme.components.TopAppBar
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.user.MatrixUser
@@ -203,7 +203,7 @@ private fun RoomMemberListTopBar(
onBackPressed: () -> Unit = {},
onInvitePressed: () -> Unit = {},
) {
- CenterAlignedTopAppBar(
+ TopAppBar(
modifier = modifier,
title = {
Text(
diff --git a/features/roomdetails/impl/src/main/res/values-de/translations.xml b/features/roomdetails/impl/src/main/res/values-de/translations.xml
index 0678faf8a4..992ca94b85 100644
--- a/features/roomdetails/impl/src/main/res/values-de/translations.xml
+++ b/features/roomdetails/impl/src/main/res/values-de/translations.xml
@@ -13,7 +13,7 @@
"Nachrichten sind mit Schlössern gesichert. Nur du und der Empfänger haben die eindeutigen Schlüssel, um sie zu entsperren."
"Nachrichtenverschlüsselung aktiviert"
"Personen einladen"
- "Benachrichtigung"
+ "Benachrichtigungen"
"Raumname"
"Raum teilen"
"Aktualisiere Raum…"
diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml
index fd5cff79df..3f20205458 100644
--- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml
+++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml
@@ -14,7 +14,7 @@
"Správy sú zabezpečené zámkami. Jedine vy a príjemcovia máte jedinečné kľúče na ich odomknutie."
"Šifrovanie správ je zapnuté"
"Pozvať ľudí"
- "Oznámenie"
+ "Oznámenia"
"Názov miestnosti"
"Zdieľať miestnosť"
"Aktualizácia miestnosti…"
diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt
index f9d947615a..ccd1476c3a 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/RoomDetailsPresenterTests.kt
@@ -20,7 +20,10 @@ import app.cash.molecule.RecompositionClock
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
+import io.element.android.features.leaveroom.api.LeaveRoomEvent
+import io.element.android.features.leaveroom.api.LeaveRoomPresenter
import io.element.android.features.leaveroom.fake.LeaveRoomPresenterFake
+import io.element.android.features.roomdetails.impl.RoomDetailsEvent
import io.element.android.features.roomdetails.impl.RoomDetailsPresenter
import io.element.android.features.roomdetails.impl.RoomDetailsType
import io.element.android.features.roomdetails.impl.RoomTopicState
@@ -44,13 +47,13 @@ import org.junit.Test
@ExperimentalCoroutinesApi
class RoomDetailsPresenterTests {
- private fun aRoomDetailsPresenter(room: MatrixRoom): RoomDetailsPresenter {
+ private fun aRoomDetailsPresenter(room: MatrixRoom, leaveRoomPresenter: LeaveRoomPresenter = LeaveRoomPresenterFake()): RoomDetailsPresenter {
val roomMemberDetailsPresenterFactory = object : RoomMemberDetailsPresenter.Factory {
override fun create(roomMemberId: UserId): RoomMemberDetailsPresenter {
return RoomMemberDetailsPresenter(FakeMatrixClient(), room, roomMemberId)
}
}
- return RoomDetailsPresenter(room, roomMemberDetailsPresenterFactory, LeaveRoomPresenterFake())
+ return RoomDetailsPresenter(room, roomMemberDetailsPresenterFactory, leaveRoomPresenter)
}
@Test
@@ -173,6 +176,64 @@ class RoomDetailsPresenterTests {
}
}
+ @Test
+ fun `present - initial state when user can edit attributes in a DM`() = runTest {
+ val myRoomMember = aRoomMember(A_SESSION_ID)
+ val otherRoomMember = aRoomMember(A_USER_ID_2)
+ val room = aMatrixRoom(
+ isEncrypted = true,
+ isDirect = true,
+ ).apply {
+ val roomMembers = listOf(myRoomMember, otherRoomMember)
+ givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
+
+ givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
+ givenCanSendStateResult(StateEventType.ROOM_NAME, Result.success(true))
+ givenCanSendStateResult(StateEventType.ROOM_AVATAR, Result.success(true))
+ givenCanInviteResult(Result.success(false))
+ }
+ val presenter = aRoomDetailsPresenter(room)
+ moleculeFlow(RecompositionClock.Immediate) {
+ presenter.present()
+ }.test {
+ // Initially false
+ assertThat(awaitItem().canEdit).isFalse()
+ // Then the asynchronous check completes, but editing is still disallowed because it's a DM
+ val settledState = awaitItem()
+ assertThat(settledState.canEdit).isFalse()
+ // If there is a topic, it's visible
+ assertThat(settledState.roomTopic).isEqualTo(RoomTopicState.ExistingTopic(room.topic!!))
+
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
+ @Test
+ fun `present - initial state when in a DM with no topic`() = runTest {
+ val myRoomMember = aRoomMember(A_SESSION_ID)
+ val otherRoomMember = aRoomMember(A_USER_ID_2)
+ val room = aMatrixRoom(
+ isEncrypted = true,
+ isDirect = true,
+ topic = null,
+ ).apply {
+ val roomMembers = listOf(myRoomMember, otherRoomMember)
+ givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
+
+ givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
+ }
+ val presenter = aRoomDetailsPresenter(room)
+ moleculeFlow(RecompositionClock.Immediate) {
+ presenter.present()
+ }.test {
+ skipItems(1)
+
+ // There's no topic, so we hide the entire UI for DMs
+ assertThat(awaitItem().roomTopic).isEqualTo(RoomTopicState.Hidden)
+
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
+
@Test
fun `present - initial state when user can edit all attributes`() = runTest {
val room = aMatrixRoom().apply {
@@ -247,6 +308,22 @@ class RoomDetailsPresenterTests {
cancelAndIgnoreRemainingEvents()
}
}
+
+ @Test
+ fun `present - leave room event is passed on to leave room presenter`() = runTest {
+ val leaveRoomPresenter = LeaveRoomPresenterFake()
+ val room = aMatrixRoom()
+ val presenter = aRoomDetailsPresenter(room, leaveRoomPresenter)
+ moleculeFlow(RecompositionClock.Immediate) {
+ presenter.present()
+ }.test {
+ awaitItem().eventSink(RoomDetailsEvent.LeaveRoom)
+
+ assertThat(leaveRoomPresenter.events).contains(LeaveRoomEvent.ShowConfirmation(room.roomId))
+
+ cancelAndIgnoreRemainingEvents()
+ }
+ }
}
fun aMatrixRoom(
diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt
index 17b2b80cb9..657648df42 100644
--- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt
+++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListView.kt
@@ -231,8 +231,6 @@ fun RoomListContent(
SnackbarHost(snackbarHostState) { data ->
Snackbar(
snackbarData = data,
- containerColor = MaterialTheme.colorScheme.surfaceVariant,
- contentColor = MaterialTheme.colorScheme.primary
)
}
},
diff --git a/features/roomlist/impl/src/main/res/values-sk/translations.xml b/features/roomlist/impl/src/main/res/values-sk/translations.xml
index 22e8fa193f..250822f4c9 100644
--- a/features/roomlist/impl/src/main/res/values-sk/translations.xml
+++ b/features/roomlist/impl/src/main/res/values-sk/translations.xml
@@ -2,6 +2,6 @@
"Vytvorte novú konverzáciu alebo miestnosť"
"Všetky konverzácie"
- "Vyzerá to tak, že používate nové zariadenie. Overte, či ste to vy, aby ste mali prístup k zašifrovaným správam."
- "Získajte prístup k histórii vašich správ"
+ "Vyzerá to tak, že používate nové zariadenie. Overte svoj prístup k zašifrovaným správam pomocou vášho druhého zariadenia."
+ "Overte, že ste to vy"
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index c71e609a21..0c5ea537a5 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -152,7 +152,6 @@ sqldelight-coroutines = { module = "com.squareup.sqldelight:coroutines-extension
sqlcipher = "net.zetetic:android-database-sqlcipher:4.5.4"
sqlite = "androidx.sqlite:sqlite:2.3.1"
unifiedpush = "com.github.UnifiedPush:android-connector:2.1.1"
-gujun_span = "me.gujun.android:span:1.7"
otaliastudios_transcoder = "com.otaliastudios:transcoder:0.10.5"
vanniktech_blurhash = "com.vanniktech:blurhash:0.1.0"
vanniktech_emoji = "com.vanniktech:emoji-google:0.16.0"
diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt
index cc97b5fda0..562f62de6d 100644
--- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt
+++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/extensions/BasicExtensions.kt
@@ -58,6 +58,21 @@ fun String?.insertBeforeLast(insert: String, delimiter: String = "."): String {
}
}
+/**
+ * Truncate and ellipsize text if it exceeds the given length.
+ *
+ * Throws if length is < 1.
+ */
+fun String.ellipsize(length: Int): String {
+ require(length > 1)
+
+ if (this.length <= length) {
+ return this
+ }
+
+ return "${this.take(length)}…"
+}
+
inline fun Any?.takeAs(): R? {
return takeIf { it is R } as R?
}
diff --git a/libraries/core/src/test/kotlin/io/element/android/libraries/core/extensions/BasicExtensionsTest.kt b/libraries/core/src/test/kotlin/io/element/android/libraries/core/extensions/BasicExtensionsTest.kt
new file mode 100644
index 0000000000..5a3baa1297
--- /dev/null
+++ b/libraries/core/src/test/kotlin/io/element/android/libraries/core/extensions/BasicExtensionsTest.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.extensions
+
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+class BasicExtensionsTest {
+
+ @Test(expected = IllegalArgumentException::class)
+ fun `test ellipsize at 0`() {
+ "1234567890".ellipsize(0)
+ }
+
+ @Test
+ fun `test ellipsize at 1`() {
+ assertEquals(
+ "1…",
+ "1234567890".ellipsize(1)
+ )
+ }
+
+ @Test
+ fun `test ellipsize at 5`() {
+ val output = "1234567890".ellipsize(5)
+ assertEquals("12345…", output)
+ }
+
+ @Test
+ fun `test ellipsize noop 1`() {
+ val input = "12345"
+ val output = input.ellipsize(5)
+ assertEquals(input, output)
+ }
+
+ @Test
+ fun `test ellipsize noop 2`() {
+ val input = "123"
+ val output = input.ellipsize(5)
+ assertEquals(input, output)
+ }
+}
diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt
index df26ef2fa0..d16d31fb82 100644
--- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt
+++ b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/Constants.kt
@@ -18,3 +18,7 @@ package io.element.android.libraries.deeplink
internal const val SCHEME = "elementx"
internal const val HOST = "open"
+
+object DeepLinkPaths {
+ const val INVITE_LIST = "invites"
+}
diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt
index 71aa7ebddd..0cf2a7fca8 100644
--- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt
+++ b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeepLinkCreator.kt
@@ -22,7 +22,7 @@ import io.element.android.libraries.matrix.api.core.ThreadId
import javax.inject.Inject
class DeepLinkCreator @Inject constructor() {
- fun create(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String {
+ fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String {
return buildString {
append("$SCHEME://$HOST/")
append(sessionId.value)
@@ -36,4 +36,13 @@ class DeepLinkCreator @Inject constructor() {
}
}
}
+
+ fun inviteList(sessionId: SessionId): String {
+ return buildString {
+ append("$SCHEME://$HOST/")
+ append(sessionId.value)
+ append("/")
+ append(DeepLinkPaths.INVITE_LIST)
+ }
+ }
}
diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt
index d393a37c16..aa373411c7 100644
--- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt
+++ b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkData.kt
@@ -20,8 +20,16 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
-data class DeeplinkData(
- val sessionId: SessionId,
- val roomId: RoomId? = null,
- val threadId: ThreadId? = null,
-)
+sealed interface DeeplinkData {
+ /** Session id is common for all deep links. */
+ val sessionId: SessionId
+
+ /** The target is the root of the app, with the given [sessionId]. */
+ data class Root(override val sessionId: SessionId) : DeeplinkData
+
+ /** The target is a room, with the given [sessionId], [roomId] and optionally a [threadId]. */
+ data class Room(override val sessionId: SessionId, val roomId: RoomId, val threadId: ThreadId?) : DeeplinkData
+
+ /** The target is the invites list, with the given [sessionId]. */
+ data class InviteList(override val sessionId: SessionId) : DeeplinkData
+}
diff --git a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt
index 616cd58245..7d2c8af135 100644
--- a/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt
+++ b/libraries/deeplink/src/main/kotlin/io/element/android/libraries/deeplink/DeeplinkParser.kt
@@ -18,6 +18,7 @@ package io.element.android.libraries.deeplink
import android.content.Intent
import android.net.Uri
+import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
@@ -36,12 +37,21 @@ class DeeplinkParser @Inject constructor() {
if (host != HOST) return null
val pathBits = path.orEmpty().split("/").drop(1)
val sessionId = pathBits.elementAtOrNull(0)?.let(::SessionId) ?: return null
- val roomId = pathBits.elementAtOrNull(1)?.let(::RoomId)
- val threadId = pathBits.elementAtOrNull(2)?.let(::ThreadId)
- return DeeplinkData(
- sessionId = sessionId,
- roomId = roomId,
- threadId = threadId,
- )
+ val screenPathComponent = pathBits.elementAtOrNull(1)
+ val roomId = tryOrNull { screenPathComponent?.let(::RoomId) }
+
+ return when {
+ roomId != null -> {
+ val threadId = pathBits.elementAtOrNull(2)?.let(::ThreadId)
+ DeeplinkData.Room(sessionId, roomId, threadId)
+ }
+ screenPathComponent == DeepLinkPaths.INVITE_LIST -> {
+ DeeplinkData.InviteList(sessionId)
+ }
+ screenPathComponent == null -> {
+ DeeplinkData.Root(sessionId)
+ }
+ else -> null
+ }
}
}
diff --git a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt b/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt
index 730bdde248..70c047f8ed 100644
--- a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt
+++ b/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeepLinkCreatorTest.kt
@@ -25,13 +25,20 @@ import org.junit.Test
class DeepLinkCreatorTest {
@Test
- fun create() {
+ fun room() {
val sut = DeepLinkCreator()
- assertThat(sut.create(A_SESSION_ID, null, null))
+ assertThat(sut.room(A_SESSION_ID, null, null))
.isEqualTo("elementx://open/@alice:server.org")
- assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, null))
+ assertThat(sut.room(A_SESSION_ID, A_ROOM_ID, null))
.isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain")
- assertThat(sut.create(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID))
+ assertThat(sut.room(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID))
.isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId")
}
+
+ @Test
+ fun inviteList() {
+ val sut = DeepLinkCreator()
+ assertThat(sut.inviteList(A_SESSION_ID))
+ .isEqualTo("elementx://open/@alice:server.org/invites")
+ }
}
diff --git a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt b/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt
index 4ebb079189..553850a4d6 100644
--- a/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt
+++ b/libraries/deeplink/src/test/kotlin/io/element/android/libraries/deeplink/DeeplinkParserTest.kt
@@ -36,6 +36,8 @@ class DeeplinkParserTest {
"elementx://open/@alice:server.org/!aRoomId:domain"
const val A_URI_WITH_ROOM_WITH_THREAD =
"elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId"
+ const val A_URI_FOR_INVITE_LIST =
+ "elementx://open/@alice:server.org/invites"
}
private val sut = DeeplinkParser()
@@ -43,11 +45,13 @@ class DeeplinkParserTest {
@Test
fun `nominal cases`() {
assertThat(sut.getFromIntent(createIntent(A_URI)))
- .isEqualTo(DeeplinkData(A_SESSION_ID, null, null))
+ .isEqualTo(DeeplinkData.Root(A_SESSION_ID))
assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM)))
- .isEqualTo(DeeplinkData(A_SESSION_ID, A_ROOM_ID, null))
+ .isEqualTo(DeeplinkData.Room(A_SESSION_ID, A_ROOM_ID, null))
assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM_WITH_THREAD)))
- .isEqualTo(DeeplinkData(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID))
+ .isEqualTo(DeeplinkData.Room(A_SESSION_ID, A_ROOM_ID, A_THREAD_ID))
+ assertThat(sut.getFromIntent(createIntent(A_URI_FOR_INVITE_LIST)))
+ .isEqualTo(DeeplinkData.InviteList(A_SESSION_ID))
}
@Test
diff --git a/libraries/designsystem/build.gradle.kts b/libraries/designsystem/build.gradle.kts
index c6c1836a23..8ffdb17cdd 100644
--- a/libraries/designsystem/build.gradle.kts
+++ b/libraries/designsystem/build.gradle.kts
@@ -27,6 +27,13 @@ android {
buildConfig = true
}
+ buildTypes {
+ getByName("release") {
+ isMinifyEnabled = true
+ consumerProguardFiles("proguard-rules.pro")
+ }
+ }
+
dependencies {
api(projects.libraries.theme)
// Should not be there, but this is a POC
diff --git a/libraries/designsystem/proguard-rules.pro b/libraries/designsystem/proguard-rules.pro
index ff59496d81..dabf5661a4 100644
--- a/libraries/designsystem/proguard-rules.pro
+++ b/libraries/designsystem/proguard-rules.pro
@@ -18,4 +18,6 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
+#-renamesourcefileattribute SourceFile
+
+-keep class io.element.android.libraries.designsystem.showkase.DesignSystemShowkaseRootModuleCodegen { }
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt
index 7a6eaf327d..5c44d48f24 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt
@@ -50,6 +50,7 @@ fun PreferenceView(
title: String,
modifier: Modifier = Modifier,
onBackPressed: () -> Unit = {},
+ snackbarHost: @Composable () -> Unit = {},
content: @Composable ColumnScope.() -> Unit,
) {
Scaffold(
@@ -64,6 +65,7 @@ fun PreferenceView(
onBackPressed = onBackPressed,
)
},
+ snackbarHost = snackbarHost,
content = {
Column(
modifier = Modifier
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/swipe/SwipeableActionsState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/swipe/SwipeableActionsState.kt
new file mode 100644
index 0000000000..77d80cdde5
--- /dev/null
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/swipe/SwipeableActionsState.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.designsystem.swipe
+
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.MutatePriority
+import androidx.compose.foundation.gestures.DraggableState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+
+/**
+ * Inspired from https://github.com/bmarty/swipe/blob/trunk/swipe/src/main/kotlin/me/saket/swipe/SwipeableActionsState.kt
+ */
+@Composable
+fun rememberSwipeableActionsState(): SwipeableActionsState {
+ return remember { SwipeableActionsState() }
+}
+
+@Stable
+class SwipeableActionsState {
+ /**
+ * The current position (in pixels) of the content.
+ */
+ val offset: State get() = offsetState
+ private var offsetState = mutableStateOf(0f)
+
+ /**
+ * Whether the content is currently animating to reset its offset after it was swiped.
+ */
+ var isResettingOnRelease: Boolean by mutableStateOf(false)
+ private set
+
+ val draggableState = DraggableState { delta ->
+ val targetOffset = offsetState.value + delta
+ val isAllowed = isResettingOnRelease || targetOffset > 0f
+
+ offsetState.value += if (isAllowed) delta else 0f
+ }
+
+ suspend fun resetOffset() {
+ draggableState.drag(MutatePriority.PreventUserInput) {
+ isResettingOnRelease = true
+ try {
+ Animatable(offsetState.value).animateTo(
+ targetValue = 0f,
+ animationSpec = tween(durationMillis = 300),
+ ) {
+ dragBy(value - offsetState.value)
+ }
+ } finally {
+ isResettingOnRelease = false
+ }
+ }
+ }
+}
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt
deleted file mode 100644
index dab180e1c2..0000000000
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.designsystem.theme.components
-
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.TopAppBarColors
-import androidx.compose.material3.TopAppBarDefaults
-import androidx.compose.material3.TopAppBarScrollBehavior
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.tooling.preview.Preview
-import io.element.android.libraries.designsystem.preview.ElementThemedPreview
-import io.element.android.libraries.designsystem.preview.PreviewGroup
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-fun CenterAlignedTopAppBar(
- title: @Composable () -> Unit,
- modifier: Modifier = Modifier,
- navigationIcon: @Composable () -> Unit = {},
- actions: @Composable RowScope.() -> Unit = {},
- windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
- colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(),
- scrollBehavior: TopAppBarScrollBehavior? = null,
-) {
- androidx.compose.material3.CenterAlignedTopAppBar(
- title = title,
- modifier = modifier,
- navigationIcon = navigationIcon,
- actions = actions,
- windowInsets = windowInsets,
- colors = colors,
- scrollBehavior = scrollBehavior,
- )
-}
-
-@Preview(group = PreviewGroup.AppBars)
-@Composable
-internal fun CenterAlignedTopAppBarPreview() =
- ElementThemedPreview { ContentToPreview() }
-
-@OptIn(ExperimentalMaterial3Api::class)
-@Composable
-private fun ContentToPreview() {
- CenterAlignedTopAppBar(title = { Text(text = "Title") })
-}
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt
index c24268852d..f4e44779d1 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/utils/Snackbar.kt
@@ -25,7 +25,6 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -69,14 +68,13 @@ fun SnackbarDispatcher.collectSnackbarMessageAsState(): State
@Composable
fun rememberSnackbarHostState(snackbarMessage: SnackbarMessage?): SnackbarHostState {
val snackbarHostState = remember { SnackbarHostState() }
- val coroutineScope = rememberCoroutineScope()
val snackbarMessageText = snackbarMessage?.let {
stringResource(id = snackbarMessage.messageResId)
}
val dispatcher = LocalSnackbarDispatcher.current
LaunchedEffect(snackbarMessage) {
if (snackbarMessageText == null) return@LaunchedEffect
- coroutineScope.launch {
+ launch {
snackbarHostState.showSnackbar(
message = snackbarMessageText,
duration = snackbarMessage.duration,
diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt
index eb6e9998ac..4ded947d56 100644
--- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt
+++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt
@@ -19,6 +19,8 @@ package io.element.android.libraries.matrix.api.notification
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.core.UserId
+import io.element.android.libraries.matrix.api.room.RoomMembershipState
+import io.element.android.libraries.matrix.api.timeline.item.event.MessageType
data class NotificationData(
val senderId: UserId,
@@ -36,7 +38,60 @@ data class NotificationData(
data class NotificationEvent(
val timestamp: Long,
- val content: String,
+ val content: NotificationContent,
// For images for instance
val contentUrl: String?
)
+
+sealed interface NotificationContent {
+ sealed interface MessageLike : NotificationContent {
+ object CallAnswer : MessageLike
+ object CallInvite : MessageLike
+ object CallHangup : MessageLike
+ object CallCandidates : MessageLike
+ object KeyVerificationReady : MessageLike
+ object KeyVerificationStart : MessageLike
+ object KeyVerificationCancel : MessageLike
+ object KeyVerificationAccept : MessageLike
+ object KeyVerificationKey : MessageLike
+ object KeyVerificationMac : MessageLike
+ object KeyVerificationDone : MessageLike
+ data class ReactionContent(
+ val relatedEventId: String
+ ) : MessageLike
+ object RoomEncrypted : MessageLike
+ data class RoomMessage(
+ val messageType: MessageType
+ ) : MessageLike
+ object RoomRedaction : MessageLike
+ object Sticker : MessageLike
+ }
+
+ sealed interface StateEvent : NotificationContent {
+ object PolicyRuleRoom : StateEvent
+ object PolicyRuleServer : StateEvent
+ object PolicyRuleUser : StateEvent
+ object RoomAliases : StateEvent
+ object RoomAvatar : StateEvent
+ object RoomCanonicalAlias : StateEvent
+ object RoomCreate : StateEvent
+ object RoomEncryption : StateEvent
+ object RoomGuestAccess : StateEvent
+ object RoomHistoryVisibility : StateEvent
+ object RoomJoinRules : StateEvent
+ data class RoomMemberContent(
+ val userId: String,
+ val membershipState: RoomMembershipState
+ ) : StateEvent
+ object RoomName : StateEvent
+ object RoomPinnedEvents : StateEvent
+ object RoomPowerLevels : StateEvent
+ object RoomServerAcl : StateEvent
+ object RoomThirdPartyInvite : StateEvent
+ object RoomTombstone : StateEvent
+ object RoomTopic : StateEvent
+ object SpaceChild : StateEvent
+ object SpaceParent : StateEvent
+ }
+
+}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt
index b62063ddc5..957f2ff7b9 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt
@@ -28,19 +28,19 @@ class NotificationMapper {
private val timelineEventMapper = TimelineEventMapper()
fun map(notificationItem: NotificationItem): NotificationData {
- return notificationItem.use {
+ return notificationItem.use { item ->
NotificationData(
- senderId = UserId(it.event.senderId()),
- eventId = EventId(it.event.eventId()),
- roomId = RoomId(it.roomInfo.id),
- senderAvatarUrl = it.senderInfo.avatarUrl,
- senderDisplayName = it.senderInfo.displayName,
- roomAvatarUrl = it.roomInfo.avatarUrl,
- roomDisplayName = it.roomInfo.displayName,
- isDirect = it.roomInfo.isDirect,
- isEncrypted = it.roomInfo.isEncrypted.orFalse(),
- isNoisy = it.isNoisy,
- event = it.event.use { event -> timelineEventMapper.map(event) }
+ senderId = UserId(item.event.senderId()),
+ eventId = EventId(item.event.eventId()),
+ roomId = RoomId(item.roomInfo.id),
+ senderAvatarUrl = item.senderInfo.avatarUrl,
+ senderDisplayName = item.senderInfo.displayName,
+ roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { item.roomInfo.isDirect },
+ roomDisplayName = item.roomInfo.displayName,
+ isDirect = item.roomInfo.isDirect,
+ isEncrypted = item.roomInfo.isEncrypted.orFalse(),
+ isNoisy = item.isNoisy,
+ event = item.event.use { event -> timelineEventMapper.map(event) }
)
}
}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt
index 99e5991719..7d523abdc7 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt
@@ -36,7 +36,8 @@ class RustNotificationService(
filterByPushRules: Boolean,
): Result {
return runCatching {
- client.getNotificationItem(roomId.value, eventId.value, filterByPushRules)?.use(notificationMapper::map)
+ val item = client.getNotificationItem(roomId.value, eventId.value, filterByPushRules)
+ item?.use(notificationMapper::map)
}
}
}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt
index 18d6d389e2..f7d4a00188 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt
@@ -16,9 +16,11 @@
package io.element.android.libraries.matrix.impl.notification
+import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.api.notification.NotificationEvent
+import io.element.android.libraries.matrix.impl.room.RoomMemberMapper
+import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper
import org.matrix.rustcomponents.sdk.MessageLikeEventContent
-import org.matrix.rustcomponents.sdk.MessageType
import org.matrix.rustcomponents.sdk.StateEventContent
import org.matrix.rustcomponents.sdk.TimelineEvent
import org.matrix.rustcomponents.sdk.TimelineEventType
@@ -38,71 +40,62 @@ class TimelineEventMapper @Inject constructor() {
}
}
-private fun TimelineEventType.toContent(): String {
+private fun TimelineEventType.toContent(): NotificationContent {
return when (this) {
is TimelineEventType.MessageLike -> content.toContent()
is TimelineEventType.State -> content.toContent()
}
}
-private fun StateEventContent.toContent(): String {
+private fun StateEventContent.toContent(): NotificationContent.StateEvent {
return when (this) {
- StateEventContent.PolicyRuleRoom -> "PolicyRuleRoom"
- StateEventContent.PolicyRuleServer -> "PolicyRuleServer"
- StateEventContent.PolicyRuleUser -> "PolicyRuleUser"
- StateEventContent.RoomAliases -> "RoomAliases"
- StateEventContent.RoomAvatar -> "RoomAvatar"
- StateEventContent.RoomCanonicalAlias -> "RoomCanonicalAlias"
- StateEventContent.RoomCreate -> "RoomCreate"
- StateEventContent.RoomEncryption -> "RoomEncryption"
- StateEventContent.RoomGuestAccess -> "RoomGuestAccess"
- StateEventContent.RoomHistoryVisibility -> "RoomHistoryVisibility"
- StateEventContent.RoomJoinRules -> "RoomJoinRules"
- is StateEventContent.RoomMemberContent -> "$userId is now $membershipState"
- StateEventContent.RoomName -> "RoomName"
- StateEventContent.RoomPinnedEvents -> "RoomPinnedEvents"
- StateEventContent.RoomPowerLevels -> "RoomPowerLevels"
- StateEventContent.RoomServerAcl -> "RoomServerAcl"
- StateEventContent.RoomThirdPartyInvite -> "RoomThirdPartyInvite"
- StateEventContent.RoomTombstone -> "RoomTombstone"
- StateEventContent.RoomTopic -> "RoomTopic"
- StateEventContent.SpaceChild -> "SpaceChild"
- StateEventContent.SpaceParent -> "SpaceParent"
+ StateEventContent.PolicyRuleRoom -> NotificationContent.StateEvent.PolicyRuleRoom
+ StateEventContent.PolicyRuleServer -> NotificationContent.StateEvent.PolicyRuleServer
+ StateEventContent.PolicyRuleUser -> NotificationContent.StateEvent.PolicyRuleUser
+ StateEventContent.RoomAliases -> NotificationContent.StateEvent.RoomAliases
+ StateEventContent.RoomAvatar -> NotificationContent.StateEvent.RoomAvatar
+ StateEventContent.RoomCanonicalAlias -> NotificationContent.StateEvent.RoomCanonicalAlias
+ StateEventContent.RoomCreate -> NotificationContent.StateEvent.RoomCreate
+ StateEventContent.RoomEncryption -> NotificationContent.StateEvent.RoomEncryption
+ StateEventContent.RoomGuestAccess -> NotificationContent.StateEvent.RoomGuestAccess
+ StateEventContent.RoomHistoryVisibility -> NotificationContent.StateEvent.RoomHistoryVisibility
+ StateEventContent.RoomJoinRules -> NotificationContent.StateEvent.RoomJoinRules
+ is StateEventContent.RoomMemberContent -> {
+ NotificationContent.StateEvent.RoomMemberContent(userId, RoomMemberMapper.mapMembership(membershipState))
+ }
+ StateEventContent.RoomName -> NotificationContent.StateEvent.RoomName
+ StateEventContent.RoomPinnedEvents -> NotificationContent.StateEvent.RoomPinnedEvents
+ StateEventContent.RoomPowerLevels -> NotificationContent.StateEvent.RoomPowerLevels
+ StateEventContent.RoomServerAcl -> NotificationContent.StateEvent.RoomServerAcl
+ StateEventContent.RoomThirdPartyInvite -> NotificationContent.StateEvent.RoomThirdPartyInvite
+ StateEventContent.RoomTombstone -> NotificationContent.StateEvent.RoomTombstone
+ StateEventContent.RoomTopic -> NotificationContent.StateEvent.RoomTopic
+ StateEventContent.SpaceChild -> NotificationContent.StateEvent.SpaceChild
+ StateEventContent.SpaceParent -> NotificationContent.StateEvent.SpaceParent
}
}
-private fun MessageLikeEventContent.toContent(): String {
+private fun MessageLikeEventContent.toContent(): NotificationContent.MessageLike {
return use {
when (it) {
- MessageLikeEventContent.CallAnswer -> "CallAnswer"
- MessageLikeEventContent.CallCandidates -> "CallCandidates"
- MessageLikeEventContent.CallHangup -> "CallHangup"
- MessageLikeEventContent.CallInvite -> "CallInvite"
- MessageLikeEventContent.KeyVerificationAccept -> "KeyVerificationAccept"
- MessageLikeEventContent.KeyVerificationCancel -> "KeyVerificationCancel"
- MessageLikeEventContent.KeyVerificationDone -> "KeyVerificationDone"
- MessageLikeEventContent.KeyVerificationKey -> "KeyVerificationKey"
- MessageLikeEventContent.KeyVerificationMac -> "KeyVerificationMac"
- MessageLikeEventContent.KeyVerificationReady -> "KeyVerificationReady"
- MessageLikeEventContent.KeyVerificationStart -> "KeyVerificationStart"
- is MessageLikeEventContent.ReactionContent -> "Reacted to ${it.relatedEventId.take(8)}…"
- MessageLikeEventContent.RoomEncrypted -> "RoomEncrypted"
- is MessageLikeEventContent.RoomMessage -> it.messageType.toContent()
- MessageLikeEventContent.RoomRedaction -> "RoomRedaction"
- MessageLikeEventContent.Sticker -> "Sticker"
+ MessageLikeEventContent.CallAnswer -> NotificationContent.MessageLike.CallAnswer
+ MessageLikeEventContent.CallCandidates -> NotificationContent.MessageLike.CallCandidates
+ MessageLikeEventContent.CallHangup -> NotificationContent.MessageLike.CallHangup
+ MessageLikeEventContent.CallInvite -> NotificationContent.MessageLike.CallInvite
+ MessageLikeEventContent.KeyVerificationAccept -> NotificationContent.MessageLike.KeyVerificationAccept
+ MessageLikeEventContent.KeyVerificationCancel -> NotificationContent.MessageLike.KeyVerificationCancel
+ MessageLikeEventContent.KeyVerificationDone -> NotificationContent.MessageLike.KeyVerificationDone
+ MessageLikeEventContent.KeyVerificationKey -> NotificationContent.MessageLike.KeyVerificationKey
+ MessageLikeEventContent.KeyVerificationMac -> NotificationContent.MessageLike.KeyVerificationMac
+ MessageLikeEventContent.KeyVerificationReady -> NotificationContent.MessageLike.KeyVerificationReady
+ MessageLikeEventContent.KeyVerificationStart -> NotificationContent.MessageLike.KeyVerificationStart
+ is MessageLikeEventContent.ReactionContent -> NotificationContent.MessageLike.ReactionContent(it.relatedEventId)
+ MessageLikeEventContent.RoomEncrypted -> NotificationContent.MessageLike.RoomEncrypted
+ is MessageLikeEventContent.RoomMessage -> {
+ NotificationContent.MessageLike.RoomMessage(EventMessageMapper().mapMessageType(it.messageType))
+ }
+ MessageLikeEventContent.RoomRedaction -> NotificationContent.MessageLike.RoomRedaction
+ MessageLikeEventContent.Sticker -> NotificationContent.MessageLike.Sticker
}
}
}
-
-private fun MessageType.toContent(): String {
- return when (this) {
- is MessageType.Audio -> content.use { it.body }
- is MessageType.Emote -> content.body
- is MessageType.File -> content.use { it.body }
- is MessageType.Image -> content.use { it.body }
- is MessageType.Location -> content.body
- is MessageType.Notice -> content.body
- is MessageType.Text -> content.body
- is MessageType.Video -> content.use { it.body }
- }
-}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt
index 2103833704..c89c50ab9b 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/sync/RustSyncService.kt
@@ -24,23 +24,30 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import org.matrix.rustcomponents.sdk.RoomListService
import org.matrix.rustcomponents.sdk.RoomListServiceState
+import timber.log.Timber
+import java.util.concurrent.atomic.AtomicBoolean
class RustSyncService(
private val roomListService: RoomListService,
sessionCoroutineScope: CoroutineScope
) : SyncService {
+ private val isSyncing = AtomicBoolean(false)
+
override fun startSync() = runCatching {
- if (!roomListService.isSyncing()) {
+ if (isSyncing.compareAndSet(false, true)) {
+ Timber.v("Start sync")
roomListService.sync()
}
}
override fun stopSync() = runCatching {
- if (roomListService.isSyncing()) {
+ if (isSyncing.compareAndSet(true, false)) {
+ Timber.v("Stop sync")
roomListService.stopSync()
}
}
@@ -49,6 +56,10 @@ class RustSyncService(
roomListService
.stateFlow()
.map(RoomListServiceState::toSyncState)
+ .onEach { state ->
+ Timber.v("Sync state=$state")
+ isSyncing.set(state == SyncState.Syncing)
+ }
.distinctUntilChanged()
- .stateIn(sessionCoroutineScope, SharingStarted.WhileSubscribed(), SyncState.Idle)
+ .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle)
}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt
index c4148de745..2ecad95e4f 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventMessageMapper.kt
@@ -33,48 +33,17 @@ import io.element.android.libraries.matrix.api.timeline.item.event.UnknownMessag
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
import io.element.android.libraries.matrix.impl.media.map
import org.matrix.rustcomponents.sdk.Message
-import org.matrix.rustcomponents.sdk.MessageType
import org.matrix.rustcomponents.sdk.ProfileDetails
import org.matrix.rustcomponents.sdk.RepliedToEventDetails
import org.matrix.rustcomponents.sdk.use
import org.matrix.rustcomponents.sdk.FormattedBody as RustFormattedBody
import org.matrix.rustcomponents.sdk.MessageFormat as RustMessageFormat
+import org.matrix.rustcomponents.sdk.MessageType as RustMessageType
class EventMessageMapper {
fun map(message: Message): MessageContent = message.use {
- val type = it.msgtype().use { type ->
- when (type) {
- is MessageType.Audio -> {
- AudioMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
- }
- is MessageType.File -> {
- FileMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
- }
- is MessageType.Image -> {
- ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
- }
- is MessageType.Location -> {
- LocationMessageType(type.content.body, type.content.geoUri, type.content.description)
- }
- is MessageType.Notice -> {
- NoticeMessageType(type.content.body, type.content.formatted?.map())
- }
- is MessageType.Text -> {
- TextMessageType(type.content.body, type.content.formatted?.map())
- }
- is MessageType.Emote -> {
- EmoteMessageType(type.content.body, type.content.formatted?.map())
- }
- is MessageType.Video -> {
- VideoMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
- }
- null -> {
- UnknownMessageType
- }
-
- }
- }
+ val type = it.msgtype().use(this::mapMessageType)
val inReplyToId = it.inReplyTo()?.eventId?.let(::EventId)
val inReplyToEvent: InReplyTo? = (it.inReplyTo()?.event)?.use { details ->
when (details) {
@@ -99,6 +68,34 @@ class EventMessageMapper {
type = type
)
}
+
+ fun mapMessageType(type: RustMessageType?) = when (type) {
+ is RustMessageType.Audio -> {
+ AudioMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
+ }
+ is RustMessageType.File -> {
+ FileMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
+ }
+ is RustMessageType.Image -> {
+ ImageMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
+ }
+ is RustMessageType.Notice -> {
+ NoticeMessageType(type.content.body, type.content.formatted?.map())
+ }
+ is RustMessageType.Text -> {
+ TextMessageType(type.content.body, type.content.formatted?.map())
+ }
+ is RustMessageType.Emote -> {
+ EmoteMessageType(type.content.body, type.content.formatted?.map())
+ }
+ is RustMessageType.Video -> {
+ VideoMessageType(type.content.body, type.content.source.map(), type.content.info?.map())
+ }
+ is RustMessageType.Location -> {
+ LocationMessageType(type.content.body, type.content.geoUri, type.content.description)
+ }
+ null -> UnknownMessageType
+ }
}
private fun RustFormattedBody.map(): FormattedBody = FormattedBody(
diff --git a/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationDrawerManager.kt b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationDrawerManager.kt
new file mode 100644
index 0000000000..9a778195fa
--- /dev/null
+++ b/libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationDrawerManager.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.push.api.notifications
+
+import io.element.android.libraries.matrix.api.core.RoomId
+import io.element.android.libraries.matrix.api.core.SessionId
+
+interface NotificationDrawerManager {
+ fun clearMembershipNotificationForSession(sessionId: SessionId)
+ fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId)
+}
diff --git a/libraries/push/impl/build.gradle.kts b/libraries/push/impl/build.gradle.kts
index be302eb57d..ebd4c8f105 100644
--- a/libraries/push/impl/build.gradle.kts
+++ b/libraries/push/impl/build.gradle.kts
@@ -44,6 +44,7 @@ dependencies {
implementation(projects.libraries.network)
implementation(projects.libraries.matrix.api)
implementation(projects.libraries.matrixui)
+ implementation(projects.libraries.uiStrings)
api(projects.libraries.pushproviders.api)
api(projects.libraries.pushstore.api)
api(projects.libraries.push.api)
@@ -52,10 +53,6 @@ dependencies {
implementation(projects.services.appnavstate.api)
implementation(projects.services.toolbox.api)
- api(libs.gujun.span) {
- exclude(group = "com.android.support", module = "support-annotations")
- }
-
// TODO Temporary use the deprecated LocalBroadcastManager, to be changed later.
implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.1.0")
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt
index f57651c3a7..b16908269d 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/DefaultPushService.kt
@@ -20,8 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.push.api.PushService
-import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
-import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
+import io.element.android.libraries.push.impl.notifications.DefaultNotificationDrawerManager
import io.element.android.libraries.pushproviders.api.Distributor
import io.element.android.libraries.pushproviders.api.PushProvider
import io.element.android.libraries.pushstore.api.UserPushStoreFactory
@@ -29,13 +28,13 @@ import javax.inject.Inject
@ContributesBinding(AppScope::class)
class DefaultPushService @Inject constructor(
- private val notificationDrawerManager: NotificationDrawerManager,
+ private val defaultNotificationDrawerManager: DefaultNotificationDrawerManager,
private val pushersManager: PushersManager,
private val userPushStoreFactory: UserPushStoreFactory,
private val pushProviders: Set<@JvmSuppressWildcards PushProvider>,
) : PushService {
override fun notificationStyleChanged() {
- notificationDrawerManager.notificationStyleChanged()
+ defaultNotificationDrawerManager.notificationStyleChanged()
}
override fun getAvailablePushProviders(): List {
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushBindsModule.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushBindsModule.kt
new file mode 100644
index 0000000000..63c5198514
--- /dev/null
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushBindsModule.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.push.impl.di
+
+import com.squareup.anvil.annotations.ContributesTo
+import dagger.Binds
+import dagger.Module
+import io.element.android.libraries.di.AppScope
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
+import io.element.android.libraries.push.impl.notifications.DefaultNotificationDrawerManager
+
+@Module
+@ContributesTo(AppScope::class)
+abstract class PushBindsModule {
+ @Binds
+ abstract fun bindNotificationDrawerManager(
+ defaultNotificationDrawerManager: DefaultNotificationDrawerManager
+ ): NotificationDrawerManager
+}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt
index ce2b1d3fce..8e0dd3e6f2 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt
@@ -23,11 +23,16 @@ import io.element.android.libraries.matrix.api.core.ThreadId
interface IntentProvider {
/**
- * Provide an intent to start the application.
+ * Provide an intent to start the application on a room or thread.
*/
- fun getViewIntent(
+ fun getViewRoomIntent(
sessionId: SessionId,
roomId: RoomId?,
threadId: ThreadId?,
): Intent
+
+ /**
+ * Provide an intent to start the application on the invite list.
+ */
+ fun getInviteListIntent(sessionId: SessionId): Intent
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationDrawerManager.kt
similarity index 91%
rename from libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt
rename to libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationDrawerManager.kt
index 87d37e7e33..cd0274016b 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDrawerManager.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotificationDrawerManager.kt
@@ -24,14 +24,16 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
+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.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.user.MatrixUser
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
import io.element.android.libraries.push.api.store.PushDataStore
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
-import io.element.android.libraries.push.impl.notifications.model.shouldIgnoreMessageEventInRoom
+import io.element.android.libraries.push.impl.notifications.model.shouldIgnoreEventInRoom
import io.element.android.services.appnavstate.api.AppNavigationState
import io.element.android.services.appnavstate.api.AppNavigationStateService
import kotlinx.coroutines.CoroutineScope
@@ -47,7 +49,7 @@ import javax.inject.Inject
* Events can be grouped into the same notification, old (already read) events can be removed to do some cleaning.
*/
@SingleIn(AppScope::class)
-class NotificationDrawerManager @Inject constructor(
+class DefaultNotificationDrawerManager @Inject constructor(
private val pushDataStore: PushDataStore,
private val notifiableEventProcessor: NotifiableEventProcessor,
private val notificationRenderer: NotificationRenderer,
@@ -58,7 +60,7 @@ class NotificationDrawerManager @Inject constructor(
private val dispatchers: CoroutineDispatchers,
private val buildMeta: BuildMeta,
private val matrixAuthenticationService: MatrixAuthenticationService,
-) {
+) : NotificationDrawerManager {
/**
* Lazily initializes the NotificationState as we rely on having a current session in order to fetch the persisted queue of events.
*/
@@ -152,12 +154,27 @@ class NotificationDrawerManager @Inject constructor(
}
}
+ override fun clearMembershipNotificationForSession(sessionId: SessionId) {
+ updateEvents {
+ it.clearMembershipNotificationForSession(sessionId)
+ }
+ }
+
/**
* Clear invitation notification for the provided room.
*/
- fun clearMemberShipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
+ override fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
updateEvents {
- it.clearMemberShipNotificationForRoom(sessionId, roomId)
+ it.clearMembershipNotificationForRoom(sessionId, roomId)
+ }
+ }
+
+ /**
+ * Clear the notifications for a single event.
+ */
+ fun clearEvent(eventId: EventId) {
+ updateEvents {
+ it.clearEvent(eventId)
}
}
@@ -183,7 +200,7 @@ class NotificationDrawerManager @Inject constructor(
}
}
- private fun updateEvents(action: NotificationDrawerManager.(NotificationEventQueue) -> Unit) {
+ private fun updateEvents(action: DefaultNotificationDrawerManager.(NotificationEventQueue) -> Unit) {
notificationState.updateQueuedEvents(this) { queuedEvents, _ ->
action(queuedEvents)
}
@@ -260,6 +277,6 @@ class NotificationDrawerManager @Inject constructor(
}
fun shouldIgnoreMessageEventInRoom(resolvedEvent: NotifiableMessageEvent): Boolean {
- return resolvedEvent.shouldIgnoreMessageEventInRoom(currentAppNavigationState)
+ return resolvedEvent.shouldIgnoreEventInRoom(currentAppNavigationState)
}
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessor.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessor.kt
index 07c3a99708..4202ef78d4 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessor.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessor.kt
@@ -17,11 +17,12 @@
package io.element.android.libraries.push.impl.notifications
import io.element.android.libraries.matrix.api.timeline.item.event.EventType
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
-import io.element.android.libraries.push.impl.notifications.model.shouldIgnoreMessageEventInRoom
+import io.element.android.libraries.push.impl.notifications.model.shouldIgnoreEventInRoom
import io.element.android.services.appnavstate.api.AppNavigationState
import timber.log.Timber
import javax.inject.Inject
@@ -41,7 +42,7 @@ class NotifiableEventProcessor @Inject constructor(
val type = when (it) {
is InviteNotifiableEvent -> ProcessedEvent.Type.KEEP
is NotifiableMessageEvent -> when {
- it.shouldIgnoreMessageEventInRoom(appNavigationState) -> {
+ it.shouldIgnoreEventInRoom(appNavigationState) -> {
ProcessedEvent.Type.REMOVE
.also { Timber.d("notification message removed due to currently viewing the same room or thread") }
}
@@ -53,6 +54,13 @@ class NotifiableEventProcessor @Inject constructor(
EventType.REDACTION -> ProcessedEvent.Type.REMOVE
else -> ProcessedEvent.Type.KEEP
}
+ is FallbackNotifiableEvent -> when {
+ it.shouldIgnoreEventInRoom(appNavigationState) -> {
+ ProcessedEvent.Type.REMOVE
+ .also { Timber.d("notification fallback removed due to currently viewing the same room or thread") }
+ }
+ else -> ProcessedEvent.Type.KEEP
+ }
}
ProcessedEvent(type, it)
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt
index faa8eb86d8..f0b70d8fac 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt
@@ -22,12 +22,26 @@ import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
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.core.SessionId
-import io.element.android.libraries.matrix.api.core.UserId
+import io.element.android.libraries.matrix.api.core.ThreadId
+import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.api.notification.NotificationData
-import io.element.android.libraries.matrix.api.notification.NotificationEvent
+import io.element.android.libraries.matrix.api.room.RoomMembershipState
+import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.UnknownMessageType
+import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
+import io.element.android.libraries.push.impl.R
import io.element.android.libraries.push.impl.log.pushLoggerTag
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
+import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
+import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.toolbox.api.strings.StringProvider
import io.element.android.services.toolbox.api.systemclock.SystemClock
import timber.log.Timber
@@ -53,73 +67,163 @@ class NotifiableEventResolver @Inject constructor(
suspend fun resolveEvent(sessionId: SessionId, roomId: RoomId, eventId: EventId): NotifiableEvent? {
// Restore session
val session = matrixAuthenticationService.restoreSession(sessionId).getOrNull() ?: return null
- // TODO EAx, no need for a session?
- val notificationData = session.let {// TODO Use make the app crashes
- it.notificationService().getNotification(
+ val notificationService = session.notificationService()
+ val notificationData = notificationService.getNotification(
userId = sessionId,
roomId = roomId,
eventId = eventId,
- filterByPushRules = true,
- )
- }.fold(
- {
- it
- },
- {
- Timber.tag(loggerTag.value).e(it, "Unable to resolve event.")
- null
+ // FIXME should be true in the future, but right now it's broken
+ // (https://github.com/vector-im/element-x-android/issues/640#issuecomment-1612913658)
+ filterByPushRules = false,
+ ).onFailure {
+ Timber.tag(loggerTag.value).e(it, "Unable to resolve event: $eventId.")
+ }.getOrNull()
+
+ // TODO this notificationData is not always valid at the moment, sometimes the Rust SDK can't fetch the matching event
+ return notificationData?.asNotifiableEvent(sessionId)
+ ?: fallbackNotifiableEvent(sessionId, roomId, eventId)
+ }
+
+ private fun NotificationData.asNotifiableEvent(userId: SessionId): NotifiableEvent? {
+ return when (val content = this.event.content) {
+ is NotificationContent.MessageLike.RoomMessage -> {
+ buildNotifiableMessageEvent(
+ sessionId = userId,
+ roomId = roomId,
+ eventId = eventId,
+ noisy = isNoisy,
+ timestamp = event.timestamp,
+ senderName = senderDisplayName,
+ senderId = senderId.value,
+ body = descriptionFromMessageContent(content),
+ imageUriString = event.contentUrl,
+ roomName = roomDisplayName,
+ roomIsDirect = isDirect,
+ roomAvatarPath = roomAvatarUrl,
+ senderAvatarPath = senderAvatarUrl,
+ )
}
- ).orDefault(roomId, eventId)
-
- return notificationData.asNotifiableEvent(sessionId)
+ is NotificationContent.StateEvent.RoomMemberContent -> {
+ if (content.membershipState == RoomMembershipState.INVITE) {
+ InviteNotifiableEvent(
+ sessionId = userId,
+ roomId = roomId,
+ eventId = eventId,
+ editedEventId = null,
+ canBeReplaced = true,
+ roomName = roomDisplayName,
+ noisy = isNoisy,
+ timestamp = event.timestamp,
+ soundName = null,
+ isRedacted = false,
+ isUpdated = false,
+ description = descriptionFromRoomMembershipContent(content, isDirect) ?: return null,
+ type = null, // TODO check if type is needed anymore
+ title = null, // TODO check if title is needed anymore
+ )
+ } else {
+ null
+ }
+ }
+ else -> null
+ }
}
- private fun NotificationData.asNotifiableEvent(userId: SessionId): NotifiableEvent {
- return NotifiableMessageEvent(
- sessionId = userId,
- roomId = roomId,
- eventId = eventId,
- editedEventId = null,
- canBeReplaced = true,
- noisy = isNoisy,
- timestamp = event.timestamp,
- senderName = senderDisplayName,
- senderId = senderId.value,
- body = event.content,
- imageUriString = event.contentUrl,
- threadId = null,
- roomName = roomDisplayName,
- roomIsDirect = isDirect,
- roomAvatarPath = roomAvatarUrl,
- senderAvatarPath = senderAvatarUrl,
- soundName = null,
- outGoingMessage = false,
- outGoingMessageFailed = false,
- isRedacted = false,
- isUpdated = false
- )
+ private fun fallbackNotifiableEvent(
+ userId: SessionId,
+ roomId: RoomId,
+ eventId: EventId
+ ) = FallbackNotifiableEvent(
+ sessionId = userId,
+ roomId = roomId,
+ eventId = eventId,
+ editedEventId = null,
+ canBeReplaced = true,
+ isRedacted = false,
+ isUpdated = false,
+ timestamp = clock.epochMillis(),
+ description = stringProvider.getString(R.string.notification_fallback_content),
+ )
+
+ private fun descriptionFromMessageContent(
+ content: NotificationContent.MessageLike.RoomMessage,
+ ): String {
+ return when (val messageType = content.messageType) {
+ is AudioMessageType -> messageType.body
+ is EmoteMessageType -> messageType.body
+ is FileMessageType -> messageType.body
+ is ImageMessageType -> messageType.body
+ is NoticeMessageType -> messageType.body
+ is TextMessageType -> messageType.body
+ is VideoMessageType -> messageType.body
+ is LocationMessageType -> messageType.body
+ is UnknownMessageType -> stringProvider.getString(CommonStrings.common_unsupported_event)
+ }
}
- /**
- * TODO This is a temporary method for EAx.
- */
- private fun NotificationData?.orDefault(roomId: RoomId, eventId: EventId): NotificationData {
- return this ?: NotificationData(
- eventId = eventId,
- senderId = UserId("@user:domain"),
- roomId = roomId,
- senderAvatarUrl = null,
- senderDisplayName = null,
- roomAvatarUrl = null,
- roomDisplayName = null,
- isNoisy = false,
- isEncrypted = false,
- isDirect = false,
- event = NotificationEvent(
- timestamp = clock.epochMillis(),
- content = "Message ${eventId.value.take(8)}… in room ${roomId.value.take(8)}…",
- contentUrl = null
- )
- )
+ private fun descriptionFromRoomMembershipContent(
+ content: NotificationContent.StateEvent.RoomMemberContent,
+ isDirectRoom: Boolean
+ ): String? {
+ return when (content.membershipState) {
+ RoomMembershipState.INVITE -> {
+ if (isDirectRoom) {
+ stringProvider.getString(R.string.notification_invite_body)
+ } else {
+ stringProvider.getString(R.string.notification_room_invite_body)
+ }
+ }
+ else -> null
+ }
}
}
+
+@Suppress("LongParameterList")
+private fun buildNotifiableMessageEvent(
+ sessionId: SessionId,
+ roomId: RoomId,
+ eventId: EventId,
+ editedEventId: EventId? = null,
+ canBeReplaced: Boolean = false,
+ noisy: Boolean,
+ timestamp: Long,
+ senderName: String?,
+ senderId: String?,
+ body: String?,
+ // We cannot use Uri? type here, as that could trigger a
+ // NotSerializableException when persisting this to storage
+ imageUriString: String? = null,
+ threadId: ThreadId? = null,
+ roomName: String? = null,
+ roomIsDirect: Boolean = false,
+ roomAvatarPath: String? = null,
+ senderAvatarPath: String? = null,
+ soundName: String? = null,
+ // This is used for >N notification, as the result of a smart reply
+ outGoingMessage: Boolean = false,
+ outGoingMessageFailed: Boolean = false,
+ isRedacted: Boolean = false,
+ isUpdated: Boolean = false
+) = NotifiableMessageEvent(
+ sessionId = sessionId,
+ roomId = roomId,
+ eventId = eventId,
+ editedEventId = editedEventId,
+ canBeReplaced = canBeReplaced,
+ noisy = noisy,
+ timestamp = timestamp,
+ senderName = senderName,
+ senderId = senderId,
+ body = body,
+ imageUriString = imageUriString,
+ threadId = threadId,
+ roomName = roomName,
+ roomIsDirect = roomIsDirect,
+ roomAvatarPath = roomAvatarPath,
+ senderAvatarPath = senderAvatarPath,
+ soundName = soundName,
+ outGoingMessage = outGoingMessage,
+ outGoingMessageFailed = outGoingMessageFailed,
+ isRedacted = isRedacted,
+ isUpdated = isUpdated
+)
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationActionIds.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationActionIds.kt
index bc20d49917..6141079130 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationActionIds.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationActionIds.kt
@@ -34,6 +34,8 @@ data class NotificationActionIds @Inject constructor(
val smartReply = "${buildMeta.applicationId}.NotificationActions.SMART_REPLY_ACTION"
val dismissSummary = "${buildMeta.applicationId}.NotificationActions.DISMISS_SUMMARY_ACTION"
val dismissRoom = "${buildMeta.applicationId}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION"
+ val dismissInvite = "${buildMeta.applicationId}.NotificationActions.DISMISS_INVITE_NOTIF_ACTION"
+ val dismissEvent = "${buildMeta.applicationId}.NotificationActions.DISMISS_EVENT_NOTIF_ACTION"
val diagnostic = "${buildMeta.applicationId}.NotificationActions.DIAGNOSTIC"
val push = "${buildMeta.applicationId}.PUSH"
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBitmapLoader.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBitmapLoader.kt
index c2cdfc5677..1ad38bf787 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBitmapLoader.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBitmapLoader.kt
@@ -49,6 +49,7 @@ class NotificationBitmapLoader @Inject constructor(
return try {
val imageRequest = ImageRequest.Builder(context)
.data(MediaRequestData(MediaSource(path), MediaRequestData.Kind.Thumbnail(1024)))
+ .transformations(CircleCropTransformation())
.build()
val result = context.imageLoader.execute(imageRequest)
result.drawable?.toBitmap()
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiver.kt
index de97986026..d5df1001ca 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiver.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiver.kt
@@ -22,6 +22,7 @@ import android.content.Intent
import androidx.core.app.RemoteInput
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.core.log.logger.LoggerTag
+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.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
@@ -37,7 +38,7 @@ private val loggerTag = LoggerTag("NotificationBroadcastReceiver", notificationL
*/
class NotificationBroadcastReceiver : BroadcastReceiver() {
- @Inject lateinit var notificationDrawerManager: NotificationDrawerManager
+ @Inject lateinit var defaultNotificationDrawerManager: DefaultNotificationDrawerManager
//@Inject lateinit var activeSessionHolder: ActiveSessionHolder
//@Inject lateinit var analyticsTracker: AnalyticsTracker
@@ -50,24 +51,31 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
Timber.tag(loggerTag.value).v("NotificationBroadcastReceiver received : $intent")
val sessionId = intent.extras?.getString(KEY_SESSION_ID)?.let(::SessionId) ?: return
val roomId = intent.getStringExtra(KEY_ROOM_ID)?.let(::RoomId)
+ val eventId = intent.getStringExtra(KEY_EVENT_ID)?.let(::EventId)
when (intent.action) {
actionIds.smartReply ->
handleSmartReply(intent, context)
actionIds.dismissRoom -> if (roomId != null) {
- notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
+ defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
}
actionIds.dismissSummary ->
- notificationDrawerManager.clearAllEvents(sessionId)
+ defaultNotificationDrawerManager.clearAllEvents(sessionId)
+ actionIds.dismissInvite -> if (roomId != null) {
+ defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
+ }
+ actionIds.dismissEvent -> if (eventId != null) {
+ defaultNotificationDrawerManager.clearEvent(eventId)
+ }
actionIds.markRoomRead -> if (roomId != null) {
- notificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
+ defaultNotificationDrawerManager.clearMessagesForRoom(sessionId, roomId)
handleMarkAsRead(sessionId, roomId)
}
actionIds.join -> if (roomId != null) {
- notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
+ defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
handleJoinRoom(sessionId, roomId)
}
actionIds.reject -> if (roomId != null) {
- notificationDrawerManager.clearMemberShipNotificationForRoom(sessionId, roomId)
+ defaultNotificationDrawerManager.clearMembershipNotificationForRoom(sessionId, roomId)
handleRejectRoom(sessionId, roomId)
}
}
@@ -240,6 +248,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
const val KEY_SESSION_ID = "sessionID"
const val KEY_ROOM_ID = "roomID"
const val KEY_THREAD_ID = "threadID"
+ const val KEY_EVENT_ID = "eventID"
const val KEY_TEXT_REPLY = "key_text_reply"
}
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueue.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueue.kt
index 862b4784ac..97b90476b0 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueue.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueue.kt
@@ -21,6 +21,7 @@ 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.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
@@ -45,6 +46,7 @@ data class NotificationEventQueue constructor(
is InviteNotifiableEvent -> it.copy(isRedacted = true)
is NotifiableMessageEvent -> it.copy(isRedacted = true)
is SimpleNotifiableEvent -> it.copy(isRedacted = true)
+ is FallbackNotifiableEvent -> it.copy(isRedacted = true)
}
}
}
@@ -57,7 +59,8 @@ data class NotificationEventQueue constructor(
when (it) {
is NotifiableMessageEvent -> roomsLeft.contains(it.roomId)
is InviteNotifiableEvent -> roomsLeft.contains(it.roomId) || roomsJoined.contains(it.roomId)
- else -> false
+ is SimpleNotifiableEvent -> false
+ is FallbackNotifiableEvent -> roomsLeft.contains(it.roomId)
}
}
}
@@ -127,11 +130,21 @@ data class NotificationEventQueue constructor(
is InviteNotifiableEvent -> with.copy(isUpdated = true)
is NotifiableMessageEvent -> with.copy(isUpdated = true)
is SimpleNotifiableEvent -> with.copy(isUpdated = true)
+ is FallbackNotifiableEvent -> with.copy(isUpdated = true)
}
)
}
- fun clearMemberShipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
+ fun clearEvent(eventId: EventId) {
+ queue.removeAll { it.eventId == eventId }
+ }
+
+ fun clearMembershipNotificationForSession(sessionId: SessionId) {
+ Timber.d("clearMemberShipOfSession $sessionId")
+ queue.removeAll { it is InviteNotifiableEvent && it.sessionId == sessionId }
+ }
+
+ fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
Timber.d("clearMemberShipOfRoom $sessionId, $roomId")
queue.removeAll { it is InviteNotifiableEvent && it.sessionId == sessionId && it.roomId == roomId }
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt
index 79173611dc..0addc1276a 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationFactory.kt
@@ -20,6 +20,7 @@ import android.app.Notification
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.push.impl.notifications.factories.NotificationFactory
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
@@ -94,16 +95,35 @@ class NotificationFactory @Inject constructor(
}
}
+ fun List>.toNotifications(): List {
+ return map { (processed, event) ->
+ when (processed) {
+ ProcessedEvent.Type.REMOVE -> OneShotNotification.Removed(key = event.eventId.value)
+ ProcessedEvent.Type.KEEP -> OneShotNotification.Append(
+ notificationFactory.createFallbackNotification(event),
+ OneShotNotification.Append.Meta(
+ key = event.eventId.value,
+ summaryLine = event.description.orEmpty(),
+ isNoisy = false,
+ timestamp = event.timestamp
+ )
+ )
+ }
+ }
+ }
+
fun createSummaryNotification(
currentUser: MatrixUser,
roomNotifications: List,
invitationNotifications: List,
simpleNotifications: List,
+ fallbackNotifications: List,
useCompleteNotificationFormat: Boolean
): SummaryNotification {
val roomMeta = roomNotifications.filterIsInstance().map { it.meta }
val invitationMeta = invitationNotifications.filterIsInstance().map { it.meta }
val simpleMeta = simpleNotifications.filterIsInstance().map { it.meta }
+ val fallbackMeta = simpleNotifications.filterIsInstance().map { it.meta }
return when {
roomMeta.isEmpty() && invitationMeta.isEmpty() && simpleMeta.isEmpty() -> SummaryNotification.Removed
else -> SummaryNotification.Update(
@@ -112,6 +132,7 @@ class NotificationFactory @Inject constructor(
roomNotifications = roomMeta,
invitationNotifications = invitationMeta,
simpleNotifications = simpleMeta,
+ fallbackNotifications = fallbackMeta,
useCompleteNotificationFormat = useCompleteNotificationFormat
)
)
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProvider.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProvider.kt
index 3ce941de2f..050edfcc11 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProvider.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationIdProvider.kt
@@ -37,12 +37,17 @@ class NotificationIdProvider @Inject constructor() {
return getOffset(sessionId) + ROOM_INVITATION_NOTIFICATION_ID
}
+ fun getFallbackNotificationId(sessionId: SessionId): Int {
+ return getOffset(sessionId) + FALLBACK_NOTIFICATION_ID
+ }
+
private fun getOffset(sessionId: SessionId): Int {
// Compute a int from a string with a low risk of collision.
return abs(sessionId.value.hashCode() % 100_000) * 10
}
companion object {
+ private const val FALLBACK_NOTIFICATION_ID = -1
private const val SUMMARY_NOTIFICATION_ID = 0
private const val ROOM_MESSAGES_NOTIFICATION_ID = 1
private const val ROOM_EVENT_NOTIFICATION_ID = 2
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt
index 428420211b..a6179b3ec8 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt
@@ -18,6 +18,7 @@ package io.element.android.libraries.push.impl.notifications
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.user.MatrixUser
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
@@ -36,16 +37,18 @@ class NotificationRenderer @Inject constructor(
useCompleteNotificationFormat: Boolean,
eventsToProcess: List>
) {
- val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType()
+ val groupedEvents = eventsToProcess.groupByType()
with(notificationFactory) {
- val roomNotifications = roomEvents.toNotifications(currentUser)
- val invitationNotifications = invitationEvents.toNotifications()
- val simpleNotifications = simpleEvents.toNotifications()
+ val roomNotifications = groupedEvents.roomEvents.toNotifications(currentUser)
+ val invitationNotifications = groupedEvents.invitationEvents.toNotifications()
+ val simpleNotifications = groupedEvents.simpleEvents.toNotifications()
+ val fallbackNotifications = groupedEvents.fallbackEvents.toNotifications()
val summaryNotification = createSummaryNotification(
currentUser = currentUser,
roomNotifications = roomNotifications,
invitationNotifications = invitationNotifications,
simpleNotifications = simpleNotifications,
+ fallbackNotifications = fallbackNotifications,
useCompleteNotificationFormat = useCompleteNotificationFormat
)
@@ -118,6 +121,26 @@ class NotificationRenderer @Inject constructor(
}
}
+ fallbackNotifications.forEach { wrapper ->
+ when (wrapper) {
+ is OneShotNotification.Removed -> {
+ Timber.d("Removing fallback notification ${wrapper.key}")
+ notificationDisplayer.cancelNotificationMessage(
+ tag = wrapper.key,
+ id = notificationIdProvider.getFallbackNotificationId(currentUser.userId)
+ )
+ }
+ is OneShotNotification.Append -> if (useCompleteNotificationFormat) {
+ Timber.d("Updating fallback notification ${wrapper.meta.key}")
+ notificationDisplayer.showNotificationMessage(
+ tag = wrapper.meta.key,
+ id = notificationIdProvider.getFallbackNotificationId(currentUser.userId),
+ notification = wrapper.notification
+ )
+ }
+ }
+ }
+
// Update summary last to avoid briefly displaying it before other notifications
if (summaryNotification is SummaryNotification.Update) {
Timber.d("Updating summary notification")
@@ -139,6 +162,7 @@ private fun List>.groupByType(): GroupedNotifica
val roomIdToEventMap: MutableMap>> = LinkedHashMap()
val simpleEvents: MutableList> = ArrayList()
val invitationEvents: MutableList> = ArrayList()
+ val fallbackEvents: MutableList> = ArrayList()
forEach {
when (val event = it.event) {
is InviteNotifiableEvent -> invitationEvents.add(it.castedToEventType())
@@ -147,9 +171,12 @@ private fun List>.groupByType(): GroupedNotifica
roomEvents.add(it.castedToEventType())
}
is SimpleNotifiableEvent -> simpleEvents.add(it.castedToEventType())
+ is FallbackNotifiableEvent -> {
+ fallbackEvents.add(it.castedToEventType())
+ }
}
}
- return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents)
+ return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents, fallbackEvents)
}
@Suppress("UNCHECKED_CAST")
@@ -158,5 +185,6 @@ private fun ProcessedEvent.castedToEventT
data class GroupedNotificationEvents(
val roomEvents: Map>>,
val simpleEvents: List>,
- val invitationEvents: List>
+ val invitationEvents: List>,
+ val fallbackEvents: List>,
)
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationState.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationState.kt
index 808bf4114b..4737e891aa 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationState.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationState.kt
@@ -39,8 +39,8 @@ class NotificationState(
) {
fun updateQueuedEvents(
- drawerManager: NotificationDrawerManager,
- action: NotificationDrawerManager.(NotificationEventQueue, List>) -> T
+ drawerManager: DefaultNotificationDrawerManager,
+ action: DefaultNotificationDrawerManager.(NotificationEventQueue, List>) -> T
): T {
return synchronized(queuedEvents) {
action(drawerManager, queuedEvents, renderedEvents)
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt
index 5656b81dd9..5f2f6db263 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt
@@ -17,8 +17,12 @@
package io.element.android.libraries.push.impl.notifications
import android.graphics.Bitmap
+import android.graphics.Typeface
+import android.text.style.StyleSpan
import androidx.core.app.NotificationCompat
import androidx.core.app.Person
+import androidx.core.text.buildSpannedString
+import androidx.core.text.inSpans
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.push.impl.R
@@ -26,8 +30,6 @@ import io.element.android.libraries.push.impl.notifications.debug.annotateForDeb
import io.element.android.libraries.push.impl.notifications.factories.NotificationFactory
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
import io.element.android.services.toolbox.api.strings.StringProvider
-import me.gujun.android.span.Span
-import me.gujun.android.span.span
import timber.log.Timber
import javax.inject.Inject
@@ -151,30 +153,31 @@ class RoomGroupMessageCreator @Inject constructor(
}
}
- private fun createFirstMessageSummaryLine(event: NotifiableMessageEvent, roomName: String, roomIsDirect: Boolean): Span {
+ private fun createFirstMessageSummaryLine(event: NotifiableMessageEvent, roomName: String, roomIsDirect: Boolean): CharSequence {
return if (roomIsDirect) {
- span {
- span {
- textStyle = "bold"
- +String.format("%s: ", event.senderName)
+ buildSpannedString {
+ inSpans(StyleSpan(Typeface.BOLD)) {
+ append(event.senderName)
+ append(": ")
}
- +(event.description)
+ append(event.description)
}
} else {
- span {
- span {
- textStyle = "bold"
- +String.format("%s: %s ", roomName, event.senderName)
+ buildSpannedString {
+ inSpans(StyleSpan(Typeface.BOLD)) {
+ append(roomName)
+ append(": ")
+ event.senderName
+ append(" ")
}
- +(event.description)
+ append(event.description)
}
}
}
private suspend fun getRoomBitmap(events: List): Bitmap? {
// Use the last event (most recent?)
- return events.lastOrNull()
- ?.roomAvatarPath
+ return events.reversed().firstNotNullOfOrNull { it.roomAvatarPath }
?.let { bitmapLoader.getRoomBitmap(it) }
}
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/SummaryGroupMessageCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/SummaryGroupMessageCreator.kt
index 5a7f3d36e8..f999456107 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/SummaryGroupMessageCreator.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/SummaryGroupMessageCreator.kt
@@ -49,12 +49,14 @@ class SummaryGroupMessageCreator @Inject constructor(
roomNotifications: List,
invitationNotifications: List,
simpleNotifications: List,
+ fallbackNotifications: List,
useCompleteNotificationFormat: Boolean
): Notification {
val summaryInboxStyle = NotificationCompat.InboxStyle().also { style ->
roomNotifications.forEach { style.addLine(it.summaryLine.annotateForDebug(40)) }
invitationNotifications.forEach { style.addLine(it.summaryLine.annotateForDebug(41)) }
simpleNotifications.forEach { style.addLine(it.summaryLine.annotateForDebug(42)) }
+ fallbackNotifications.forEach { style.addLine(it.summaryLine) }
}
val summaryIsNoisy = roomNotifications.any { it.shouldBing } ||
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationFactory.kt
index 9da47a6569..7b7b395862 100755
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationFactory.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationFactory.kt
@@ -32,10 +32,9 @@ import io.element.android.libraries.push.impl.R
import io.element.android.libraries.push.impl.notifications.RoomEventGroupInfo
import io.element.android.libraries.push.impl.notifications.channels.NotificationChannels
import io.element.android.libraries.push.impl.notifications.debug.annotateForDebug
-import io.element.android.libraries.push.impl.notifications.factories.action.AcceptInvitationActionFactory
import io.element.android.libraries.push.impl.notifications.factories.action.MarkAsReadActionFactory
import io.element.android.libraries.push.impl.notifications.factories.action.QuickReplyActionFactory
-import io.element.android.libraries.push.impl.notifications.factories.action.RejectInvitationActionFactory
+import io.element.android.libraries.push.impl.notifications.model.FallbackNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
import io.element.android.services.toolbox.api.strings.StringProvider
@@ -49,8 +48,6 @@ class NotificationFactory @Inject constructor(
private val pendingIntentFactory: PendingIntentFactory,
private val markAsReadActionFactory: MarkAsReadActionFactory,
private val quickReplyActionFactory: QuickReplyActionFactory,
- private val rejectInvitationActionFactory: RejectInvitationActionFactory,
- private val acceptInvitationActionFactory: AcceptInvitationActionFactory,
) {
/**
* Create a notification for a Room.
@@ -154,22 +151,12 @@ class NotificationFactory @Inject constructor(
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_ALL)
.setSmallIcon(smallIcon)
.setColor(accentColor)
- .addAction(rejectInvitationActionFactory.create(inviteNotifiableEvent))
- .addAction(acceptInvitationActionFactory.create(inviteNotifiableEvent))
+ // TODO removed for now, will be added back later
+// .addAction(rejectInvitationActionFactory.create(inviteNotifiableEvent))
+// .addAction(acceptInvitationActionFactory.create(inviteNotifiableEvent))
.apply {
- /*
// Build the pending intent for when the notification is clicked
- val contentIntent = HomeActivity.newIntent(
- context,
- firstStartMainActivity = true,
- inviteNotificationRoomId = inviteNotifiableEvent.roomId
- )
- contentIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
- // pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
- contentIntent.data = createIgnoredUri(inviteNotifiableEvent.eventId)
- setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, PendingIntentCompat.FLAG_IMMUTABLE))
-
- */
+ setContentIntent(pendingIntentFactory.createInviteListPendingIntent(inviteNotifiableEvent.sessionId))
if (inviteNotifiableEvent.noisy) {
// Compat
@@ -183,6 +170,12 @@ class NotificationFactory @Inject constructor(
} else {
priority = NotificationCompat.PRIORITY_LOW
}
+ setDeleteIntent(
+ pendingIntentFactory.createDismissInvitePendingIntent(
+ inviteNotifiableEvent.sessionId,
+ inviteNotifiableEvent.roomId,
+ )
+ )
setAutoCancel(true)
}
.build()
@@ -223,6 +216,39 @@ class NotificationFactory @Inject constructor(
.build()
}
+ fun createFallbackNotification(
+ fallbackNotifiableEvent: FallbackNotifiableEvent,
+ ): Notification {
+ val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color)
+ val smallIcon = R.drawable.ic_notification
+
+ val channelId = notificationChannels.getChannelIdForMessage(false)
+ return NotificationCompat.Builder(context, channelId)
+ .setOnlyAlertOnce(true)
+ .setContentTitle(buildMeta.applicationName.annotateForDebug(7))
+ .setContentText(fallbackNotifiableEvent.description.orEmpty().annotateForDebug(8))
+ .setGroup(fallbackNotifiableEvent.sessionId.value)
+ .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_ALL)
+ .setSmallIcon(smallIcon)
+ .setColor(accentColor)
+ .setAutoCancel(true)
+ // Ideally we'd use `createOpenRoomPendingIntent` here, but the broken notification might apply to an invite
+ // and the user won't have access to the room yet, resulting in an error screen.
+ .setContentIntent(pendingIntentFactory.createOpenSessionPendingIntent(fallbackNotifiableEvent.sessionId))
+ .setDeleteIntent(
+ pendingIntentFactory.createDismissEventPendingIntent(
+ fallbackNotifiableEvent.sessionId,
+ fallbackNotifiableEvent.roomId,
+ fallbackNotifiableEvent.eventId
+ )
+ )
+ .apply {
+ priority = NotificationCompat.PRIORITY_LOW
+ setAutoCancel(true)
+ }
+ .build()
+ }
+
/**
* Create the summary notification.
*/
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt
index d04bae7e18..fc7586cbd7 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt
@@ -19,8 +19,10 @@ package io.element.android.libraries.push.impl.notifications.factories
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
+import androidx.core.app.PendingIntentCompat
import io.element.android.libraries.androidutils.uri.createIgnoredUri
import io.element.android.libraries.di.ApplicationContext
+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.core.SessionId
import io.element.android.libraries.matrix.api.core.ThreadId
@@ -39,19 +41,19 @@ class PendingIntentFactory @Inject constructor(
private val actionIds: NotificationActionIds,
) {
fun createOpenSessionPendingIntent(sessionId: SessionId): PendingIntent? {
- return createPendingIntent(sessionId = sessionId, roomId = null, threadId = null)
+ return createRoomPendingIntent(sessionId = sessionId, roomId = null, threadId = null)
}
fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent? {
- return createPendingIntent(sessionId = sessionId, roomId = roomId, threadId = null)
+ return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, threadId = null)
}
fun createOpenThreadPendingIntent(roomInfo: RoomEventGroupInfo, threadId: ThreadId?): PendingIntent? {
- return createPendingIntent(sessionId = roomInfo.sessionId, roomId = roomInfo.roomId, threadId = threadId)
+ return createRoomPendingIntent(sessionId = roomInfo.sessionId, roomId = roomInfo.roomId, threadId = threadId)
}
- private fun createPendingIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): PendingIntent? {
- val intent = intentProvider.getViewIntent(sessionId = sessionId, roomId = roomId, threadId = threadId)
+ private fun createRoomPendingIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): PendingIntent? {
+ val intent = intentProvider.getViewRoomIntent(sessionId = sessionId, roomId = roomId, threadId = threadId)
return PendingIntent.getActivity(
context,
clock.epochMillis().toInt(),
@@ -87,6 +89,35 @@ class PendingIntentFactory @Inject constructor(
)
}
+ fun createDismissInvitePendingIntent(sessionId: SessionId, roomId: RoomId): PendingIntent {
+ val intent = Intent(context, NotificationBroadcastReceiver::class.java)
+ intent.action = actionIds.dismissInvite
+ intent.data = createIgnoredUri("deleteInvite/$sessionId/$roomId")
+ intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
+ intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
+ return PendingIntent.getBroadcast(
+ context,
+ clock.epochMillis().toInt(),
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ }
+
+ fun createDismissEventPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId): PendingIntent {
+ val intent = Intent(context, NotificationBroadcastReceiver::class.java)
+ intent.action = actionIds.dismissEvent
+ intent.data = createIgnoredUri("deleteEvent/$sessionId/$roomId")
+ intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
+ intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
+ intent.putExtra(NotificationBroadcastReceiver.KEY_EVENT_ID, eventId.value)
+ return PendingIntent.getBroadcast(
+ context,
+ clock.epochMillis().toInt(),
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ }
+
fun createTestPendingIntent(): PendingIntent? {
val testActionIntent = Intent(context, TestNotificationReceiver::class.java)
testActionIntent.action = actionIds.diagnostic
@@ -97,4 +128,9 @@ class PendingIntentFactory @Inject constructor(
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
+
+ fun createInviteListPendingIntent(sessionId: SessionId): PendingIntent {
+ val intent = intentProvider.getInviteListIntent(sessionId)
+ return PendingIntentCompat.getActivity(context, 0, intent, 0, false)
+ }
}
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/FallbackNotifiableEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/FallbackNotifiableEvent.kt
new file mode 100644
index 0000000000..fe6cc537d0
--- /dev/null
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/FallbackNotifiableEvent.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.push.impl.notifications.model
+
+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.core.SessionId
+
+/**
+ * Used for notifications with events that couldn't be retrieved or decrypted, so we don't know their contents.
+ * These are created separately from message notifications, so they can be displayed differently.
+ */
+data class FallbackNotifiableEvent(
+ override val sessionId: SessionId,
+ override val roomId: RoomId,
+ override val eventId: EventId,
+ override val editedEventId: EventId?,
+ override val description: String?,
+ override val canBeReplaced: Boolean,
+ override val isRedacted: Boolean,
+ override val isUpdated: Boolean,
+ val timestamp: Long,
+) : NotifiableEvent
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/InviteNotifiableEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/InviteNotifiableEvent.kt
index 4524d27ac2..6b562a434e 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/InviteNotifiableEvent.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/InviteNotifiableEvent.kt
@@ -27,8 +27,8 @@ data class InviteNotifiableEvent(
override val canBeReplaced: Boolean,
val roomName: String?,
val noisy: Boolean,
- val title: String,
- val description: String,
+ val title: String?,
+ override val description: String,
val type: String?,
val timestamp: Long,
val soundName: String?,
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableEvent.kt
index b1bb7cd032..ddfbbf8b07 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableEvent.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableEvent.kt
@@ -29,6 +29,7 @@ sealed interface NotifiableEvent : Serializable {
val roomId: RoomId
val eventId: EventId
val editedEventId: EventId?
+ val description: String?
// Used to know if event should be replaced with the one coming from eventstream
val canBeReplaced: Boolean
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt
index 1216e0fe12..7730066d31 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt
@@ -16,6 +16,8 @@
package io.element.android.libraries.push.impl.notifications.model
import android.net.Uri
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.ProcessLifecycleOwner
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.core.SessionId
@@ -54,7 +56,7 @@ data class NotifiableMessageEvent(
) : NotifiableEvent {
val type: String = EventType.MESSAGE
- val description: String = body ?: ""
+ override val description: String = body ?: ""
val title: String = senderName ?: ""
// TODO EAx The image has to be downloaded and expose using the file provider.
@@ -64,12 +66,21 @@ data class NotifiableMessageEvent(
get() = imageUriString?.let { Uri.parse(it) }
}
-fun NotifiableMessageEvent.shouldIgnoreMessageEventInRoom(
+/**
+ * Used to check if a notification should be ignored based on the current app and navigation state.
+ */
+fun NotifiableEvent.shouldIgnoreEventInRoom(
appNavigationState: AppNavigationState?
): Boolean {
val currentSessionId = appNavigationState?.currentSessionId() ?: return false
return when (val currentRoomId = appNavigationState.currentRoomId()) {
null -> false
- else -> sessionId == currentSessionId && roomId == currentRoomId && threadId == appNavigationState.currentThreadId()
+ else -> isAppInForeground
+ && sessionId == currentSessionId
+ && roomId == currentRoomId
+ && (this as? NotifiableMessageEvent)?.threadId == appNavigationState.currentThreadId()
}
}
+
+private val isAppInForeground: Boolean
+ get() = ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt
index 5cfd04474a..f252765530 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/SimpleNotifiableEvent.kt
@@ -26,7 +26,7 @@ data class SimpleNotifiableEvent(
override val editedEventId: EventId?,
val noisy: Boolean,
val title: String,
- val description: String,
+ override val description: String,
val type: String?,
val timestamp: Long,
val soundName: String?,
diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt
index 1bc0ceae93..3ad848aeb4 100644
--- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt
+++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/push/DefaultPushHandler.kt
@@ -31,7 +31,7 @@ import io.element.android.libraries.push.impl.PushersManager
import io.element.android.libraries.push.impl.log.pushLoggerTag
import io.element.android.libraries.push.impl.notifications.NotifiableEventResolver
import io.element.android.libraries.push.impl.notifications.NotificationActionIds
-import io.element.android.libraries.push.impl.notifications.NotificationDrawerManager
+import io.element.android.libraries.push.impl.notifications.DefaultNotificationDrawerManager
import io.element.android.libraries.push.impl.store.DefaultPushDataStore
import io.element.android.libraries.pushproviders.api.PushData
import io.element.android.libraries.pushproviders.api.PushHandler
@@ -48,7 +48,7 @@ private val loggerTag = LoggerTag("PushHandler", pushLoggerTag)
@ContributesBinding(AppScope::class)
class DefaultPushHandler @Inject constructor(
- private val notificationDrawerManager: NotificationDrawerManager,
+ private val defaultNotificationDrawerManager: DefaultNotificationDrawerManager,
private val notifiableEventResolver: NotifiableEventResolver,
private val defaultPushDataStore: DefaultPushDataStore,
private val userPushStoreFactory: UserPushStoreFactory,
@@ -121,9 +121,9 @@ class DefaultPushHandler @Inject constructor(
return
}
- val notificationData = notifiableEventResolver.resolveEvent(userId, pushData.roomId, pushData.eventId)
+ val notifiableEvent = notifiableEventResolver.resolveEvent(userId, pushData.roomId, pushData.eventId)
- if (notificationData == null) {
+ if (notifiableEvent == null) {
Timber.w("Unable to get a notification data")
return
}
@@ -135,7 +135,7 @@ class DefaultPushHandler @Inject constructor(
return
}
- notificationDrawerManager.onNotifiableEventReceived(notificationData)
+ defaultNotificationDrawerManager.onNotifiableEventReceived(notifiableEvent)
} catch (e: Exception) {
Timber.tag(loggerTag.value).e(e, "## handleInternal() failed")
}
diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml
index 987728304a..0d66ac1336 100644
--- a/libraries/push/impl/src/main/res/values/localazy.xml
+++ b/libraries/push/impl/src/main/res/values/localazy.xml
@@ -4,6 +4,7 @@
"Listening for events"
"Noisy notifications"
"Silent notifications"
+ "Notification"
"** Failed to send - please open room"
"Join"
"Reject"
@@ -47,6 +48,5 @@
"Background synchronization"
"Google Services"
"No valid Google Play Services found. Notifications may not work properly."
- "Notification"
"Quick reply"
diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessorTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessorTest.kt
index 38f2edd476..a1398ef429 100644
--- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessorTest.kt
+++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventProcessorTest.kt
@@ -120,6 +120,7 @@ class NotifiableEventProcessorTest {
@Test
fun `given viewing the same room main timeline when processing main timeline message event then removes message`() {
val events = listOf(aNotifiableMessageEvent(eventId = AN_EVENT_ID, roomId = A_ROOM_ID, threadId = null))
+ events.forEach { outdatedDetector.givenEventIsOutOfDate(it) }
val result = eventProcessor.process(events, VIEWING_A_ROOM, renderedEvents = emptyList())
@@ -133,6 +134,7 @@ class NotifiableEventProcessorTest {
@Test
fun `given viewing the same thread timeline when processing thread message event then removes message`() {
val events = listOf(aNotifiableMessageEvent(eventId = AN_EVENT_ID, roomId = A_ROOM_ID, threadId = A_THREAD_ID))
+ events.forEach { outdatedDetector.givenEventIsOutOfDate(it) }
val result = eventProcessor.process(events, VIEWING_A_THREAD, renderedEvents = emptyList())
diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueueTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueueTest.kt
index eebf420591..f9b63eb9dc 100644
--- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueueTest.kt
+++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationEventQueueTest.kt
@@ -208,7 +208,7 @@ class NotificationEventQueueTest {
)
)
- queue.clearMemberShipNotificationForRoom(A_SESSION_ID, A_ROOM_ID)
+ queue.clearMembershipNotificationForRoom(A_SESSION_ID, A_ROOM_ID)
assertThat(queue.rawEvents()).isEqualTo(listOf(aNotifiableMessageEvent(roomId = A_ROOM_ID)))
}
diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRendererTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRendererTest.kt
index c109edb40a..80875406c7 100644
--- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRendererTest.kt
+++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRendererTest.kt
@@ -33,7 +33,7 @@ private const val MY_USER_AVATAR_URL = "avatar-url"
private const val USE_COMPLETE_NOTIFICATION_FORMAT = true
private val AN_EVENT_LIST = listOf>()
-private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyList(), emptyList())
+private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyList(), emptyList(), emptyList())
private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk())
private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed
private val A_NOTIFICATION = mockk()
@@ -202,13 +202,14 @@ class NotificationRendererTest {
}
private fun givenNoNotifications() {
- givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_REMOVE_SUMMARY_NOTIFICATION)
+ givenNotifications(emptyList(), emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_REMOVE_SUMMARY_NOTIFICATION)
}
private fun givenNotifications(
roomNotifications: List = emptyList(),
invitationNotifications: List = emptyList(),
simpleNotifications: List = emptyList(),
+ fallbackNotifications: List = emptyList(),
useCompleteNotificationFormat: Boolean = USE_COMPLETE_NOTIFICATION_FORMAT,
summaryNotification: SummaryNotification = A_SUMMARY_NOTIFICATION
) {
@@ -219,6 +220,7 @@ class NotificationRendererTest {
roomNotifications = roomNotifications,
invitationNotifications = invitationNotifications,
simpleNotifications = simpleNotifications,
+ fallbackNotifications = fallbackNotifications,
summaryNotification = summaryNotification
)
}
diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationFactory.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationFactory.kt
index 09957e2cf2..60b9e10c3d 100644
--- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationFactory.kt
+++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationFactory.kt
@@ -36,12 +36,14 @@ class FakeNotificationFactory {
roomNotifications: List,
invitationNotifications: List,
simpleNotifications: List,
+ fallbackNotifications: List,
summaryNotification: SummaryNotification
) {
with(instance) {
coEvery { groupedEvents.roomEvents.toNotifications(matrixUser) } returns roomNotifications
every { groupedEvents.invitationEvents.toNotifications() } returns invitationNotifications
every { groupedEvents.simpleEvents.toNotifications() } returns simpleNotifications
+ every { groupedEvents.fallbackEvents.toNotifications() } returns fallbackNotifications
every {
createSummaryNotification(
@@ -49,6 +51,7 @@ class FakeNotificationFactory {
roomNotifications,
invitationNotifications,
simpleNotifications,
+ fallbackNotifications,
useCompleteNotificationFormat
)
} returns summaryNotification
diff --git a/libraries/push/test/build.gradle.kts b/libraries/push/test/build.gradle.kts
new file mode 100644
index 0000000000..9fccadb9be
--- /dev/null
+++ b/libraries/push/test/build.gradle.kts
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+plugins {
+ id("io.element.android-library")
+}
+
+android {
+ namespace = "io.element.android.libraries.push.test"
+}
+
+dependencies {
+ api(projects.libraries.push.api)
+ implementation(projects.libraries.matrix.api)
+ implementation(projects.tests.testutils)
+}
diff --git a/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/notifications/FakeNotificationDrawerManager.kt b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/notifications/FakeNotificationDrawerManager.kt
new file mode 100644
index 0000000000..1531d2df48
--- /dev/null
+++ b/libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/notifications/FakeNotificationDrawerManager.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.push.test.notifications
+
+import io.element.android.libraries.matrix.api.core.RoomId
+import io.element.android.libraries.matrix.api.core.SessionId
+import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
+
+class FakeNotificationDrawerManager : NotificationDrawerManager {
+ private val clearMemberShipNotificationForSessionCallsCount = mutableMapOf()
+ private val clearMemberShipNotificationForRoomCallsCount = mutableMapOf()
+
+ override fun clearMembershipNotificationForSession(sessionId: SessionId) {
+ clearMemberShipNotificationForSessionCallsCount.merge(sessionId.value, 1) { oldValue, value -> oldValue + value }
+ }
+
+ override fun clearMembershipNotificationForRoom(sessionId: SessionId, roomId: RoomId) {
+ val key = getMembershipNotificationKey(sessionId, roomId)
+ clearMemberShipNotificationForRoomCallsCount.merge(key, 1) { oldValue, value -> oldValue + value }
+ }
+
+ fun getClearMembershipNotificationForSessionCount(sessionId: SessionId): Int {
+ return clearMemberShipNotificationForRoomCallsCount[sessionId.value] ?: 0
+ }
+
+ fun getClearMembershipNotificationForRoomCount(sessionId: SessionId, roomId: RoomId): Int {
+ val key = getMembershipNotificationKey(sessionId, roomId)
+ return clearMemberShipNotificationForRoomCallsCount[key] ?: 0
+ }
+
+ private fun getMembershipNotificationKey(sessionId: SessionId, roomId: RoomId): String {
+ return "$sessionId-$roomId"
+ }
+}
diff --git a/libraries/ui-strings/src/main/res/values-de/translations.xml b/libraries/ui-strings/src/main/res/values-de/translations.xml
index bb469ad0b1..5c4b92c95d 100644
--- a/libraries/ui-strings/src/main/res/values-de/translations.xml
+++ b/libraries/ui-strings/src/main/res/values-de/translations.xml
@@ -140,7 +140,10 @@
"Reisen & Orte"
"Symbole"
"Fehler beim Erstellen des Permalinks"
+ "Element konnte die Karte nicht laden. Bitte versuche es später erneut."
"Fehler beim Laden der Nachrichten"
+ "Element konnte nicht auf deinen Standort zugreifen. Bitte versuche es später erneut."
+ "Element hat keine Berechtigung, auf deinen Standort zuzugreifen. Du kannst den Zugriff unter Einstellungen > Standort aktivieren."
"Einige Nachrichten wurden nicht gesendet"
"Entschuldigung, ein Fehler ist aufgetreten."
"🔐️ Besuchen Sie mich auf %1$s"
@@ -174,6 +177,12 @@
"In OpenStreetMap öffnen"
"Diesen Ort teilen"
"Standort"
+ "Anrufe, Standortfreigabe, Suche und mehr werden später in diesem Jahr hinzugefügt."
+ "Der Nachrichtenverlauf für verschlüsselte Räume wird in diesem Update nicht verfügbar sein."
+ "Wir würden uns freuen, wenn du uns über die Einstellungsseite deine Meinung mitteilst."
+ "Los geht\'s!"
+ "Folgendes musst du wissen:"
+ "Willkommen bei %1$s!"
"Rageshake"
"Erkennungsschwelle"
"Allgemein"
diff --git a/libraries/ui-strings/src/main/res/values-sk/translations.xml b/libraries/ui-strings/src/main/res/values-sk/translations.xml
index 707032b237..a6684f8781 100644
--- a/libraries/ui-strings/src/main/res/values-sk/translations.xml
+++ b/libraries/ui-strings/src/main/res/values-sk/translations.xml
@@ -140,7 +140,10 @@
"Cestovanie a miesta"
"Symboly"
"Nepodarilo sa vytvoriť trvalý odkaz"
+ "Element nedokázal načítať mapu. Skúste to prosím neskôr."
"Načítanie správ zlyhalo"
+ "Element nemohol získať prístup k vašej polohe. Skúste to prosím neskôr."
+ "Element nemá povolenie na prístup k vašej polohe. Prístup môžete povoliť v Nastavenia > Poloha"
"Niektoré správy neboli odoslané"
"Prepáčte, vyskytla sa chyba"
"🔐️ Pripojte sa ku mne na %1$s"
@@ -167,6 +170,11 @@
"Nepodarilo sa nahrať médiá, skúste to prosím znova."
"Ide o jednorazový proces, ďakujeme za trpezlivosť."
"Nastavenie vášho účtu."
+ "Povoliť oznámenia na tomto zariadení"
+ "Ak chcete dostávať oznámenia, zmeňte prosím svoje %1$s."
+ "nastavenia systému"
+ "Systémové oznámenia sú vypnuté"
+ "Oznámenia"
"Označte, či chcete skryť všetky aktuálne a budúce správy od tohto používateľa"
"Zdieľať polohu"
"Zdieľať moju polohu"
@@ -175,6 +183,12 @@
"Otvoriť v OpenStreetMap"
"Zdieľajte túto polohu"
"Poloha"
+ "Hovory, zdieľanie polohy, vyhľadávanie a ďalšie funkcie pribudnú neskôr v tomto roku."
+ "História správ pre zašifrované miestnosti nebude v tejto aktualizácii k dispozícii."
+ "Radi by sme od vás počuli, dajte nám vedieť, čo si myslíte, prostredníctvom stránky nastavení."
+ "Poďme na to!"
+ "Tu je to, čo potrebujete vedieť:"
+ "Vitajte v %1$s!"
"Zúrivé potrasenie"
"Prahová hodnota detekcie"
"Všeobecné"
diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml
index 315c32ecb9..81b76f988e 100644
--- a/libraries/ui-strings/src/main/res/values/localazy.xml
+++ b/libraries/ui-strings/src/main/res/values/localazy.xml
@@ -182,12 +182,6 @@
"Open in OpenStreetMap"
"Share this location"
"Location"
- "There\'s a high demand for %1$s on %2$s at the moment. Come back to the app in a few days and try again.
-
-Thanks for your patience!"
- "Welcome to %1$s!"
- "You’re almost there."
- "You\'re in."
"Calls, location sharing, search and more will be added later this year."
"Message history for encrypted rooms won’t be available in this update."
"We’d love to hear from you, let us know what you think via the settings page."
diff --git a/settings.gradle.kts b/settings.gradle.kts
index da6c0affd5..408c9e2934 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -36,8 +36,6 @@ dependencyResolutionManagement {
includeModule("com.github.matrix-org", "matrix-analytics-events")
}
}
- //noinspection JcenterRepositoryObsolete
- jcenter()
flatDir {
dirs("libraries/matrix/libs")
}
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index bfbde54478..3a6043a873 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4814342a28371f6a6dcc13080c362483368f67946e0b21e7ff44ab08da4809c2
-size 13639
+oid sha256:df4db13529aa1125687e4cdbd2282b9511cbd533e8fbc9b5fcb1226ef93cfd86
+size 13613
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index 1c162be7f9..92a554c5f5 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:db05c9dc303b03a8965e199981cb786491fcf814bf78244b3fc5b7e323807700
-size 28097
+oid sha256:b74b37e5bcc506e7351512b2b2c9f6b933877e67920ab90033259ecb2f0849d2
+size 28040
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 165abeaa8a..0f09964928 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:220facc6d655662a3427127164de3232b1e91fa0918d7e50851ca95993fb6518
-size 14665
+oid sha256:a5576ba05fa04c1110e76a3ddb3a0d61778f007da38eac639e6f9794ec296110
+size 14625
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index b0bc5674b0..6e134d0f6f 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.addpeople_null_DefaultGroup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bdb04dc4e9f047baa6209478c3083c80738e208938d2f25df282fb84dd3aecd0
-size 28855
+oid sha256:d04ba274e93685d099ba9c407c38c339604514a446ae2055d0900b8a6f35b39f
+size 28840
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index c072807440..ad77dac232 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2b598c1ed004c33d661e84b1147874abad8d555c51601d9c0ec066d684dae37d
-size 56711
+oid sha256:a9f5b609ec3828639f4f9257cf6f69affdf802238cb6d87dbd879d922c9889b6
+size 56715
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index d3f6f62b84..f8b7ccd95f 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8d04e77e3a7e7862f29868be068df658382ed7dec94fcea86665bbd5074591bd
-size 82804
+oid sha256:00030af95c37343791901f6990cd3c41aa65ae00d9515915b2d841cdbb0247ef
+size 82801
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 0484c72595..c8d9f2943a 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b4da5f287307632890a06dab913e744f4194e231d873096666a92beb24790a72
-size 60183
+oid sha256:7a2d26a6b91a57621f178d09b2c54ab769760145f23b216c5e9d62db82493941
+size 60140
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index 7276539768..c996af04ae 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.configureroom_null_DefaultGroup_ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4f8de89448ff5f4f95c7611657e38e0ba75c2f503b82fb04f584f3116353ae51
-size 85954
+oid sha256:4d327234d494f77c3c8a11cf32f16e80fdadbe42ea87df8b34770e000545e8de
+size 85937
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 2a74a92a2e..747f41d1c2 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ae48bb96d6865c6dd9cc8af39a9efd82455cd1483d93bab40fabfe9a7d0ffb2d
-size 21442
+oid sha256:873df9138a6dbf973c37cb76a0880d29894bda0fd92ba49c166ef7167a791344
+size 21419
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 9fb8b8730b..bee8e18720 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.createroom.impl.root_null_DefaultGroup_CreateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cd79ba2875e99289e8b419408a32e9c7faafb1c85afae499e877ad17aefb1d0b
-size 23087
+oid sha256:18a343f9fce08b0ff9e12f22e1c8e4efb6f16b3eac886675c9534d088dbe3f80
+size 23098
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_0,NEXUS_5,1.0,en].png
deleted file mode 100644
index 4d8d03c708..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6ec7c0893d93a5b1c6b42e13826ac9978363d7acc0943e66db0312552b71d8db
-size 143797
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_1,NEXUS_5,1.0,en].png
deleted file mode 100644
index 5d4ae5723f..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d92879626836d2e4378a985a972dced835609c461f5e89a5ecf294d78bda103d
-size 146493
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-D-1_2_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderLightPreview_0_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-D-1_2_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-D-1_2_null_1,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderLightPreview_0_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-D-1_2_null_1,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_0,NEXUS_5,1.0,en].png
new file mode 100644
index 0000000000..ac43bdd1ef
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_0,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ffdebd1981c4e28216f4b16b39180d93d37358bef3a4ecf9cd58aeb9cbac5267
+size 143680
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_1,NEXUS_5,1.0,en].png
new file mode 100644
index 0000000000..048dde9a5c
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api.internal_null_DefaultGroup_StaticMapPlaceholderPreview-N-1_3_null_1,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a24dc75c160ba1b75dbeb13c3e581434564a25997f90788ce3866f1736a11f46
+size 146329
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewDarkPreview_0_null,NEXUS_5,1.0,en].png
deleted file mode 100644
index 4d8d03c708..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewDarkPreview_0_null,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6ec7c0893d93a5b1c6b42e13826ac9978363d7acc0943e66db0312552b71d8db
-size 143797
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewPreview-D-0_1_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewLightPreview_0_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewPreview-D-0_1_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewPreview-N-0_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewPreview-N-0_2_null,NEXUS_5,1.0,en].png
new file mode 100644
index 0000000000..ac43bdd1ef
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.api_null_DefaultGroup_StaticMapViewPreview-N-0_2_null,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ffdebd1981c4e28216f4b16b39180d93d37358bef3a4ecf9cd58aeb9cbac5267
+size 143680
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index d639c16ee7..ab90a4e957 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f1f40593f1075d245f98547fea35ab6861858cb02568efd1e9c6d1f1e07d85a9
-size 10193
+oid sha256:04e73f8f15fb519a5b18e925e79bbf91e67e1dd90669bcdfce6e6a232be9fed0
+size 10203
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index 0b0fe1c24d..8d07b56c5d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9f571102bed06886257392347b27a935d3d34187de1004311395ee6f849e44a2
-size 13504
+oid sha256:7c1b39e7513068bf8ddc201869c33cd2d7205645d0a1411f1a12ba7e7f27a3db
+size 13511
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index e3e6a8641e..ca8b2fffc8 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e13f80abff301cf0d345434a2010c7aa9e84f65514842712b1c8be64fde81160
-size 23003
+oid sha256:3a12aa006922a93fbd2228c5ee6932099483dfa02f71ca35fd242b9b266007c4
+size 23012
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 76abe2b489..102f057622 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:779f80e6cc4cb9ca9c3dd113cfaaeb528244b48d3b915f262ae5c797ad0b6524
-size 10101
+oid sha256:708ed8b1f055ed2d43f4e0b079ad5d1c8d068a49c496907d805c2874d540f0c3
+size 10105
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index 893997718f..6c86729038 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:57852301ef65b259a7b3a28943918fc37261c3d183d5b543e246ef9fd07b542f
-size 13937
+oid sha256:8e67861de492c5aae34dc3759b3569120c9b5f7c57347115c197bcf1e1b71fb0
+size 13944
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
index d713d3675a..ab412d4a32 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl.show_null_DefaultGroup_ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3f1d57e7cbabd106d236a9afb49cfbaf5546c1f2d6b490d11a5d313d101632b4
+oid sha256:c27ad781b929d859ea2738f392c7b0c8dd3cea02907c5ac195b52ebc78c623f9
size 24994
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 19a09eb962..1658e60c95 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fd4a7d61010660b1c9081c48e562b219fd454e6ef23088bf0a6a1529d5fa67f6
-size 17379
+oid sha256:67efcb12a0c2c09070249e44b92b511f8891c56ea6b5fbca165309b89221771b
+size 17363
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index fbffd41d56..474a50406b 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.location.impl_null_DefaultGroup_SendLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7204bf50f6f7352160f9f45dbbecebbb2186b0d2e59d51e4d5237b536f345867
-size 18062
+oid sha256:8a5dc7d65b00e6d3624cc20d47e476a5257de37b0750c096ad896bb382e6aebe
+size 17994
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 763bc57c99..5e3b6fa814 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a5676571f9f913a010aa18e2602404ee25f1bb95e8881dc46c54cac9b8597b87
-size 12451
+oid sha256:f3877f94c6335412dd595f51be4573a4e4b49d36ac2b7cf3fc09c685b119bb2f
+size 12417
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index d5fde6a598..be703d52a7 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4d14329e6301fc3b1d29f7b39dba09ca30d6fa59d91ab7da3098bed0f1de1465
-size 11999
+oid sha256:4c7cc060073e2457af7db15e01e4055db66334d152e9c171d1f59a1760877854
+size 11981
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index 617292e9a9..7164b3ee51 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:245701b0b6fbb5f886af725435ea62ac2ed2164ae51cc74ed3560c49d5692144
-size 26585
+oid sha256:a633c54b3562761c36acf2415468659f335d073440f3799183ad30f4c7a6947a
+size 26560
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index 734c725877..c29fc5bc8d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f38a35d97468eca5ed4172b089e4b95f146a37e39e62c9cbabbbca9efb90a85b
-size 26188
+oid sha256:c52b426d5460521fee492f356ec40e71938a0176be8b2cd5762379ee6a9aa344
+size 26163
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
index 03384dd7f7..27e1a363ed 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fa887dcb1f4d9ab2d91e9779a4099b6e15f42afa634deb8a96c288e42359a542
-size 26368
+oid sha256:9d2ac1de1b15fb89eedcea26cb926cad1ae1cfcda87136f76ba2fd6e918d493b
+size 26349
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
index 03384dd7f7..27e1a363ed 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fa887dcb1f4d9ab2d91e9779a4099b6e15f42afa634deb8a96c288e42359a542
-size 26368
+oid sha256:9d2ac1de1b15fb89eedcea26cb926cad1ae1cfcda87136f76ba2fd6e918d493b
+size 26349
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png
index 03384dd7f7..27e1a363ed 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fa887dcb1f4d9ab2d91e9779a4099b6e15f42afa634deb8a96c288e42359a542
-size 26368
+oid sha256:9d2ac1de1b15fb89eedcea26cb926cad1ae1cfcda87136f76ba2fd6e918d493b
+size 26349
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index d42b0a08ff..8b77f0f9b7 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f8e751591d6dc12abae358539398b88d1e943fbe315c5c490b5fb6dfeca3f04f
-size 13415
+oid sha256:6c4828c4c081d1d610acb37c78fbb1ca2b9d1ec3903b0da2d3fdf91b6804d20b
+size 13477
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index 89c3e56d57..e42d2d6eaa 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6a6ed0774b8b68ea0693f9edced7450d2dcf81d69d0b064d30901c4f961592fc
-size 12808
+oid sha256:4f04eb58ed65b7a9d51afa20e76bbe624498ed0571122a06a82f3b51405b6752
+size 12865
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
index b3333c4be3..ea38e3b9ce 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b089c60e4dab83a100c5946f7898d6ade97af23c4cfe0adf46a2974dda77ec10
-size 27808
+oid sha256:f754c327ceb268d973e7dd52c2a78bf842d927f6445b13d7a51fb8cc9d1bf866
+size 27888
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
index 4e86e231df..ce5aa65b39 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:470c321d59f1c03bf0e3b3b63114dc69e97ae92064b5455d5cc26120f6c25dbb
-size 27198
+oid sha256:7e9cd8e04cb930622991acc0bc49847275b099be9c43c3890cbb355696bec35f
+size 27272
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
index 03acb51dc3..bc40f1214d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cc715090a67a07b9cba6a437b2e5b844f4ca2b5cd50d4716cfd9be818229927f
-size 27604
+oid sha256:a9d9933cdf7ec57e13e5a668ffb689f225669d4c879d396a9ae73a596d71dbfd
+size 27645
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
index 03acb51dc3..bc40f1214d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cc715090a67a07b9cba6a437b2e5b844f4ca2b5cd50d4716cfd9be818229927f
-size 27604
+oid sha256:a9d9933cdf7ec57e13e5a668ffb689f225669d4c879d396a9ae73a596d71dbfd
+size 27645
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_7,NEXUS_5,1.0,en].png
index 03acb51dc3..bc40f1214d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_7,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.forward_null_DefaultGroup_ForwardMessagesViewLightPreview_0_null_7,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cc715090a67a07b9cba6a437b2e5b844f4ca2b5cd50d4716cfd9be818229927f
-size 27604
+oid sha256:a9d9933cdf7ec57e13e5a668ffb689f225669d4c879d396a9ae73a596d71dbfd
+size 27645
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 38111bad42..13f8fbcab2 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8e59cb5fc3740546a3918a49ac6bfc3faef335b12707b3f0f0be642a2f28c83d
-size 43183
+oid sha256:cbc1cd15a2141a8e5417ce1a5e959c2cfafa4d7416ffafdd6156cea2bb2b3bcd
+size 43145
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index 6dbb80364a..d57a35c139 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:26c7f2b4f83a213767b00c2e211188cc6f26b46de49b67b4723bf7f8ae5d3ea6
-size 44140
+oid sha256:125bdc840f4fd422019ad5bca1381fe0adff224bbb02fdbf6f65674476cbe7a8
+size 44127
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index b97210f045..46bbe1f386 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6e10ae8bc3b582786ed7e44588571a8b2a35b8a9d7491417f2e0b018c86b16f3
-size 43692
+oid sha256:b08ddc4986270f2d241bd6b6c79cca624e80a4bf1c448041369c082ac262c755
+size 43677
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index aacfe1ca7c..e4315f0952 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1e2cdd134b8024177cd12a46af515eee77f483fb24b1f3b29055245158d6de09
-size 41821
+oid sha256:ec59e8210351b16ed675191d86dfc7df828533199aa14f958d0f09789c01176b
+size 41809
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
index 2383643aaf..a382de20d1 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b28562dbffd412c09d42de609e7826d9d91fce0bded3cae902935994550a50de
-size 34856
+oid sha256:e067c1dc85dade74422c4d7bf6ae9c4c154acac48db93652af1d1445f6d1db1f
+size 34728
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 842622572c..ec22846745 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6d5cfca43410cd1fb0af61a3d3cb923361762e18ca3343ff5605aa41497917ea
-size 44792
+oid sha256:b8fe5aae19936e6175e5dc4890b6f8174682a781a0072a81a873370b89a9da1d
+size 44727
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index f8d7c49a2b..63b5db1f73 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c159cea8c882dac45b2bc6d44dd40eeba99fbf5351a648199594f8ea8df48487
-size 46488
+oid sha256:593c5bb850a4494b5583cb6dd61cb12f603f58d166ba8257608c961a50402c34
+size 46398
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
index 4e57582b99..e1f3f42427 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fe4c64862737d9d956c840976ff2ddfbb346ab25c0400dd633b062cf6671c9bf
-size 45990
+oid sha256:d67429652308c81fc1ac29ab38ec668f64c56bc4086cc454e33195f97388b08e
+size 45898
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
index 22267ba094..823f4a005b 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:70170bcaf14f3dcb0c5e49cc7edaa1a630c914062b8b6af3b3c0b52ac1cecf27
-size 44247
+oid sha256:7ad3df640c4ccbaceed6851d7324f4693b553f82c6df70c274078615e67d721a
+size 44185
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
index 57be7ab85a..fadc83bb1d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.report_null_DefaultGroup_ReportMessageViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6c855a5aa7baceb74915e93ebc5af910b2ce0eaf79cb65e7ab06a976db615352
-size 36120
+oid sha256:cf084c895ef8a8d292cb51f1fd61eeaa551bb902b8fbea261a78dccad6a194f9
+size 36075
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_1,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_1,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-0_1_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-2_3_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_1,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_1,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-0_2_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-2_4_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-1_2_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-1_2_null,NEXUS_5,1.0,en].png
deleted file mode 100644
index e89391d7fa..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-1_2_null,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b024b20585c98eddb6032795e2a434bf675f7254d1f3a649ccccbe4fb2351c8f
-size 7844
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-3_4_null,NEXUS_5,1.0,en].png
new file mode 100644
index 0000000000..782ffc1350
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-D-3_4_null,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f1da445cf56c818ddcbc8ebb75fc0390122812a4a866ad14170ed2f652fac785
+size 11163
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-1_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-1_3_null,NEXUS_5,1.0,en].png
deleted file mode 100644
index 9df80a5dea..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-1_3_null,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:cb3b2ccab39aa4cb7afde21d8a9b2c0d18f54d9f397e7020413281b3bfebaa2f
-size 7634
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-3_5_null,NEXUS_5,1.0,en].png
new file mode 100644
index 0000000000..8f6ebb274c
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionExtraButtonsPreview-N-3_5_null,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8687ae17659becc872db2f643bc1fd777e396db28bfcad18ef8c849140018ce7
+size 10661
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowDarkPreview_0_null,NEXUS_5,1.0,en].png
index 2eb0d560be..b5b12ec81d 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowDarkPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowDarkPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b8ca3e1c8ce3c9476cdc7db46aebc8b6970486ff01e05b82c162256373c8957f
-size 141055
+oid sha256:323b80f3b2fcee42ffe50f333ff9d3952da05138f413f15882bf8ff7079347d8
+size 138598
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowLightPreview_0_null,NEXUS_5,1.0,en].png
index bcda87bb06..9664edfe08 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowLightPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowLightPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2bf89d0228a9771360eaad8a0bc514731153a351551df427cf7f7e44b886edfe
-size 145398
+oid sha256:21c3a584e3d47d030e45aac8d2162bd9b1d03f0ef43c3b8681f69eadd2d6fcc2
+size 142344
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 02fef0faa0..82fefe69c1 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:043097099dd08f0e192debd0ef650e8effe76c71f29dd3a993bf756d8e933d25
-size 62314
+oid sha256:7d62f35da442eba33e6913f6704de1e80918e50cef6237c00678ec9de5a23759
+size 62310
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index 4f80e82b44..633ab693fd 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:4fe9d9d0ff870ccbb095c53b37900c00feb8153e76965ba432bad9d37387e512
-size 64523
+oid sha256:8d488277351ea1f53f11cabef46ff46768a42d61dc913b903b670635b9e44816
+size 64503
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index aaae1b427f..b27bf20e06 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e78c43cdaa5532d854087567fb8deef13fe89b1e896450428186df6b6cd83443
-size 68731
+oid sha256:e6b3750046ba185168395f20c75451524754b003a293cfcb0ed5a45be8f3335b
+size 68707
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index a18580d94f..f9b8fdd599 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:960e7c05075107db3a2b57f630f114927d4d019ffc5d38f5d501d44107753ea5
-size 70789
+oid sha256:963bf003585c82dddbb2efe1f6cf2f0564db88ea5de69e2b4322a6d256639de8
+size 70761
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 6f7db0fa68..43da505724 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f39fd269e68edb95e0b7c49bbf21a51c6c4233bfbfc173fdbc0e80eec2cf8d83
+oid sha256:b75482695c36693390a1100ff2758ed8910f65da42ddb270cbc07252c25ae439
size 64252
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_1,NEXUS_5,1.0,en].png
index dd02e31b94..0dfb072ab2 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:eeb7f709da25c8864e712ab1532fd7803ab1d692c7baea970283a4702640840c
-size 66900
+oid sha256:401cbd6022543957388ec5fe81181604495238e80c95c1baa036c67bd62460d6
+size 66869
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_2,NEXUS_5,1.0,en].png
index ff1cdcee31..ed1bb381da 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:79493cad80934a053f300864189dd47bf6c1d9aabac780a5c5ea1ca497fc7a47
-size 71250
+oid sha256:ac20d25de28ae59dd2e9ea2743480792c3c10644128219966af1eee1e2034ac0
+size 71215
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_3,NEXUS_5,1.0,en].png
index 00d73a45bb..b0b268e568 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowTimestampLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c2b4ed0df17a6f96dd0031b820585346ec6ccac419a2f1237e0decdfb50dddb7
-size 73644
+oid sha256:5ca3befc8d4142f5be8252ffffef5ac82a25786085b0552b348d4f0a412bc9ae
+size 73743
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsDarkPreview_0_null,NEXUS_5,1.0,en].png
index 599ea51395..579d5884e4 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsDarkPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsDarkPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:82b4fb72cd3517b4eedeba3172cc428ba67199df816c686d998027ed021c1bb0
-size 84164
+oid sha256:1963827d549b8144bd1c71f85da6208307b8939f621b57c705a2ca61309f2e0d
+size 84239
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsLightPreview_0_null,NEXUS_5,1.0,en].png
index e4cd1354cc..1aa0b25463 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsLightPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithManyReactionsLightPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7c95c7df9616dca071528f4185e63485e7e738e51e595d828f94b08205c6e33d
-size 87695
+oid sha256:6e4ae356384002a19f779236ed6f2a3722c8f7bda91357dee3cacbb95d6aa61e
+size 87794
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyDarkPreview_0_null,NEXUS_5,1.0,en].png
index 40a5b155d3..c306c70ed3 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyDarkPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyDarkPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:02f2eb6e37f1022aa13cbcdfc34e7955b99ee4c3d6b35668b548afc94d33ae31
-size 119137
+oid sha256:dcd2fb7256950a8a31267d6be90c342ae8774e945b04d954a7cc3d83878cb25a
+size 119550
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyLightPreview_0_null,NEXUS_5,1.0,en].png
index 09c6f7efe7..1749f4f823 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyLightPreview_0_null,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemEventRowWithReplyLightPreview_0_null,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d50e5ac4433e4a44091623f1813373884007506002cc0c657ca7231a6e309462
-size 123938
+oid sha256:5628adde34216d1888481918628c82655252acfc15296c4fddd3220d0b72eaa4
+size 124893
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-D-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-D-5_6_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-D-3_4_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-D-5_6_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-N-3_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-N-5_7_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-N-3_5_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-N-5_7_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-D-4_5_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-D-6_7_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-D-4_5_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-D-6_7_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-N-4_6_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-N-6_8_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-N-4_6_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-N-6_8_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-D-2_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-D-4_5_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-D-2_3_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-D-4_5_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-N-2_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-N-4_6_null,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-N-2_4_null,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-N-4_6_null,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index a60497faa3..ad4f61c942 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b23f7c97f2b6dea4043bc0ac5e8600c7848cb59247e6a7a22c817be2de45c691
-size 29339
+oid sha256:41cd81bc9196eaa7f194db0c339d29bc3f29af209087c47f4dfae872ec2376d2
+size 29292
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index af9b491586..66030b2af2 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bfec640dba23986b6a3f6b7a2fec545c0b61df3c6cf8b629da54683ef718d28e
-size 23092
+oid sha256:f7a025bca4736747268568ec96384fb251cb07d5c4e73fa93fc62b339c6ad14f
+size 23049
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index ba2a9a5de9..3e3c9024e1 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:956b1dfbb351f6de4ca4148d756531f38d31b29d18ae8ed64859d61484ea8e92
-size 53820
+oid sha256:eda7e8fecf7b6944abd433e1bae4f0c6850919525176a7a38340bdabf47d43cd
+size 53797
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index 450be6d532..aa6e9a7c9c 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f23fd955243dd393de0a12ac508a6630b8ae4db0052ecd392467949b45804e8a
-size 27941
+oid sha256:936a8daa6b7a79d47bf79652c51886f6b24132e45d2edca84dde46be8d2f399d
+size 27931
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
index b63380edde..be886f18f0 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f7d540493f78b0ab98fec757361ab01a23c05b7ae6ecea79b9dc6fad08eaca49
-size 27518
+oid sha256:76579d4034f668ebbd6d1aa032a04255bc55c247af8bb55bfb84b710bf024835
+size 27508
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
index 3aab8f6f7c..ab9274de1c 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:515a7e2caef9632737b92db6fd7419ea3657f0ce2805516e5abc7b5a889246e6
-size 28541
+oid sha256:9111f56dfa945e83d2c2e972be5e37b66d9019c2d3a094fc336e79259c98651a
+size 28560
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png
index bc966f8707..e338cb04f2 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:afb71416708be935e224f83a461982b2833b613f2119c951be67e5c787798cd1
-size 25205
+oid sha256:4adf359eab66867a5edc21b4d1d6dde19649573966e2482816a264af7d80a2c3
+size 25209
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 23dce25e93..179e17a51a 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d04001f8a3611535b6215eea1bc33f77894511d7993a134a8db24d493017ef53
-size 30402
+oid sha256:be81cc5d8694542208b32429ad2f026c6753a17a645400ea65669454ac3a8780
+size 30389
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
index 0c9840dabc..6a62bdc452 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1eb423c9a244d03fd11e8cf3acd11d216c8e3fc785c945221156647fb4885a0a
-size 23889
+oid sha256:c89ce7911d177fdfc1fb5a57f6a4bfae27a910e02386837940ffee2bea8e29db
+size 23877
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
index 1c1ad814f7..466d0f6e81 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7a5143cb8266340f1e9ad5396cfcf472aa1fc0244da26ae3ecdcffeb731abdd9
-size 55270
+oid sha256:b0fc4404f13add1b4ee4c6e3ab4cb0d0c3bc9f5029c235047f8bdd7ea388c739
+size 55249
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
index f81ab1c2c9..ae225171fe 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:09c5d9512c718462454576d4be5c9c9745aba1030f2ca9166afe9ae5272ce70d
-size 30063
+oid sha256:ebf4fcca7906be4377d89066cfb9b025d4e352105a9a3406dc473de17b629673
+size 30031
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
index da73b7a5b1..c7606e5a1c 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b0be2938bbbedb9858591f4e5395f78e5e6946fc88448f4b277cd89741eae649
-size 28802
+oid sha256:a21c282d805a88f53a9b9755393dc9509424348dbe61326d84e8da6792c49ee9
+size 28772
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
index 0a4539f7e2..0721a71426 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ccdda8dd64b642c974cf9a150bc0013c0499d9b2c0ff6b82da9fe170cd0c6605
-size 29025
+oid sha256:03a19dbe5526aeefda8e9516768c05d47990b5c4e63908901412ebe215045c98
+size 29017
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_6,NEXUS_5,1.0,en].png
index f146f56fe9..d073d86493 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.edit_null_DefaultGroup_RoomDetailsEditViewLightPreview_0_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:92b26dba342157323d72de8badbe31797708bf678db888be5c4bfd991f3c0587
-size 26200
+oid sha256:a80f1905023c833d509409714fb78130bcff4ac6a32d38668e1496c57307ca5b
+size 26192
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 85af653215..6bc2149593 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9a1d979a10fcc7f50f5f7ec3db733e9ad12bc1457a002d227accef09ff472473
-size 13484
+oid sha256:126c4482baec46cd99fa76db534795f9d69aa84e1a9f07f5accf05a069e1a427
+size 13458
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index 288c55d26f..fb00213954 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b3baa6bf50f8b678515279f5b917378df8ef78813e5fdb1b2a67f179156b2ea6
-size 28058
+oid sha256:aacc8efb2cafc108299a2e942941019337320872b268f7e9ee0693cb98fba7df
+size 28051
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index 6c23dd0805..f2f3f64545 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:af5fae399e39f3c01e40b80954ba28f1f79c8b0b81bad8f89a0932bed78395f8
-size 10969
+oid sha256:30ca67c51a8d571f70656a67156912897e5cd99abfce1bc9d49523599810e245
+size 10947
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index b79f51126d..d5b8a9a696 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c7dbe5e65d74c6edb544bb4c498a440df3891bdc8b798479c5ce017419cd6602
-size 25828
+oid sha256:641b8937c9c8c3657fc20db830866cb520c1c44152587476d658a30b6e97167f
+size 25811
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_4,NEXUS_5,1.0,en].png
index 44830fe961..b028111235 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:dd9f4e88ddcebc1c92038653b3f34e623e3249ac1e1a5672674bfefb728ab281
-size 13024
+oid sha256:366160511e1c87464825a18b20d8f36915afa7b312c4d35d4da8ee55eed4eeb9
+size 13007
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_5,NEXUS_5,1.0,en].png
index 23ac8f0788..c34bfeaf68 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6c790f664c7f3f8ec93533d62ddcf9905f3af21ffbcd083cbbd59d1e30548c99
-size 44649
+oid sha256:7490dd57b743fa7941ec589cc55eb4a2d60e3a6a5ccbe2cd15303aa15b4f7c97
+size 44632
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_6,NEXUS_5,1.0,en].png
index 30575635dc..cc88932af7 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersDarkPreview_0_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:593306f9c6d53f263ad1c27803aa14cffb71841fcd705742727dfb7473ff6fea
-size 38029
+oid sha256:5dba7c08a4c47b4fe3381f7d9b9b228dbfc1c83dfc68555741c5d94374eb749a
+size 38013
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_0,NEXUS_5,1.0,en].png
index a707c5b139..285845cedd 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b86c0eb468a9b09463c412656c955be1d08bd9bc6685160e6a4f260adfc1bf32
-size 14465
+oid sha256:b33574e50b37a48247fe299ee1261a4b368b827721c0486d491304452e9ce1ca
+size 14478
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_1,NEXUS_5,1.0,en].png
index 3368ac84fd..e1b29cc42a 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d0e6eef94a2ad618dff40cd23e3f37b8dec3552f88083fe23c26925eb96e4a50
+oid sha256:c9e6dd492e82654ef3b572946d378b92f05ba05dd2453780e96c34bd2680a004
size 28818
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_2,NEXUS_5,1.0,en].png
index 2835225ddb..b722ff4594 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7720d35d7329d655a2a80de6cc1ba240abc464cea6042ba8a121709148dcca57
-size 11779
+oid sha256:76aedfc30081ed7f0b019f647e5001dea24c6eb361c2de1e922965c6a7c95866
+size 11794
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_3,NEXUS_5,1.0,en].png
index 62894a7585..d6882e62f3 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:33d758f64df1a5471d77effa6a177cb2d3d046bb35ce165b56ec613b8ebd150a
-size 26745
+oid sha256:0d6dca2f331218e3edde3341afcbdc7abbbd240107aea3276692c338db9be107
+size 26759
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_4,NEXUS_5,1.0,en].png
index c29e12bcb1..eaea2b831b 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_4,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_4,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f005e0903310b609a406df173e57a99226b8d71e853ec5a2ef51e1ffc1e29a8a
-size 13868
+oid sha256:9ae4bd7d3389eee5f92a38814de0f3cc7348033007152c1607725aebdb3009a6
+size 13876
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_5,NEXUS_5,1.0,en].png
index 50f68ab20d..b8de86ce82 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_5,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_5,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:053a2261d263728afcf2f6fdb843ca94ae81d63c91e7ca687fa4598d46685832
-size 46199
+oid sha256:e9b4548e0274ef20d216343e78274df12c0f78be5fd8bce14deaabe18fffc8b6
+size 46200
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_6,NEXUS_5,1.0,en].png
index 767c8e6dce..346f70c44f 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_6,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.invite_null_DefaultGroup_RoomInviteMembersLightPreview_0_null_6,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6c6dda22040e95a26c18bb7bbe695756f0cde6cbf6ca70354c91e7d535cae395
-size 40104
+oid sha256:2ac7cb3a6ce79f522fbb180b6b9206940d3bd7f5276f960f550f88f9f41c4eb0
+size 40093
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png
index 03d3f3f49e..b1a06d6589 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bdba3cffd72bc132eed3c054f9904b1a9f80e80f1696aae6607b7c216340fdae
-size 37514
+oid sha256:6582b16170cde1c1d90fda50231649d2b5bb145459e2d54373c3e3a8983fde3a
+size 37525
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_1,NEXUS_5,1.0,en].png
index d93a93396c..dc7287b125 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c212ddfb8962786953f91289ff6edcfb6f6b0997e156bec9a5177f89e51e85af
-size 13507
+oid sha256:b9f4c25dad22ac5f446bc042c9cf5875765823f1f8bae4959ed2d21938576ee2
+size 13521
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_2,NEXUS_5,1.0,en].png
index e900085ae1..bbf243cfa5 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c36a5d0f968165088e9d0d61a00b3ee173ffe8895833992ffd80bb985db9fba6
-size 12756
+oid sha256:499a2728453b74348a7eaafaba4c1ce209749ac2c704ba4d8cd36040435395bd
+size 12754
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_3,NEXUS_5,1.0,en].png
index 4f15ed1f33..780c8c5a87 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListDarkPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:eda885654511fbf9ed8f04dc6bca58be358cbb7cbd10c55203f2439a33c6822c
-size 11852
+oid sha256:99f6e69be2446d4bb49a2fbeeaf6a962af4eac29a4219c1b160afaa50c9737b6
+size 11872
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png
index 9ecd12a203..c91a45f3a5 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1f0438c395e75d9f4048f09b46d46862115abaa41cebbf62e13e3f911c0142f1
-size 38664
+oid sha256:f26ac372f90ad3d17ba780d41ca6d14bb3db5771966398b594c7c7cca48b6f7f
+size 38617
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_1,NEXUS_5,1.0,en].png
index e35a8c6eef..bae928b107 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_1,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_1,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fa1639ee25d6d48ad365581fd3064c499df4b59fe2b42ef12547176b42670d9e
-size 14392
+oid sha256:1658b33c0af05893bf34c8b9ad1ad396f154e3a654cd9085734bd58fd30b0e3c
+size 14337
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_2,NEXUS_5,1.0,en].png
index 308aa50797..2513a852ba 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_2,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_2,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:17ce39fef39dd8f940933796daad169eaac28b5a66c764c3d29096dc9261cefb
-size 13670
+oid sha256:dd5653b99dbe4dd5cb028b65c003fa8e45e247a8cfafd283e26720691db4fb03
+size 13621
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_3,NEXUS_5,1.0,en].png
index 6b87fa7a06..ab7bb267e9 100644
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_3,NEXUS_5,1.0,en].png
+++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.roomdetails.impl.members_null_DefaultGroup_RoomMemberListLightPreview_0_null_3,NEXUS_5,1.0,en].png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:89b089039953999c2210066c5edba0f75caa1da601a1dda87868bb98f557de2b
-size 12665
+oid sha256:af181c0f2f3b23e43fdd42aa0d05898ad7dcaf500a45d6aa13efc52ae1252189
+size 12610
diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_CenterAlignedTopAppBarPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_CenterAlignedTopAppBarPreview_0_null,NEXUS_5,1.0,en].png
deleted file mode 100644
index ac67d64828..0000000000
--- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_AppBars_CenterAlignedTopAppBarPreview_0_null,NEXUS_5,1.0,en].png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6d56800e18c52f88a232ced0d74d6d648e045525eeebfa8baa8ba0c2ee20d1d2
-size 6947
diff --git a/tools/strings/importStringsFromElement.sh b/tools/strings/importStringsFromElement.sh
deleted file mode 100755
index b17adf06a5..0000000000
--- a/tools/strings/importStringsFromElement.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# 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.
-#
-
-printf "\n"
-printf "================================================================================\n"
-printf "| Importing strings from Element |\n"
-printf "================================================================================\n"
-
-basedir=`pwd`
-tmpPath="${basedir}/tmpStrings"
-
-## Delete tmp dir
-#rm -rf ${tmpPath}
-
-# Create tmp dir
-mkdir ${tmpPath}
-
-printf "\n================================================================================\n"
-printf "Downloading Element Android source from develop...\n"
-
-curl https://github.com/vector-im/element-android/archive/refs/heads/develop.zip -i -L -o ${tmpPath}/element.zip
-
-printf "\n================================================================================\n"
-printf "Unzipping Element Android source...\n"
-
-unzip -q ${tmpPath}/element.zip -d ${tmpPath}
-
-printf "\n================================================================================\n"
-printf "Importing the strings...\n"
-elementAndroidPath="${tmpPath}/element-android-develop"
-
-cp -R ${elementAndroidPath}/library/ui-strings/src/main/res ${basedir}/libraries/ui-strings/src/main
-
-## Delete tmp dir
-rm -rf ${tmpPath}
-
-# Commit all changes to git
-# git commit -a -m "Import strings from Element Android"
-
-printf "\n================================================================================\n"
-printf "Done\n"
-printf "================================================================================\n"