From 8beb8c5f6b9c4feedf2c4b1c224e7bc16fcda2b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:26:39 +0000 Subject: [PATCH 01/33] Update dependency io.nlopez.compose.rules:detekt to v0.1.12 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index bb112659b1..e56d5d89bf 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 From 043ed3e0aa3e03b4a318560ec064f85a82a967b7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Fri, 7 Jul 2023 13:59:05 +0100 Subject: [PATCH 02/33] Remove CenterAlignedTopAppBar Centering the titles is very iOS-y and not aligned with the material guidelines (which say center aligned top bars are only for the main root page in the app). They also present issues when we have titles and textual actions that end up being quite long in other languages, as they end up merging together. Fixes #655 --- .../impl/addpeople/AddPeopleView.kt | 4 +- .../impl/configureroom/ConfigureRoomView.kt | 4 +- .../impl/root/CreateRoomRootView.kt | 4 +- .../location/impl/SendLocationView.kt | 4 +- .../location/impl/show/ShowLocationView.kt | 4 +- .../impl/forward/ForwardMessagesView.kt | 4 +- .../messages/impl/report/ReportMessageView.kt | 4 +- .../impl/edit/RoomDetailsEditView.kt | 4 +- .../impl/invite/RoomInviteMembersView.kt | 4 +- .../impl/members/RoomMemberListView.kt | 4 +- .../components/CenterAlignedTopAppBar.kt | 62 ------------------- 11 files changed, 20 insertions(+), 82 deletions(-) delete mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/CenterAlignedTopAppBar.kt 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..4f50f01e2c 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( 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/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/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/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") }) -} From 587117484e726988b1d537909615f5fdf7c25cb7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 6 Jul 2023 15:52:46 +0100 Subject: [PATCH 03/33] Room details: don't allow edits in DMs If the room is a DM, we won't allow any editing functionality regardless of power levels. If there is no topic set, then the entire section is hidden, like in rooms without a topic where you lack the power level to change it. Closes #799 --- .../roomdetails/impl/RoomDetailsPresenter.kt | 28 ++++----- .../roomdetails/RoomDetailsPresenterTests.kt | 58 +++++++++++++++++++ 2 files changed, 68 insertions(+), 18 deletions(-) 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/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..60e8d248b5 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 @@ -173,6 +173,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 { From 8eabb3bd941e4b85e801eb428231cbd11146e707 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 6 Jul 2023 16:22:49 +0100 Subject: [PATCH 04/33] Add test for leaving rooms Completely unrelated to what I was doing, but might appease the code coverage gods? --- .../roomdetails/RoomDetailsPresenterTests.kt | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) 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 60e8d248b5..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 @@ -305,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( From 03a80292e575813cd83825b300fae8a6ac9f21a5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 15:14:53 +0200 Subject: [PATCH 05/33] ignore typo. --- .idea/dictionaries/shared.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.idea/dictionaries/shared.xml b/.idea/dictionaries/shared.xml index dc5f8f7504..fd825db3f0 100644 --- a/.idea/dictionaries/shared.xml +++ b/.idea/dictionaries/shared.xml @@ -8,6 +8,7 @@ onboarding placeables showkase + snackbar textfields From 31ed77e79c5fb0d6d92f78760c30a3a4f47b236b Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 7 Jul 2023 13:24:14 +0000 Subject: [PATCH 06/33] Update screenshots --- ...roup_AddPeopleViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...roup_AddPeopleViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...oup_AddPeopleViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...oup_AddPeopleViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._ConfigureRoomViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._ConfigureRoomViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ConfigureRoomViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ConfigureRoomViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...reateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...p_ShowLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...p_ShowLocationViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...p_ShowLocationViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._ShowLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._ShowLocationViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._ShowLocationViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 2 +- ...p_SendLocationViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._SendLocationViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...orwardMessagesViewDarkPreview_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...rwardMessagesViewLightPreview_0_null_7,NEXUS_5,1.0,en].png | 4 ++-- ..._ReportMessageViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._ReportMessageViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._ReportMessageViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._ReportMessageViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._ReportMessageViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...ReportMessageViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...ReportMessageViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...ReportMessageViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...ReportMessageViewLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...ReportMessageViewLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...oomDetailsEditViewDarkPreview_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...omDetailsEditViewLightPreview_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ..._RoomInviteMembersDarkPreview_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_1,NEXUS_5,1.0,en].png | 2 +- ...RoomInviteMembersLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_4,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_5,NEXUS_5,1.0,en].png | 4 ++-- ...RoomInviteMembersLightPreview_0_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...oup_RoomMemberListDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...oup_RoomMemberListDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...oup_RoomMemberListDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...oup_RoomMemberListDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...up_RoomMemberListLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...up_RoomMemberListLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...up_RoomMemberListLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...up_RoomMemberListLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...s_CenterAlignedTopAppBarPreview_0_null,NEXUS_5,1.0,en].png | 3 --- 79 files changed, 154 insertions(+), 157 deletions(-) delete mode 100644 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 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..b1f8fcafbb 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:ccbfe7657d6c99f776e115a6b891e7aea332fc5918f4b31876754b6dbbeb897e +size 21447 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..de01520271 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:4cafa7cca7251f4d629660278dd756621e1d1d0726f7a14b19a68b50cc5dcc15 +size 23052 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.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 From af323d863655a76f9ada103e75cf4ec123baa985 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 15:34:15 +0200 Subject: [PATCH 07/33] Show Snackbar once the verification is finish in the correct screen (#812) --- .../impl/root/PreferencesRootPresenter.kt | 8 +++++++- .../impl/root/PreferencesRootState.kt | 4 +++- .../impl/root/PreferencesRootStateProvider.kt | 5 ++++- .../impl/root/PreferencesRootView.kt | 17 ++++++++++++++++- .../components/preferences/PreferenceScreen.kt | 2 ++ 5 files changed, 32 insertions(+), 4 deletions(-) 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..745e001b6d 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,9 @@ 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.MaterialTheme +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 +42,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 +59,22 @@ 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, + containerColor = MaterialTheme.colorScheme.surfaceVariant, + contentColor = MaterialTheme.colorScheme.primary + ) + } + } ) { UserPreferences(state.myUser) if (state.showCompleteVerification) { 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 From 7fef7552343c1dfb198df0985c65c607ca32ac29 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 15:35:16 +0200 Subject: [PATCH 08/33] Use the CoroutineScope from the LaunchedEffect. --- .../element/android/libraries/designsystem/utils/Snackbar.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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..ce1181887e 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 @@ -69,14 +69,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, From cd469e67bd512b2bebb37e0cd18e5f7a29d7a9cb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 15:39:43 +0200 Subject: [PATCH 09/33] Fix Snackbar colors. --- .../features/preferences/impl/root/PreferencesRootView.kt | 3 --- .../io/element/android/features/roomlist/impl/RoomListView.kt | 2 -- 2 files changed, 5 deletions(-) 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 745e001b6d..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,7 +24,6 @@ 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.MaterialTheme import androidx.compose.material3.Snackbar import androidx.compose.material3.SnackbarHost import androidx.compose.runtime.Composable @@ -70,8 +69,6 @@ fun PreferencesRootView( SnackbarHost(snackbarHostState) { data -> Snackbar( snackbarData = data, - containerColor = MaterialTheme.colorScheme.surfaceVariant, - contentColor = MaterialTheme.colorScheme.primary ) } } 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 ) } }, From eea92b9d3676dcc60dcc47b0c4c380359fc61205 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Fri, 7 Jul 2023 14:45:35 +0100 Subject: [PATCH 10/33] Create room: close icon should be on the left This is a navigation icon, which goes on the LHS of the top bar. --- .../android/features/createroom/impl/root/CreateRoomRootView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4f50f01e2c..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 @@ -142,7 +142,7 @@ fun CreateRoomRootViewTopBar( fontWeight = FontWeight.SemiBold, ) }, - actions = { + navigationIcon = { IconButton(onClick = onClosePressed) { Icon( imageVector = Icons.Default.Close, From 8940ba1714ba73c597dc6785c2b2f34b13daa325 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 7 Jul 2023 13:56:16 +0000 Subject: [PATCH 11/33] Update screenshots --- ...CreateRoomRootViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...reateRoomRootViewLightPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) 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 b1f8fcafbb..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:ccbfe7657d6c99f776e115a6b891e7aea332fc5918f4b31876754b6dbbeb897e -size 21447 +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 de01520271..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:4cafa7cca7251f4d629660278dd756621e1d1d0726f7a14b19a68b50cc5dcc15 -size 23052 +oid sha256:18a343f9fce08b0ff9e12f22e1c8e4efb6f16b3eac886675c9534d088dbe3f80 +size 23098 From 4b90904bc0b9f8685275206ebd9af5fa2b952c05 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 16:15:59 +0200 Subject: [PATCH 12/33] Cleanup --- .../io/element/android/libraries/designsystem/utils/Snackbar.kt | 1 - 1 file changed, 1 deletion(-) 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 ce1181887e..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 From 6eab2ea6947d62410540c5bfaddfedca381a95fe Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 16:22:42 +0200 Subject: [PATCH 13/33] Fix test. --- .../preferences/impl/root/PreferencesRootPresenterTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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() From 3c6f658a1fb6d4de866387775a14efc7b19b708c Mon Sep 17 00:00:00 2001 From: jonnyandrew Date: Sat, 8 Jul 2023 17:53:29 +0100 Subject: [PATCH 14/33] Truncate and ellipsize long reactions (#821) * Truncate and ellipsize long reactions * Update screenshots --------- Co-authored-by: ElementBot --- changelog.d/821.bugfix | 1 + .../components/MessagesReactionButton.kt | 13 ++++- .../impl/timeline/model/AggregatedReaction.kt | 24 +++++++- .../timeline/model/AggregatedReactionTest.kt | 34 +++++++++++ .../core/extensions/BasicExtensions.kt | 15 +++++ .../core/extensions/BasicExtensionsTest.kt | 56 +++++++++++++++++++ ...nPreview-D-1_2_null_0,NEXUS_5,1.0,en].png} | 0 ...nPreview-D-1_2_null_1,NEXUS_5,1.0,en].png} | 0 ...nPreview-D-1_2_null_2,NEXUS_5,1.0,en].png} | 0 ...nPreview-D-1_2_null_3,NEXUS_5,1.0,en].png} | 0 ...nPreview-N-1_3_null_0,NEXUS_5,1.0,en].png} | 0 ...nPreview-N-1_3_null_1,NEXUS_5,1.0,en].png} | 0 ...nPreview-N-1_3_null_2,NEXUS_5,1.0,en].png} | 0 ...nPreview-N-1_3_null_3,NEXUS_5,1.0,en].png} | 0 ...tonsPreview-D-1_2_null,NEXUS_5,1.0,en].png | 3 - ...tonsPreview-D-2_3_null,NEXUS_5,1.0,en].png | 3 + ...tonsPreview-N-1_3_null,NEXUS_5,1.0,en].png | 3 - ...tonsPreview-N-2_4_null,NEXUS_5,1.0,en].png | 3 + ...sedPreview-D-4_5_null,NEXUS_5,1.0,en].png} | 0 ...sedPreview-N-4_6_null,NEXUS_5,1.0,en].png} | 0 ...dedPreview-D-5_6_null,NEXUS_5,1.0,en].png} | 0 ...dedPreview-N-5_7_null,NEXUS_5,1.0,en].png} | 0 ...iewPreview-D-3_4_null,NEXUS_5,1.0,en].png} | 0 ...iewPreview-N-3_5_null,NEXUS_5,1.0,en].png} | 0 24 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 changelog.d/821.bugfix create mode 100644 features/messages/impl/src/test/kotlin/io/element/android/features/messages/timeline/model/AggregatedReactionTest.kt create mode 100644 libraries/core/src/test/kotlin/io/element/android/libraries/core/extensions/BasicExtensionsTest.kt rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-1_2_null_0,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-1_2_null_1,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-1_2_null_2,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-D-1_2_null_3,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-1_3_null_0,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-1_3_null_1,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-1_3_null_2,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_MessagesReactionButtonPreview-N-1_3_null_3,NEXUS_5,1.0,en].png} (100%) delete mode 100644 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 create mode 100644 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-2_3_null,NEXUS_5,1.0,en].png delete mode 100644 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 create mode 100644 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-2_4_null,NEXUS_5,1.0,en].png rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-D-4_5_null,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewCollapsedPreview-N-4_6_null,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-D-5_6_null,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewExpandedPreview-N-5_7_null,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-D-3_4_null,NEXUS_5,1.0,en].png} (100%) rename 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 => io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.messages.impl.timeline.components_null_DefaultGroup_TimelineItemReactionsViewPreview-N-3_5_null,NEXUS_5,1.0,en].png} (100%) 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/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/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/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/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/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-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.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-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.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-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.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-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.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-1_2_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-1_2_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-1_2_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-1_2_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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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_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-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_MessagesReactionExtraButtonsPreview-D-2_3_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-2_3_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-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_MessagesReactionExtraButtonsPreview-N-2_4_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-2_4_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_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-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_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-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_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-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_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-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.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-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_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-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_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-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_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-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_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-3_4_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-3_4_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-3_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-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-3_5_null,NEXUS_5,1.0,en].png From fd6cf1d7fda5689df5395083d1c14e3204421f7a Mon Sep 17 00:00:00 2001 From: bmarty Date: Mon, 10 Jul 2023 00:11:05 +0000 Subject: [PATCH 15/33] Sync Strings from Localazy --- .../impl/src/main/res/values-cs/translations.xml | 1 + .../impl/src/main/res/values-de/translations.xml | 1 + .../impl/src/main/res/values-ro/translations.xml | 1 + .../impl/src/main/res/values-sk/translations.xml | 1 + .../impl/src/main/res/values-de/translations.xml | 3 +++ .../impl/src/main/res/values-sk/translations.xml | 3 +++ .../messages/impl/src/main/res/values/localazy.xml | 5 ----- .../impl/src/main/res/values-de/translations.xml | 2 +- .../impl/src/main/res/values-sk/translations.xml | 2 +- .../impl/src/main/res/values-sk/translations.xml | 4 ++-- .../src/main/res/values-de/translations.xml | 9 +++++++++ .../src/main/res/values-sk/translations.xml | 14 ++++++++++++++ .../ui-strings/src/main/res/values/localazy.xml | 6 ------ 13 files changed, 37 insertions(+), 15 deletions(-) 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/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..5ba6a2ebd8 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -4,11 +4,6 @@ "%1$d room change" "%1$d room changes" - "Show less" - - "%1$d more" - - "Add emoji" "Camera" "Take photo" "Record a video" 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/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/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." From 3436d743687323095f970fc9b2b802cc3097f4b1 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 10 Jul 2023 09:42:34 +0200 Subject: [PATCH 16/33] Update screenshots (#831) Co-authored-by: ElementBot --- ...essagesReactionButtonPreview-D-2_3_null_0,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-D-2_3_null_1,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-D-2_3_null_2,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-D-2_3_null_3,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-N-2_4_null_0,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-N-2_4_null_1,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-N-2_4_null_2,NEXUS_5,1.0,en].png} | 0 ...essagesReactionButtonPreview-N-2_4_null_3,NEXUS_5,1.0,en].png} | 0 ...gesReactionExtraButtonsPreview-D-3_4_null,NEXUS_5,1.0,en].png} | 0 ...gesReactionExtraButtonsPreview-N-3_5_null,NEXUS_5,1.0,en].png} | 0 ...mReactionsViewCollapsedPreview-D-5_6_null,NEXUS_5,1.0,en].png} | 0 ...mReactionsViewCollapsedPreview-N-5_7_null,NEXUS_5,1.0,en].png} | 0 ...emReactionsViewExpandedPreview-D-6_7_null,NEXUS_5,1.0,en].png} | 0 ...emReactionsViewExpandedPreview-N-6_8_null,NEXUS_5,1.0,en].png} | 0 ...melineItemReactionsViewPreview-D-4_5_null,NEXUS_5,1.0,en].png} | 0 ...melineItemReactionsViewPreview-N-4_6_null,NEXUS_5,1.0,en].png} | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename 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-1_2_null_0,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_2_null_1,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_2_null_2,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_2_null_3,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_3_null_0,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_3_null_1,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_3_null_2,NEXUS_5,1.0,en].png => 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} (100%) rename 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-1_3_null_3,NEXUS_5,1.0,en].png => 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} (100%) rename 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-2_3_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-2_4_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-4_5_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-4_6_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-5_6_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-5_7_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-3_4_null,NEXUS_5,1.0,en].png => 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} (100%) rename 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-3_5_null,NEXUS_5,1.0,en].png => 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} (100%) 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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-1_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-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-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.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-1_3_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-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.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-1_3_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-1_3_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-1_3_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-1_3_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-1_3_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-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_MessagesReactionExtraButtonsPreview-D-3_4_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_MessagesReactionExtraButtonsPreview-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_MessagesReactionExtraButtonsPreview-D-3_4_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_MessagesReactionExtraButtonsPreview-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_MessagesReactionExtraButtonsPreview-N-3_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_MessagesReactionExtraButtonsPreview-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_MessagesReactionExtraButtonsPreview-N-3_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_TimelineItemReactionsViewCollapsedPreview-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_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-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_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-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_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-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_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-5_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-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-5_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-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-5_7_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-5_7_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-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_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-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_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-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_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-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_TimelineItemReactionsViewPreview-N-4_6_null,NEXUS_5,1.0,en].png From c0df303c22a2249ac3b46c8fea5f110edd150f6e Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 10 Jul 2023 10:10:22 +0200 Subject: [PATCH 17/33] Make Showkase browser work in the nightly versions (#829) --- libraries/designsystem/build.gradle.kts | 7 +++++++ libraries/designsystem/proguard-rules.pro | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) 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 { } From 4d8c929ad36e1cc496935819d34b2b08b4fe7469 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 10 Jul 2023 10:45:02 +0200 Subject: [PATCH 18/33] Remove extra `syncService.startSync()` call (#830) --- .../main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt | 1 - 1 file changed, 1 deletion(-) 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..f10d3e0f31 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -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) From 3e69985fd6bb98ecf7b038355396b249aa075298 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Mon, 10 Jul 2023 10:45:11 +0200 Subject: [PATCH 19/33] Use @DayNightPreviews for static map (#832) * Use @DayNightPreviews for static map To properly screenshot the dark pin. * Update screenshots --------- Co-authored-by: ElementBot --- .../features/location/api/StaticMapView.kt | 18 ++++----------- .../api/internal/StaticMapPlaceholder.kt | 22 +++++-------------- ...erDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 3 --- ...erDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 3 --- ...rPreview-D-1_2_null_0,NEXUS_5,1.0,en].png} | 0 ...rPreview-D-1_2_null_1,NEXUS_5,1.0,en].png} | 0 ...erPreview-N-1_3_null_0,NEXUS_5,1.0,en].png | 3 +++ ...erPreview-N-1_3_null_1,NEXUS_5,1.0,en].png | 3 +++ ...ViewDarkPreview_0_null,NEXUS_5,1.0,en].png | 3 --- ...iewPreview-D-0_1_null,NEXUS_5,1.0,en].png} | 0 ...ViewPreview-N-0_2_null,NEXUS_5,1.0,en].png | 3 +++ 11 files changed, 19 insertions(+), 39 deletions(-) delete mode 100644 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 delete mode 100644 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 rename 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 => 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} (100%) rename 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 => 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} (100%) create mode 100644 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 create mode 100644 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 delete mode 100644 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 rename 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 => 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} (100%) create mode 100644 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 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/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 From aa7db3150dda4eda490fe7fde9c41425ce773aca Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 18:54:08 +0200 Subject: [PATCH 20/33] Fix bad modifier parameter usage. --- .../components/TimelineItemEventRow.kt | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) 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..815c3a753c 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 @@ -121,56 +121,57 @@ fun TimelineItemEventRow( inReplyToClick(inReplyToEventId) } - if (canReply) { - val dismissState = rememberDismissState( - confirmValueChange = { - if (it == DismissValue.DismissedToEnd) { - onSwipeToReply() + Column(modifier = modifier.fillMaxWidth()) { + if (canReply) { + val dismissState = rememberDismissState( + confirmValueChange = { + if (it == DismissValue.DismissedToEnd) { + onSwipeToReply() + } + // Do not dismiss the message, return false! + false } - // 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) }, - ) - } - // 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)) + ) + 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) }, + ) + } + if (event.groupPosition.isNew()) { + Spacer(modifier = Modifier.height(16.dp)) + } else { + Spacer(modifier = Modifier.height(2.dp)) + } } } From 1bc13d16d9524d945a38b7c561daf0694611ab0e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 7 Jul 2023 19:06:19 +0200 Subject: [PATCH 21/33] Improve animation of Swipe to reply: replace usage of SwipeToDismiss by Modifier.draggable --- .../components/TimelineItemEventRow.kt | 116 ++++++++---------- .../swipe/SwipeableActionsState.kt | 75 +++++++++++ 2 files changed, 127 insertions(+), 64 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/swipe/SwipeableActionsState.kt 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 815c3a753c..6152a752cf 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,15 +36,10 @@ 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.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -55,6 +51,7 @@ 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 @@ -78,6 +75,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 +93,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 +113,7 @@ fun TimelineItemEventRow( onSwipeToReply: () -> Unit, modifier: Modifier = Modifier ) { + val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } fun onUserDataClicked() { @@ -123,54 +127,47 @@ fun TimelineItemEventRow( Column(modifier = modifier.fillMaxWidth()) { if (canReply) { - val dismissState = rememberDismissState( - confirmValueChange = { - if (it == DismissValue.DismissedToEnd) { - onSwipeToReply() - } - // Do not dismiss the message, return false! - false + val state: SwipeableActionsState = rememberSwipeableActionsState() + val offset = state.offset.value + val swipeThresholdPx = 40.dp.toPx() + val thresholdCrossed = abs(offset) > swipeThresholdPx + Box(Modifier.fillMaxWidth()) { + Row(modifier = Modifier.matchParentSize()) { + ReplySwipeIndicator({ offset / 120 }) } - ) - 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) }, - ) - } - if (event.groupPosition.isNew()) { - Spacer(modifier = Modifier.height(16.dp)) - } else { - Spacer(modifier = Modifier.height(2.dp)) + 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) }, + ) + } + if (event.groupPosition.isNew()) { + Spacer(modifier = Modifier.height(16.dp)) + } else { + Spacer(modifier = Modifier.height(2.dp)) + } } } } @@ -267,14 +264,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, @@ -700,7 +689,6 @@ private fun ContentTimestampToPreview(event: TimelineItem.Event) { } } - @Preview @Composable internal fun TimelineItemEventRowWithManyReactionsLightPreview() = 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 + } + } + } +} From 1c7c8e6c9a0541b91da202b9dec5072215f61946 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 10:36:28 +0200 Subject: [PATCH 22/33] Add missing content when canReply is false. --- .../components/TimelineItemEventRow.kt | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) 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 6152a752cf..34f088397f 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 @@ -163,11 +163,24 @@ fun TimelineItemEventRow( onMoreReactionsClicked = { onMoreReactionsClick(event) }, ) } - if (event.groupPosition.isNew()) { - Spacer(modifier = Modifier.height(16.dp)) - } else { - Spacer(modifier = Modifier.height(2.dp)) - } + } 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) }, + ) + } + if (event.groupPosition.isNew()) { + Spacer(modifier = Modifier.height(16.dp)) + } else { + Spacer(modifier = Modifier.height(2.dp)) } } } From 02dd796d830c50cfceb6c0e510bc23d4569cc280 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 10:46:36 +0200 Subject: [PATCH 23/33] Space must be above the item. --- .../impl/timeline/components/TimelineItemEventRow.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 34f088397f..45f001c1b4 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 @@ -126,6 +126,11 @@ fun TimelineItemEventRow( } 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 @@ -177,11 +182,6 @@ fun TimelineItemEventRow( onMoreReactionsClicked = { onMoreReactionsClick(event) }, ) } - if (event.groupPosition.isNew()) { - Spacer(modifier = Modifier.height(16.dp)) - } else { - Spacer(modifier = Modifier.height(2.dp)) - } } } From dca5ee80514f6f034d66717845d2b8297627cda3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 10:50:54 +0200 Subject: [PATCH 24/33] Improve preview rendering. --- .../impl/timeline/components/TimelineItemEventRow.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 45f001c1b4..02eb7404ad 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 @@ -63,6 +63,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 @@ -547,6 +548,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, @@ -565,6 +567,7 @@ private fun ContentToPreview() { content = aTimelineItemImageContent().copy( aspectRatio = 5f ), + groupPosition = TimelineItemGroupPosition.Last, ), isHighlighted = false, canReply = true, @@ -609,7 +612,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, @@ -628,7 +632,8 @@ private fun ContentToPreviewWithReply() { content = aTimelineItemImageContent().copy( aspectRatio = 5f ), - inReplyTo = aInReplyToReady(replyContent) + inReplyTo = aInReplyToReady(replyContent), + groupPosition = TimelineItemGroupPosition.Last, ), isHighlighted = false, canReply = true, From 3e0b9822f0f9577b93057b886d38c9c495be475e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 11:54:44 +0200 Subject: [PATCH 25/33] Attempt to reduce swipe sensitivity (#810) --- .../components/TimelineItemEventRow.kt | 88 ++++++++++++------- 1 file changed, 58 insertions(+), 30 deletions(-) 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 02eb7404ad..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 @@ -38,6 +38,7 @@ import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme 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 @@ -45,6 +46,8 @@ 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 @@ -137,37 +140,39 @@ fun TimelineItemEventRow( val offset = state.offset.value val swipeThresholdPx = 40.dp.toPx() val thresholdCrossed = abs(offset) > swipeThresholdPx - 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() + 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.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) }, - ) + }, + 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) }, + ) + } } } else { TimelineItemEventRowContent( @@ -186,6 +191,29 @@ fun TimelineItemEventRow( } } +/** + * 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() + } +} + @Composable private fun TimelineItemEventRowContent( event: TimelineItem.Event, From 5b9966f33c574cff777fb90e4f8903f0ed8fc4ac Mon Sep 17 00:00:00 2001 From: ElementBot Date: Mon, 10 Jul 2023 10:12:38 +0000 Subject: [PATCH 26/33] Update screenshots --- ...TimelineItemEventRowDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...imelineItemEventRowLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...mEventRowTimestampDarkPreview_0_null_0,NEXUS_5,1.0,en].png | 4 ++-- ...mEventRowTimestampDarkPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...mEventRowTimestampDarkPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...mEventRowTimestampDarkPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...EventRowTimestampLightPreview_0_null_0,NEXUS_5,1.0,en].png | 2 +- ...EventRowTimestampLightPreview_0_null_1,NEXUS_5,1.0,en].png | 4 ++-- ...EventRowTimestampLightPreview_0_null_2,NEXUS_5,1.0,en].png | 4 ++-- ...EventRowTimestampLightPreview_0_null_3,NEXUS_5,1.0,en].png | 4 ++-- ...RowWithManyReactionsDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...owWithManyReactionsLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...temEventRowWithReplyDarkPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...emEventRowWithReplyLightPreview_0_null,NEXUS_5,1.0,en].png | 4 ++-- 14 files changed, 27 insertions(+), 27 deletions(-) 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 From 6ee4056ccaf66161eb4f3f4edd0236553dd1e1a6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 12:14:25 +0200 Subject: [PATCH 27/33] Sync again after adding missing value in Localazy. --- features/messages/impl/src/main/res/values/localazy.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index 5ba6a2ebd8..03ac9ea46b 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -4,6 +4,9 @@ "%1$d room change" "%1$d room changes" + + "%1$d more" + "Camera" "Take photo" "Record a video" @@ -20,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" From 73fa6fc6beefa0ec13a8f25f2ea94f7eb66637a3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 12:15:41 +0200 Subject: [PATCH 28/33] Remove the legacy script which imports Strigns from Element Android project. --- tools/strings/importStringsFromElement.sh | 57 ----------------------- 1 file changed, 57 deletions(-) delete mode 100755 tools/strings/importStringsFromElement.sh 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" From fa9c5a7ccc089733add8ac1fa5791bb93bca6528 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 13:02:19 +0200 Subject: [PATCH 29/33] avoid typo report --- .idea/dictionaries/shared.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.idea/dictionaries/shared.xml b/.idea/dictionaries/shared.xml index fd825db3f0..abe4b190df 100644 --- a/.idea/dictionaries/shared.xml +++ b/.idea/dictionaries/shared.xml @@ -9,6 +9,7 @@ placeables showkase snackbar + swipeable textfields From c3ddc628a4a2dbacb56b37c87c9444788946e8f2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 10 Jul 2023 13:03:55 +0200 Subject: [PATCH 30/33] Add exepction for SwipeableActionsState. --- build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle.kts b/build.gradle.kts index 40f0b8706c..b5d082b8ce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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 From 785c4a52f1db455bc5508833e5f7778b2e103e2b Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 10 Jul 2023 13:08:55 +0200 Subject: [PATCH 31/33] Sync: should avoid having multiple sync loops --- .../matrix/impl/sync/RustSyncService.kt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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..3ce188a0b7 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,12 @@ class RustSyncService( roomListService .stateFlow() .map(RoomListServiceState::toSyncState) + .onEach { state -> + Timber.v("Sync state=$state") + if (state == SyncState.InError || state == SyncState.Terminated) { + isSyncing.set(false) + } + } .distinctUntilChanged() - .stateIn(sessionCoroutineScope, SharingStarted.WhileSubscribed(), SyncState.Idle) + .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle) } From 65210b72f5a7415d50f4a454a24bf4579d708938 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 10 Jul 2023 13:24:54 +0200 Subject: [PATCH 32/33] Sync: add more safety to avoid some race conditions --- .../android/libraries/matrix/impl/sync/RustSyncService.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 3ce188a0b7..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 @@ -58,9 +58,7 @@ class RustSyncService( .map(RoomListServiceState::toSyncState) .onEach { state -> Timber.v("Sync state=$state") - if (state == SyncState.InError || state == SyncState.Terminated) { - isSyncing.set(false) - } + isSyncing.set(state == SyncState.Syncing) } .distinctUntilChanged() .stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle) From a0c1f2c18a5cfdce2408b4af6782271b38c9d6d4 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 10 Jul 2023 14:34:58 +0200 Subject: [PATCH 33/33] Display room invitation notification (#735) * Notifications: Add some extra mappings so we keep the original contents and can pass it later to an UI layer * Fix notifications not appearing for a room if the app was on that room when it went to background. * Modernize how we create spannable strings for notifications, remove unneeded dependency * Remove actions from invite notifications temporarily * Add `NotificationDrawerManager` interface to be able to clear membership notifications when accepting or rejecting a room invite * Fix tests * Add comment to clarify some weird behaviours * Address review comments * Set circle shape for `largeBitmap` in message notifications * Fix no avatar in DM rooms * Fix rebase issues * Add invite list pending intent: - Refactor pending intents. - Make `DeepLinkData` a sealed interface. - Fix and add tests. * Rename `navigate__` functions to `attach__` * Add an extra test case for the `InviteList` deep link * Address most review comments. * Fix rebase issue * Add fallback notification type, allow dismissing invite notifications. Fallback notifications have a different underlying type and can be dismissed at will. * Fix tests --- app/src/main/AndroidManifest.xml | 6 +- .../element/android/x/ElementXApplication.kt | 2 +- .../android/x/intent/IntentProviderImpl.kt | 11 +- .../android/appnav/LoggedInFlowNode.kt | 15 +- .../io/element/android/appnav/RootFlowNode.kt | 11 +- .../android/appnav/intent/IntentResolver.kt | 2 + features/invitelist/impl/build.gradle.kts | 2 + .../invitelist/impl/InviteListPresenter.kt | 7 +- .../impl/InviteListPresenterTests.kt | 76 +++--- gradle/libs.versions.toml | 1 - .../android/libraries/deeplink/Constants.kt | 4 + .../libraries/deeplink/DeepLinkCreator.kt | 11 +- .../libraries/deeplink/DeeplinkData.kt | 18 +- .../libraries/deeplink/DeeplinkParser.kt | 24 +- .../libraries/deeplink/DeepLinkCreatorTest.kt | 15 +- .../libraries/deeplink/DeeplinkParserTest.kt | 10 +- .../api/notification/NotificationData.kt | 57 ++++- .../impl/notification/NotificationMapper.kt | 24 +- .../notification/RustNotificationService.kt | 3 +- .../impl/notification/TimelineEventMapper.kt | 101 ++++---- .../timeline/item/event/EventMessageMapper.kt | 63 +++-- .../NotificationDrawerManager.kt | 25 ++ libraries/push/impl/build.gradle.kts | 5 +- .../libraries/push/impl/DefaultPushService.kt | 7 +- .../libraries/push/impl/di/PushBindsModule.kt | 33 +++ .../push/impl/intent/IntentProvider.kt | 9 +- ...kt => DefaultNotificationDrawerManager.kt} | 31 ++- .../notifications/NotifiableEventProcessor.kt | 12 +- .../notifications/NotifiableEventResolver.kt | 228 +++++++++++++----- .../notifications/NotificationActionIds.kt | 2 + .../notifications/NotificationBitmapLoader.kt | 1 + .../NotificationBroadcastReceiver.kt | 21 +- .../notifications/NotificationEventQueue.kt | 17 +- .../impl/notifications/NotificationFactory.kt | 21 ++ .../notifications/NotificationIdProvider.kt | 5 + .../notifications/NotificationRenderer.kt | 40 ++- .../impl/notifications/NotificationState.kt | 4 +- .../notifications/RoomGroupMessageCreator.kt | 33 +-- .../SummaryGroupMessageCreator.kt | 2 + .../factories/NotificationFactory.kt | 62 +++-- .../factories/PendingIntentFactory.kt | 46 +++- .../model/FallbackNotifiableEvent.kt | 37 +++ .../model/InviteNotifiableEvent.kt | 4 +- .../notifications/model/NotifiableEvent.kt | 1 + .../model/NotifiableMessageEvent.kt | 17 +- .../model/SimpleNotifiableEvent.kt | 2 +- .../push/impl/push/DefaultPushHandler.kt | 10 +- .../impl/src/main/res/values/localazy.xml | 2 +- .../NotifiableEventProcessorTest.kt | 2 + .../NotificationEventQueueTest.kt | 2 +- .../notifications/NotificationRendererTest.kt | 6 +- .../fake/FakeNotificationFactory.kt | 3 + libraries/push/test/build.gradle.kts | 29 +++ .../FakeNotificationDrawerManager.kt | 48 ++++ settings.gradle.kts | 2 - 55 files changed, 905 insertions(+), 327 deletions(-) create mode 100644 libraries/push/api/src/main/kotlin/io/element/android/libraries/push/api/notifications/NotificationDrawerManager.kt create mode 100644 libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/di/PushBindsModule.kt rename libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/{NotificationDrawerManager.kt => DefaultNotificationDrawerManager.kt} (91%) create mode 100644 libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/FallbackNotifiableEvent.kt create mode 100644 libraries/push/test/build.gradle.kts create mode 100644 libraries/push/test/src/main/kotlin/io/element/android/libraries/push/test/notifications/FakeNotificationDrawerManager.kt 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 f10d3e0f31..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( @@ -340,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/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/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9038c7a72a..a5c98b7f3c 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/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/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/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/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") }