From 1012272a0831ed9809fc73ecfffa8d160b139d39 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 18 Nov 2024 15:52:16 +0100 Subject: [PATCH 01/47] Fix long click not working for media timeline items (#3879) --- .../impl/pinned/list/PinnedMessagesListView.kt | 1 + .../timeline/components/ATimelineItemEventRow.kt | 2 +- .../timeline/components/TimelineItemEventRow.kt | 16 +++++++--------- .../components/TimelineItemGroupedEventsRow.kt | 6 ++++-- .../impl/timeline/components/TimelineItemRow.kt | 3 ++- .../components/TimelineItemStateEventRow.kt | 3 ++- .../event/TimelineItemEventContentView.kt | 7 +++++-- .../components/event/TimelineItemImageView.kt | 11 ++++++++--- .../components/event/TimelineItemLocationView.kt | 5 +---- .../components/event/TimelineItemStickerView.kt | 10 +++++++--- .../components/event/TimelineItemVideoView.kt | 11 ++++++++--- 11 files changed, 46 insertions(+), 29 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt index 7ae88b9647..35a0a1e893 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/pinned/list/PinnedMessagesListView.kt @@ -265,6 +265,7 @@ private fun TimelineItemEventContentViewWrapper( eventSink = { }, modifier = modifier, onContentClick = onContentClick, + onLongClick = null, onContentLayoutChange = onContentLayoutChange ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt index 85e9854919..02ef734ccc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt @@ -30,7 +30,7 @@ internal fun ATimelineItemEventRow( timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, isHighlighted = isHighlighted, - onContentClick = {}, + onEventClick = {}, onLongClick = {}, onLinkClick = {}, onUserDataClick = {}, 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 0061ebe6df..c358dcdd0a 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 @@ -114,7 +114,7 @@ fun TimelineItemEventRow( renderReadReceipts: Boolean, isLastOutgoingMessage: Boolean, isHighlighted: Boolean, - onContentClick: () -> Unit, + onEventClick: () -> Unit, onLongClick: () -> Unit, onLinkClick: (String) -> Unit, onUserDataClick: (UserId) -> Unit, @@ -127,10 +127,14 @@ fun TimelineItemEventRow( eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, modifier: Modifier = Modifier, eventContentView: @Composable (Modifier, (ContentAvoidingLayoutData) -> Unit) -> Unit = { contentModifier, onContentLayoutChange -> + // Only pass down a custom clickable lambda if the content can be clicked separately + val onContentClick = onEventClick.takeUnless { event.isWholeContentClickable } + TimelineItemEventContentView( content = event.content, hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), onContentClick = onContentClick, + onLongClick = onLongClick, onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onLinkClick = onLinkClick, eventSink = eventSink, @@ -151,12 +155,6 @@ fun TimelineItemEventRow( inReplyToClick(inReplyToEventId) } - val onWholeItemClick = if (event.isWholeContentClickable) { - onContentClick - } else { - {} - } - Column(modifier = modifier.fillMaxWidth()) { if (event.groupPosition.isNew()) { Spacer(modifier = Modifier.height(16.dp)) @@ -180,7 +178,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onWholeItemClick, + onContentClick = onEventClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, @@ -214,7 +212,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onWholeItemClick, + onContentClick = onEventClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt index fe89d6de02..d65c9186aa 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt @@ -61,7 +61,8 @@ fun TimelineItemGroupedEventsRow( onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, - onContentClick = {}, + onContentClick = null, + onLongClick = null, onContentLayoutChange = onContentLayoutChange ) }, @@ -126,7 +127,8 @@ private fun TimelineItemGroupedEventsRowContent( onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, - onContentClick = {}, + onContentClick = null, + onLongClick = null, onContentLayoutChange = onContentLayoutChange ) }, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 047f9b3d04..859c9f3ccf 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -61,6 +61,7 @@ internal fun TimelineItemRow( hideMediaContent = timelineProtectionState.hideMediaContent(event.eventId), onShowContentClick = { timelineProtectionState.eventSink(TimelineProtectionEvent.ShowContent(event.eventId)) }, onContentClick = { onContentClick(event) }, + onLongClick = { onLongClick(event) }, onLinkClick = onLinkClick, eventSink = eventSink, modifier = contentModifier, @@ -118,7 +119,7 @@ internal fun TimelineItemRow( timelineProtectionState = timelineProtectionState, isLastOutgoingMessage = isLastOutgoingMessage, isHighlighted = timelineItem.isEvent(focusedEventId), - onContentClick = { onContentClick(timelineItem) }, + onEventClick = { onContentClick(timelineItem) }, onLongClick = { onLongClick(timelineItem) }, onLinkClick = onLinkClick, onUserDataClick = onUserDataClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt index 6172686016..d523152977 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemStateEventRow.kt @@ -74,7 +74,8 @@ fun TimelineItemStateEventRow( hideMediaContent = false, onShowContentClick = {}, eventSink = eventSink, - onContentClick = {}, + onContentClick = null, + onLongClick = null, modifier = Modifier.defaultTimelineContentPadding() ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt index 3a3a43a6fc..35a8cda293 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemEventContentView.kt @@ -36,7 +36,8 @@ import io.element.android.libraries.architecture.Presenter fun TimelineItemEventContentView( content: TimelineItemEventContent, hideMediaContent: Boolean, - onContentClick: () -> Unit, + onContentClick: (() -> Unit)?, + onLongClick: (() -> Unit)?, onShowContentClick: () -> Unit, onLinkClick: (url: String) -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, @@ -68,13 +69,13 @@ fun TimelineItemEventContentView( ) is TimelineItemLocationContent -> TimelineItemLocationView( content = content, - onContentClick = onContentClick, modifier = modifier ) is TimelineItemImageContent -> TimelineItemImageView( content = content, hideMediaContent = hideMediaContent, onContentClick = onContentClick, + onLongClick = onLongClick, onShowContentClick = onShowContentClick, onLinkClick = onLinkClick, onContentLayoutChange = onContentLayoutChange, @@ -84,6 +85,7 @@ fun TimelineItemEventContentView( content = content, hideMediaContent = hideMediaContent, onContentClick = onContentClick, + onLongClick = onLongClick, onShowClick = onShowContentClick, modifier = modifier, ) @@ -91,6 +93,7 @@ fun TimelineItemEventContentView( content = content, hideMediaContent = hideMediaContent, onContentClick = onContentClick, + onLongClick = onLongClick, onShowContentClick = onShowContentClick, onLinkClick = onLinkClick, onContentLayoutChange = onContentLayoutChange, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt index 123ba195f1..84b7026142 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt @@ -8,8 +8,9 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -55,11 +56,13 @@ import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.wysiwyg.compose.EditorStyledText +@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemImageView( content: TimelineItemImageContent, hideMediaContent: Boolean, - onContentClick: () -> Unit, + onContentClick: (() -> Unit)?, + onLongClick: (() -> Unit)?, onLinkClick: (String) -> Unit, onShowContentClick: () -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, @@ -87,7 +90,7 @@ fun TimelineItemImageView( modifier = Modifier .fillMaxWidth() .then(if (isLoaded) Modifier.background(Color.White) else Modifier) - .clickable(onClick = onContentClick), + .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier), model = content.thumbnailMediaRequestData, contentScale = ContentScale.Fit, alignment = Alignment.Center, @@ -132,6 +135,7 @@ internal fun TimelineItemImageViewPreview(@PreviewParameter(TimelineItemImageCon hideMediaContent = false, onShowContentClick = {}, onContentClick = {}, + onLongClick = {}, onLinkClick = {}, onContentLayoutChange = {}, ) @@ -145,6 +149,7 @@ internal fun TimelineItemImageViewHideMediaContentPreview() = ElementPreview { hideMediaContent = true, onShowContentClick = {}, onContentClick = {}, + onLongClick = {}, onLinkClick = {}, onContentLayoutChange = {}, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt index 5d402bc8f1..964f3ecb18 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemLocationView.kt @@ -7,7 +7,6 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn @@ -26,10 +25,9 @@ import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemLocationView( content: TimelineItemLocationContent, - onContentClick: () -> Unit, modifier: Modifier = Modifier, ) { - Column(modifier = modifier.clickable(onClick = onContentClick).fillMaxWidth()) { + Column(modifier = modifier.fillMaxWidth()) { content.description?.let { Text( text = it, @@ -55,6 +53,5 @@ internal fun TimelineItemLocationViewPreview(@PreviewParameter(TimelineItemLocat ElementPreview { TimelineItemLocationView( content = content, - onContentClick = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt index df087769ed..9037d0dffa 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt @@ -7,8 +7,9 @@ package io.element.android.features.messages.impl.timeline.components.event +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable @@ -37,11 +38,13 @@ import io.element.android.libraries.ui.strings.CommonStrings private const val STICKER_SIZE_IN_DP = 128 +@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemStickerView( content: TimelineItemStickerContent, hideMediaContent: Boolean, - onContentClick: () -> Unit, + onContentClick: (() -> Unit)?, + onLongClick: (() -> Unit)?, onShowClick: () -> Unit, modifier: Modifier = Modifier, ) { @@ -64,7 +67,7 @@ fun TimelineItemStickerView( modifier = Modifier .fillMaxSize() .then(if (isLoaded) Modifier.background(Color.White) else Modifier) - .clickable(onClick = onContentClick), + .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier), model = MediaRequestData( source = content.preferredMediaSource, kind = MediaRequestData.Kind.File( @@ -89,6 +92,7 @@ internal fun TimelineItemStickerViewPreview(@PreviewParameter(TimelineItemSticke content = content, hideMediaContent = false, onContentClick = {}, + onLongClick = {}, onShowClick = {}, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index 65f59cd631..afd45b171a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -8,9 +8,10 @@ package io.element.android.features.messages.impl.timeline.components.event import android.text.SpannedString +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -64,11 +65,13 @@ import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.wysiwyg.compose.EditorStyledText +@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineItemVideoView( content: TimelineItemVideoContent, hideMediaContent: Boolean, - onContentClick: () -> Unit, + onContentClick: (() -> Unit)?, + onLongClick: (() -> Unit)?, onShowContentClick: () -> Unit, onLinkClick: (String) -> Unit, onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, @@ -99,7 +102,7 @@ fun TimelineItemVideoView( modifier = Modifier .fillMaxWidth() .then(if (isLoaded) Modifier.background(Color.White) else Modifier) - .clickable(onClick = onContentClick), + .then(if (onContentClick != null) Modifier.combinedClickable(onClick = onContentClick, onLongClick = onLongClick) else Modifier), model = MediaRequestData( source = content.thumbnailSource, kind = MediaRequestData.Kind.Thumbnail( @@ -161,6 +164,7 @@ internal fun TimelineItemVideoViewPreview(@PreviewParameter(TimelineItemVideoCon hideMediaContent = false, onShowContentClick = {}, onContentClick = {}, + onLongClick = {}, onLinkClick = {}, onContentLayoutChange = {}, ) @@ -174,6 +178,7 @@ internal fun TimelineItemVideoViewHideMediaContentPreview() = ElementPreview { hideMediaContent = true, onShowContentClick = {}, onContentClick = {}, + onLongClick = {}, onLinkClick = {}, onContentLayoutChange = {}, ) From 3968bb82aaeed3ae76a59c658a32c250dbbe42b5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 07:56:06 +0000 Subject: [PATCH 02/47] Update appyx to v1.5.1 (#3889) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update appyx to v1.5.1 * Fix api breaks --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- app/src/main/kotlin/io/element/android/x/MainActivity.kt | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/io/element/android/x/MainActivity.kt b/app/src/main/kotlin/io/element/android/x/MainActivity.kt index 69808409cf..158622b4a3 100644 --- a/app/src/main/kotlin/io/element/android/x/MainActivity.kt +++ b/app/src/main/kotlin/io/element/android/x/MainActivity.kt @@ -87,7 +87,7 @@ class MainActivity : NodeActivity() { @Composable private fun MainNodeHost() { - NodeHost(integrationPoint = appyxIntegrationPoint) { + NodeHost(integrationPoint = appyxV1IntegrationPoint) { MainNode( it, plugins = listOf( diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 15acacebdd..d6c9c417df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,7 +44,7 @@ serialization_json = "1.7.3" #other coil = "2.7.0" showkase = "1.0.3" -appyx = "1.4.0" +appyx = "1.5.1" sqldelight = "2.0.2" wysiwyg = "2.37.13" telephoto = "0.14.0" From 07ed68ea84be779fb75b9fb36d08c7a6af8a9d40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 07:57:09 +0000 Subject: [PATCH 03/47] Update dependency io.sentry:sentry-android to v7.18.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6c9c417df..41cd94e3a8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -195,7 +195,7 @@ zxing_cpp = "io.github.zxing-cpp:android:2.2.0" # Analytics posthog = "com.posthog:posthog-android:3.9.2" -sentry = "io.sentry:sentry-android:7.17.0" +sentry = "io.sentry:sentry-android:7.18.0" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.28.0" From 9e744690ebf525c5d4dd9f801ea6eba108bfb02e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 19 Nov 2024 11:07:50 +0100 Subject: [PATCH 04/47] fix : display security banner for room list empty state --- .../impl/RoomListContentStateProvider.kt | 7 ++- .../roomlist/impl/RoomListPresenter.kt | 4 +- .../features/roomlist/impl/RoomListState.kt | 4 +- .../impl/components/RoomListContentView.kt | 53 ++++++++++++++----- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt index 8b216f3854..4c9e7e0595 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListContentStateProvider.kt @@ -21,6 +21,7 @@ open class RoomListContentStateProvider : PreviewParameterProvider RoomListContentState.Empty + showEmpty -> RoomListContentState.Empty(securityBannerState = securityBannerState) showSkeleton -> RoomListContentState.Skeleton(count = 16) else -> { - val securityBannerState by rememberSecurityBannerState(securityBannerDismissed, needsSlidingSyncMigration) RoomListContentState.Rooms( securityBannerState = securityBannerState, fullScreenIntentPermissionsState = fullScreenIntentPermissionsPresenter.present(), diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt index 642c7d879b..a6b9673b54 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListState.kt @@ -61,7 +61,9 @@ enum class SecurityBannerState { @Immutable sealed interface RoomListContentState { data class Skeleton(val count: Int) : RoomListContentState - data object Empty : RoomListContentState + data class Empty( + val securityBannerState: SecurityBannerState, + ) : RoomListContentState data class Rooms( val securityBannerState: SecurityBannerState, val fullScreenIntentPermissionsState: FullScreenIntentPermissionsState, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt index d4af5a3fe5..503b00f348 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListContentView.kt @@ -76,6 +76,10 @@ fun RoomListContentView( } is RoomListContentState.Empty -> { EmptyView( + state = contentState, + eventSink = eventSink, + onSetUpRecoveryClick = onSetUpRecoveryClick, + onConfirmRecoveryKeyClick = onConfirmRecoveryKeyClick, onCreateRoomClick = onCreateRoomClick, ) } @@ -110,21 +114,44 @@ private fun SkeletonView(count: Int, modifier: Modifier = Modifier) { @Composable private fun EmptyView( + state: RoomListContentState.Empty, + eventSink: (RoomListEvents) -> Unit, + onSetUpRecoveryClick: () -> Unit, + onConfirmRecoveryKeyClick: () -> Unit, onCreateRoomClick: () -> Unit, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { - EmptyScaffold( - title = R.string.screen_roomlist_empty_title, - subtitle = R.string.screen_roomlist_empty_message, - action = { - Button( - text = stringResource(CommonStrings.action_start_chat), - leadingIcon = IconSource.Vector(CompoundIcons.Compose()), - onClick = onCreateRoomClick, - ) - }, - modifier = modifier.fillMaxSize(), - ) + Box(modifier.fillMaxSize()) { + EmptyScaffold( + title = R.string.screen_roomlist_empty_title, + subtitle = R.string.screen_roomlist_empty_message, + action = { + Button( + text = stringResource(CommonStrings.action_start_chat), + leadingIcon = IconSource.Vector(CompoundIcons.Compose()), + onClick = onCreateRoomClick, + ) + }, + modifier = Modifier.align(Alignment.Center), + ) + Box { + when (state.securityBannerState) { + SecurityBannerState.SetUpRecovery -> { + SetUpRecoveryKeyBanner( + onContinueClick = onSetUpRecoveryClick, + onDismissClick = { eventSink(RoomListEvents.DismissBanner) } + ) + } + SecurityBannerState.RecoveryKeyConfirmation -> { + ConfirmRecoveryKeyBanner( + onContinueClick = onConfirmRecoveryKeyClick, + onDismissClick = { eventSink(RoomListEvents.DismissBanner) } + ) + } + else -> Unit + } + } + } } @Composable From 063f6df29e430df9fd7d207a10c152913a90cd86 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 19 Nov 2024 10:19:01 +0000 Subject: [PATCH 05/47] Update screenshots --- ....roomlist.impl.components_RoomListContentView_Day_4_en.png | 4 ++-- ....roomlist.impl.components_RoomListContentView_Day_5_en.png | 3 +++ ...oomlist.impl.components_RoomListContentView_Night_4_en.png | 4 ++-- ...oomlist.impl.components_RoomListContentView_Night_5_en.png | 3 +++ 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_4_en.png index 8952f01b7f..a465700eef 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a78abedec8a3aad14bf6368bf73d46621feaf8e6fd6e019d381077ef05856259 -size 72236 +oid sha256:f07e339529fa15809163745520ccd2d187d858f88148a37e59ec9df1d9559cdd +size 46528 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_5_en.png new file mode 100644 index 0000000000..8952f01b7f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a78abedec8a3aad14bf6368bf73d46621feaf8e6fd6e019d381077ef05856259 +size 72236 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_4_en.png index 1e6d6d626d..ef72333797 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f60d07c4be6d75142e753dec5071f7a6d5dd15519d87a2eb491b708fa7aeea4b -size 70917 +oid sha256:44b0af23c318bc8c4e881bca9ad61127d821d4d82f43de2d9e785860bbda2fcf +size 45038 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_5_en.png new file mode 100644 index 0000000000..1e6d6d626d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_RoomListContentView_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f60d07c4be6d75142e753dec5071f7a6d5dd15519d87a2eb491b708fa7aeea4b +size 70917 From 478445ebe8ba0efb2bc43801956aaf787b3d862d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:25:42 +0000 Subject: [PATCH 06/47] Update plugin sonarqube to v6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6c9c417df..e73fcaf3ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -241,6 +241,6 @@ paparazzi = "app.cash.paparazzi:1.3.5" sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } -sonarqube = "org.sonarqube:5.1.0.4882" +sonarqube = "org.sonarqube:6.0.0.5145" licensee = "app.cash.licensee:1.12.0" compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } From 541c1570343f51a89952679f516ddebea2416082 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 19 Nov 2024 13:58:13 +0100 Subject: [PATCH 07/47] Instantiate the verification controller ASAP (#3893) * Instantiate the verification controller when possible This is needed to get incoming verification requests * Workaround test failure --- .../verification/RustSessionVerificationService.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index ed3ddec98b..84435119c0 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -96,6 +96,17 @@ class RustSessionVerificationService( private var listener: SessionVerificationServiceListener? = null + init { + // Instantiate the verification controller when possible, this is needed to get incoming verification requests + sessionCoroutineScope.launch { + // Needed to avoid crashes on unit tests due to the Rust SDK not being available + tryOrNull { + encryptionService.waitForE2eeInitializationTasks() + initVerificationControllerIfNeeded() + } + } + } + override fun setListener(listener: SessionVerificationServiceListener?) { this.listener = listener } From b58145a9d9ae2c79de5cde1f32728b9a5cdf548d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:16:02 +0000 Subject: [PATCH 08/47] Update dependency org.matrix.rustcomponents:sdk-android to v0.2.63 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6c9c417df..11c8d3d749 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -173,7 +173,7 @@ jsoup = "org.jsoup:jsoup:1.18.1" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.62" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.63" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } From c577c8c9bff7406b134033b14ab38cdc8d894ccb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 04:25:44 +0000 Subject: [PATCH 09/47] Update dependency io.nlopez.compose.rules:detekt to v0.4.19 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 1336b5dc05..187b09de54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -49,7 +49,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.4.18") + detektPlugins("io.nlopez.compose.rules:detekt:0.4.19") } // KtLint From ca62c24d4ac0cd9f11a92454da992d18681a47bb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 09:08:27 +0100 Subject: [PATCH 10/47] Fix compilation issue --- .../android/libraries/matrix/impl/timeline/RustTimeline.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 98f7ccfba1..2b6d8543c4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -394,6 +394,8 @@ class RustTimeline( inner.sendFile( url = file.path, fileInfo = fileInfo.map(), + caption = null, + formattedCaption = null, useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher(), ) From 0a0e96c2b68f7b5c6e6d3c25387395a00dfa3232 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 10:07:35 +0100 Subject: [PATCH 11/47] Iterate on send button design. --- .../textcomposer/components/SendButton.kt | 67 +++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt index 7f1efe55d2..6b5d601333 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt @@ -7,7 +7,6 @@ package io.element.android.libraries.textcomposer.components -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding @@ -17,7 +16,13 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.LinearGradientShader +import androidx.compose.ui.graphics.RadialGradientShader +import androidx.compose.ui.graphics.ShaderBrush import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme @@ -31,6 +36,10 @@ import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTran import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.ui.strings.CommonStrings +/** + * Send button for the message composer. + * Figma: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1956-37575&node-type=frame&m=dev + */ @Composable internal fun SendButton( canSendMessage: Boolean, @@ -46,7 +55,7 @@ internal fun SendButton( ) { val iconVector = when (composerMode) { is MessageComposerMode.Edit -> CompoundIcons.Check() - else -> CompoundIcons.Send() + else -> CompoundIcons.SendSolid() } val iconStartPadding = when (composerMode) { is MessageComposerMode.Edit -> 0.dp @@ -60,7 +69,13 @@ internal fun SendButton( modifier = Modifier .clip(CircleShape) .size(36.dp) - .background(if (canSendMessage) ElementTheme.colors.iconAccentTertiary else Color.Transparent) + .then( + if (canSendMessage) { + buttonBackgroundModifier() + } else { + Modifier + } + ) ) { Icon( modifier = Modifier @@ -68,13 +83,55 @@ internal fun SendButton( .align(Alignment.Center), imageVector = iconVector, contentDescription = contentDescription, - // Exception here, we use Color.White instead of ElementTheme.colors.iconOnSolidPrimary - tint = if (canSendMessage) Color.White else ElementTheme.colors.iconDisabled + tint = if (canSendMessage) { + if (ElementTheme.colors.isLight) { + ElementTheme.colors.iconOnSolidPrimary + } else { + ElementTheme.colors.iconPrimary + } + } else { + ElementTheme.colors.iconQuaternary + } ) } } } +private fun buttonBackgroundModifier() = Modifier.drawWithCache { + // We have a square button, so height == width. + val height = size.height + val verticalGradientBrush = ShaderBrush( + LinearGradientShader( + from = Offset(0f, 0f), + to = Offset(0f, height), + colors = listOf( + Color(0xFF0BC491), + Color(0xFF0467DD), + ) + ) + ) + val radialGradientBrush = ShaderBrush( + RadialGradientShader( + center = Offset(height / 2f, height / 2f), + radius = height / 2f, + colors = listOf( + Color(0xFF0BC491), + Color(0xFF0467DD), + ) + ) + ) + onDrawBehind { + drawRect( + brush = verticalGradientBrush, + ) + drawRect( + brush = radialGradientBrush, + alpha = 0.4f, + blendMode = BlendMode.Overlay, + ) + } +} + @PreviewsDayNight @Composable internal fun SendButtonPreview() = ElementPreview { From ee5c72cda379c796daf53c6503aa64aa70fdf209 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 20 Nov 2024 09:27:57 +0000 Subject: [PATCH 12/47] Update screenshots --- ...messages.impl.attachments.preview_AttachmentsView_0_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_1_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_2_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_3_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_4_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_5_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_0_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_10_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_11_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_12_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_13_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_1_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_4_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_5_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_6_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_7_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_0_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_10_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_11_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_12_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_13_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_1_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_4_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_5_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_6_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_7_en.png | 4 ++-- .../libraries.textcomposer.components_SendButton_Day_0_en.png | 4 ++-- ...ibraries.textcomposer.components_SendButton_Night_0_en.png | 4 ++-- ...braries.textcomposer_MarkdownTextComposerEdit_Day_0_en.png | 4 ++-- ...aries.textcomposer_MarkdownTextComposerEdit_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerCaption_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerCaption_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerEdit_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerEdit_Night_0_en.png | 4 ++-- ...libraries.textcomposer_TextComposerFormatting_Day_0_en.png | 4 ++-- ...braries.textcomposer_TextComposerFormatting_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_10_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_11_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_1_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_2_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_3_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_4_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_5_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_6_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_7_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Day_9_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_10_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_11_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_1_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_2_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_3_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_4_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_5_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_6_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_7_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_8_en.png | 4 ++-- .../libraries.textcomposer_TextComposerReply_Night_9_en.png | 4 ++-- .../libraries.textcomposer_TextComposerSimple_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerSimple_Night_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerVoice_Day_0_en.png | 4 ++-- .../libraries.textcomposer_TextComposerVoice_Night_0_en.png | 4 ++-- 64 files changed, 128 insertions(+), 128 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png index dd26109be0..1a48fb35cf 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:899eff34c421e13bf62d6828582c715f87588cfb17c1063aae65baae79a472cf -size 394631 +oid sha256:2399ee4cd37cbafec07e87bfab90e66ee3df5b6aba602d5cd9bd1114c7365642 +size 397379 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png index 7514170564..3982a58c4c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c41c7438f46e62a4a6f115647040005aba9fd057599fbb17aba844337642d525 -size 15963 +oid sha256:d18f7e2c169f7e4b9e435584d868454ae5f765a32d29bbbfe48d65b45f4161d6 +size 18845 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png index b5ca13b59e..c94414246c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a9d51bdba64cbd7c453ac177e9c77fb6aa3c611ac16746701b22b024abf3560 -size 13770 +oid sha256:9e0ec7e2a9dbe70a2deddf2bd621ac721b03e1b5bd367020fc68485e4d387ba8 +size 16610 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png index d9ea161fab..0d2dcbf67c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9be7c12e6de6bd2975f11ff06eab1b6fa973edcda0ca90c93eed164cb1d6bf18 -size 14841 +oid sha256:a44e40c0d586b41a0e47aa7d40a564eb820c2692051e795c87c460df92e81ca6 +size 17739 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png index 5f643fefc6..e799726c52 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9434a531c57fa65c9996f5b5c6254af73ac50433ceeeaa7f1dd1243fe3c3b1c6 -size 50355 +oid sha256:361ff23fd2ff99aecfdffd10b45e9235d86183d4856cb2a3e99f85b9e04c2d59 +size 51376 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png index ac695699f0..df965394aa 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c36d5b0d29f1533829f80c33e042bb88648890ad2b629136f8a2af01c511f7a -size 87977 +oid sha256:efbfed755b29293009f45fca33f58863b612772de9a1d55593c979dbb04ff6f2 +size 88981 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_0_en.png index abeb47fb3d..3b66fd9f8e 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f1646315278ac6e3346a14e2559b5cb308cc08082e9654ede2d49d1d710a671 -size 56795 +oid sha256:ad01f084328ff5c31019c00bfdda18660f464164f68a9f92375afb7854dda7fa +size 59491 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png index 4d2eddbede..5779f0e9b3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6df3677e4bba63bbde74adbd2731be5c97afdce1bcee7064965b917a5ddd8ef1 -size 58370 +oid sha256:3ce4299e4c585abf3635b37c6003ac50a8ed25ffa0e9258dfbc07d61fb04569f +size 61074 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png index 33d8266124..67315b78fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:55be986aa88651bdfd7d6c81a0617609496e30d81c949d41cb16896b5e37e387 -size 48526 +oid sha256:035d793ee33682785b98974c6357b99bfb879f8a86cba7117bb2b9c4c4bc13d5 +size 49533 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png index 16e6068a60..2c917a94f2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2a487db559d6638db0d9b93c98ed795bca2a82f68e26a85cd0a7a76f006bb63 -size 56817 +oid sha256:7d1ed9a282d3363fa4e28d924a750d0a46f7564533f687ab102d559e2dd1606b +size 59518 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png index 85056e15fc..2f6c08ed16 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccf967ae3867651786c1e47e5bfef60aa0ad03bc62d5a72db329e95f758f07ea -size 59886 +oid sha256:9660c7ea6ca5101c6b5fa9e774d4063d4011b9f8fdb64bf8e32cbc89c231531c +size 62605 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png index d1b3466534..c7c8f2d132 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b839efb7173b3f18624cf1570f56b62aeee25a097f977c50c9950e7edc907a17 -size 55968 +oid sha256:31856cb9bed162d0bfa6d9b72a693cdd1fce231130b6f031ef7212b11068c6eb +size 58650 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_4_en.png index 0301d7fa91..dbb59f9ad3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:19a591c39e3be571e4ebb852696313fdcef008e583818c21df300d9900bca320 -size 54610 +oid sha256:097625b9d81cc5a6f426a5a50292848f4ca7c282feca650a08a520380dc9ec95 +size 55590 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png index 5391f51acf..74460ddcae 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0dff30d6403a88c9c237865fe9bc1a65d1ea8b5b439df70ad1c7622fa199f372 -size 54627 +oid sha256:53e8bb8dc1e9de5d02ed59a9d9384cb02394eb7e509ee1d30a718231fd82f08c +size 57292 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_6_en.png index 423532b6ce..922d09a430 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c48911e2132a696c4a0d2cc9a233ceacc0c5b3bb02f9b655e82cb7d98480ce6 -size 54361 +oid sha256:a90aeb879d3819506f3899d822f5f70e29728b9650f22aebbd307477f7d95f41 +size 54179 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_7_en.png index 596b04b01d..a9bf5e3fd4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da4713d6094c00750ae3f2ad486ab180b33e1e46e69b9604590f5169681b66f8 -size 57729 +oid sha256:ab476787bcc93bd00037ebf2bf1367b7feaa788f37c1e1478208866c7fbac9d6 +size 58696 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_0_en.png index 21fb9e301e..7300f46f29 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c1033d39367ea410596ffb4029ea22bc90840f59645cd303cdc8d019fb0415d6 -size 56494 +oid sha256:d40877679c1b9cff47940631f237243d3d9b715e50f44591d2f7588279c9052c +size 59176 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png index 5815ce453e..39c5faa542 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d57c4a876860276a5a13e630fd80391e87ad068d3ab622179d0142d9e54d91a3 -size 57952 +oid sha256:7e9412f3e84b63be532188e13a976d1954404466136633f3f8cd41851617e753 +size 60668 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png index ace8091885..df384039ee 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce0840cc1849a2e074be9b7f86f156e1ac494a7658cc72531cbd90b6dba105d7 -size 44414 +oid sha256:1da55e4b116cbf0ebd74afee2a47d34b99d87192cdf9a5f8698118fcd4bbe239 +size 45466 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png index 37c20e1304..eee7da7dda 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ac6c99cb780160d47290324c93c9d0a93e3c3e1d5837bc146cdbdce5a46e72b3 -size 56539 +oid sha256:76faea3ec5b9e01a7e1ad77dea4f44b060bee26cf1d0b56df8eabb692cf764df +size 59225 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png index c4a70cc709..8643a775a1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e8d23096a1be9ec638a40d8e14dd25a2f49b373de3ff49863ec5720b33f45a7 -size 59232 +oid sha256:0f9df03bc6cba3fbf8ae454768064c9141b05e319c40c568a0a3edf3a53fed4e +size 61961 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png index 7d1e4f7bee..af5c8df13a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2558438b5dce74e03bf203f9aeb951ffd5cb6f52eab5d28fea9d48a34c74c7d1 -size 55393 +oid sha256:952e2bbcee90fb03f522da1850112b88496b5851bbc0c9908505fe371d0bd34c +size 58047 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_4_en.png index d681df3ad5..dd5acfbb26 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:867175a499ed1e1dc0fad33e83e51190af105342a8f79e3a125926ffcaac465d -size 50656 +oid sha256:fba26f4a18cd5ea132275b9edf499b51a1c7ef3ecd1c61f30768ef3236cfaa06 +size 51723 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png index c17b705762..7c7b652089 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0dda6dc9737457bcc8001e886cd369a70baa1db568bbf3da237325e15881dc14 -size 54272 +oid sha256:8f1d5a9f286af43a8d026a62a7059c221cfa824217f362c9daeb9b0552fc7bb5 +size 56907 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_6_en.png index bfb73f77ed..e1b9edef18 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77a7e2084010487034b19258cdda04a3b39c810f43e06cf3c13e207ffc9a9e75 -size 53909 +oid sha256:45df1ecf99266ef43891a1dcf3b3d3b99c57d1b51179028589b74f83e942126e +size 53739 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_7_en.png index be1ffe8a6b..3235fa972d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b10080f2a866f28a65604ba3b895f8bb79769f05a51536b1f33a7611dfe26615 -size 53465 +oid sha256:d59298e9a6d21c17038b6e71f709853068d4182df41ba31338946e2a220f7f5a +size 54511 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png index 0c2ad6eead..dfb1958e28 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa94eb0e472b9caaa94bfdb5c441a5cd97325b7fa6e4f2a3fb100f86486cbc94 -size 7693 +oid sha256:177e16989220804b9472ec9e7435e1a6cdb14dc3a26c17b5b00cece634439ff1 +size 12602 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png index ad0d175bac..257bf3cd99 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer.components_SendButton_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:edb1143fbe31d6c9d68dcfe1b3d9fad90f49a645b2786587c9d79787be31b4d2 -size 7618 +oid sha256:58b45b8b1a73eec401d922e8f422902e3a594927a26100345807fa654d83929f +size 12433 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en.png index 4927ef3385..2bb281cfd1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:997f06a80f20ea48389fc05cf0abb7eb584ef02688f6eebb3e5dc0151afbaa04 -size 50460 +oid sha256:71550eeba48a6c9ccd4c26cb0e26f0136e8a5611089a8ea6c7cc92a8133b82d2 +size 60259 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en.png index 96a5311a1e..6fd5454a37 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f05e63ae7b68f0049c8c702c584ec276c0cca2d7680d9b401f652d155870717d -size 48946 +oid sha256:4f1f000c6baf5be3468b2a28ea43f2131d20a73cdbf1c22f52ce075b3f36bf25 +size 58223 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Day_0_en.png index 151c86e357..b5330db5c9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:391d3741acfd768614a9bc70e948f7fc49b37d75e65591721b922e678d520bac -size 44773 +oid sha256:1b9b24eafbcaa2143c199a0522fa1aae98d9c7bddb80364602f0662567a2f1a1 +size 56485 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Night_0_en.png index 91dfb69902..dea84aaa40 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerCaption_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:713a314ecd36e4d95e5c287ab9a4b5968f5a5090dbb4910d9739e66969fdd424 -size 43417 +oid sha256:fc7a5491acff69b64ea73c1a62b7ae9e148ce57768697de2ec280327cd72298d +size 55402 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Day_0_en.png index 4927ef3385..2bb281cfd1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:997f06a80f20ea48389fc05cf0abb7eb584ef02688f6eebb3e5dc0151afbaa04 -size 50460 +oid sha256:71550eeba48a6c9ccd4c26cb0e26f0136e8a5611089a8ea6c7cc92a8133b82d2 +size 60259 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Night_0_en.png index 96a5311a1e..6fd5454a37 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEdit_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f05e63ae7b68f0049c8c702c584ec276c0cca2d7680d9b401f652d155870717d -size 48946 +oid sha256:4f1f000c6baf5be3468b2a28ea43f2131d20a73cdbf1c22f52ce075b3f36bf25 +size 58223 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Day_0_en.png index a075c67fc8..50ff6999af 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a2232abaacfc851133d6c30e6c88a83304beb7a3ba594793c70dad307330c36 -size 51848 +oid sha256:4dd98ff64e3ffd15c4004370ea627690e3bd2e186363cd584fe632f37c50c0eb +size 60036 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Night_0_en.png index b5b2dd3d60..c04d42a89d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerFormatting_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c215ef11337a05564282b052d6a725f41d9e929c493fd74bc1e785f21293acbe -size 50191 +oid sha256:1c6f606b522f53ed525cee3ecf798b7fb15cd907fd2caf8a98625b0fc3a5e720 +size 57708 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png index a567a7d6af..28c77cdeac 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f515200dc9a53f034ad2476ede89f4c3c94cfd6fd316ee61e6fa13deb7ba6e02 -size 74514 +oid sha256:ed6b061bc090ded2fffc3af1003e0eb8fb0b933d7bb826d6bc31e6e633f11f26 +size 82464 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png index 405eba9d83..6566c02a27 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee4c30220a64f8751bf2d51b9b09d75ab1e69bbbe4d34b63093740070e7c35c4 -size 57833 +oid sha256:4ef12ab84784c2b8dc91f1521c4a6191ae7fba10fa9da4fe74805078f7aa8bdb +size 65823 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png index 89c19bc86a..23c35528a9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ab63cc4ccf3082558b1571e7ee5399d3409ab8f6205f68b907c6359fdaea7be4 -size 72521 +oid sha256:6508ce0bdd1f2e56f6ba63a69908bde3e83b169c6681f378850c16b68dbfc21a +size 80509 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png index b8407463e0..2f5e863686 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c51b345180a86b2826430c121e54aabbfad2405f6d422b7c0e1112582fa9f755 -size 83966 +oid sha256:bbe4d0343d8cbdcdd4c2026cff3e6e015fe0b1b9cd34cb1a54e4fa1fcee563e4 +size 91834 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png index a0875268d8..516ea20b85 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1c8e13e73696d0aa32cdf17915a6e488072db61af2349dba78e6add23c6a8e5 -size 60982 +oid sha256:2bb2e3854f3c9d5ddd2f40ba7ef0f8a6e36da232f029044c36491e59bfb95ead +size 69082 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png index 69d175e03d..15e1996bf6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0207816e0da278a25a7da9d456d664cf925ed419f8a5046a69465ffef985ff95 -size 59299 +oid sha256:83ae14f812b9b1ade316b017ca7334a1550b9993c1b284018485fb9e3c5df3a1 +size 67376 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png index 7c5bbc0f59..2ce7eb8a4d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da1e22e5b3de270fba766ff027113ce7836ffd72b1cf4de2e6cac6544086fff4 -size 67786 +oid sha256:1b107f28fdc4020cbc0a21a6e78cca7effb5a166080803315b97dd5f2b8c4a7a +size 75497 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png index 691a386ea4..9799a6fc5c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10510c2a67fc859d0564c6e34a7021e81f1119eaca448c5b5e928bc0a7d5a619 -size 58228 +oid sha256:915fee1b03b18db0f372d3e31e81cc0606dbe28e9a33aeaeef68d3476c5c8509 +size 66276 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png index e2351db809..9494d1ff32 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1b7e7050bc5135b0166a752f5d3a5276348e6fa4a35cab8721a2adb324360ed -size 59040 +oid sha256:8bee25ec96fd67cf9ade2e54d44ec393ca9ee4070a725eddec64f134207c7a2a +size 67115 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png index 204be1a21f..9888ab99ce 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d7e4015c9c11b473205c611694cf2b5d52d20d49bee6cd6f61474f09a87de696 -size 61191 +oid sha256:0b941b5215d059929b5ef64de769bfe3eb594a984237c110d8203bf763fa9322 +size 69286 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png index 7ca52ef726..9d6a6c4e11 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5b274f77b1b017d7385ae1dfffb8051bb95db6372a7f32ce6838fa692c3f2562 -size 68381 +oid sha256:90baf1795797e36aa26ddd2a0efa40f0ee893cc985606c55d184f60a57cda93c +size 76020 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png index a4495f3476..1ba8016b16 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc0952625f2a7c5901a3949135c1a0a343f40b33d4192425a97245dbe6b5a04a -size 58502 +oid sha256:8230e078a5c0aec1791b1cc1ffd813660a1bd64d0a082ee9d5cd37024d923d81 +size 66567 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png index cff4bec3f7..cd1fa5cb75 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b06693cde76b2ac00c31b1c767910e46dbac4f099abf17e66ceb2de87acb445 -size 72106 +oid sha256:b023ac31c1df8e542e4ba012c14aa0f083000cd82687628b78d03c7fa0fc7462 +size 79967 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png index 11c89aba8e..da99e6a4fa 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fff7343bff8fe781d50732fb4e1fd7e6caf228f9520b9f639cab367db4dfd5c -size 55852 +oid sha256:0011599e9bcfb6cfce356e4ded07053927b1c2971db457a1e68235b4fd805bad +size 63814 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png index 8edecf2449..b4f653fcf8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08d653cdcc4c65cc1b1dbd89789cf24594e00a8f7fa2941d56fb93fda7681e4e -size 70210 +oid sha256:b0ad6ff8d00e0b8880428bfc4b17fa1b2accb0117cd48a3c6630e6d8577c0b38 +size 78103 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png index 46923d92a5..bc98034f4e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01c2360b1d526713d82566794154743924fb15e1bb6e8ec250a2cc5629b5db02 -size 81247 +oid sha256:e42199bbe520151ba537e93e87911f0870437686128684227044c48bcc3fb754 +size 89090 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png index 60901ff09c..d568fef987 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:447b98cc3293ed3eee779cb9ffca62191b5f2d8911bc6e5912c4b23a2115b514 -size 59195 +oid sha256:7212eef12bdf4e6bcf8db3a1471b279d21bab71bc68661a0b09cacb6d062d35c +size 67125 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png index 9d761b243f..b3fb3dac63 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:862065af54f5ceaba8304d3c15f24c7021146db4e9becec859705888cdde4bae -size 57523 +oid sha256:381724bffe2b22e3c768addc1016d8d77d1e2969c43f76c7b4aaa59e8d0c2700 +size 65452 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png index d8774c39a0..bb16d1803d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a61b8ca772feebb1ccb86949b4a63080d42f2d26a29ec3ea90e47404e9ff3912 -size 65950 +oid sha256:603baddbff53df34bbe7b3a1ce4119f20b8b3255da86e80b6255a0ebc55661d6 +size 73862 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png index b561d79b42..67dff83222 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e75e80ffc8761b0a91f0ee3137df1987104b9a0546a6edc05d55cbc29262c313 -size 56483 +oid sha256:7bda76b1f85a8c9902f634ca2f62bbfc33657cb77643cdb80ae25f1065fc9802 +size 64412 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png index 807283d490..61d867d5f2 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ccbf26f9c3cbbba607bcb1d1a4f3701717a8d39d7c4194a393a0fb1746114c1 -size 57164 +oid sha256:86de5beaddd424dd827f2286b1b76374078726776ff3faf33ecc73693a37a9ab +size 65071 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png index 24f085a0bf..602ea53735 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:224bc191f6bd8761d5301039f29bebf1b3a9773ee454820cb9c64ab2d9c7b612 -size 59458 +oid sha256:5e4e6decdec0cbf92774c9f2ae8cbca23063637de9dff06eb1f19488bc66c3b6 +size 67391 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png index 8b5db4956e..fa0b4f95d3 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c491288bfd12be3e23272f35a49beafac768bac836b43cc1bde0507ed810094e -size 66436 +oid sha256:18eb91d33345655ed1fad1ff08798e37aa812e7dd11d2352ac35897f14246f2a +size 74340 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png index db33b596b2..7d2ce12419 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerReply_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:079cd865d0feb88d5746c3966f8ec0d72e40140626d5ffd6a918095e38f09fcd -size 56699 +oid sha256:e08ac324ef5285da4214adaa4b692e74a78cdaa12a4b23127ab959e34b7d83b3 +size 64614 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Day_0_en.png index 6f43f90e61..e65c6cc81f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c9d3fca9aaaa854d0fe1242a9ff043f17258827e1197c92ae251e251670e65b -size 44970 +oid sha256:05bb6bfd1b1e35015dcbebd9b96c0729e16db6e9a37741e35d1baf4e7c3f9009 +size 51684 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Night_0_en.png index 11897e4584..f715d5a115 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerSimple_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79d62f9d342571992714742ec7db4ca98e4631dc33305ea7d1306c39258328d0 -size 42990 +oid sha256:5a86352ebab4c72f028e476db8fb8b514f57b6f237788583533088d05b8fe1be +size 50646 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png index 475ac4ddc4..effc0f4d8b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1e561869c72ee9f5a3c05a8d88fdf2db239a7933173bb4428f325cdca660cf4 -size 25459 +oid sha256:a19ef7fac4398287f12076331f774f7b368980787af5f9d205d1e75c0f382525 +size 30324 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png index 279e57b04a..2c75b11c3d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerVoice_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93919babb3761ebbee289226e316c20ecbdf1f53686eade21175d6c7de22242a -size 24499 +oid sha256:231e7a071cb71f78a61eeacff63f8726bac02bc0c0011d1125fd0b3916f2b078 +size 29288 From 19ec31f1806c157421188633078cb0af3db4dbc1 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 20 Nov 2024 11:39:33 +0100 Subject: [PATCH 13/47] version++ --- plugins/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index c014a8a763..2730a94337 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -47,7 +47,7 @@ private const val versionMinor = 7 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -private const val versionPatch = 4 +private const val versionPatch = 5 object Versions { const val VERSION_CODE = 4_000_000 + versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch From 80a215b0b42466e49742b7e5b5ea0bc3e74a4eef Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 20 Nov 2024 12:15:15 +0100 Subject: [PATCH 14/47] Changelog for version 0.7.4 --- CHANGES.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 777cd401c9..3dc07f4c66 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,53 @@ +Changes in Element X v0.7.4 (2024-11-20) +======================================== + +## What's Changed +### 🙌 Improvements +* Update the strings for unsupported calls by @bmarty in https://github.com/element-hq/element-x-android/pull/3857 +### 🐛 Bugfixes +* Stop incoming call ringing if answered on another device. by @bmarty in https://github.com/element-hq/element-x-android/pull/3842 +* Use formatted captions for images and video by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3864 +* Fix unified push unregister by @bmarty in https://github.com/element-hq/element-x-android/pull/3877 +* Hide the keyboard when navigating from the chat room screen by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3878 +* Fix long click not working for media timeline items by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3879 +* Instantiate the verification controller ASAP by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3893 +* fix : display security banner for room list empty state by @ganfra in https://github.com/element-hq/element-x-android/pull/3892 +### 🗣 Translations +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/3852 +* Sync Strings - add translations to Finnish by @ElementBot in https://github.com/element-hq/element-x-android/pull/3883 +### 🚧 In development 🚧 +* Create room : improve handling of room address by @ganfra in https://github.com/element-hq/element-x-android/pull/3868 +### Dependency upgrades +* Update anvil to v0.4.0 by @renovate in https://github.com/element-hq/element-x-android/pull/3792 +* Update kotlin to v2.0.21-1.0.27 by @renovate in https://github.com/element-hq/element-x-android/pull/3836 +* Update dependency org.maplibre.gl:android-sdk to v11.6.1 by @renovate in https://github.com/element-hq/element-x-android/pull/3793 +* Update android.gradle.plugin to v8.7.2 by @renovate in https://github.com/element-hq/element-x-android/pull/3785 +* Update lifecycle to v2.8.7 by @renovate in https://github.com/element-hq/element-x-android/pull/3763 +* Update plugin dependencycheck to v11 by @renovate in https://github.com/element-hq/element-x-android/pull/3723 +* Update dependency org.matrix.rustcomponents:sdk-android to v0.2.61 by @renovate in https://github.com/element-hq/element-x-android/pull/3841 +* Update mobile-dev-inc/action-maestro-cloud action to v1.9.6 by @renovate in https://github.com/element-hq/element-x-android/pull/3846 +* Update dependency com.posthog:posthog-android to v3.9.1 by @renovate in https://github.com/element-hq/element-x-android/pull/3856 +* Update core to v1.15.0 by @renovate in https://github.com/element-hq/element-x-android/pull/3766 +* Update dependency com.android.tools:desugar_jdk_libs to v2.1.3 by @renovate in https://github.com/element-hq/element-x-android/pull/3825 +* Update dependency io.nlopez.compose.rules:detekt to v0.4.18 by @renovate in https://github.com/element-hq/element-x-android/pull/3860 +* Update dependency com.posthog:posthog-android to v3.9.2 by @renovate in https://github.com/element-hq/element-x-android/pull/3861 +* Update dependency io.sentry:sentry-android to v7.17.0 by @renovate in https://github.com/element-hq/element-x-android/pull/3862 +* Update dependency androidx.compose:compose-bom to v2024.11.00 by @renovate in https://github.com/element-hq/element-x-android/pull/3869 +* Update telephoto to v0.14.0 by @renovate in https://github.com/element-hq/element-x-android/pull/3870 +* Update SDK bindings version to `0.2.62` and fix `SendHandle` usages by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3876 +* Update codecov/codecov-action action to v5 by @renovate in https://github.com/element-hq/element-x-android/pull/3874 +* Update dependency com.google.firebase:firebase-bom to v33.6.0 by @renovate in https://github.com/element-hq/element-x-android/pull/3880 +* Update kotlin to v2.0.21-1.0.28 by @renovate in https://github.com/element-hq/element-x-android/pull/3881 +* Update dependency org.robolectric:robolectric to v4.14 by @renovate in https://github.com/element-hq/element-x-android/pull/3882 +* Update appyx to v1.5.1 by @renovate in https://github.com/element-hq/element-x-android/pull/3889 +* Update dependency io.nlopez.compose.rules:detekt to v0.4.19 by @renovate in https://github.com/element-hq/element-x-android/pull/3900 +* Update dependency org.matrix.rustcomponents:sdk-android to v0.2.63 by @renovate in https://github.com/element-hq/element-x-android/pull/3898 +### Others +* Design system : implement new TextField by @ganfra in https://github.com/element-hq/element-x-android/pull/3834 +* Remove :samples:minimal module by @bmarty in https://github.com/element-hq/element-x-android/pull/3871 +* Replace `textPlaceholder` color usages with `textSecondary` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/3873 +* Room Preview API changes by @ganfra in https://github.com/element-hq/element-x-android/pull/3875 + Changes in Element X v0.7.3 (2024-11-08) ======================================== From 7324c4fedf7cef80873ca68ddf3fc85554323d50 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 14:32:22 +0100 Subject: [PATCH 15/47] Use human readable name for filename of taken photos and videos. Fixes #3894. --- .../libraries/mediapickers/impl/DefaultPickerProvider.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt index ab48de0eaa..33b4e4ea08 100644 --- a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt +++ b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt @@ -24,7 +24,6 @@ import io.element.android.libraries.mediapickers.api.PickerLauncher import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediapickers.api.PickerType import java.io.File -import java.util.UUID import javax.inject.Inject @ContributesBinding(AppScope::class) @@ -111,7 +110,7 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { NoOpPickerLauncher { onResult(null) } } else { val context = LocalContext.current - val tmpFile = remember { getTemporaryFile(context) } + val tmpFile = remember { getTemporaryFile(context, "photo.jpg") } val tmpFileUri = remember(tmpFile) { getTemporaryUri(context, tmpFile) } rememberPickerLauncher(type = PickerType.Camera.Photo(tmpFileUri)) { success -> // Execute callback @@ -131,7 +130,7 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { NoOpPickerLauncher { onResult(null) } } else { val context = LocalContext.current - val tmpFile = remember { getTemporaryFile(context) } + val tmpFile = remember { getTemporaryFile(context, "video.mp4") } val tmpFileUri = remember(tmpFile) { getTemporaryUri(context, tmpFile) } rememberPickerLauncher(type = PickerType.Camera.Video(tmpFileUri)) { success -> // Execute callback @@ -142,8 +141,8 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { private fun getTemporaryFile( context: Context, + filename: String, baseFolder: File = context.cacheDir, - filename: String = UUID.randomUUID().toString(), ): File { return File(baseFolder, filename) } From c57af9d01017275462deec68e413845242fe4797 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 14:37:04 +0100 Subject: [PATCH 16/47] DefaultPickerProvider: inject the application context and cleanup dead code. It seems that `isInTest = true` is not used anymore. --- .../impl/DefaultPickerProvider.kt | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt index 33b4e4ea08..8622c8cc32 100644 --- a/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt +++ b/libraries/mediapickers/impl/src/main/kotlin/io/element/android/libraries/mediapickers/impl/DefaultPickerProvider.kt @@ -13,11 +13,11 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.PickVisualMediaRequest import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode import androidx.core.content.FileProvider import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.di.AppScope +import io.element.android.libraries.di.ApplicationContext import io.element.android.libraries.mediapickers.api.ComposePickerLauncher import io.element.android.libraries.mediapickers.api.NoOpPickerLauncher import io.element.android.libraries.mediapickers.api.PickerLauncher @@ -27,10 +27,9 @@ import java.io.File import javax.inject.Inject @ContributesBinding(AppScope::class) -class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { - @Inject - constructor() : this(false) - +class DefaultPickerProvider @Inject constructor( + @ApplicationContext private val context: Context, +) : PickerProvider { /** * Remembers and returns a [PickerLauncher] for a certain media/file [type]. */ @@ -39,7 +38,7 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { type: PickerType, onResult: (Output) -> Unit, ): PickerLauncher { - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { } } else { val contract = type.getContract() @@ -55,7 +54,7 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { @Composable override fun registerGalleryImagePicker(onResult: (Uri?) -> Unit): PickerLauncher { // Tests and UI preview can't handle Contexts, so we might as well disable the whole picker - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { onResult(null) } } else { rememberPickerLauncher(type = PickerType.Image) { uri -> onResult(uri) } @@ -71,10 +70,9 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { onResult: (uri: Uri?, mimeType: String?) -> Unit ): PickerLauncher { // Tests and UI preview can't handle Contexts, so we might as well disable the whole picker - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { onResult(null, null) } } else { - val context = LocalContext.current rememberPickerLauncher(type = PickerType.ImageAndVideo) { uri -> val mimeType = uri?.let { context.contentResolver.getType(it) } onResult(uri, mimeType) @@ -92,7 +90,7 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { onResult: (Uri?) -> Unit, ): PickerLauncher { // Tests and UI preview can't handle Context or FileProviders, so we might as well disable the whole picker - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { onResult(null) } } else { rememberPickerLauncher(type = PickerType.File(mimeType)) { uri -> onResult(uri) } @@ -106,12 +104,11 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { @Composable override fun registerCameraPhotoPicker(onResult: (Uri?) -> Unit): PickerLauncher { // Tests and UI preview can't handle Context or FileProviders, so we might as well disable the whole picker - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { onResult(null) } } else { - val context = LocalContext.current - val tmpFile = remember { getTemporaryFile(context, "photo.jpg") } - val tmpFileUri = remember(tmpFile) { getTemporaryUri(context, tmpFile) } + val tmpFile = remember { getTemporaryFile("photo.jpg") } + val tmpFileUri = remember(tmpFile) { getTemporaryUri(tmpFile) } rememberPickerLauncher(type = PickerType.Camera.Photo(tmpFileUri)) { success -> // Execute callback onResult(if (success) tmpFileUri else null) @@ -126,12 +123,11 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { @Composable override fun registerCameraVideoPicker(onResult: (Uri?) -> Unit): PickerLauncher { // Tests and UI preview can't handle Context or FileProviders, so we might as well disable the whole picker - return if (LocalInspectionMode.current || isInTest) { + return if (LocalInspectionMode.current) { NoOpPickerLauncher { onResult(null) } } else { - val context = LocalContext.current - val tmpFile = remember { getTemporaryFile(context, "video.mp4") } - val tmpFileUri = remember(tmpFile) { getTemporaryUri(context, tmpFile) } + val tmpFile = remember { getTemporaryFile("video.mp4") } + val tmpFileUri = remember(tmpFile) { getTemporaryUri(tmpFile) } rememberPickerLauncher(type = PickerType.Camera.Video(tmpFileUri)) { success -> // Execute callback onResult(if (success) tmpFileUri else null) @@ -140,15 +136,12 @@ class DefaultPickerProvider(private val isInTest: Boolean) : PickerProvider { } private fun getTemporaryFile( - context: Context, filename: String, - baseFolder: File = context.cacheDir, ): File { - return File(baseFolder, filename) + return File(context.cacheDir, filename) } private fun getTemporaryUri( - context: Context, file: File, ): Uri { val authority = "${context.packageName}.fileprovider" From 98520d3f67a3f57d152f45a0a19420d88c026421 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 16:22:13 +0100 Subject: [PATCH 17/47] Protected Content: ensure that user cannot open fullscreen unless the content has first been revealed in the timeline. --- .../impl/timeline/components/TimelineItemEventRow.kt | 12 ++++++++++-- 1 file changed, 10 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 c358dcdd0a..fa14877c6d 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 @@ -72,6 +72,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState +import io.element.android.features.messages.impl.timeline.protection.mustBeProtected import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar @@ -146,6 +147,13 @@ fun TimelineItemEventRow( val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } + val onContentClick = if (event.mustBeProtected()) { + // In this case, let the content handle the click + {} + } else { + onEventClick + } + fun onUserDataClick() { onUserDataClick(event.senderId) } @@ -178,7 +186,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onEventClick, + onContentClick = onContentClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, @@ -212,7 +220,7 @@ fun TimelineItemEventRow( isHighlighted = isHighlighted, timelineRoomInfo = timelineRoomInfo, interactionSource = interactionSource, - onContentClick = onEventClick, + onContentClick = onContentClick, onLongClick = onLongClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, From 4d00f968b7c982906ae2b483f82e96ec37157810 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 18:49:52 +0100 Subject: [PATCH 18/47] Render edited caption. --- .../TimelineItemContentMessageFactory.kt | 7 +++++++ .../TimelineItemContentStickerFactory.kt | 1 + .../model/event/TimelineItemAudioContent.kt | 1 + .../event/TimelineItemAudioContentProvider.kt | 1 + .../model/event/TimelineItemEventContent.kt | 19 ++++++++++++------- .../model/event/TimelineItemFileContent.kt | 1 + .../event/TimelineItemFileContentProvider.kt | 1 + .../model/event/TimelineItemImageContent.kt | 1 + .../event/TimelineItemImageContentProvider.kt | 1 + .../model/event/TimelineItemPollContent.kt | 5 +++-- .../model/event/TimelineItemStickerContent.kt | 1 + .../TimelineItemStickerContentProvider.kt | 1 + .../event/TimelineItemTextBasedContent.kt | 7 +++---- .../model/event/TimelineItemVideoContent.kt | 1 + .../event/TimelineItemVideoContentProvider.kt | 1 + .../model/event/TimelineItemVoiceContent.kt | 1 + .../event/TimelineItemVoiceContentProvider.kt | 1 + 17 files changed, 38 insertions(+), 13 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt index ff5ca57c11..867cb694db 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt @@ -87,6 +87,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -106,6 +107,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, mediaSource = messageType.source, thumbnailSource = messageType.info?.thumbnailSource, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -143,6 +145,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, thumbnailSource = messageType.info?.thumbnailSource, videoSource = messageType.source, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -162,6 +165,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -177,6 +181,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -188,6 +193,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, mediaSource = messageType.source, duration = messageType.info?.duration ?: Duration.ZERO, mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream, @@ -203,6 +209,7 @@ class TimelineItemContentMessageFactory @Inject constructor( filename = messageType.filename, caption = messageType.caption?.trimEnd(), formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(), + isEdited = content.isEdited, thumbnailSource = messageType.info?.thumbnailSource, fileSource = messageType.source, mimeType = messageType.info?.mimetype ?: MimeTypes.fromFileExtension(fileExtension), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentStickerFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentStickerFactory.kt index b76dfdf07b..0d725d0e29 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentStickerFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentStickerFactory.kt @@ -36,6 +36,7 @@ class TimelineItemContentStickerFactory @Inject constructor( filename = content.filename, caption = content.body, formattedCaption = null, + isEdited = false, mediaSource = content.source, thumbnailSource = content.info.thumbnailSource, mimeType = content.info.mimetype ?: MimeTypes.OctetStream, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt index 0ecf45ec55..46176cc474 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContent.kt @@ -15,6 +15,7 @@ data class TimelineItemAudioContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val duration: Duration, val mediaSource: MediaSource, val mimeType: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt index 7d4f6baf84..41dab0cfb6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt @@ -25,6 +25,7 @@ fun aTimelineItemAudioContent(fileName: String = "A sound.mp3") = TimelineItemAu filename = fileName, caption = null, formattedCaption = null, + isEdited = false, mimeType = MimeTypes.Mp3, formattedFileSize = "100kB", fileExtension = "mp3", diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt index fafadcbf79..62c55c22ef 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemEventContent.kt @@ -14,8 +14,15 @@ sealed interface TimelineItemEventContent { val type: String } +interface TimelineItemEventMutableContent { + /** Whether the event has been edited. */ + val isEdited: Boolean +} + @Immutable -sealed interface TimelineItemEventContentWithAttachment : TimelineItemEventContent { +sealed interface TimelineItemEventContentWithAttachment : + TimelineItemEventContent, + TimelineItemEventMutableContent { val filename: String val caption: String? val formattedCaption: CharSequence? @@ -74,9 +81,7 @@ fun TimelineItemEventContent.canReact(): Boolean = /** * Whether the event content has been edited. */ -fun TimelineItemEventContent.isEdited(): Boolean = - when (this) { - is TimelineItemTextBasedContent -> isEdited - is TimelineItemPollContent -> isEdited - else -> false - } +fun TimelineItemEventContent.isEdited(): Boolean = when (this) { + is TimelineItemEventMutableContent -> isEdited + else -> false +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt index b7007c8bbc..3f1d8fe041 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContent.kt @@ -14,6 +14,7 @@ data class TimelineItemFileContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val fileSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt index d7852134a2..405759f45d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemFileContentProvider.kt @@ -26,6 +26,7 @@ fun aTimelineItemFileContent( filename = fileName, caption = null, formattedCaption = null, + isEdited = false, thumbnailSource = null, fileSource = MediaSource(url = ""), mimeType = MimeTypes.Pdf, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt index b13c7a4e37..78323166b4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContent.kt @@ -17,6 +17,7 @@ data class TimelineItemImageContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val mediaSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt index 60edb0e6d7..a5d7a8e9f3 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemImageContentProvider.kt @@ -31,6 +31,7 @@ fun aTimelineItemImageContent( filename = filename, caption = caption, formattedCaption = null, + isEdited = false, mediaSource = MediaSource(""), thumbnailSource = null, mimeType = MimeTypes.IMAGE_JPEG, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt index 4355727419..ad4bc1794a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemPollContent.kt @@ -19,7 +19,8 @@ data class TimelineItemPollContent( val answerItems: List, val pollKind: PollKind, val isEnded: Boolean, - val isEdited: Boolean -) : TimelineItemEventContent { + override val isEdited: Boolean, +) : TimelineItemEventContent, + TimelineItemEventMutableContent { override val type: String = "TimelineItemPollContent" } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt index 06886307ae..ebaeb53b4b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContent.kt @@ -13,6 +13,7 @@ data class TimelineItemStickerContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val mediaSource: MediaSource, val thumbnailSource: MediaSource?, val formattedFileSize: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContentProvider.kt index 7b776a6fd1..76934df3ad 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemStickerContentProvider.kt @@ -29,6 +29,7 @@ fun aTimelineItemStickerContent( filename = "a sticker.gif", caption = "a body", formattedCaption = null, + isEdited = false, mediaSource = MediaSource(""), thumbnailSource = null, mimeType = MimeTypes.IMAGE_JPEG, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt index 756c59f53e..5d61200d0e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemTextBasedContent.kt @@ -14,7 +14,9 @@ import org.jsoup.nodes.Document * Represents a text based content of a timeline item event (a message, a notice, an emote event...). */ @Immutable -sealed interface TimelineItemTextBasedContent : TimelineItemEventContent { +sealed interface TimelineItemTextBasedContent : + TimelineItemEventContent, + TimelineItemEventMutableContent { /** The raw body of the event, in Markdown format. */ val body: String @@ -30,9 +32,6 @@ sealed interface TimelineItemTextBasedContent : TimelineItemEventContent { /** The plain text version of the event body. This is the Markdown version without actual Markdown formatting. */ val plainText: String - /** Whether the event has been edited. */ - val isEdited: Boolean - /** The raw HTML body of the event. */ val htmlBody: String? get() = htmlDocument?.body()?.html() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt index 486a71b5d4..caee06ef64 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContent.kt @@ -14,6 +14,7 @@ data class TimelineItemVideoContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val duration: Duration, val videoSource: MediaSource, val thumbnailSource: MediaSource?, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt index b9390b4e52..1ed05fa606 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVideoContentProvider.kt @@ -30,6 +30,7 @@ fun aTimelineItemVideoContent( filename = "Video.mp4", caption = null, formattedCaption = null, + isEdited = false, thumbnailSource = null, blurHash = blurhash, aspectRatio = aspectRatio, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt index ebeabef715..21b6696ffe 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContent.kt @@ -17,6 +17,7 @@ data class TimelineItemVoiceContent( override val filename: String, override val caption: String?, override val formattedCaption: CharSequence?, + override val isEdited: Boolean, val duration: Duration, val mediaSource: MediaSource, val mimeType: String, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContentProvider.kt index ddd731eceb..bd7308d970 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemVoiceContentProvider.kt @@ -48,6 +48,7 @@ fun aTimelineItemVoiceContent( filename = filename, caption = caption, formattedCaption = null, + isEdited = false, duration = duration, mediaSource = mediaSource, mimeType = mimeType, From 9aa8536d295ac91b80a8a4a11d5c5ef2dd1f35dd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 18:17:29 +0100 Subject: [PATCH 19/47] Protected Content: ensure that the ratio is not too extreme so that the "Show" button is always visible. --- .../components/event/TimelineItemImageView.kt | 3 ++- .../event/TimelineItemStickerView.kt | 3 ++- .../components/event/TimelineItemVideoView.kt | 3 ++- .../protection/AspectRatioPreviewProvider.kt | 19 +++++++++++++++++++ .../impl/timeline/protection/ProtectedView.kt | 14 ++++++++------ .../impl/timeline/protection/RatioHelper.kt | 19 +++++++++++++++++++ 6 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt index 84b7026142..651f361d6c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemImageView.kt @@ -49,6 +49,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContentProvider import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -79,7 +80,7 @@ fun TimelineItemImageView( } TimelineItemAspectRatioBox( modifier = containerModifier.blurHashBackground(content.blurhash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), ) { ProtectedView( hideContent = hideMediaContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt index 9037d0dffa..fd78699ac1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemStickerView.kt @@ -30,6 +30,7 @@ import coil.compose.AsyncImagePainter import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContentProvider import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -54,7 +55,7 @@ fun TimelineItemStickerView( ) { TimelineItemAspectRatioBox( modifier = Modifier.blurHashBackground(content.blurhash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), minHeight = STICKER_SIZE_IN_DP, maxHeight = STICKER_SIZE_IN_DP, ) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt index afd45b171a..eadd84d130 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVideoView.kt @@ -54,6 +54,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContentProvider import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVideoContent import io.element.android.features.messages.impl.timeline.protection.ProtectedView +import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.modifiers.roundedBackground import io.element.android.libraries.designsystem.preview.ElementPreview @@ -90,7 +91,7 @@ fun TimelineItemVideoView( } TimelineItemAspectRatioBox( modifier = containerModifier.blurHashBackground(content.blurHash, alpha = 0.9f), - aspectRatio = content.aspectRatio, + aspectRatio = coerceRatioWhenHidingContent(content.aspectRatio, hideMediaContent), contentAlignment = Alignment.Center, ) { ProtectedView( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt new file mode 100644 index 0000000000..fb296ef7bf --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.protection + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +class AspectRatioPreviewProvider : PreviewParameterProvider { + override val values: Sequence = sequenceOf( + null, + 0.05f, + 1f, + 20f, + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt index 0387572388..631967b6c2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable @@ -23,8 +22,10 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.components.event.TimelineItemAspectRatioBox import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -79,11 +80,12 @@ fun ProtectedView( @PreviewsDayNight @Composable -internal fun ProtectedViewPreview() = ElementPreview { - Box( - modifier = Modifier - .size(160.dp) - .blurHashBackground(A_BLUR_HASH) +internal fun ProtectedViewPreview( + @PreviewParameter(AspectRatioPreviewProvider::class) aspectRatio: Float?, +) = ElementPreview { + TimelineItemAspectRatioBox( + modifier = Modifier.blurHashBackground(A_BLUR_HASH, alpha = 0.9f), + aspectRatio = coerceRatioWhenHidingContent(aspectRatio, true), ) { ProtectedView( hideContent = true, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt new file mode 100644 index 0000000000..2386dff5f4 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/RatioHelper.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.protection + +fun coerceRatioWhenHidingContent(aspectRatio: Float?, hideContent: Boolean): Float? { + return if (hideContent) { + aspectRatio?.coerceIn( + minimumValue = 0.5f, + maximumValue = 3f + ) + } else { + aspectRatio + } +} From fdf8e498944c8744076c876e9695c03fc6ecc0b6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 20:01:02 +0100 Subject: [PATCH 20/47] Fix tests --- .../messages/impl/MessagesPresenterTest.kt | 3 ++ .../TimelineItemContentMessageFactoryTest.kt | 29 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 9ca5c0b98e..f66c8c50b8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -318,6 +318,7 @@ class MessagesPresenterTest { filename = "image.jpg", caption = null, formattedCaption = null, + isEdited = false, mediaSource = MediaSource(AN_AVATAR_URL), thumbnailSource = null, mimeType = MimeTypes.Jpeg, @@ -359,6 +360,7 @@ class MessagesPresenterTest { filename = "video.mp4", caption = null, formattedCaption = null, + isEdited = false, duration = 10.milliseconds, videoSource = MediaSource(AN_AVATAR_URL), thumbnailSource = MediaSource(AN_AVATAR_URL), @@ -400,6 +402,7 @@ class MessagesPresenterTest { content = TimelineItemFileContent( filename = "file.pdf", caption = null, + isEdited = false, formattedCaption = null, fileSource = MediaSource(AN_AVATAR_URL), thumbnailSource = MediaSource(AN_AVATAR_URL), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt index a34e601e5d..07ff31690e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactoryTest.kt @@ -237,6 +237,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = null, formattedCaption = null, + isEdited = false, duration = Duration.ZERO, videoSource = MediaSource(url = "url", json = null), thumbnailSource = null, @@ -278,7 +279,8 @@ class TimelineItemContentMessageFactoryTest { thumbnailSource = MediaSource("url_thumbnail"), blurhash = A_BLUR_HASH, ), - ) + ), + isEdited = true, ), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, @@ -287,6 +289,7 @@ class TimelineItemContentMessageFactoryTest { filename = "body.mp4", caption = "body.mp4 caption", formattedCaption = SpannedString("formatted"), + isEdited = true, duration = 1.minutes, videoSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource("url_thumbnail"), @@ -315,6 +318,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = null, formattedCaption = null, + isEdited = false, duration = Duration.ZERO, mediaSource = MediaSource(url = "url", json = null), mimeType = MimeTypes.OctetStream, @@ -339,7 +343,8 @@ class TimelineItemContentMessageFactoryTest { size = 123L, mimetype = MimeTypes.Mp3, ) - ) + ), + isEdited = true, ), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, @@ -348,6 +353,7 @@ class TimelineItemContentMessageFactoryTest { filename = "body.mp3", caption = null, formattedCaption = null, + isEdited = true, duration = 1.minutes, mediaSource = MediaSource(url = "url", json = null), mimeType = MimeTypes.Mp3, @@ -370,6 +376,7 @@ class TimelineItemContentMessageFactoryTest { eventId = AN_EVENT_ID, caption = null, formattedCaption = null, + isEdited = false, duration = Duration.ZERO, mediaSource = MediaSource(url = "url", json = null), mimeType = MimeTypes.OctetStream, @@ -397,7 +404,8 @@ class TimelineItemContentMessageFactoryTest { duration = 1.minutes, waveform = persistentListOf(1f, 2f), ), - ) + ), + isEdited = true, ), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, @@ -407,6 +415,7 @@ class TimelineItemContentMessageFactoryTest { filename = "body.ogg", caption = null, formattedCaption = null, + isEdited = true, duration = 1.minutes, mediaSource = MediaSource(url = "url", json = null), mimeType = MimeTypes.Ogg, @@ -433,6 +442,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = null, formattedCaption = null, + isEdited = false, duration = Duration.ZERO, mediaSource = MediaSource(url = "url", json = null), mimeType = MimeTypes.OctetStream, @@ -454,6 +464,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = "body", formattedCaption = null, + isEdited = false, mediaSource = MediaSource(url = "url", json = null), thumbnailSource = null, formattedFileSize = "0 Bytes", @@ -483,6 +494,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = null, formattedCaption = null, + isEdited = false, mediaSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource(url = "thumbnail://url", json = null), formattedFileSize = "8192 Bytes", @@ -520,15 +532,17 @@ class TimelineItemContentMessageFactoryTest { thumbnailSource = MediaSource("url_thumbnail"), blurhash = A_BLUR_HASH, ) - ) + ), + isEdited = true, ), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, ) val expected = TimelineItemImageContent( filename = "body.jpg", - formattedCaption = SpannedString("formatted"), caption = "body.jpg caption", + formattedCaption = SpannedString("formatted"), + isEdited = true, mediaSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource("url_thumbnail"), formattedFileSize = "888 Bytes", @@ -556,6 +570,7 @@ class TimelineItemContentMessageFactoryTest { filename = "filename", caption = null, formattedCaption = null, + isEdited = false, fileSource = MediaSource(url = "url", json = null), thumbnailSource = null, formattedFileSize = "0 Bytes", @@ -586,7 +601,8 @@ class TimelineItemContentMessageFactoryTest { ), thumbnailSource = MediaSource("url_thumbnail"), ) - ) + ), + isEdited = true, ), senderDisambiguatedDisplayName = "Bob", eventId = AN_EVENT_ID, @@ -595,6 +611,7 @@ class TimelineItemContentMessageFactoryTest { filename = "body.pdf", caption = null, formattedCaption = null, + isEdited = true, fileSource = MediaSource(url = "url", json = null), thumbnailSource = MediaSource("url_thumbnail"), formattedFileSize = "123 Bytes", From 86042eb19e32adaeeab000bd1949154b82125f5a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 23:43:34 +0000 Subject: [PATCH 21/47] Update dependency org.matrix.rustcomponents:sdk-android to v0.2.64 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index afa7fb3cef..61a08c3c45 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -173,7 +173,7 @@ jsoup = "org.jsoup:jsoup:1.18.1" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.63" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.64" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } From 4fd731b8f6ebc0423ca6101be8ae517a6c665a24 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 20 Nov 2024 21:35:29 +0100 Subject: [PATCH 22/47] Fix test compilation issue. --- .../libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt index c2c23fe6d9..d00582270d 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/RoomPreviewInfo.kt @@ -32,5 +32,6 @@ internal fun aRustRoomPreviewInfo( isHistoryWorldReadable = true, membership = membership, joinRule = joinRule, + heroes = null, ) } From fc0f48570d687d6401c3b6b4e9091c2cf398578f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 21 Nov 2024 08:19:57 +0000 Subject: [PATCH 23/47] Update screenshots --- ...ssages.impl.timeline.protection_ProtectedView_Day_0_en.png | 4 ++-- ...ssages.impl.timeline.protection_ProtectedView_Day_1_en.png | 3 +++ ...ssages.impl.timeline.protection_ProtectedView_Day_2_en.png | 3 +++ ...ssages.impl.timeline.protection_ProtectedView_Day_3_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_0_en.png | 4 ++-- ...ages.impl.timeline.protection_ProtectedView_Night_1_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_2_en.png | 3 +++ ...ages.impl.timeline.protection_ProtectedView_Night_3_en.png | 3 +++ 8 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png index 6dd8676eee..b08546ebae 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db067468af10a72fbaa437a00937afddba100f5345317b9c23b03c8920d5cffa -size 33401 +oid sha256:f40c56aa3b794ce62db9688bf481561d5229a459921e54f55885a6db8f74fe21 +size 64604 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png new file mode 100644 index 0000000000..0103ed2548 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78ea6cbfcf12e405eca8b953b3d847e73f80121ad47beb6346563a2e9b5d567b +size 56342 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png new file mode 100644 index 0000000000..17cfaf70ee --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07ab4fb940d9cae7dcd82d1d6e7235091154414bbb1a6f3a7f557775f8730497 +size 79880 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png new file mode 100644 index 0000000000..6293147f11 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4bafcbc5bc5a62e686adc7194f72a7394b462ad4d99afb0a35380c2f8e1fbeb +size 37409 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png index 3c4052880c..119082c561 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0fc9f20bae5c54d807f5917844669bb8909514483d2ad29b348ef18f8f986a6 -size 33356 +oid sha256:2e3dfc75223f91ecd21c59980a393244be7dfb93a0ebee0885d75fdf5d33d53a +size 64347 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png new file mode 100644 index 0000000000..9e571c9b94 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:047da66e7f7e78478b1d8442028224073e3d31493b5facf926472fc526532be1 +size 56473 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png new file mode 100644 index 0000000000..b38384d81f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d16153ecf852fc504cabc60722eccbe484c992c1bced50f067fb58c46dfd4f7 +size 79088 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png new file mode 100644 index 0000000000..c43a15f287 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.protection_ProtectedView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2aa2e5da25b8a83db35d9b065f0b89cc745cfbda3f6a81d31e445fa31bf4431a +size 37381 From ece62b797883f42f2f4ea108f2a935d28aa5a2ac Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 18 Nov 2024 17:26:12 +0100 Subject: [PATCH 24/47] Allow caption for audio and file. Need to preview all the attachments now, to be able to type a caption. --- .../messages/impl/MessagesStateProvider.kt | 11 ----- .../features/messages/impl/MessagesView.kt | 15 ------ .../preview/AttachmentsPreviewState.kt | 8 +--- .../messagecomposer/MessageComposerEvents.kt | 1 - .../MessageComposerPresenter.kt | 46 +------------------ .../messagecomposer/MessageComposerState.kt | 4 -- .../libraries/matrix/api/room/MatrixRoom.kt | 16 ++++++- .../libraries/matrix/api/timeline/Timeline.kt | 16 ++++++- .../matrix/impl/room/RustMatrixRoom.kt | 32 +++++++++++-- .../matrix/impl/timeline/RustTimeline.kt | 29 +++++++++--- .../matrix/test/room/FakeMatrixRoom.kt | 16 +++++-- .../matrix/test/timeline/FakeTimeline.kt | 16 ++++++- .../libraries/mediaupload/api/MediaSender.kt | 4 ++ 13 files changed, 112 insertions(+), 102 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index e8dc5329f4..c3daabf3ed 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -12,7 +12,6 @@ import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.crypto.identity.IdentityChangeState import io.element.android.features.messages.impl.crypto.identity.anIdentityChangeState -import io.element.android.features.messages.impl.messagecomposer.AttachmentsState import io.element.android.features.messages.impl.messagecomposer.MessageComposerState import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState @@ -62,16 +61,6 @@ open class MessagesStateProvider : PreviewParameterProvider { enableVoiceMessages = true, voiceMessageComposerState = aVoiceMessageComposerState(showPermissionRationaleDialog = true), ), - aMessagesState( - composerState = aMessageComposerState( - attachmentsState = AttachmentsState.Sending.Processing(persistentListOf()) - ), - ), - aMessagesState( - composerState = aMessageComposerState( - attachmentsState = AttachmentsState.Sending.Uploading(0.33f) - ), - ), aMessagesState( roomCallState = anOngoingCallState(), ), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 4351dbcae9..49cbac6268 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -83,8 +83,6 @@ import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorVi import io.element.android.features.roomcall.api.RoomCallState import io.element.android.libraries.androidutils.ui.hideKeyboard import io.element.android.libraries.designsystem.atomic.molecules.IconTitlePlaceholdersRowMolecule -import io.element.android.libraries.designsystem.components.ProgressDialog -import io.element.android.libraries.designsystem.components.ProgressDialogType import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.CompositeAvatar @@ -134,7 +132,6 @@ fun MessagesView( AttachmentStateView( state = state.composerState.attachmentsState, onPreviewAttachments = onPreviewAttachments, - onCancel = { state.composerState.eventSink(MessageComposerEvents.CancelSendAttachment) }, ) val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage) @@ -280,7 +277,6 @@ private fun ReinviteDialog(state: MessagesState) { private fun AttachmentStateView( state: AttachmentsState, onPreviewAttachments: (ImmutableList) -> Unit, - onCancel: () -> Unit, ) { when (state) { AttachmentsState.None -> Unit @@ -290,17 +286,6 @@ private fun AttachmentStateView( latestOnPreviewAttachments(state.attachments) } } - is AttachmentsState.Sending -> { - ProgressDialog( - type = when (state) { - is AttachmentsState.Sending.Uploading -> ProgressDialogType.Determinate(state.progress) - is AttachmentsState.Sending.Processing -> ProgressDialogType.Indeterminate - }, - text = stringResource(id = CommonStrings.common_sending), - showCancelButton = true, - onDismissRequest = onCancel, - ) - } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewState.kt index 5ffe9364ff..5fed2acfb2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/attachments/preview/AttachmentsPreviewState.kt @@ -9,9 +9,6 @@ package io.element.android.features.messages.impl.attachments.preview import androidx.compose.runtime.Immutable import io.element.android.features.messages.impl.attachments.Attachment -import io.element.android.libraries.core.bool.orFalse -import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeImage -import io.element.android.libraries.core.mimetype.MimeTypes.isMimeTypeVideo import io.element.android.libraries.textcomposer.model.TextEditorState data class AttachmentsPreviewState( @@ -20,9 +17,8 @@ data class AttachmentsPreviewState( val textEditorState: TextEditorState, val eventSink: (AttachmentsPreviewEvents) -> Unit ) { - val allowCaption: Boolean = (attachment as? Attachment.Media)?.localMedia?.info?.mimeType?.let { - it.isMimeTypeImage() || it.isMimeTypeVideo() - }.orFalse() + // Keep the val to eventually set to false for some mimetypes. + val allowCaption: Boolean = true } @Immutable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt index fca9948339..036401bb1a 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerEvents.kt @@ -31,7 +31,6 @@ sealed interface MessageComposerEvents { data object Poll : PickAttachmentSource } data class ToggleTextFormatting(val enabled: Boolean) : MessageComposerEvents - data object CancelSendAttachment : MessageComposerEvents data class Error(val error: Throwable) : MessageComposerEvents data class TypingNotice(val isTyping: Boolean) : MessageComposerEvents data class SuggestionReceived(val suggestion: Suggestion?) : MessageComposerEvents diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 6101f48c1f..7ad64c21d0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -42,7 +42,6 @@ import io.element.android.libraries.di.RoomScope import io.element.android.libraries.di.SingleIn import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags -import io.element.android.libraries.matrix.api.core.ProgressCallback import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder import io.element.android.libraries.matrix.api.permalink.PermalinkData @@ -81,7 +80,6 @@ import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.collect @@ -89,11 +87,9 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.merge -import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject -import kotlin.coroutines.coroutineContext import kotlin.time.Duration.Companion.seconds import io.element.android.libraries.core.mimetype.MimeTypes.Any as AnyMimeTypes @@ -180,26 +176,12 @@ class MessageComposerPresenter @Inject constructor( val isFullScreen = rememberSaveable { mutableStateOf(false) } - val ongoingSendAttachmentJob = remember { mutableStateOf(null) } - var showAttachmentSourcePicker: Boolean by remember { mutableStateOf(false) } val sendTypingNotifications by sessionPreferencesStore.isSendTypingNotificationsEnabled().collectAsState(initial = true) val roomAliasSuggestions by roomAliasSuggestionsDataSource.getAllRoomAliasSuggestions().collectAsState(initial = emptyList()) - LaunchedEffect(attachmentsState.value) { - when (val attachmentStateValue = attachmentsState.value) { - is AttachmentsState.Sending.Processing -> { - ongoingSendAttachmentJob.value = localCoroutineScope.sendAttachment( - attachmentStateValue.attachments.first(), - attachmentsState, - ) - } - else -> Unit - } - } - LaunchedEffect(cameraPermissionState.permissionGranted) { if (cameraPermissionState.permissionGranted) { when (pendingEvent) { @@ -338,12 +320,6 @@ class MessageComposerPresenter @Inject constructor( showAttachmentSourcePicker = false // Navigation to the create poll screen is done at the view layer } - is MessageComposerEvents.CancelSendAttachment -> { - ongoingSendAttachmentJob.value?.let { - it.cancel() - ongoingSendAttachmentJob.value == null - } - } is MessageComposerEvents.ToggleTextFormatting -> { showAttachmentSourcePicker = false localCoroutineScope.toggleTextFormatting(event.enabled, markdownTextEditorState, richTextEditorState) @@ -505,17 +481,7 @@ class MessageComposerPresenter @Inject constructor( formattedFileSize = null ) val mediaAttachment = Attachment.Media(localMedia) - val isPreviewable = when { - MimeTypes.isImage(localMedia.info.mimeType) -> true - MimeTypes.isVideo(localMedia.info.mimeType) -> true - MimeTypes.isAudio(localMedia.info.mimeType) -> true - else -> false - } - attachmentsState.value = if (isPreviewable) { - AttachmentsState.Previewing(persistentListOf(mediaAttachment)) - } else { - AttachmentsState.Sending.Processing(persistentListOf(mediaAttachment)) - } + attachmentsState.value = AttachmentsState.Previewing(persistentListOf(mediaAttachment)) } private suspend fun sendMedia( @@ -523,18 +489,10 @@ class MessageComposerPresenter @Inject constructor( mimeType: String, attachmentState: MutableState, ) = runCatching { - val context = coroutineContext - val progressCallback = object : ProgressCallback { - override fun onProgress(current: Long, total: Long) { - if (context.isActive) { - attachmentState.value = AttachmentsState.Sending.Uploading(current.toFloat() / total.toFloat()) - } - } - } mediaSender.sendMedia( uri = uri, mimeType = mimeType, - progressCallback = progressCallback + progressCallback = null, ).getOrThrow() } .onSuccess { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index 5ca4a9c52b..d0e9528e48 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -35,8 +35,4 @@ data class MessageComposerState( sealed interface AttachmentsState { data object None : AttachmentsState data class Previewing(val attachments: ImmutableList) : AttachmentsState - sealed interface Sending : AttachmentsState { - data class Processing(val attachments: ImmutableList) : Sending - data class Uploading(val progress: Float) : Sending - } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index 8dd1c5ec5f..989c301e92 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -147,9 +147,21 @@ interface MatrixRoom : Closeable { progressCallback: ProgressCallback? ): Result - suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result + suspend fun sendAudio( + file: File, + audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result - suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result + suspend fun sendFile( + file: File, + fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt index 695fe906c5..2b7c121dec 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt @@ -91,9 +91,21 @@ interface Timeline : AutoCloseable { suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result - suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result + suspend fun sendAudio( + file: File, + audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result - suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result + suspend fun sendFile( + file: File, + fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index c12fc17553..e3a7e2dfc7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -467,12 +467,36 @@ class RustMatrixRoom( return liveTimeline.sendVideo(file, thumbnailFile, videoInfo, caption, formattedCaption, progressCallback) } - override suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result { - return liveTimeline.sendAudio(file, audioInfo, progressCallback) + override suspend fun sendAudio( + file: File, + audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result { + return liveTimeline.sendAudio( + file = file, + audioInfo = audioInfo, + caption = caption, + formattedCaption = formattedCaption, + progressCallback = progressCallback, + ) } - override suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result { - return liveTimeline.sendFile(file, fileInfo, progressCallback) + override suspend fun sendFile( + file: File, + fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result { + return liveTimeline.sendFile( + file, + fileInfo, + caption, + formattedCaption, + progressCallback, + ) } override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 2b6d8543c4..813cc9c7cb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -373,29 +373,44 @@ class RustTimeline( } } - override suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result { + override suspend fun sendAudio( + file: File, + audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result { val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOf(file)) { inner.sendAudio( url = file.path, audioInfo = audioInfo.map(), - // Maybe allow a caption in the future? - caption = null, - formattedCaption = null, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher() ) } } - override suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result { + override suspend fun sendFile( + file: File, + fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, + progressCallback: ProgressCallback?, + ): Result { val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue) return sendAttachment(listOf(file)) { inner.sendFile( url = file.path, fileInfo = fileInfo.map(), - caption = null, - formattedCaption = null, + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, useSendQueue = useSendQueue, progressWatcher = progressCallback?.toProgressWatcher(), ) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index 9574a2a22c..9974e36746 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -92,10 +92,10 @@ class FakeMatrixRoom( { _, _, _, _, _, _ -> lambdaError() }, private val sendVideoResult: (File, File?, VideoInfo, String?, String?, ProgressCallback?) -> Result = { _, _, _, _, _, _ -> lambdaError() }, - private val sendFileResult: (File, FileInfo, ProgressCallback?) -> Result = - { _, _, _ -> lambdaError() }, - private val sendAudioResult: (File, AudioInfo, ProgressCallback?) -> Result = - { _, _, _ -> lambdaError() }, + private val sendFileResult: (File, FileInfo, String?, String?, ProgressCallback?) -> Result = + { _, _, _, _, _ -> lambdaError() }, + private val sendAudioResult: (File, AudioInfo, String?, String?, ProgressCallback?) -> Result = + { _, _, _, _, _ -> lambdaError() }, private val sendVoiceMessageResult: (File, AudioInfo, List, ProgressCallback?) -> Result = { _, _, _, _ -> lambdaError() }, private val setNameResult: (String) -> Result = { lambdaError() }, @@ -354,12 +354,16 @@ class FakeMatrixRoom( override suspend fun sendAudio( file: File, audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback? ): Result = simulateLongTask { simulateSendMediaProgress(progressCallback) sendAudioResult( file, audioInfo, + caption, + formattedCaption, progressCallback, ) } @@ -367,12 +371,16 @@ class FakeMatrixRoom( override suspend fun sendFile( file: File, fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback? ): Result = simulateLongTask { simulateSendMediaProgress(progressCallback) sendFileResult( file, fileInfo, + caption, + formattedCaption, progressCallback, ) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt index ae40a0a51e..f96815c85a 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt @@ -173,36 +173,48 @@ class FakeTimeline( var sendAudioLambda: ( file: File, audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback?, - ) -> Result = { _, _, _ -> + ) -> Result = { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } override suspend fun sendAudio( file: File, audioInfo: AudioInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback?, ): Result = sendAudioLambda( file, audioInfo, + caption, + formattedCaption, progressCallback ) var sendFileLambda: ( file: File, fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback?, - ) -> Result = { _, _, _ -> + ) -> Result = { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } override suspend fun sendFile( file: File, fileInfo: FileInfo, + caption: String?, + formattedCaption: String?, progressCallback: ProgressCallback?, ): Result = sendFileLambda( file, fileInfo, + caption, + formattedCaption, progressCallback ) diff --git a/libraries/mediaupload/api/src/main/kotlin/io/element/android/libraries/mediaupload/api/MediaSender.kt b/libraries/mediaupload/api/src/main/kotlin/io/element/android/libraries/mediaupload/api/MediaSender.kt index 09b8de4b41..77e6d021d5 100644 --- a/libraries/mediaupload/api/src/main/kotlin/io/element/android/libraries/mediaupload/api/MediaSender.kt +++ b/libraries/mediaupload/api/src/main/kotlin/io/element/android/libraries/mediaupload/api/MediaSender.kt @@ -125,6 +125,8 @@ class MediaSender @Inject constructor( sendAudio( file = uploadInfo.file, audioInfo = uploadInfo.audioInfo, + caption = caption, + formattedCaption = formattedCaption, progressCallback = progressCallback ) } @@ -140,6 +142,8 @@ class MediaSender @Inject constructor( sendFile( file = uploadInfo.file, fileInfo = uploadInfo.fileInfo, + caption = caption, + formattedCaption = formattedCaption, progressCallback = progressCallback ) } From f353ecdd45154296ad1c28eada8afaf554ec5fb0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2024 10:00:43 +0100 Subject: [PATCH 25/47] Render caption below audio and file Event in the timeline. --- .../event/TimelineItemAttachmentView.kt | 128 ++++++++++++++++++ .../components/event/TimelineItemAudioView.kt | 52 +------ .../components/event/TimelineItemFileView.kt | 52 +------ .../event/TimelineItemAudioContentProvider.kt | 11 +- .../event/TimelineItemFileContentProvider.kt | 7 +- 5 files changed, 155 insertions(+), 95 deletions(-) create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt new file mode 100644 index 0000000000..2624a8b5e7 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAttachmentView.kt @@ -0,0 +1,128 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.messages.impl.timeline.components.event + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayout +import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData +import io.element.android.libraries.designsystem.theme.components.Text + +/** + * package-private, you should only use TimelineItemFileView and TimelineItemAudioView. + */ +@Composable +fun TimelineItemAttachmentView( + filename: String, + fileExtensionAndSize: String, + caption: String?, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, + icon: (@Composable () -> Unit) = {}, +) { + Column( + modifier = modifier, + ) { + TimelineItemAttachmentHeaderView( + filename = filename, + fileExtensionAndSize = fileExtensionAndSize, + hasCaption = caption != null, + onContentLayoutChange = onContentLayoutChange, + icon = icon, + ) + if (caption != null) { + TimelineItemAttachmentCaptionView( + modifier = Modifier.padding(top = 4.dp), + caption = caption, + onContentLayoutChange = onContentLayoutChange, + ) + } + } +} + +@Composable +private fun TimelineItemAttachmentHeaderView( + filename: String, + fileExtensionAndSize: String, + hasCaption: Boolean, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, + icon: (@Composable () -> Unit), +) { + val iconSize = 32.dp + val spacing = 8.dp + Row( + modifier = modifier, + ) { + Box( + modifier = Modifier + .size(iconSize) + .clip(CircleShape) + .background(ElementTheme.materialColors.background), + contentAlignment = Alignment.Center, + ) { + icon() + } + Spacer(Modifier.width(spacing)) + Column { + Text( + text = filename, + color = ElementTheme.materialColors.primary, + maxLines = 2, + style = ElementTheme.typography.fontBodyLgRegular, + overflow = TextOverflow.Ellipsis + ) + Text( + text = fileExtensionAndSize, + color = ElementTheme.materialColors.secondary, + style = ElementTheme.typography.fontBodySmRegular, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + onTextLayout = if (hasCaption) { + {} + } else { + ContentAvoidingLayout.measureLastTextLine( + onContentLayoutChange = onContentLayoutChange, + extraWidth = iconSize + spacing + ) + }, + ) + } + } +} + +@Composable +private fun TimelineItemAttachmentCaptionView( + caption: String, + onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, + modifier: Modifier = Modifier, +) { + Text( + modifier = modifier, + text = caption, + color = ElementTheme.materialColors.primary, + style = ElementTheme.typography.fontBodyLgRegular, + onTextLayout = ContentAvoidingLayout.measureLastTextLine( + onContentLayoutChange = onContentLayoutChange, + ) + ) +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt index 23069a1fac..32e97eed58 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemAudioView.kt @@ -7,32 +7,20 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.GraphicEq import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayout import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContentProvider import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemAudioView( @@ -40,18 +28,13 @@ fun TimelineItemAudioView( onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { - val iconSize = 32.dp - val spacing = 8.dp - Row( + TimelineItemAttachmentView( + filename = content.filename, + fileExtensionAndSize = content.fileExtensionAndSize, + caption = content.caption, + onContentLayoutChange = onContentLayoutChange, modifier = modifier, - ) { - Box( - modifier = Modifier - .size(iconSize) - .clip(CircleShape) - .background(ElementTheme.materialColors.background), - contentAlignment = Alignment.Center, - ) { + icon = { Icon( imageVector = Icons.Outlined.GraphicEq, contentDescription = null, @@ -60,28 +43,7 @@ fun TimelineItemAudioView( .size(16.dp), ) } - Spacer(Modifier.width(spacing)) - Column { - Text( - text = content.bestDescription, - color = ElementTheme.materialColors.primary, - maxLines = 2, - style = ElementTheme.typography.fontBodyLgRegular, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.fileExtensionAndSize, - color = ElementTheme.materialColors.secondary, - style = ElementTheme.typography.fontBodySmRegular, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - onTextLayout = ContentAvoidingLayout.measureLastTextLine( - onContentLayoutChange = onContentLayoutChange, - extraWidth = iconSize + spacing - ) - ) - } - } + ) } @PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt index dadfadc299..a3cdd7701e 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemFileView.kt @@ -7,24 +7,13 @@ package io.element.android.features.messages.impl.timeline.components.event -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.rotate -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayout import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContentProvider @@ -32,7 +21,6 @@ import io.element.android.libraries.designsystem.icons.CompoundDrawables import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Text @Composable fun TimelineItemFileView( @@ -40,18 +28,13 @@ fun TimelineItemFileView( onContentLayoutChange: (ContentAvoidingLayoutData) -> Unit, modifier: Modifier = Modifier, ) { - val iconSize = 32.dp - val spacing = 8.dp - Row( + TimelineItemAttachmentView( + filename = content.filename, + fileExtensionAndSize = content.fileExtensionAndSize, + caption = content.caption, + onContentLayoutChange = onContentLayoutChange, modifier = modifier, - ) { - Box( - modifier = Modifier - .size(iconSize) - .clip(CircleShape) - .background(ElementTheme.materialColors.background), - contentAlignment = Alignment.Center, - ) { + icon = { Icon( resourceId = CompoundDrawables.ic_compound_attachment, contentDescription = null, @@ -61,28 +44,7 @@ fun TimelineItemFileView( .rotate(-45f), ) } - Spacer(Modifier.width(spacing)) - Column { - Text( - text = content.bestDescription, - color = ElementTheme.materialColors.primary, - maxLines = 2, - style = ElementTheme.typography.fontBodyLgRegular, - overflow = TextOverflow.Ellipsis - ) - Text( - text = content.fileExtensionAndSize, - color = ElementTheme.materialColors.secondary, - style = ElementTheme.typography.fontBodySmRegular, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - onTextLayout = ContentAvoidingLayout.measureLastTextLine( - onContentLayoutChange = onContentLayoutChange, - extraWidth = iconSize + spacing - ) - ) - } - } + ) } @PreviewsDayNight diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt index 41dab0cfb6..d3ca18e836 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/event/TimelineItemAudioContentProvider.kt @@ -17,13 +17,18 @@ open class TimelineItemAudioContentProvider : PreviewParameterProvider Date: Tue, 19 Nov 2024 11:55:46 +0100 Subject: [PATCH 26/47] Edit / Add / Remove caption --- .../messages/impl/MessagesPresenter.kt | 40 +++++++ .../impl/actionlist/ActionListPresenter.kt | 11 ++ .../actionlist/model/TimelineItemAction.kt | 3 + .../MessageComposerPresenter.kt | 27 ++++- .../libraries/matrix/api/timeline/Timeline.kt | 9 +- .../matrix/impl/timeline/RustTimeline.kt | 48 +++++--- .../matrix/test/timeline/FakeTimeline.kt | 18 +++ .../textcomposer/ComposerModeView.kt | 15 ++- .../libraries/textcomposer/TextComposer.kt | 112 +++++++++++++----- .../textcomposer/components/SendButton.kt | 12 +- .../textcomposer/model/MessageComposerMode.kt | 15 +-- .../src/main/res/values/localazy.xml | 5 + 12 files changed, 246 insertions(+), 69 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 7840c307c7..49d3015c05 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -43,6 +43,7 @@ import io.element.android.features.messages.impl.timeline.components.customreact import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState import io.element.android.features.messages.impl.timeline.model.TimelineItem +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent @@ -273,6 +274,9 @@ class MessagesPresenter @AssistedInject constructor( TimelineItemAction.CopyLink -> handleCopyLink(targetEvent) TimelineItemAction.Redact -> handleActionRedact(targetEvent) TimelineItemAction.Edit -> handleActionEdit(targetEvent, composerState, enableTextFormatting) + TimelineItemAction.AddCaption -> handleActionAddCaption(targetEvent, composerState) + TimelineItemAction.EditCaption -> handleActionEditCaption(targetEvent, composerState) + TimelineItemAction.RemoveCaption -> handleRemoveCaption(targetEvent) TimelineItemAction.Reply, TimelineItemAction.ReplyInThread -> handleActionReply(targetEvent, composerState, timelineProtectionState) TimelineItemAction.ViewSource -> handleShowDebugInfoAction(targetEvent) @@ -285,6 +289,16 @@ class MessagesPresenter @AssistedInject constructor( } } + private suspend fun handleRemoveCaption(targetEvent: TimelineItem.Event) { + timelineController.invokeOnCurrentTimeline { + editCaption( + eventOrTransactionId = targetEvent.eventOrTransactionId, + caption = null, + formattedCaption = null, + ) + } + } + private suspend fun handlePinAction(targetEvent: TimelineItem.Event) { if (targetEvent.eventId == null) return analyticsService.capture( @@ -387,6 +401,32 @@ class MessagesPresenter @AssistedInject constructor( } } + private fun handleActionAddCaption( + targetEvent: TimelineItem.Event, + composerState: MessageComposerState, + ) { + val composerMode = MessageComposerMode.EditCaption( + eventOrTransactionId = targetEvent.eventOrTransactionId, + content = "", + ) + composerState.eventSink( + MessageComposerEvents.SetMode(composerMode) + ) + } + + private fun handleActionEditCaption( + targetEvent: TimelineItem.Event, + composerState: MessageComposerState, + ) { + val composerMode = MessageComposerMode.EditCaption( + eventOrTransactionId = targetEvent.eventOrTransactionId, + content = (targetEvent.content as? TimelineItemEventContentWithAttachment)?.caption.orEmpty(), + ) + composerState.eventSink( + MessageComposerEvents.SetMode(composerMode) + ) + } + private suspend fun handleActionReply( targetEvent: TimelineItem.Event, composerState: MessageComposerState, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 39e6cd8836..7bd4668ed4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -27,6 +27,7 @@ import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUser import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent @@ -154,6 +155,16 @@ class DefaultActionListPresenter @AssistedInject constructor( } if (timelineItem.isEditable) { add(TimelineItemAction.Edit) + } else { + // Caption + if (timelineItem.isMine && timelineItem.content is TimelineItemEventContentWithAttachment) { + if (timelineItem.content.caption == null) { + add(TimelineItemAction.AddCaption) + } else { + add(TimelineItemAction.EditCaption) + add(TimelineItemAction.RemoveCaption) + } + } } if (canRedact && timelineItem.content is TimelineItemPollContent && !timelineItem.content.isEnded) { add(TimelineItemAction.EndPoll) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt index cddf3ff8e4..979f041297 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt @@ -28,6 +28,9 @@ sealed class TimelineItemAction( data object Reply : TimelineItemAction(CommonStrings.action_reply, CompoundDrawables.ic_compound_reply) data object ReplyInThread : TimelineItemAction(CommonStrings.action_reply_in_thread, CompoundDrawables.ic_compound_reply) data object Edit : TimelineItemAction(CommonStrings.action_edit, CompoundDrawables.ic_compound_edit) + data object EditCaption : TimelineItemAction(CommonStrings.action_edit_caption, CompoundDrawables.ic_compound_edit) + data object AddCaption : TimelineItemAction(CommonStrings.action_add_caption, CompoundDrawables.ic_compound_edit) + data object RemoveCaption : TimelineItemAction(CommonStrings.action_remove_caption, CompoundDrawables.ic_compound_delete, destructive = true) data object ViewSource : TimelineItemAction(CommonStrings.action_view_source, CommonDrawables.ic_developer_options) data object ReportContent : TimelineItemAction(CommonStrings.action_report_content, CompoundDrawables.ic_compound_chat_problem, destructive = true) data object EndPoll : TimelineItemAction(CommonStrings.action_end_poll, CompoundDrawables.ic_compound_polls_end) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 7ad64c21d0..ebccc8dff4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -254,7 +254,7 @@ class MessageComposerPresenter @Inject constructor( when (event) { MessageComposerEvents.ToggleFullScreenState -> isFullScreen.value = !isFullScreen.value MessageComposerEvents.CloseSpecialMode -> { - if (messageComposerContext.composerMode is MessageComposerMode.Edit) { + if (messageComposerContext.composerMode.isEditing) { localCoroutineScope.launch { resetComposer(markdownTextEditorState, richTextEditorState, fromEdit = true) } @@ -431,7 +431,15 @@ class MessageComposerPresenter @Inject constructor( } } } - + is MessageComposerMode.EditCaption -> { + timelineController.invokeOnCurrentTimeline { + editCaption( + capturedMode.eventOrTransactionId, + caption = message.markdown, + formattedCaption = message.html + ) + } + } is MessageComposerMode.Reply -> { timelineController.invokeOnCurrentTimeline { replyMessage(capturedMode.eventId, message.markdown, message.html, message.intentionalMentions) @@ -570,6 +578,10 @@ class MessageComposerPresenter @Inject constructor( mode.eventOrTransactionId.eventId?.let { eventId -> ComposerDraftType.Edit(eventId) } } is MessageComposerMode.Reply -> ComposerDraftType.Reply(mode.eventId) + is MessageComposerMode.EditCaption -> { + // TODO Need a new type to save caption in the SDK + null + } } return if (draftType == null || message.markdown.isBlank()) { null @@ -644,7 +656,14 @@ class MessageComposerPresenter @Inject constructor( val currentComposerMode = messageComposerContext.composerMode when (newComposerMode) { is MessageComposerMode.Edit -> { - if (currentComposerMode !is MessageComposerMode.Edit) { + if (currentComposerMode.isEditing.not()) { + val draft = createDraftFromState(markdownTextEditorState, richTextEditorState) + updateDraft(draft, isVolatile = true).join() + } + setText(newComposerMode.content, markdownTextEditorState, richTextEditorState) + } + is MessageComposerMode.EditCaption -> { + if (currentComposerMode.isEditing.not()) { val draft = createDraftFromState(markdownTextEditorState, richTextEditorState) updateDraft(draft, isVolatile = true).join() } @@ -652,7 +671,7 @@ class MessageComposerPresenter @Inject constructor( } else -> { // When coming from edit, just clear the composer as it'd be weird to reset a volatile draft in this scenario. - if (currentComposerMode is MessageComposerMode.Edit) { + if (currentComposerMode.isEditing) { setText("", markdownTextEditorState, richTextEditorState) } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt index 2b7c121dec..00f7a9a17c 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt @@ -59,10 +59,17 @@ interface Timeline : AutoCloseable { suspend fun editMessage( eventOrTransactionId: EventOrTransactionId, - body: String, htmlBody: String?, + body: String, + htmlBody: String?, intentionalMentions: List, ): Result + suspend fun editCaption( + eventOrTransactionId: EventOrTransactionId, + caption: String?, + formattedCaption: String?, + ): Result + suspend fun replyMessage( eventId: EventId, body: String, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 813cc9c7cb..200f1289b4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -295,22 +295,40 @@ class RustTimeline( body: String, htmlBody: String?, intentionalMentions: List, - ): Result = - withContext(dispatcher) { - runCatching { - val editedContent = EditedContent.RoomMessage( - content = MessageEventContent.from( - body = body, - htmlBody = htmlBody, - intentionalMentions = intentionalMentions - ), - ) - inner.edit( - newContent = editedContent, - eventOrTransactionId = eventOrTransactionId.toRustEventOrTransactionId(), - ) - } + ): Result = withContext(dispatcher) { + runCatching { + val editedContent = EditedContent.RoomMessage( + content = MessageEventContent.from( + body = body, + htmlBody = htmlBody, + intentionalMentions = intentionalMentions + ), + ) + inner.edit( + newContent = editedContent, + eventOrTransactionId = eventOrTransactionId.toRustEventOrTransactionId(), + ) } + } + + override suspend fun editCaption( + eventOrTransactionId: EventOrTransactionId, + caption: String?, + formattedCaption: String?, + ): Result = withContext(dispatcher) { + runCatching { + val editedContent = EditedContent.MediaCaption( + caption = caption, + formattedCaption = formattedCaption?.let { + FormattedBody(body = it, format = MessageFormat.Html) + }, + ) + inner.edit( + newContent = editedContent, + eventOrTransactionId = eventOrTransactionId.toRustEventOrTransactionId(), + ) + } + } override suspend fun replyMessage( eventId: EventId, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt index f96815c85a..6edfd22c50 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt @@ -92,6 +92,24 @@ class FakeTimeline( intentionalMentions ) + var editCaptionLambda: ( + eventOrTransactionId: EventOrTransactionId, + caption: String?, + formattedCaption: String?, + ) -> Result = { _, _, _ -> + lambdaError() + } + + override suspend fun editCaption( + eventOrTransactionId: EventOrTransactionId, + caption: String?, + formattedCaption: String?, + ): Result = editCaptionLambda( + eventOrTransactionId, + caption, + formattedCaption, + ) + var replyMessageLambda: ( eventId: EventId, body: String, diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt index 218a8653cf..eaa5669206 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/ComposerModeView.kt @@ -47,6 +47,16 @@ internal fun ComposerModeView( when (composerMode) { is MessageComposerMode.Edit -> { EditingModeView( + text = stringResource(CommonStrings.common_editing), + modifier = modifier, + onResetComposerMode = onResetComposerMode, + ) + } + is MessageComposerMode.EditCaption -> { + EditingModeView( + text = stringResource( + if (composerMode.content.isEmpty()) CommonStrings.common_adding_caption else CommonStrings.common_editing_caption + ), modifier = modifier, onResetComposerMode = onResetComposerMode, ) @@ -65,6 +75,7 @@ internal fun ComposerModeView( @Composable private fun EditingModeView( onResetComposerMode: () -> Unit, + text: String, modifier: Modifier = Modifier, ) { Row( @@ -76,14 +87,14 @@ private fun EditingModeView( ) { Icon( imageVector = CompoundIcons.Edit(), - contentDescription = stringResource(CommonStrings.common_editing), + contentDescription = null, tint = ElementTheme.materialColors.secondary, modifier = Modifier .padding(vertical = 8.dp) .size(16.dp), ) Text( - stringResource(CommonStrings.common_editing), + text = text, style = ElementTheme.typography.fontBodySmRegular, textAlign = TextAlign.Start, color = ElementTheme.materialColors.secondary, diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index eca7340219..81cc7a739f 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -121,19 +121,25 @@ fun TextComposer( } val layoutModifier = modifier - .fillMaxSize() - .height(IntrinsicSize.Min) + .fillMaxSize() + .height(IntrinsicSize.Min) - val composerOptionsButton: @Composable () -> Unit = remember { + val composerOptionsButton: @Composable () -> Unit = remember(composerMode) { @Composable { - if (composerMode is MessageComposerMode.Attachment) { - Spacer(modifier = Modifier.width(9.dp)) - } else { - ComposerOptionsButton( - modifier = Modifier - .size(48.dp), - onClick = onAddAttachment - ) + when (composerMode) { + is MessageComposerMode.Attachment -> { + Spacer(modifier = Modifier.width(9.dp)) + } + is MessageComposerMode.EditCaption -> { + Spacer(modifier = Modifier.width(16.dp)) + } + else -> { + ComposerOptionsButton( + modifier = Modifier + .size(48.dp), + onClick = onAddAttachment + ) + } } } } @@ -331,8 +337,8 @@ private fun StandardLayout( if (voiceMessageState is VoiceMessageState.Preview || voiceMessageState is VoiceMessageState.Recording) { Box( modifier = Modifier - .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) - .size(48.dp), + .padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp) + .size(48.dp), contentAlignment = Alignment.Center, ) { voiceDeleteButton() @@ -342,8 +348,8 @@ private fun StandardLayout( } Box( modifier = Modifier - .padding(bottom = 8.dp, top = 8.dp) - .weight(1f) + .padding(bottom = 8.dp, top = 8.dp) + .weight(1f) ) { voiceRecording() } @@ -356,16 +362,16 @@ private fun StandardLayout( } Box( modifier = Modifier - .padding(bottom = 8.dp, top = 8.dp) - .weight(1f) + .padding(bottom = 8.dp, top = 8.dp) + .weight(1f) ) { textInput() } } Box( - Modifier - .padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp) - .size(48.dp), + Modifier + .padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp) + .size(48.dp), contentAlignment = Alignment.Center, ) { endButton() @@ -387,8 +393,8 @@ private fun TextFormattingLayout( ) { Box( modifier = Modifier - .weight(1f) - .padding(horizontal = 12.dp) + .weight(1f) + .padding(horizontal = 12.dp) ) { textInput() } @@ -432,11 +438,11 @@ private fun TextInputBox( Column( modifier = Modifier - .clip(roundedCorners) - .border(0.5.dp, borderColor, roundedCorners) - .background(color = bgColor) - .requiredHeightIn(min = 42.dp) - .fillMaxSize(), + .clip(roundedCorners) + .border(0.5.dp, borderColor, roundedCorners) + .background(color = bgColor) + .requiredHeightIn(min = 42.dp) + .fillMaxSize(), ) { if (composerMode is MessageComposerMode.Special) { ComposerModeView( @@ -447,9 +453,9 @@ private fun TextInputBox( val defaultTypography = ElementTheme.typography.fontBodyLgRegular Box( modifier = Modifier - .padding(top = 4.dp, bottom = 4.dp, start = 12.dp, end = 12.dp) - // Apply test tag only once, otherwise 2 nodes will have it (both the normal and subcomposing one) and tests will fail - .then(if (!subcomposing) Modifier.testTag(TestTags.textEditor) else Modifier), + .padding(top = 4.dp, bottom = 4.dp, start = 12.dp, end = 12.dp) + // Apply test tag only once, otherwise 2 nodes will have it (both the normal and subcomposing one) and tests will fail + .then(if (!subcomposing) Modifier.testTag(TestTags.textEditor) else Modifier), contentAlignment = Alignment.CenterStart, ) { // Placeholder @@ -495,8 +501,8 @@ private fun TextInput( // This prevents it gaining focus and mutating the state. registerStateUpdates = !subcomposing, modifier = Modifier - .padding(top = 6.dp, bottom = 6.dp) - .fillMaxWidth(), + .padding(top = 6.dp, bottom = 6.dp) + .fillMaxWidth(), style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus), resolveMentionDisplay = resolveMentionDisplay, resolveRoomMentionDisplay = resolveRoomMentionDisplay, @@ -573,6 +579,40 @@ internal fun TextComposerEditPreview() = ElementPreview { } } +@PreviewsDayNight +@Composable +internal fun TextComposerEditCaptionPreview() = ElementPreview { + PreviewColumn( + items = aTextEditorStateRichList() + ) { _, textEditorState -> + ATextComposer( + state = textEditorState, + voiceMessageState = VoiceMessageState.Idle, + composerMode = aMessageComposerModeEditCaption( + content = "A caption", + ), + enableVoiceMessages = false, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun TextComposerAddCaptionPreview() = ElementPreview { + PreviewColumn( + items = aTextEditorStateRichList() + ) { _, textEditorState -> + ATextComposer( + state = textEditorState, + voiceMessageState = VoiceMessageState.Idle, + composerMode = aMessageComposerModeEditCaption( + content = "", + ), + enableVoiceMessages = false, + ) + } +} + @PreviewsDayNight @Composable internal fun MarkdownTextComposerEditPreview() = ElementPreview { @@ -717,6 +757,14 @@ fun aMessageComposerModeEdit( content = content ) +fun aMessageComposerModeEditCaption( + eventOrTransactionId: EventOrTransactionId = EventId("$1234").toEventOrTransactionId(), + content: String = "Some caption", +) = MessageComposerMode.EditCaption( + eventOrTransactionId = eventOrTransactionId, + content = content +) + fun aMessageComposerModeReply( replyToDetails: InReplyToDetails, hideImage: Boolean = false, diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt index 6b5d601333..b7b0368aeb 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/SendButton.kt @@ -53,16 +53,16 @@ internal fun SendButton( onClick = onClick, enabled = canSendMessage, ) { - val iconVector = when (composerMode) { - is MessageComposerMode.Edit -> CompoundIcons.Check() + val iconVector = when { + composerMode.isEditing -> CompoundIcons.Check() else -> CompoundIcons.SendSolid() } - val iconStartPadding = when (composerMode) { - is MessageComposerMode.Edit -> 0.dp + val iconStartPadding = when { + composerMode.isEditing -> 0.dp else -> 2.dp } - val contentDescription = when (composerMode) { - is MessageComposerMode.Edit -> stringResource(CommonStrings.action_edit) + val contentDescription = when { + composerMode.isEditing -> stringResource(CommonStrings.action_edit) else -> stringResource(CommonStrings.action_send) } Box( diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt index 1915359c83..4ef6cfc019 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/MessageComposerMode.kt @@ -27,6 +27,11 @@ sealed interface MessageComposerMode { val content: String ) : Special + data class EditCaption( + val eventOrTransactionId: EventOrTransactionId, + val content: String + ) : Special + data class Reply( val replyToDetails: InReplyToDetails, val hideImage: Boolean, @@ -34,16 +39,8 @@ sealed interface MessageComposerMode { val eventId: EventId = replyToDetails.eventId() } - val relatedEventId: EventId? - get() = when (this) { - is Normal, - is Attachment -> null - is Edit -> eventOrTransactionId.eventId - is Reply -> eventId - } - val isEditing: Boolean - get() = this is Edit + get() = this is Edit || this is EditCaption val isReply: Boolean get() = this is Reply diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index ab3a93a692..2245657b6b 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -32,6 +32,7 @@ "Record voice message." "Stop recording" "Accept" + "Add caption" "Add to timeline" "Back" "Call" @@ -57,6 +58,7 @@ "Discard" "Done" "Edit" + "Edit caption" "Edit poll" "Enable" "End poll" @@ -91,6 +93,7 @@ "React" "Reject" "Remove" + "Remove caption" "Reply" "Reply in thread" "Report bug" @@ -123,6 +126,7 @@ "Yes" "About" "Acceptable use policy" + "Adding caption" "Advanced settings" "Analytics" "Appearance" @@ -143,6 +147,7 @@ "Do not show this again" "(edited)" "Editing" + "Editing caption" "* %1$s %2$s" "Encryption" "Encryption enabled" From f3e0a4dc00327adf6b51d20627c10a26d5ead9b3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2024 14:56:15 +0100 Subject: [PATCH 27/47] Add matrix_sdk::send_queue to be able to configure it. --- .../libraries/matrix/api/tracing/TracingFilterConfiguration.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt index ec80d320c5..8516401350 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/tracing/TracingFilterConfiguration.kt @@ -57,6 +57,7 @@ enum class Target(open val filter: String) { MATRIX_SDK_HTTP_CLIENT("matrix_sdk::http_client"), MATRIX_SDK_CLIENT("matrix_sdk::client"), MATRIX_SDK_OIDC("matrix_sdk::oidc"), + MATRIX_SDK_SEND_QUEUE("matrix_sdk::send_queue"), MATRIX_SDK_SLIDING_SYNC("matrix_sdk::sliding_sync"), MATRIX_SDK_BASE_SLIDING_SYNC("matrix_sdk_base::sliding_sync"), MATRIX_SDK_UI_TIMELINE("matrix_sdk_ui::timeline"), From d6ee0846b33b028909116ca673aef2218c79ce53 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2024 17:32:41 +0100 Subject: [PATCH 28/47] Fix tests --- .../impl/actionlist/ActionListPresenter.kt | 5 +- .../actionlist/ActionListPresenterTest.kt | 53 ++++++++++++++- .../AttachmentsPreviewPresenterTest.kt | 4 +- .../MessageComposerPresenterTest.kt | 64 +------------------ .../features/share/impl/SharePresenterTest.kt | 2 +- .../mediaupload/api/MediaSenderTest.kt | 2 +- .../tests/konsist/KonsistPreviewTest.kt | 2 + 7 files changed, 63 insertions(+), 69 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 7bd4668ed4..2ae72c86c6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -32,6 +32,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent +import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.model.event.canBeCopied import io.element.android.features.messages.impl.timeline.model.event.canBeForwarded import io.element.android.features.messages.impl.timeline.model.event.canReact @@ -157,7 +158,9 @@ class DefaultActionListPresenter @AssistedInject constructor( add(TimelineItemAction.Edit) } else { // Caption - if (timelineItem.isMine && timelineItem.content is TimelineItemEventContentWithAttachment) { + if (timelineItem.isMine && + timelineItem.content is TimelineItemEventContentWithAttachment && + timelineItem.content !is TimelineItemVoiceContent) { if (timelineItem.content.caption == null) { add(TimelineItemAction.AddCaption) } else { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 078fb9e676..98d6ad0ec7 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.features.poll.api.pollcontent.aPollAnswerItemList import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_CAPTION import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.room.FakeMatrixRoom @@ -444,8 +445,6 @@ class ActionListPresenterTest { ), ) ) - // val loadingState = awaitItem() - // assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent)) val successState = awaitItem() assertThat(successState.target).isEqualTo( ActionListState.Target.Success( @@ -455,6 +454,56 @@ class ActionListPresenterTest { actions = persistentListOf( TimelineItemAction.Reply, TimelineItemAction.Forward, + TimelineItemAction.AddCaption, + TimelineItemAction.Pin, + TimelineItemAction.CopyLink, + TimelineItemAction.ViewSource, + TimelineItemAction.Redact, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + + @Test + fun `present - compute for a media with caption item`() = runTest { + val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = true, + isEditable = false, + content = aTimelineItemImageContent( + caption = A_CAPTION, + ), + ) + initialState.eventSink.invoke( + ActionListEvents.ComputeForMessage( + event = messageEvent, + userEventPermissions = aUserEventPermissions( + canRedactOwn = true, + canRedactOther = false, + canSendMessage = true, + canSendReaction = true, + canPinUnpin = true, + ), + ) + ) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + event = messageEvent, + displayEmojiReactions = true, + verifiedUserSendFailure = VerifiedUserSendFailure.None, + actions = persistentListOf( + TimelineItemAction.Reply, + TimelineItemAction.Forward, + TimelineItemAction.EditCaption, + TimelineItemAction.RemoveCaption, TimelineItemAction.Pin, TimelineItemAction.CopyLink, TimelineItemAction.ViewSource, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt index ac753f6cdb..bc61728cb1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt @@ -60,7 +60,7 @@ class AttachmentsPreviewPresenterTest { @Test fun `present - send media success scenario`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val room = FakeMatrixRoom( @@ -192,7 +192,7 @@ class AttachmentsPreviewPresenterTest { @Test fun `present - send media failure scenario`() = runTest { val failure = MediaPreProcessor.Failure(null) - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.failure(failure) } val room = FakeMatrixRoom( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 2e68c9b199..c1d1fd8c11 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -30,9 +30,7 @@ import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.core.ProgressCallback import io.element.android.libraries.matrix.api.core.RoomId -import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder @@ -58,7 +56,6 @@ import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.A_USER_ID_4 import io.element.android.libraries.matrix.test.core.aBuildMeta -import io.element.android.libraries.matrix.test.media.FakeMediaUploadHandler import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.room.FakeMatrixRoom @@ -684,17 +681,8 @@ class MessageComposerPresenterTest { } @Test - fun `present - Pick file from storage`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> - Result.success(FakeMediaUploadHandler()) - } + fun `present - Pick file from storage will open the preview`() = runTest { val room = FakeMatrixRoom( - progressCallbackValues = listOf( - Pair(0, 10), - Pair(5, 10), - Pair(10, 10) - ), - sendFileResult = sendFileResult, typingNoticeResult = { Result.success(Unit) } ) val presenter = createPresenter(this, room = room) @@ -705,13 +693,7 @@ class MessageComposerPresenterTest { initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) val sendingState = awaitItem() assertThat(sendingState.showAttachmentSourcePicker).isFalse() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending.Processing::class.java) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(0f)) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(0.5f)) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.Sending.Uploading(1f)) - val sentState = awaitItem() - assertThat(sentState.attachmentsState).isEqualTo(AttachmentsState.None) - sendFileResult.assertions().isCalledOnce() + assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) } } @@ -851,48 +833,6 @@ class MessageComposerPresenterTest { } } - @Test - fun `present - Uploading media failure can be recovered from`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> - Result.failure(Exception()) - } - val room = FakeMatrixRoom( - sendFileResult = sendFileResult, - typingNoticeResult = { Result.success(Unit) } - ) - val presenter = createPresenter(this, room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitFirstItem() - initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - val sendingState = awaitItem() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending::class.java) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.None::class.java) - snackbarDispatcher.snackbarMessage.test { - // Assert error message received - assertThat(awaitItem()).isNotNull() - } - } - } - - @Test - fun `present - CancelSendAttachment stops media upload`() = runTest { - val presenter = createPresenter(this) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitFirstItem() - initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - val sendingState = awaitItem() - assertThat(sendingState.showAttachmentSourcePicker).isFalse() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Sending.Processing::class.java) - sendingState.eventSink(MessageComposerEvents.CancelSendAttachment) - assertThat(awaitItem().attachmentsState).isEqualTo(AttachmentsState.None) - } - } - @Test fun `present - errors are tracked`() = runTest { val testException = Exception("Test error") diff --git a/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt b/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt index 10d42716a9..e59e2d74c8 100644 --- a/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt +++ b/features/share/impl/src/test/kotlin/io/element/android/features/share/impl/SharePresenterTest.kt @@ -116,7 +116,7 @@ class SharePresenterTest { @Test fun `present - send media ok`() = runTest { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val matrixRoom = FakeMatrixRoom( diff --git a/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt b/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt index 1cfb46c20e..39f139afec 100644 --- a/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt +++ b/libraries/mediaupload/api/src/test/kotlin/io/element/android/libraries/mediaupload/api/MediaSenderTest.kt @@ -91,7 +91,7 @@ class MediaSenderTest { @OptIn(ExperimentalCoroutinesApi::class) @Test fun `given a cancellation in the media upload when sending the job is cancelled`() = runTest(StandardTestDispatcher()) { - val sendFileResult = lambdaRecorder> { _, _, _ -> + val sendFileResult = lambdaRecorder> { _, _, _, _, _ -> Result.success(FakeMediaUploadHandler()) } val room = FakeMatrixRoom( diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index 83541624a1..8d26082157 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -101,8 +101,10 @@ class KonsistPreviewTest { "SasEmojisPreview", "SecureBackupSetupViewChangePreview", "SelectedUserCannotRemovePreview", + "TextComposerAddCaptionPreview", "TextComposerCaptionPreview", "TextComposerEditPreview", + "TextComposerEditCaptionPreview", "TextComposerFormattingPreview", "TextComposerLinkDialogCreateLinkPreview", "TextComposerLinkDialogCreateLinkWithoutTextPreview", From e0964299c36b12427573f6e4bc5efb8f3ffc5a68 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 19 Nov 2024 18:02:07 +0100 Subject: [PATCH 29/47] Add missing test to check for TimelineItemAction.ReplyInThread --- .../actionlist/ActionListPresenterTest.kt | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 98d6ad0ec7..463e5108c7 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.test import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest import org.junit.Rule @@ -185,6 +186,51 @@ class ActionListPresenterTest { } } + @Test + fun `present - compute for others message in a thread`() = runTest { + val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) + presenter.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = false, + isEditable = false, + isThreaded = true, + content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) + ) + initialState.eventSink.invoke( + ActionListEvents.ComputeForMessage( + event = messageEvent, + userEventPermissions = aUserEventPermissions( + canRedactOwn = false, + canRedactOther = false, + canSendMessage = true, + canSendReaction = true, + canPinUnpin = true, + ) + ) + ) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + event = messageEvent, + displayEmojiReactions = true, + verifiedUserSendFailure = VerifiedUserSendFailure.None, + actions = persistentListOf( + TimelineItemAction.ReplyInThread, + TimelineItemAction.Forward, + TimelineItemAction.Pin, + TimelineItemAction.Copy, + TimelineItemAction.CopyLink, + TimelineItemAction.ViewSource, + TimelineItemAction.ReportContent, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + @Test fun `present - compute for others message cannot sent message`() = runTest { val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) @@ -374,6 +420,51 @@ class ActionListPresenterTest { } } + @Test + fun `present - compute for my message in a thread`() = runTest { + val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) + presenter.test { + val initialState = awaitItem() + val messageEvent = aMessageEvent( + isMine = true, + isThreaded = true, + content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) + ) + initialState.eventSink.invoke( + ActionListEvents.ComputeForMessage( + event = messageEvent, + userEventPermissions = aUserEventPermissions( + canRedactOwn = true, + canRedactOther = false, + canSendMessage = true, + canSendReaction = true, + canPinUnpin = true, + ) + ) + ) + val successState = awaitItem() + assertThat(successState.target).isEqualTo( + ActionListState.Target.Success( + event = messageEvent, + displayEmojiReactions = true, + verifiedUserSendFailure = VerifiedUserSendFailure.None, + actions = persistentListOf( + TimelineItemAction.ReplyInThread, + TimelineItemAction.Forward, + TimelineItemAction.Edit, + TimelineItemAction.Pin, + TimelineItemAction.Copy, + TimelineItemAction.CopyLink, + TimelineItemAction.ViewSource, + TimelineItemAction.Redact, + ) + ) + ) + initialState.eventSink.invoke(ActionListEvents.Clear) + assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None) + } + } + @Test fun `present - compute for my message cannot redact`() = runTest { val presenter = createActionListPresenter(isDeveloperModeEnabled = true, isPinFeatureEnabled = true) From 8bcc9203ad4ab017ff8f0391c07a0160e3f05b22 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 20 Nov 2024 13:10:52 +0000 Subject: [PATCH 30/47] Update screenshots --- ...messages.impl.attachments.preview_AttachmentsView_2_en.png | 4 ++-- ...messages.impl.attachments.preview_AttachmentsView_3_en.png | 4 ++-- ...meline.components.event_TimelineItemAudioView_Day_3_en.png | 3 +++ ...meline.components.event_TimelineItemAudioView_Day_4_en.png | 3 +++ ...line.components.event_TimelineItemAudioView_Night_3_en.png | 3 +++ ...line.components.event_TimelineItemAudioView_Night_4_en.png | 3 +++ ...imeline.components.event_TimelineItemFileView_Day_2_en.png | 4 ++-- ...imeline.components.event_TimelineItemFileView_Day_3_en.png | 3 +++ ...imeline.components.event_TimelineItemFileView_Day_4_en.png | 3 +++ ...eline.components.event_TimelineItemFileView_Night_2_en.png | 4 ++-- ...eline.components.event_TimelineItemFileView_Night_3_en.png | 3 +++ ...eline.components.event_TimelineItemFileView_Night_4_en.png | 3 +++ .../images/features.messages.impl_MessagesView_Day_10_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_11_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_12_en.png | 3 --- .../images/features.messages.impl_MessagesView_Day_13_en.png | 3 --- .../images/features.messages.impl_MessagesView_Day_8_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Day_9_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_10_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_11_en.png | 4 ++-- .../features.messages.impl_MessagesView_Night_12_en.png | 3 --- .../features.messages.impl_MessagesView_Night_13_en.png | 3 --- .../images/features.messages.impl_MessagesView_Night_8_en.png | 4 ++-- .../images/features.messages.impl_MessagesView_Night_9_en.png | 4 ++-- ...libraries.textcomposer_TextComposerAddCaption_Day_0_en.png | 3 +++ ...braries.textcomposer_TextComposerAddCaption_Night_0_en.png | 3 +++ ...ibraries.textcomposer_TextComposerEditCaption_Day_0_en.png | 3 +++ ...raries.textcomposer_TextComposerEditCaption_Night_0_en.png | 3 +++ 28 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Night_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png index c94414246c..2cb5dc89f8 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e0ec7e2a9dbe70a2deddf2bd621ac721b03e1b5bd367020fc68485e4d387ba8 -size 16610 +oid sha256:3250fa9767aec264308719c6fdf6cea94d5ccea21bfa8a735d7df5d79b572555 +size 21214 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png index 0d2dcbf67c..e34eb6e69c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.attachments.preview_AttachmentsView_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a44e40c0d586b41a0e47aa7d40a564eb820c2692051e795c87c460df92e81ca6 -size 17739 +oid sha256:4ba70221a149ce0f8abaa4e4f870011bea82630edf99ecacea560a737f56346f +size 22215 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en.png new file mode 100644 index 0000000000..c54fbf3183 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d2c41387ac8ac6f06845e584abda8c7cdfdf59c5d969d8611724222d85d061b +size 10746 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en.png new file mode 100644 index 0000000000..05c8b7f2cd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08183886dd8ecc5e402ab02cfe798fd23153c5ebed7439563f070d0a84ebed10 +size 21131 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en.png new file mode 100644 index 0000000000..8bfb865969 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8f96ad2f8c31fed8d0bbd8c4cedd2da39535cd45bb143d6fd10f2e92c470b3b4 +size 10809 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en.png new file mode 100644 index 0000000000..3675de2ae9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:151eb0a92ab7769d997bc3a459c67bb5cc04beac48cce5af7ee3867d46cbdbc0 +size 20849 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en.png index 10ca4fc77f..4c80d9632c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78ce6620309ead376b0be9a5e33da0ac935f0d6cc243d45ecfc3c69115388110 -size 21248 +oid sha256:727085653ecf863579d7fc952bf1d09aab8a41548e087435c1dd7b2b82350910 +size 21484 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en.png new file mode 100644 index 0000000000..b3e9b8f871 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8989d1bd6505db4067a8438963deb6bc8858d2a4b6c5d669df036ebca60e539f +size 10163 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en.png new file mode 100644 index 0000000000..299ad8ac2f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:518c57dfe5e6f5be40e32922808bb3eabd17f6aed525a5e62206dfee8bb14b13 +size 20576 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en.png index 218003b72f..5f7f2f5d51 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c66fb54a0b0f1c5fc30f2ff0be7a6f5e7d9bdc426f058825495a5c5194cffea6 -size 20763 +oid sha256:3cfd7c3d4fa0a2a289a15438092cb272d57be91ea221d73865a04b5ddf58b5ed +size 20996 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en.png new file mode 100644 index 0000000000..90ce08f533 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5745d06abd77e48b77fc192b911bcc60ed124af423d87c213fad67733bbb2943 +size 10113 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en.png new file mode 100644 index 0000000000..e446ff389d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:905386dfc27904f4cf36d26346e7a3dcafbf426ef4a1ac80717a45d1da0dd7d7 +size 20174 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png index 5779f0e9b3..2c917a94f2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ce4299e4c585abf3635b37c6003ac50a8ed25ffa0e9258dfbc07d61fb04569f -size 61074 +oid sha256:7d1ed9a282d3363fa4e28d924a750d0a46f7564533f687ab102d559e2dd1606b +size 59518 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png index 67315b78fe..2f6c08ed16 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:035d793ee33682785b98974c6357b99bfb879f8a86cba7117bb2b9c4c4bc13d5 -size 49533 +oid sha256:9660c7ea6ca5101c6b5fa9e774d4063d4011b9f8fdb64bf8e32cbc89c231531c +size 62605 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png deleted file mode 100644 index 2c917a94f2..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_12_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7d1ed9a282d3363fa4e28d924a750d0a46f7564533f687ab102d559e2dd1606b -size 59518 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png deleted file mode 100644 index 2f6c08ed16..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_13_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9660c7ea6ca5101c6b5fa9e774d4063d4011b9f8fdb64bf8e32cbc89c231531c -size 62605 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_8_en.png index 6f19d0f9d7..5779f0e9b3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ad0d2f2e326fd05997ef115e31971727067543c543883029411b735ce8909ff -size 40004 +oid sha256:3ce4299e4c585abf3635b37c6003ac50a8ed25ffa0e9258dfbc07d61fb04569f +size 61074 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_9_en.png index 44ec95c3e1..67315b78fe 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:281639101ede7b20bee08efdeac8c346fd13f9a9c4e3f322b6a6f37a417647b4 -size 39953 +oid sha256:035d793ee33682785b98974c6357b99bfb879f8a86cba7117bb2b9c4c4bc13d5 +size 49533 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png index 39c5faa542..eee7da7dda 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e9412f3e84b63be532188e13a976d1954404466136633f3f8cd41851617e753 -size 60668 +oid sha256:76faea3ec5b9e01a7e1ad77dea4f44b060bee26cf1d0b56df8eabb692cf764df +size 59225 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png index df384039ee..8643a775a1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1da55e4b116cbf0ebd74afee2a47d34b99d87192cdf9a5f8698118fcd4bbe239 -size 45466 +oid sha256:0f9df03bc6cba3fbf8ae454768064c9141b05e319c40c568a0a3edf3a53fed4e +size 61961 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png deleted file mode 100644 index eee7da7dda..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_12_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:76faea3ec5b9e01a7e1ad77dea4f44b060bee26cf1d0b56df8eabb692cf764df -size 59225 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png deleted file mode 100644 index 8643a775a1..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_13_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0f9df03bc6cba3fbf8ae454768064c9141b05e319c40c568a0a3edf3a53fed4e -size 61961 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_8_en.png index ce9c1e0af5..39c5faa542 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48c4460c9b57f0a438c9d0ae268eaa3823bddf3f1054e5c6b5caa64c6d075c6c -size 37392 +oid sha256:7e9412f3e84b63be532188e13a976d1954404466136633f3f8cd41851617e753 +size 60668 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_9_en.png index c3f90f4170..df384039ee 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl_MessagesView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8226bbd316c5c4ac01f5660b262623be32ec0a274c696c7a547c8baf59bf069b -size 37171 +oid sha256:1da55e4b116cbf0ebd74afee2a47d34b99d87192cdf9a5f8698118fcd4bbe239 +size 45466 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Day_0_en.png new file mode 100644 index 0000000000..fadf662965 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97d9c333fdc5684971e22593b246ca2751657691dad90ec89d891379e7a0b47f +size 60161 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Night_0_en.png new file mode 100644 index 0000000000..068ccea0fd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerAddCaption_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c08a7e954c11ff61a9130c54c0b273a5b8996c9095a4dae07cb4b5bc357fc15f +size 58458 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Day_0_en.png new file mode 100644 index 0000000000..82475e58db --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1967fa34ef6bd37c373f68badaed4e41b04efbbf929187e6ded4cfb903715325 +size 59539 diff --git a/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Night_0_en.png new file mode 100644 index 0000000000..db2e4e318d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.textcomposer_TextComposerEditCaption_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:430b30b65f5908fce562be613afa41131c4fbe8849db3d3f5a3fa424417469a4 +size 57827 From b387eac4487aac2d69f55e9321f702a070102774 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 09:55:43 +0100 Subject: [PATCH 31/47] Remove default value and clarify the code --- .../element/android/libraries/textcomposer/TextComposer.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 81cc7a739f..fe6034b8b6 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -589,7 +589,8 @@ internal fun TextComposerEditCaptionPreview() = ElementPreview { state = textEditorState, voiceMessageState = VoiceMessageState.Idle, composerMode = aMessageComposerModeEditCaption( - content = "A caption", + // Set an existing caption so that the UI will be in edit caption mode + content = "An existing caption", ), enableVoiceMessages = false, ) @@ -606,6 +607,7 @@ internal fun TextComposerAddCaptionPreview() = ElementPreview { state = textEditorState, voiceMessageState = VoiceMessageState.Idle, composerMode = aMessageComposerModeEditCaption( + // No caption so that the UI will be in add caption mode content = "", ), enableVoiceMessages = false, @@ -759,7 +761,7 @@ fun aMessageComposerModeEdit( fun aMessageComposerModeEditCaption( eventOrTransactionId: EventOrTransactionId = EventId("$1234").toEventOrTransactionId(), - content: String = "Some caption", + content: String, ) = MessageComposerMode.EditCaption( eventOrTransactionId = eventOrTransactionId, content = content From cebf8a8c811a0859e45b62e2f2060e120709b592 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 09:58:33 +0100 Subject: [PATCH 32/47] Add names to call arguments --- .../MessageComposerPresenterTest.kt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index c1d1fd8c11..8aa1110269 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -1427,17 +1427,17 @@ class MessageComposerPresenterTest { isRichTextEditorEnabled: Boolean = true, draftService: ComposerDraftService = FakeComposerDraftService(), ) = MessageComposerPresenter( - coroutineScope, - room, - pickerProvider, - featureFlagService, - sessionPreferencesStore, - localMediaFactory, - MediaSender(mediaPreProcessor, room, InMemorySessionPreferencesStore()), - snackbarDispatcher, - analyticsService, - DefaultMessageComposerContext(), - TestRichTextEditorStateFactory(), + appCoroutineScope = coroutineScope, + room = room, + mediaPickerProvider = pickerProvider, + featureFlagService = featureFlagService, + sessionPreferencesStore = sessionPreferencesStore, + localMediaFactory = localMediaFactory, + mediaSender = MediaSender(mediaPreProcessor, room, InMemorySessionPreferencesStore()), + snackbarDispatcher = snackbarDispatcher, + analyticsService = analyticsService, + messageComposerContext = DefaultMessageComposerContext(), + richTextEditorStateFactory = TestRichTextEditorStateFactory(), roomAliasSuggestionsDataSource = FakeRoomAliasSuggestionsDataSource(), permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionPresenter), permalinkParser = permalinkParser, From d643ae8cbb87b3bd54861defebb7dcf1b0557561 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 10:19:14 +0100 Subject: [PATCH 33/47] Add missing test about sending audio. --- .../AttachmentsPreviewPresenterTest.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt index bc61728cb1..4f35c592f1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/attachments/AttachmentsPreviewPresenterTest.kt @@ -21,6 +21,7 @@ import io.element.android.features.messages.impl.attachments.preview.SendActionS import io.element.android.features.messages.impl.fixtures.aMediaAttachment import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.matrix.api.core.ProgressCallback +import io.element.android.libraries.matrix.api.media.AudioInfo import io.element.android.libraries.matrix.api.media.FileInfo import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.VideoInfo @@ -41,6 +42,7 @@ import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.test import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.advanceUntilIdle @@ -189,6 +191,42 @@ class AttachmentsPreviewPresenterTest { } } + @Test + fun `present - send audio with caption success scenario`() = runTest { + val sendAudioResult = + lambdaRecorder> { _, _, _, _, _ -> + Result.success(FakeMediaUploadHandler()) + } + val mediaPreProcessor = FakeMediaPreProcessor().apply { + givenAudioResult() + } + val room = FakeMatrixRoom( + sendAudioResult = sendAudioResult, + ) + val onDoneListener = lambdaRecorder { } + val presenter = createAttachmentsPreviewPresenter( + room = room, + mediaPreProcessor = mediaPreProcessor, + onDoneListener = { onDoneListener() }, + ) + presenter.test { + val initialState = awaitItem() + assertThat(initialState.sendActionState).isEqualTo(SendActionState.Idle) + initialState.textEditorState.setMarkdown(A_CAPTION) + initialState.eventSink(AttachmentsPreviewEvents.SendAttachment) + assertThat(awaitItem().sendActionState).isEqualTo(SendActionState.Sending.Processing) + advanceUntilIdle() + sendAudioResult.assertions().isCalledOnce().with( + any(), + any(), + value(A_CAPTION), + any(), + any(), + ) + onDoneListener.assertions().isCalledOnce() + } + } + @Test fun `present - send media failure scenario`() = runTest { val failure = MediaPreProcessor.Failure(null) From 6bcfa0e6c6fd939b6d064373fae4b16d364371e5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 11:08:19 +0100 Subject: [PATCH 34/47] Add missing test on MessageComposerPresenter --- .../MessageComposerPresenterTest.kt | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 8aa1110269..1654a061c8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -47,6 +47,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.test.ANOTHER_MESSAGE import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_CAPTION import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_REPLY import io.element.android.libraries.matrix.test.A_ROOM_ID @@ -87,6 +88,7 @@ import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.assert import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.test import io.element.android.tests.testutils.waitForPredicate import io.mockk.mockk import kotlinx.collections.immutable.persistentListOf @@ -208,6 +210,91 @@ class MessageComposerPresenterTest { } } + @Test + fun `present - change mode to edit caption`() = runTest { + val loadDraftLambda = lambdaRecorder { _: RoomId, _: Boolean -> + ComposerDraft(A_MESSAGE, A_MESSAGE, ComposerDraftType.NewMessage) + } + val updateDraftLambda = lambdaRecorder { _: RoomId, _: ComposerDraft?, _: Boolean -> } + val draftService = FakeComposerDraftService().apply { + this.loadDraftLambda = loadDraftLambda + this.saveDraftLambda = updateDraftLambda + } + val presenter = createPresenter( + coroutineScope = this, + draftService = draftService, + ) + moleculeFlow(RecompositionMode.Immediate) { + val state = presenter.present() + remember(state, state.textEditorState.messageHtml()) { state } + }.test { + var state = awaitFirstItem() + val mode = anEditCaptionMode(caption = A_CAPTION) + state.eventSink.invoke(MessageComposerEvents.SetMode(mode)) + state = awaitItem() + assertThat(state.mode).isEqualTo(mode) + assertThat(state.textEditorState.messageHtml()).isEqualTo(A_CAPTION) + state = backToNormalMode(state) + // The caption that was being edited is cleared and volatile draft is loaded + assertThat(state.textEditorState.messageHtml()).isEqualTo(A_MESSAGE) + + assert(loadDraftLambda) + .isCalledExactly(2) + .withSequence( + // Automatic load of draft + listOf(value(A_ROOM_ID), value(false)), + // Load of volatile draft when closing edit mode + listOf(value(A_ROOM_ID), value(true)) + ) + assert(updateDraftLambda) + .isCalledOnce() + .with(value(A_ROOM_ID), any(), value(true)) + } + } + + @Test + fun `present - change mode to edit caption and send the caption`() = runTest { + val editCaptionLambda = lambdaRecorder { _: EventOrTransactionId, _: String?, _: String? -> + Result.success(Unit) + } + val timeline = FakeTimeline().apply { + this.editCaptionLambda = editCaptionLambda + } + val fakeMatrixRoom = FakeMatrixRoom( + liveTimeline = timeline, + typingNoticeResult = { Result.success(Unit) } + ) + val presenter = createPresenter( + coroutineScope = this, + room = fakeMatrixRoom, + isRichTextEditorEnabled = false, + ) + val permalinkBuilder = FakePermalinkBuilder(permalinkForUserLambda = { Result.success("") }) + presenter.test { + var state = awaitFirstItem() + val mode = anEditCaptionMode(caption = A_CAPTION) + state.eventSink.invoke(MessageComposerEvents.SetMode(mode)) + state = awaitItem() + assertThat(state.mode).isEqualTo(mode) + assertThat(state.textEditorState.messageMarkdown(permalinkBuilder)).isEqualTo(A_CAPTION) + state.eventSink.invoke(MessageComposerEvents.SendMessage) + val messageSentState = awaitItem() + assertThat(messageSentState.textEditorState.messageMarkdown(permalinkBuilder)).isEqualTo("") + waitForPredicate { analyticsService.capturedEvents.size == 1 } + assertThat(analyticsService.capturedEvents).containsExactly( + Composer( + inThread = false, + isEditing = true, + isReply = false, + messageType = Composer.MessageType.Text, + ) + ) + assert(editCaptionLambda) + .isCalledOnce() + .with(value(AN_EVENT_ID.toEventOrTransactionId()), value(A_CAPTION), value(null)) + } + } + @Test fun `present - change mode to reply after edit`() = runTest { val loadDraftLambda = lambdaRecorder { _: RoomId, _: Boolean -> @@ -1465,6 +1552,11 @@ fun anEditMode( message: String = A_MESSAGE, ) = MessageComposerMode.Edit(eventOrTransactionId, message) +fun anEditCaptionMode( + eventOrTransactionId: EventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(), + caption: String = A_CAPTION, +) = MessageComposerMode.EditCaption(eventOrTransactionId, caption) + fun aReplyMode() = MessageComposerMode.Reply( replyToDetails = InReplyToDetails.Loading(AN_EVENT_ID), hideImage = false, From 55032dcdc9422e99f9a75ed6ab2434eded62cacd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 11:34:14 +0100 Subject: [PATCH 35/47] Add missing tests on MessagePresenter --- .../messages/impl/MessagesPresenterTest.kt | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index f66c8c50b8..3d4969fd28 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.timeline.protection.aTimelineProtectionState @@ -59,6 +60,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransa import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.A_CAPTION import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID_2 @@ -82,6 +84,7 @@ import io.element.android.tests.testutils.lambda.assert import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -972,6 +975,103 @@ class MessagesPresenterTest { } } + @Test + fun `present - handle action edit caption`() = runTest { + val messageEvent = aMessageEvent( + content = aTimelineItemImageContent( + caption = A_CAPTION, + ) + ) + val composerRecorder = EventsRecorder() + val presenter = createMessagesPresenter( + messageComposerPresenter = { aMessageComposerState(eventSink = composerRecorder) }, + ) + presenter.test { + val initialState = awaitItem() + initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EditCaption, messageEvent)) + awaitItem() + composerRecorder.assertSingle( + MessageComposerEvents.SetMode( + composerMode = MessageComposerMode.EditCaption( + eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(), + content = A_CAPTION, + ) + ) + ) + } + } + + @Test + fun `present - handle action add caption`() = runTest { + val composerRecorder = EventsRecorder() + val presenter = createMessagesPresenter( + messageComposerPresenter = { aMessageComposerState(eventSink = composerRecorder) }, + ) + val messageEvent = aMessageEvent( + content = aTimelineItemImageContent( + caption = null, + ) + ) + presenter.test { + val initialState = awaitItem() + initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.AddCaption, messageEvent)) + awaitItem() + composerRecorder.assertSingle( + MessageComposerEvents.SetMode( + composerMode = MessageComposerMode.EditCaption( + eventOrTransactionId = AN_EVENT_ID.toEventOrTransactionId(), + content = "", + ) + ) + ) + } + } + + @Test + fun `present - handle action remove caption`() = runTest { + val messageEvent = aMessageEvent( + content = aTimelineItemImageContent( + caption = A_CAPTION, + ) + ) + val editCaptionLambda = lambdaRecorder { _: EventOrTransactionId, _: String?, _: String? -> Result.success(Unit) } + val timeline = FakeTimeline().apply { + this.editCaptionLambda = editCaptionLambda + } + val room = FakeMatrixRoom( + liveTimeline = timeline, + canUserSendMessageResult = { _, _ -> Result.success(true) }, + canRedactOwnResult = { Result.success(true) }, + canRedactOtherResult = { Result.success(true) }, + canUserJoinCallResult = { Result.success(true) }, + typingNoticeResult = { Result.success(Unit) }, + canUserPinUnpinResult = { Result.success(true) }, + ) + val presenter = createMessagesPresenter( + matrixRoom = room, + ) + presenter.test { + skipItems(1) + val initialState = awaitItem() + initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.RemoveCaption, messageEvent)) + editCaptionLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID.toEventOrTransactionId()), value(null), value(null)) + } + } + + @Test + fun `present - handle action view in timeline, it should have no effect`() = runTest { + val messageEvent = aMessageEvent( + content = aTimelineItemTextContent() + ) + val presenter = createMessagesPresenter() + presenter.test { + skipItems(1) + val initialState = awaitItem() + initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewInTimeline, messageEvent)) + // No op! + } + } + private fun TestScope.createMessagesPresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(), matrixRoom: MatrixRoom = FakeMatrixRoom( From d66dc0862f13fdc0a1f1b5709a41d968af858f02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 12:34:51 +0100 Subject: [PATCH 36/47] Update dependency com.autonomousapps.dependency-analysis to v2.5.0 (#3909) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 61a08c3c45..262bd97f77 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -50,7 +50,7 @@ wysiwyg = "2.37.13" telephoto = "0.14.0" # Dependency analysis -dependencyAnalysis = "2.4.2" +dependencyAnalysis = "2.5.0" # DI dagger = "2.52" From 6bf7b90060a37dbee34f3f6b5e05f0706507becb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:52:28 +0000 Subject: [PATCH 37/47] Update dependency io.element.android:compound-android to v0.2.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 262bd97f77..0fa2504af5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -163,7 +163,7 @@ coil = { module = "io.coil-kt:coil", version.ref = "coil" } coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" } coil_gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" } coil_test = { module = "io.coil-kt:coil-test", version.ref = "coil" } -compound = { module = "io.element.android:compound-android", version = "0.1.1" } +compound = { module = "io.element.android:compound-android", version = "0.2.0" } datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" } serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" } kotlinx_collections_immutable = "org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8" From b8fe303313bfc742401b212ea32e0b12391e21f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 09:25:33 +0100 Subject: [PATCH 38/47] Rely on the SDK to decide if a caption is editable or not Need https://github.com/matrix-org/matrix-rust-sdk/pull/4303 to work but not to compile. --- .../messages/impl/actionlist/ActionListPresenter.kt | 11 ++++------- .../impl/actionlist/ActionListPresenterTest.kt | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 2ae72c86c6..e228f3eb73 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -32,7 +32,6 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent -import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.model.event.canBeCopied import io.element.android.features.messages.impl.timeline.model.event.canBeForwarded import io.element.android.features.messages.impl.timeline.model.event.canReact @@ -155,18 +154,16 @@ class DefaultActionListPresenter @AssistedInject constructor( add(TimelineItemAction.Forward) } if (timelineItem.isEditable) { - add(TimelineItemAction.Edit) - } else { - // Caption - if (timelineItem.isMine && - timelineItem.content is TimelineItemEventContentWithAttachment && - timelineItem.content !is TimelineItemVoiceContent) { + if (timelineItem.content is TimelineItemEventContentWithAttachment) { + // Caption if (timelineItem.content.caption == null) { add(TimelineItemAction.AddCaption) } else { add(TimelineItemAction.EditCaption) add(TimelineItemAction.RemoveCaption) } + } else { + add(TimelineItemAction.Edit) } } if (canRedact && timelineItem.content is TimelineItemPollContent && !timelineItem.content.isEnded) { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 463e5108c7..b79468f820 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -521,7 +521,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = true, - isEditable = false, + isEditable = true, content = aTimelineItemImageContent(), ) initialState.eventSink.invoke( @@ -567,7 +567,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = true, - isEditable = false, + isEditable = true, content = aTimelineItemImageContent( caption = A_CAPTION, ), From 57950c0e9499ef964be87739be11cd99ba1c6a03 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 15:18:56 +0100 Subject: [PATCH 39/47] Fix test and rename class to follow naming convention for PreviewParameterProvider. --- .../{AspectRatioPreviewProvider.kt => AspectRatioProvider.kt} | 2 +- .../messages/impl/timeline/protection/ProtectedView.kt | 2 +- .../io/element/android/tests/konsist/KonsistClassNameTest.kt | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) rename features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/{AspectRatioPreviewProvider.kt => AspectRatioProvider.kt} (85%) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt similarity index 85% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt rename to features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt index fb296ef7bf..99cfff5625 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioPreviewProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/AspectRatioProvider.kt @@ -9,7 +9,7 @@ package io.element.android.features.messages.impl.timeline.protection import androidx.compose.ui.tooling.preview.PreviewParameterProvider -class AspectRatioPreviewProvider : PreviewParameterProvider { +class AspectRatioProvider : PreviewParameterProvider { override val values: Sequence = sequenceOf( null, 0.05f, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt index 631967b6c2..b52084233b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/protection/ProtectedView.kt @@ -81,7 +81,7 @@ fun ProtectedView( @PreviewsDayNight @Composable internal fun ProtectedViewPreview( - @PreviewParameter(AspectRatioPreviewProvider::class) aspectRatio: Float?, + @PreviewParameter(AspectRatioProvider::class) aspectRatio: Float?, ) = ElementPreview { TimelineItemAspectRatioBox( modifier = Modifier.blurHashBackground(A_BLUR_HASH, alpha = 0.9f), diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt index 8f7d446d67..adc2b9ceb7 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistClassNameTest.kt @@ -48,6 +48,9 @@ class KonsistClassNameTest { Konsist.scopeFromProduction() .classes() .withAllParentsOf(PreviewParameterProvider::class) + .withoutName( + "AspectRatioProvider", + ) .also { // Check that classes are actually found assertThat(it.size).isGreaterThan(100) From 5ec0d5a5f975aff9268706e8bfc5ef75d5154946 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 17:07:34 +0100 Subject: [PATCH 40/47] Remove AttachmentsState and use the MessagesNavigator --- .../messages/impl/MessagesNavigator.kt | 3 + .../features/messages/impl/MessagesNode.kt | 16 ++-- .../messages/impl/MessagesPresenter.kt | 9 ++- .../features/messages/impl/MessagesView.kt | 27 ------- .../MessagesViewWithIdentityChangePreview.kt | 1 - .../messages/impl/di/MessagesModule.kt | 5 -- .../MessageComposerPresenter.kt | 45 +++++------ .../messagecomposer/MessageComposerState.kt | 9 --- .../MessageComposerStateProvider.kt | 2 - .../messages/impl/FakeMessagesNavigator.kt | 9 +++ .../messages/impl/MessagesViewTest.kt | 2 - .../MessageComposerPresenterTest.kt | 74 ++++++++++--------- 12 files changed, 86 insertions(+), 116 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt index 3eba997eea..470d9da9c4 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt @@ -7,13 +7,16 @@ package io.element.android.features.messages.impl +import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo +import kotlinx.collections.immutable.ImmutableList interface MessagesNavigator { fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) fun onForwardEventClick(eventId: EventId) fun onReportContentClick(eventId: EventId, senderId: UserId) fun onEditPollClick(eventId: EventId) + fun onPreviewAttachment(attachments: ImmutableList) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index 9fd823445f..7d0d6cb2d0 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -30,6 +30,7 @@ import io.element.android.anvilannotations.ContributesNode import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents +import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter import io.element.android.features.messages.impl.timeline.TimelineEvents import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories @@ -60,12 +61,16 @@ class MessagesNode @AssistedInject constructor( @Assisted plugins: List, private val room: MatrixRoom, private val analyticsService: AnalyticsService, + messageComposerPresenterFactory: MessageComposerPresenter.Factory, presenterFactory: MessagesPresenter.Factory, private val timelineItemPresenterFactories: TimelineItemPresenterFactories, private val mediaPlayer: MediaPlayer, private val permalinkParser: PermalinkParser, ) : Node(buildContext, plugins = plugins), MessagesNavigator { - private val presenter = presenterFactory.create(this) + private val presenter = presenterFactory.create( + navigator = this, + composerPresenter = messageComposerPresenterFactory.create(this), + ) private val callbacks = plugins() data class Inputs(val focusedEventId: EventId?) : NodeInputs @@ -114,10 +119,6 @@ class MessagesNode @AssistedInject constructor( .orFalse() } - private fun onPreviewAttachments(attachments: ImmutableList) { - callbacks.forEach { it.onPreviewAttachments(attachments) } - } - private fun onUserDataClick(userId: UserId) { callbacks.forEach { it.onUserDataClick(userId) } } @@ -178,6 +179,10 @@ class MessagesNode @AssistedInject constructor( callbacks.forEach { it.onEditPollClick(eventId) } } + override fun onPreviewAttachment(attachments: ImmutableList) { + callbacks.forEach { it.onPreviewAttachments(attachments) } + } + private fun onViewAllPinnedMessagesClick() { callbacks.forEach { it.onViewAllPinnedEvents() } } @@ -213,7 +218,6 @@ class MessagesNode @AssistedInject constructor( onBackClick = this::navigateUp, onRoomDetailsClick = this::onRoomDetailsClick, onEventContentClick = this::onEventClick, - onPreviewAttachments = this::onPreviewAttachments, onUserDataClick = this::onUserDataClick, onLinkClick = { url -> onLinkClick(activity, isDark, url, state.timelineState.eventSink) }, onSendLocationClick = this::onSendLocationClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 49d3015c05..8f11c491e2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -89,12 +89,12 @@ import timber.log.Timber class MessagesPresenter @AssistedInject constructor( @Assisted private val navigator: MessagesNavigator, private val room: MatrixRoom, - private val composerPresenter: Presenter, + @Assisted private val composerPresenter: Presenter, private val voiceMessageComposerPresenter: Presenter, timelinePresenterFactory: TimelinePresenter.Factory, private val timelineProtectionPresenter: Presenter, private val identityChangeStatePresenter: Presenter, - private val actionListPresenterFactory: ActionListPresenter.Factory, + actionListPresenterFactory: ActionListPresenter.Factory, private val customReactionPresenter: Presenter, private val reactionSummaryPresenter: Presenter, private val readReceiptBottomSheetPresenter: Presenter, @@ -116,7 +116,10 @@ class MessagesPresenter @AssistedInject constructor( @AssistedFactory interface Factory { - fun create(navigator: MessagesNavigator): MessagesPresenter + fun create( + navigator: MessagesNavigator, + composerPresenter: Presenter, + ): MessagesPresenter } @Composable diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 49cbac6268..fa66e463bb 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -32,10 +32,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -55,10 +53,8 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListView import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction -import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.crypto.identity.IdentityChangeStateView import io.element.android.features.messages.impl.messagecomposer.AttachmentsBottomSheet -import io.element.android.features.messages.impl.messagecomposer.AttachmentsState import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents import io.element.android.features.messages.impl.messagecomposer.MessageComposerView import io.element.android.features.messages.impl.messagecomposer.suggestions.SuggestionsPickerView @@ -115,7 +111,6 @@ fun MessagesView( onEventContentClick: (event: TimelineItem.Event) -> Boolean, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, - onPreviewAttachments: (ImmutableList) -> Unit, onSendLocationClick: () -> Unit, onCreatePollClick: () -> Unit, onJoinCallClick: () -> Unit, @@ -129,11 +124,6 @@ fun MessagesView( KeepScreenOn(state.voiceMessageComposerState.keepScreenOn) - AttachmentStateView( - state = state.composerState.attachmentsState, - onPreviewAttachments = onPreviewAttachments, - ) - val snackbarHostState = rememberSnackbarHostState(snackbarMessage = state.snackbarMessage) // This is needed because the composer is inside an AndroidView that can't be affected by the FocusManager in Compose @@ -273,22 +263,6 @@ private fun ReinviteDialog(state: MessagesState) { } } -@Composable -private fun AttachmentStateView( - state: AttachmentsState, - onPreviewAttachments: (ImmutableList) -> Unit, -) { - when (state) { - AttachmentsState.None -> Unit - is AttachmentsState.Previewing -> { - val latestOnPreviewAttachments by rememberUpdatedState(onPreviewAttachments) - LaunchedEffect(state) { - latestOnPreviewAttachments(state.attachments) - } - } - } -} - @Composable private fun MessagesViewContent( state: MessagesState, @@ -557,7 +531,6 @@ internal fun MessagesViewPreview(@PreviewParameter(MessagesStateProvider::class) onEventContentClick = { false }, onUserDataClick = {}, onLinkClick = {}, - onPreviewAttachments = {}, onSendLocationClick = {}, onCreatePollClick = {}, onJoinCallClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt index 04750b6ad8..34c58bdb06 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/crypto/identity/MessagesViewWithIdentityChangePreview.kt @@ -36,7 +36,6 @@ internal fun MessagesViewWithIdentityChangePreview( onEventContentClick = { false }, onUserDataClick = {}, onLinkClick = {}, - onPreviewAttachments = {}, onSendLocationClick = {}, onCreatePollClick = {}, onJoinCallClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesModule.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesModule.kt index d987e97809..567c95bcc7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesModule.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/di/MessagesModule.kt @@ -14,8 +14,6 @@ import io.element.android.features.messages.impl.crypto.identity.IdentityChangeS import io.element.android.features.messages.impl.crypto.identity.IdentityChangeStatePresenter import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailurePresenter import io.element.android.features.messages.impl.crypto.sendfailure.resolve.ResolveVerifiedUserSendFailureState -import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter -import io.element.android.features.messages.impl.messagecomposer.MessageComposerState import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerPresenter import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter @@ -48,9 +46,6 @@ interface MessagesModule { @Binds fun bindTimelineProtectionPresenter(presenter: TimelineProtectionPresenter): Presenter - @Binds - fun bindMessageComposerPresenter(presenter: MessageComposerPresenter): Presenter - @Binds fun bindVoiceMessageComposerPresenter(presenter: VoiceMessageComposerPresenter): Presenter diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index ebccc8dff4..bf3ea2b112 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -14,7 +14,6 @@ import androidx.annotation.VisibleForTesting import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf @@ -26,8 +25,12 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.media3.common.MimeTypes import androidx.media3.common.util.UnstableApi +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.Composer import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.messages.impl.MessagesNavigator import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.attachments.preview.error.sendAttachmentError import io.element.android.features.messages.impl.draft.ComposerDraftService @@ -38,8 +41,6 @@ import io.element.android.features.messages.impl.utils.TextPillificationHelper import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage -import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.di.SingleIn import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.core.UserId @@ -89,12 +90,11 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch import timber.log.Timber -import javax.inject.Inject import kotlin.time.Duration.Companion.seconds import io.element.android.libraries.core.mimetype.MimeTypes.Any as AnyMimeTypes -@SingleIn(RoomScope::class) -class MessageComposerPresenter @Inject constructor( +class MessageComposerPresenter @AssistedInject constructor( + @Assisted private val navigator: MessagesNavigator, private val appCoroutineScope: CoroutineScope, private val room: MatrixRoom, private val mediaPickerProvider: PickerProvider, @@ -117,6 +117,11 @@ class MessageComposerPresenter @Inject constructor( private val roomMemberProfilesCache: RoomMemberProfilesCache, private val suggestionsProcessor: SuggestionsProcessor, ) : Presenter { + @AssistedFactory + interface Factory { + fun create(navigator: MessagesNavigator): MessageComposerPresenter + } + private val cameraPermissionPresenter = permissionsPresenterFactory.create(Manifest.permission.CAMERA) private var pendingEvent: MessageComposerEvents? = null private val suggestionSearchTrigger = MutableStateFlow(null) @@ -147,9 +152,6 @@ class MessageComposerPresenter @Inject constructor( } val cameraPermissionState = cameraPermissionPresenter.present() - val attachmentsState = remember { - mutableStateOf(AttachmentsState.None) - } val canShareLocation = remember { mutableStateOf(false) } LaunchedEffect(Unit) { @@ -162,16 +164,16 @@ class MessageComposerPresenter @Inject constructor( } val galleryMediaPicker = mediaPickerProvider.registerGalleryPicker { uri, mimeType -> - handlePickedMedia(attachmentsState, uri, mimeType) + handlePickedMedia(uri, mimeType) } val filesPicker = mediaPickerProvider.registerFilePicker(AnyMimeTypes) { uri -> - handlePickedMedia(attachmentsState, uri) + handlePickedMedia(uri) } val cameraPhotoPicker = mediaPickerProvider.registerCameraPhotoPicker { uri -> - handlePickedMedia(attachmentsState, uri, MimeTypes.IMAGE_JPEG) + handlePickedMedia(uri, MimeTypes.IMAGE_JPEG) } val cameraVideoPicker = mediaPickerProvider.registerCameraVideoPicker { uri -> - handlePickedMedia(attachmentsState, uri, MimeTypes.VIDEO_MP4) + handlePickedMedia(uri, MimeTypes.VIDEO_MP4) } val isFullScreen = rememberSaveable { mutableStateOf(false) @@ -277,7 +279,6 @@ class MessageComposerPresenter @Inject constructor( formattedFileSize = null ), ), - attachmentState = attachmentsState, ) is MessageComposerEvents.SetMode -> { localCoroutineScope.setMode(event.composerMode, markdownTextEditorState, richTextEditorState) @@ -396,7 +397,6 @@ class MessageComposerPresenter @Inject constructor( showTextFormatting = showTextFormatting, canShareLocation = canShareLocation.value, canCreatePoll = canCreatePoll.value, - attachmentsState = attachmentsState.value, suggestions = suggestions.toPersistentList(), resolveMentionDisplay = resolveMentionDisplay, eventSink = { handleEvents(it) }, @@ -459,14 +459,12 @@ class MessageComposerPresenter @Inject constructor( private fun CoroutineScope.sendAttachment( attachment: Attachment, - attachmentState: MutableState, ) = when (attachment) { is Attachment.Media -> { launch { sendMedia( uri = attachment.localMedia.uri, mimeType = attachment.localMedia.info.mimeType, - attachmentState = attachmentState, ) } } @@ -474,14 +472,10 @@ class MessageComposerPresenter @Inject constructor( @UnstableApi private fun handlePickedMedia( - attachmentsState: MutableState, uri: Uri?, mimeType: String? = null, ) { - if (uri == null) { - attachmentsState.value = AttachmentsState.None - return - } + uri ?: return val localMedia = localMediaFactory.createFromUri( uri = uri, mimeType = mimeType, @@ -489,13 +483,12 @@ class MessageComposerPresenter @Inject constructor( formattedFileSize = null ) val mediaAttachment = Attachment.Media(localMedia) - attachmentsState.value = AttachmentsState.Previewing(persistentListOf(mediaAttachment)) + navigator.onPreviewAttachment(persistentListOf(mediaAttachment)) } private suspend fun sendMedia( uri: Uri, mimeType: String, - attachmentState: MutableState, ) = runCatching { mediaSender.sendMedia( uri = uri, @@ -503,12 +496,8 @@ class MessageComposerPresenter @Inject constructor( progressCallback = null, ).getOrThrow() } - .onSuccess { - attachmentState.value = AttachmentsState.None - } .onFailure { cause -> Timber.e(cause, "Failed to send attachment") - attachmentState.value = AttachmentsState.None if (cause is CancellationException) { throw cause } else { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index d0e9528e48..58e40dbb14 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -7,9 +7,7 @@ package io.element.android.features.messages.impl.messagecomposer -import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable -import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.libraries.textcomposer.mentions.ResolvedSuggestion import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.TextEditorState @@ -25,14 +23,7 @@ data class MessageComposerState( val showTextFormatting: Boolean, val canShareLocation: Boolean, val canCreatePoll: Boolean, - val attachmentsState: AttachmentsState, val suggestions: ImmutableList, val resolveMentionDisplay: (String, String) -> TextDisplay, val eventSink: (MessageComposerEvents) -> Unit, ) - -@Immutable -sealed interface AttachmentsState { - data object None : AttachmentsState - data class Previewing(val attachments: ImmutableList) : AttachmentsState -} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt index a36102bc7d..7811322c3d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt @@ -31,7 +31,6 @@ fun aMessageComposerState( showAttachmentSourcePicker: Boolean = false, canShareLocation: Boolean = true, canCreatePoll: Boolean = true, - attachmentsState: AttachmentsState = AttachmentsState.None, suggestions: ImmutableList = persistentListOf(), eventSink: (MessageComposerEvents) -> Unit = {}, ) = MessageComposerState( @@ -42,7 +41,6 @@ fun aMessageComposerState( showAttachmentSourcePicker = showAttachmentSourcePicker, canShareLocation = canShareLocation, canCreatePoll = canCreatePoll, - attachmentsState = attachmentsState, suggestions = suggestions, resolveMentionDisplay = { _, _ -> TextDisplay.Plain }, eventSink = eventSink, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt index fa5e412f27..d11398bd8e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt @@ -7,9 +7,11 @@ package io.element.android.features.messages.impl +import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo +import kotlinx.collections.immutable.ImmutableList class FakeMessagesNavigator : MessagesNavigator { var onShowEventDebugInfoClickedCount = 0 @@ -24,6 +26,9 @@ class FakeMessagesNavigator : MessagesNavigator { var onEditPollClickedCount = 0 private set + var onPreviewAttachmentCount = 0 + private set + override fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) { onShowEventDebugInfoClickedCount++ } @@ -39,4 +44,8 @@ class FakeMessagesNavigator : MessagesNavigator { override fun onEditPollClick(eventId: EventId) { onEditPollClickedCount++ } + + override fun onPreviewAttachment(attachments: ImmutableList) { + onPreviewAttachmentCount++ + } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index c040ce9926..35c069e1f9 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -514,7 +514,6 @@ private fun AndroidComposeTestRule.setMessa onEventClick: (event: TimelineItem.Event) -> Boolean = EnsureNeverCalledWithParamAndResult(), onUserDataClick: (UserId) -> Unit = EnsureNeverCalledWithParam(), onLinkClick: (String) -> Unit = EnsureNeverCalledWithParam(), - onPreviewAttachments: (ImmutableList) -> Unit = EnsureNeverCalledWithParam(), onSendLocationClick: () -> Unit = EnsureNeverCalled(), onCreatePollClick: () -> Unit = EnsureNeverCalled(), onJoinCallClick: () -> Unit = EnsureNeverCalled(), @@ -532,7 +531,6 @@ private fun AndroidComposeTestRule.setMessa onEventContentClick = onEventClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onPreviewAttachments = onPreviewAttachments, onSendLocationClick = onSendLocationClick, onCreatePollClick = onCreatePollClick, onJoinCallClick = onJoinCallClick, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index 1654a061c8..fcd9102be6 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -18,6 +18,8 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Composer import im.vector.app.features.analytics.plan.Interaction +import io.element.android.features.messages.impl.FakeMessagesNavigator +import io.element.android.features.messages.impl.MessagesNavigator import io.element.android.features.messages.impl.draft.ComposerDraftService import io.element.android.features.messages.impl.draft.FakeComposerDraftService import io.element.android.features.messages.impl.messagecomposer.suggestions.SuggestionsProcessor @@ -133,7 +135,6 @@ class MessageComposerPresenterTest { assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal) assertThat(initialState.showAttachmentSourcePicker).isFalse() assertThat(initialState.canShareLocation).isTrue() - assertThat(initialState.attachmentsState).isEqualTo(AttachmentsState.None) } } @@ -685,7 +686,12 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val presenter = createPresenter(this, room = room) + val navigator = FakeMessagesNavigator() + val presenter = createPresenter( + coroutineScope = this, + room = room, + navigator = navigator, + ) pickerProvider.givenMimeType(MimeTypes.Images) mediaPreProcessor.givenResult( Result.success( @@ -709,9 +715,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) - val previewingState = awaitItem() - assertThat(previewingState.showAttachmentSourcePicker).isFalse() - assertThat(previewingState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -720,7 +724,12 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val presenter = createPresenter(this, room = room) + val navigator = FakeMessagesNavigator() + val presenter = createPresenter( + coroutineScope = this, + room = room, + navigator = navigator, + ) pickerProvider.givenMimeType(MimeTypes.Videos) mediaPreProcessor.givenResult( Result.success( @@ -745,9 +754,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) - val previewingState = awaitItem() - assertThat(previewingState.showAttachmentSourcePicker).isFalse() - assertThat(previewingState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -772,15 +779,18 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val presenter = createPresenter(this, room = room) + val navigator = FakeMessagesNavigator() + val presenter = createPresenter( + coroutineScope = this, + room = room, + navigator = navigator, + ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - val sendingState = awaitItem() - assertThat(sendingState.showAttachmentSourcePicker).isFalse() - assertThat(sendingState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -828,19 +838,19 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } + val navigator = FakeMessagesNavigator() val presenter = createPresenter( - this, + coroutineScope = this, room = room, permissionPresenter = permissionPresenter, + navigator = navigator, ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) - cancelAndIgnoreRemainingEvents() + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -850,23 +860,20 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter() + val navigator = FakeMessagesNavigator() val presenter = createPresenter( - this, + coroutineScope = this, room = room, permissionPresenter = permissionPresenter, + navigator = navigator, ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) - val permissionState = awaitItem() - assertThat(permissionState.showAttachmentSourcePicker).isFalse() - assertThat(permissionState.attachmentsState).isInstanceOf(AttachmentsState.None::class.java) permissionPresenter.setPermissionGranted() - skipItems(1) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) cancelAndIgnoreRemainingEvents() } } @@ -877,19 +884,19 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } + val navigator = FakeMessagesNavigator() val presenter = createPresenter( - this, + coroutineScope = this, room = room, permissionPresenter = permissionPresenter, + navigator = navigator, ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) - cancelAndIgnoreRemainingEvents() + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -899,10 +906,12 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter() + val navigator = FakeMessagesNavigator() val presenter = createPresenter( - this, + coroutineScope = this, room = room, permissionPresenter = permissionPresenter, + navigator = navigator, ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -911,12 +920,9 @@ class MessageComposerPresenterTest { initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) val permissionState = awaitItem() assertThat(permissionState.showAttachmentSourcePicker).isFalse() - assertThat(permissionState.attachmentsState).isInstanceOf(AttachmentsState.None::class.java) permissionPresenter.setPermissionGranted() skipItems(1) - val finalState = awaitItem() - assertThat(finalState.attachmentsState).isInstanceOf(AttachmentsState.Previewing::class.java) - cancelAndIgnoreRemainingEvents() + assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) } } @@ -1500,6 +1506,7 @@ class MessageComposerPresenterTest { room: MatrixRoom = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ), + navigator: MessagesNavigator = FakeMessagesNavigator(), pickerProvider: PickerProvider = this.pickerProvider, featureFlagService: FeatureFlagService = this.featureFlagService, sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(), @@ -1514,6 +1521,7 @@ class MessageComposerPresenterTest { isRichTextEditorEnabled: Boolean = true, draftService: ComposerDraftService = FakeComposerDraftService(), ) = MessageComposerPresenter( + navigator = navigator, appCoroutineScope = coroutineScope, room = room, mediaPickerProvider = pickerProvider, From 1c1126ba394b7792854dbf2f0075b7c29ea639d3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 17:07:50 +0100 Subject: [PATCH 41/47] No need to have `@SingleIn(RoomScope::class)` for this presenter. --- .../voicemessages/composer/VoiceMessageComposerPresenter.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt index cf8d5668a3..cc6d134802 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenter.kt @@ -23,8 +23,6 @@ import im.vector.app.features.analytics.plan.Composer import io.element.android.features.messages.api.MessageComposerContext import io.element.android.features.messages.impl.voicemessages.VoiceMessageException import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.di.RoomScope -import io.element.android.libraries.di.SingleIn import io.element.android.libraries.mediaupload.api.MediaSender import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.api.PermissionsPresenter @@ -45,7 +43,6 @@ import javax.inject.Inject import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds -@SingleIn(RoomScope::class) class VoiceMessageComposerPresenter @Inject constructor( private val appCoroutineScope: CoroutineScope, private val voiceRecorder: VoiceRecorder, From 682abb3eff9513b5e934f45bf7c5d297cf6f55a4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 17:17:21 +0100 Subject: [PATCH 42/47] Improve FakeMessagesNavigator using lambda as per the new test system. --- .../messages/impl/FakeMessagesNavigator.kt | 34 +++++-------- .../messages/impl/MessagesPresenterTest.kt | 31 ++++++++--- .../MessageComposerPresenterTest.kt | 51 ++++++++++++++----- .../impl/timeline/TimelinePresenterTest.kt | 7 ++- 4 files changed, 78 insertions(+), 45 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt index d11398bd8e..5dcc4e7496 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/FakeMessagesNavigator.kt @@ -11,41 +11,33 @@ import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo +import io.element.android.tests.testutils.lambda.lambdaError import kotlinx.collections.immutable.ImmutableList -class FakeMessagesNavigator : MessagesNavigator { - var onShowEventDebugInfoClickedCount = 0 - private set - - var onForwardEventClickedCount = 0 - private set - - var onReportContentClickedCount = 0 - private set - - var onEditPollClickedCount = 0 - private set - - var onPreviewAttachmentCount = 0 - private set - +class FakeMessagesNavigator( + private val onShowEventDebugInfoClickLambda: (eventId: EventId?, debugInfo: TimelineItemDebugInfo) -> Unit = { _, _ -> lambdaError() }, + private val onForwardEventClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() }, + private val onReportContentClickLambda: (eventId: EventId, senderId: UserId) -> Unit = { _, _ -> lambdaError() }, + private val onEditPollClickLambda: (eventId: EventId) -> Unit = { _ -> lambdaError() }, + private val onPreviewAttachmentLambda: (attachments: ImmutableList) -> Unit = { _ -> lambdaError() }, +) : MessagesNavigator { override fun onShowEventDebugInfoClick(eventId: EventId?, debugInfo: TimelineItemDebugInfo) { - onShowEventDebugInfoClickedCount++ + onShowEventDebugInfoClickLambda(eventId, debugInfo) } override fun onForwardEventClick(eventId: EventId) { - onForwardEventClickedCount++ + onForwardEventClickLambda(eventId) } override fun onReportContentClick(eventId: EventId, senderId: UserId) { - onReportContentClickedCount++ + onReportContentClickLambda(eventId, senderId) } override fun onEditPollClick(eventId: EventId) { - onEditPollClickedCount++ + onEditPollClickLambda(eventId) } override fun onPreviewAttachment(attachments: ImmutableList) { - onPreviewAttachmentCount++ + onPreviewAttachmentLambda(attachments) } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 3d4969fd28..4f4de58bf5 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -56,6 +56,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.toEventOrTransactionId import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -65,12 +66,14 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID_2 import io.element.android.libraries.matrix.test.A_THROWABLE +import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.aRoomMember import io.element.android.libraries.matrix.test.timeline.FakeTimeline +import io.element.android.libraries.matrix.test.timeline.aTimelineItemDebugInfo import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.TextEditorState @@ -217,7 +220,10 @@ class MessagesPresenterTest { @Test fun `present - handle action forward`() = runTest { - val navigator = FakeMessagesNavigator() + val onForwardEventClickLambda = lambdaRecorder { } + val navigator = FakeMessagesNavigator( + onForwardEventClickLambda = onForwardEventClickLambda, + ) val presenter = createMessagesPresenter(navigator = navigator) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -225,7 +231,7 @@ class MessagesPresenterTest { val initialState = awaitItem() initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Forward, aMessageEvent())) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) - assertThat(navigator.onForwardEventClickedCount).isEqualTo(1) + onForwardEventClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) } } @@ -452,7 +458,10 @@ class MessagesPresenterTest { @Test fun `present - handle action edit poll`() = runTest { - val navigator = FakeMessagesNavigator() + val onEditPollClickLambda = lambdaRecorder { } + val navigator = FakeMessagesNavigator( + onEditPollClickLambda = onEditPollClickLambda + ) val presenter = createMessagesPresenter(navigator = navigator) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -460,7 +469,7 @@ class MessagesPresenterTest { val initialState = awaitItem() initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.Edit, aMessageEvent(content = aTimelineItemPollContent()))) awaitItem() - assertThat(navigator.onEditPollClickedCount).isEqualTo(1) + onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) } } @@ -516,7 +525,10 @@ class MessagesPresenterTest { @Test fun `present - handle action report content`() = runTest { - val navigator = FakeMessagesNavigator() + val onReportContentClickLambda = lambdaRecorder { _: EventId, _: UserId -> } + val navigator = FakeMessagesNavigator( + onReportContentClickLambda = onReportContentClickLambda + ) val presenter = createMessagesPresenter(navigator = navigator) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -524,7 +536,7 @@ class MessagesPresenterTest { val initialState = awaitItem() initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ReportContent, aMessageEvent())) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) - assertThat(navigator.onReportContentClickedCount).isEqualTo(1) + onReportContentClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(A_USER_ID)) } } @@ -542,7 +554,10 @@ class MessagesPresenterTest { @Test fun `present - handle action show developer info`() = runTest { - val navigator = FakeMessagesNavigator() + val onShowEventDebugInfoClickLambda = lambdaRecorder { _: EventId?, _: TimelineItemDebugInfo -> } + val navigator = FakeMessagesNavigator( + onShowEventDebugInfoClickLambda = onShowEventDebugInfoClickLambda + ) val presenter = createMessagesPresenter(navigator = navigator) moleculeFlow(RecompositionMode.Immediate) { presenter.present() @@ -550,7 +565,7 @@ class MessagesPresenterTest { val initialState = awaitItem() initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.ViewSource, aMessageEvent())) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) - assertThat(navigator.onShowEventDebugInfoClickedCount).isEqualTo(1) + onShowEventDebugInfoClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID), value(aTimelineItemDebugInfo())) } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index fcd9102be6..d0b41bbb1e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -20,6 +20,7 @@ import im.vector.app.features.analytics.plan.Composer import im.vector.app.features.analytics.plan.Interaction import io.element.android.features.messages.impl.FakeMessagesNavigator import io.element.android.features.messages.impl.MessagesNavigator +import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.draft.ComposerDraftService import io.element.android.features.messages.impl.draft.FakeComposerDraftService import io.element.android.features.messages.impl.messagecomposer.suggestions.SuggestionsProcessor @@ -93,6 +94,7 @@ import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test import io.element.android.tests.testutils.waitForPredicate import io.mockk.mockk +import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -686,7 +688,10 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -715,7 +720,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } @@ -724,7 +729,10 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -754,7 +762,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromGallery) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } @@ -779,7 +787,10 @@ class MessageComposerPresenterTest { val room = FakeMatrixRoom( typingNoticeResult = { Result.success(Unit) } ) - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -790,7 +801,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.FromFiles) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } @@ -838,7 +849,10 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -850,7 +864,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } @@ -860,7 +874,10 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter() - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -873,7 +890,7 @@ class MessageComposerPresenterTest { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) permissionPresenter.setPermissionGranted() - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() cancelAndIgnoreRemainingEvents() } } @@ -884,7 +901,10 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter().apply { setPermissionGranted() } - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -896,7 +916,7 @@ class MessageComposerPresenterTest { }.test { val initialState = awaitFirstItem() initialState.eventSink(MessageComposerEvents.PickAttachmentSource.VideoFromCamera) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } @@ -906,7 +926,10 @@ class MessageComposerPresenterTest { typingNoticeResult = { Result.success(Unit) } ) val permissionPresenter = FakePermissionsPresenter() - val navigator = FakeMessagesNavigator() + val onPreviewAttachmentLambda = lambdaRecorder { _: ImmutableList -> } + val navigator = FakeMessagesNavigator( + onPreviewAttachmentLambda = onPreviewAttachmentLambda + ) val presenter = createPresenter( coroutineScope = this, room = room, @@ -922,7 +945,7 @@ class MessageComposerPresenterTest { assertThat(permissionState.showAttachmentSourcePicker).isFalse() permissionPresenter.setPermissionGranted() skipItems(1) - assertThat(navigator.onPreviewAttachmentCount).isEqualTo(1) + onPreviewAttachmentLambda.assertions().isCalledOnce() } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index d153dd5743..4326ec5545 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -431,7 +431,10 @@ import kotlin.time.Duration.Companion.seconds @Test fun `present - PollEditClicked event navigates`() = runTest { - val navigator = FakeMessagesNavigator() + val onEditPollClickLambda = lambdaRecorder { _: EventId -> } + val navigator = FakeMessagesNavigator( + onEditPollClickLambda = onEditPollClickLambda + ) val presenter = createTimelinePresenter( messagesNavigator = navigator, ) @@ -439,7 +442,7 @@ import kotlin.time.Duration.Companion.seconds presenter.present() }.test { awaitFirstItem().eventSink(TimelineEvents.EditPoll(AN_EVENT_ID)) - assertThat(navigator.onEditPollClickedCount).isEqualTo(1) + onEditPollClickLambda.assertions().isCalledOnce().with(value(AN_EVENT_ID)) } } From a81170ef74b4854d4e991225ba093ccd209eeab8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 17:29:20 +0100 Subject: [PATCH 43/47] Let the TimelinePresenter.Factory be injected in MessagesNode to have a better architecture of dependencies between presenter. --- .../features/messages/impl/MessagesNode.kt | 3 + .../messages/impl/MessagesPresenter.kt | 5 +- .../messages/impl/MessagesPresenterTest.kt | 32 ++++------ .../impl/timeline/TimelinePresenterTest.kt | 60 +++++++++---------- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index 7d0d6cb2d0..1798584853 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -32,6 +32,7 @@ import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter import io.element.android.features.messages.impl.timeline.TimelineEvents +import io.element.android.features.messages.impl.timeline.TimelinePresenter import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories import io.element.android.features.messages.impl.timeline.model.TimelineItem @@ -62,6 +63,7 @@ class MessagesNode @AssistedInject constructor( private val room: MatrixRoom, private val analyticsService: AnalyticsService, messageComposerPresenterFactory: MessageComposerPresenter.Factory, + timelinePresenterFactory: TimelinePresenter.Factory, presenterFactory: MessagesPresenter.Factory, private val timelineItemPresenterFactories: TimelineItemPresenterFactories, private val mediaPlayer: MediaPlayer, @@ -70,6 +72,7 @@ class MessagesNode @AssistedInject constructor( private val presenter = presenterFactory.create( navigator = this, composerPresenter = messageComposerPresenterFactory.create(this), + timelinePresenter = timelinePresenterFactory.create(this), ) private val callbacks = plugins() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 8f11c491e2..e39056ec9b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -37,7 +37,6 @@ import io.element.android.features.messages.impl.messagecomposer.MessageComposer import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState import io.element.android.features.messages.impl.timeline.TimelineController import io.element.android.features.messages.impl.timeline.TimelineEvents -import io.element.android.features.messages.impl.timeline.TimelinePresenter import io.element.android.features.messages.impl.timeline.TimelineState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState @@ -91,7 +90,7 @@ class MessagesPresenter @AssistedInject constructor( private val room: MatrixRoom, @Assisted private val composerPresenter: Presenter, private val voiceMessageComposerPresenter: Presenter, - timelinePresenterFactory: TimelinePresenter.Factory, + @Assisted private val timelinePresenter: Presenter, private val timelineProtectionPresenter: Presenter, private val identityChangeStatePresenter: Presenter, actionListPresenterFactory: ActionListPresenter.Factory, @@ -111,7 +110,6 @@ class MessagesPresenter @AssistedInject constructor( private val permalinkParser: PermalinkParser, private val analyticsService: AnalyticsService, ) : Presenter { - private val timelinePresenter = timelinePresenterFactory.create(navigator = navigator) private val actionListPresenter = actionListPresenterFactory.create(TimelineItemActionPostProcessor.Default) @AssistedFactory @@ -119,6 +117,7 @@ class MessagesPresenter @AssistedInject constructor( fun create( navigator: MessagesNavigator, composerPresenter: Presenter, + timelinePresenter: Presenter, ): MessagesPresenter } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 4f4de58bf5..61606a51de 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -23,8 +23,8 @@ import io.element.android.features.messages.impl.messagecomposer.MessageComposer import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState import io.element.android.features.messages.impl.pinned.banner.aLoadedPinnedMessagesBannerState import io.element.android.features.messages.impl.timeline.TimelineController -import io.element.android.features.messages.impl.timeline.TimelinePresenter -import io.element.android.features.messages.impl.timeline.createTimelinePresenter +import io.element.android.features.messages.impl.timeline.TimelineEvents +import io.element.android.features.messages.impl.timeline.aTimelineState import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent @@ -36,8 +36,6 @@ import io.element.android.features.messages.impl.timeline.protection.aTimelinePr import io.element.android.features.messages.impl.voicemessages.composer.aVoiceMessageComposerState import io.element.android.features.messages.test.timeline.FakeHtmlConverterProvider import io.element.android.features.networkmonitor.test.FakeNetworkMonitor -import io.element.android.features.poll.api.actions.EndPollAction -import io.element.android.features.poll.test.actions.FakeEndPollAction import io.element.android.features.roomcall.api.aStandByCallState import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper import io.element.android.libraries.architecture.AsyncData @@ -220,7 +218,7 @@ class MessagesPresenterTest { @Test fun `present - handle action forward`() = runTest { - val onForwardEventClickLambda = lambdaRecorder { } + val onForwardEventClickLambda = lambdaRecorder { } val navigator = FakeMessagesNavigator( onForwardEventClickLambda = onForwardEventClickLambda, ) @@ -458,7 +456,7 @@ class MessagesPresenterTest { @Test fun `present - handle action edit poll`() = runTest { - val onEditPollClickLambda = lambdaRecorder { } + val onEditPollClickLambda = lambdaRecorder { } val navigator = FakeMessagesNavigator( onEditPollClickLambda = onEditPollClickLambda ) @@ -475,16 +473,15 @@ class MessagesPresenterTest { @Test fun `present - handle action end poll`() = runTest { - val endPollAction = FakeEndPollAction() - val presenter = createMessagesPresenter(endPollAction = endPollAction) + val timelineEventSink = EventsRecorder() + val presenter = createMessagesPresenter(timelineEventSink = timelineEventSink) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitItem() - endPollAction.verifyExecutionCount(0) initialState.eventSink(MessagesEvents.HandleAction(TimelineItemAction.EndPoll, aMessageEvent(content = aTimelineItemPollContent()))) delay(1) - endPollAction.verifyExecutionCount(1) + timelineEventSink.assertSingle(TimelineEvents.EndPoll(AN_EVENT_ID)) cancelAndIgnoreRemainingEvents() } } @@ -525,7 +522,7 @@ class MessagesPresenterTest { @Test fun `present - handle action report content`() = runTest { - val onReportContentClickLambda = lambdaRecorder { _: EventId, _: UserId -> } + val onReportContentClickLambda = lambdaRecorder { _: EventId, _: UserId -> } val navigator = FakeMessagesNavigator( onReportContentClickLambda = onReportContentClickLambda ) @@ -554,7 +551,7 @@ class MessagesPresenterTest { @Test fun `present - handle action show developer info`() = runTest { - val onShowEventDebugInfoClickLambda = lambdaRecorder { _: EventId?, _: TimelineItemDebugInfo -> } + val onShowEventDebugInfoClickLambda = lambdaRecorder { _: EventId?, _: TimelineItemDebugInfo -> } val navigator = FakeMessagesNavigator( onShowEventDebugInfoClickLambda = onShowEventDebugInfoClickLambda ) @@ -1102,7 +1099,7 @@ class MessagesPresenterTest { navigator: FakeMessagesNavigator = FakeMessagesNavigator(), clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(), analyticsService: FakeAnalyticsService = FakeAnalyticsService(), - endPollAction: EndPollAction = FakeEndPollAction(), + timelineEventSink: (TimelineEvents) -> Unit = {}, permalinkParser: PermalinkParser = FakePermalinkParser(), messageComposerPresenter: Presenter = Presenter { aMessageComposerState( @@ -1112,19 +1109,12 @@ class MessagesPresenterTest { }, actionListEventSink: (ActionListEvents) -> Unit = {}, ): MessagesPresenter { - val timelinePresenterFactory = object : TimelinePresenter.Factory { - override fun create(navigator: MessagesNavigator): TimelinePresenter { - return createTimelinePresenter( - endPollAction = endPollAction, - ) - } - } val featureFlagService = FakeFeatureFlagService() return MessagesPresenter( room = matrixRoom, composerPresenter = messageComposerPresenter, voiceMessageComposerPresenter = { aVoiceMessageComposerState() }, - timelinePresenterFactory = timelinePresenterFactory, + timelinePresenter = { aTimelineState(eventSink = timelineEventSink) }, timelineProtectionPresenter = { aTimelineProtectionState() }, actionListPresenterFactory = FakeActionListPresenter.Factory(actionListEventSink), customReactionPresenter = { aCustomReactionState() }, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index 4326ec5545..a21dcb2834 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -660,35 +660,35 @@ import kotlin.time.Duration.Companion.seconds private suspend fun ReceiveTurbine.awaitFirstItem(): T { return awaitItem() } -} -internal fun TestScope.createTimelinePresenter( - timeline: Timeline = FakeTimeline(), - room: FakeMatrixRoom = FakeMatrixRoom( - liveTimeline = timeline, - canUserSendMessageResult = { _, _ -> Result.success(true) } - ), - redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(), - messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(), - endPollAction: EndPollAction = FakeEndPollAction(), - sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(), - sessionPreferencesStore: InMemorySessionPreferencesStore = InMemorySessionPreferencesStore(), - timelineItemIndexer: TimelineItemIndexer = TimelineItemIndexer(), -): TimelinePresenter { - return TimelinePresenter( - timelineItemsFactoryCreator = aTimelineItemsFactoryCreator(), - room = room, - dispatchers = testCoroutineDispatchers(), - appScope = this, - navigator = messagesNavigator, - redactedVoiceMessageManager = redactedVoiceMessageManager, - endPollAction = endPollAction, - sendPollResponseAction = sendPollResponseAction, - sessionPreferencesStore = sessionPreferencesStore, - timelineItemIndexer = timelineItemIndexer, - timelineController = TimelineController(room), - resolveVerifiedUserSendFailurePresenter = { aResolveVerifiedUserSendFailureState() }, - typingNotificationPresenter = { aTypingNotificationState() }, - roomCallStatePresenter = { aStandByCallState() }, - ) + private fun TestScope.createTimelinePresenter( + timeline: Timeline = FakeTimeline(), + room: FakeMatrixRoom = FakeMatrixRoom( + liveTimeline = timeline, + canUserSendMessageResult = { _, _ -> Result.success(true) } + ), + redactedVoiceMessageManager: RedactedVoiceMessageManager = FakeRedactedVoiceMessageManager(), + messagesNavigator: FakeMessagesNavigator = FakeMessagesNavigator(), + endPollAction: EndPollAction = FakeEndPollAction(), + sendPollResponseAction: SendPollResponseAction = FakeSendPollResponseAction(), + sessionPreferencesStore: InMemorySessionPreferencesStore = InMemorySessionPreferencesStore(), + timelineItemIndexer: TimelineItemIndexer = TimelineItemIndexer(), + ): TimelinePresenter { + return TimelinePresenter( + timelineItemsFactoryCreator = aTimelineItemsFactoryCreator(), + room = room, + dispatchers = testCoroutineDispatchers(), + appScope = this, + navigator = messagesNavigator, + redactedVoiceMessageManager = redactedVoiceMessageManager, + endPollAction = endPollAction, + sendPollResponseAction = sendPollResponseAction, + sessionPreferencesStore = sessionPreferencesStore, + timelineItemIndexer = timelineItemIndexer, + timelineController = TimelineController(room), + resolveVerifiedUserSendFailurePresenter = { aResolveVerifiedUserSendFailureState() }, + typingNotificationPresenter = { aTypingNotificationState() }, + roomCallStatePresenter = { aStandByCallState() }, + ) + } } From 703b244e19de407b7220d356661a89be2719d5ca Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 21 Nov 2024 17:53:32 +0100 Subject: [PATCH 44/47] Cleanup --- .../element/android/features/messages/impl/MessagesViewTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index 35c069e1f9..1d4e1a43b3 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -33,7 +33,6 @@ import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListState import io.element.android.features.messages.impl.actionlist.anActionListState import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction -import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure import io.element.android.features.messages.impl.crypto.sendfailure.resolve.aChangedIdentitySendFailure import io.element.android.features.messages.impl.messagecomposer.aMessageComposerState @@ -64,7 +63,6 @@ import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.ensureCalledOnce import io.element.android.tests.testutils.ensureCalledOnceWithParam import io.element.android.tests.testutils.pressBack -import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import org.junit.Rule import org.junit.Test From 62f5dc3bf0040d0cbfc1029446aad8546b9f8792 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 18 Nov 2024 16:14:08 +0100 Subject: [PATCH 45/47] fix : use RoomMembershipObserver to close room screen when leaving/declining invite/canceling knock request --- .../android/appnav/room/RoomFlowNode.kt | 16 ++++++++++++---- .../features/joinroom/impl/JoinRoomNode.kt | 6 +++--- .../leaveroom/impl/LeaveRoomPresenter.kt | 15 +++++---------- .../leaveroom/impl/LeaveRoomPresenterTest.kt | 19 +++++++++---------- .../libraries/matrix/impl/RustMatrixClient.kt | 5 +++-- .../matrix/impl/room/RustMatrixRoom.kt | 6 ++++-- .../matrix/impl/room/RustPendingRoom.kt | 4 ++++ .../matrix/impl/room/RustRoomFactory.kt | 6 ++++-- 8 files changed, 44 insertions(+), 33 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 0562c5e2d6..a70ea78a28 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -48,9 +48,11 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.getRoomInfoFlow import io.element.android.libraries.matrix.api.room.CurrentUserMembership +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch @@ -67,6 +69,7 @@ class RoomFlowNode @AssistedInject constructor( private val joinRoomEntryPoint: JoinRoomEntryPoint, private val roomAliasResolverEntryPoint: RoomAliasResolverEntryPoint, private val networkMonitor: NetworkMonitor, + private val membershipObserver: RoomMembershipObserver, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Loading, @@ -145,10 +148,6 @@ class RoomFlowNode @AssistedInject constructor( backstack.newRoot(NavTarget.JoinedRoom(roomId)) } } - CurrentUserMembership.LEFT -> { - // Left the room, navigate out of this flow - navigateUp() - } else -> { // Was invited or the room is not known, display the join room screen backstack.newRoot( @@ -161,6 +160,15 @@ class RoomFlowNode @AssistedInject constructor( } } }.launchIn(lifecycleScope) + + // If the user leaves the room from this client, close the room flow. + lifecycleScope.launch { + membershipObserver.updates + .first { it.roomId == roomId && !it.isUserInRoom } + .run { + navigateUp() + } + } } override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt index 44f4d8def0..bcd8190003 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomNode.kt @@ -43,14 +43,14 @@ class JoinRoomNode @AssistedInject constructor( state = state, onBackClick = ::navigateUp, onJoinSuccess = ::navigateUp, - onCancelKnockSuccess = ::navigateUp, - onKnockSuccess = { }, + onCancelKnockSuccess = {}, + onKnockSuccess = {}, modifier = modifier ) acceptDeclineInviteView.Render( state = state.acceptDeclineInviteState, onAcceptInvite = {}, - onDeclineInvite = { navigateUp() }, + onDeclineInvite = {}, modifier = Modifier ) } diff --git a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt index 168a684922..e36639e079 100644 --- a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt +++ b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenter.kt @@ -22,7 +22,6 @@ import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers 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.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.isDm import kotlinx.coroutines.launch import timber.log.Timber @@ -30,7 +29,6 @@ import javax.inject.Inject class LeaveRoomPresenter @Inject constructor( private val client: MatrixClient, - private val roomMembershipObserver: RoomMembershipObserver, private val dispatchers: CoroutineDispatchers, ) : Presenter { @Composable @@ -58,7 +56,6 @@ class LeaveRoomPresenter @Inject constructor( is LeaveRoomEvent.LeaveRoom -> scope.launch(dispatchers.io) { client.leaveRoom( roomId = event.roomId, - roomMembershipObserver = roomMembershipObserver, confirmation = confirmation, progress = progress, error = error, @@ -88,7 +85,6 @@ private suspend fun showLeaveRoomAlert( private suspend fun MatrixClient.leaveRoom( roomId: RoomId, - roomMembershipObserver: RoomMembershipObserver, confirmation: MutableState, progress: MutableState, error: MutableState, @@ -96,12 +92,11 @@ private suspend fun MatrixClient.leaveRoom( confirmation.value = LeaveRoomState.Confirmation.Hidden progress.value = LeaveRoomState.Progress.Shown getRoom(roomId)?.use { room -> - room.leave().onSuccess { - roomMembershipObserver.notifyUserLeftRoom(room.roomId) - }.onFailure { - Timber.e(it, "Error while leaving room ${room.displayName} - ${room.roomId}") - error.value = LeaveRoomState.Error.Shown - } + room.leave() + .onFailure { + Timber.e(it, "Error while leaving room ${room.roomId}") + error.value = LeaveRoomState.Error.Shown + } } progress.value = LeaveRoomState.Progress.Hidden } diff --git a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterTest.kt b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterTest.kt index 9689de4eb2..16edf8b980 100644 --- a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterTest.kt +++ b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/LeaveRoomPresenterTest.kt @@ -14,15 +14,15 @@ import com.google.common.truth.Truth.assertThat import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.room.RoomMembershipObserver -import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.testCoroutineDispatchers -import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test @@ -126,26 +126,27 @@ class LeaveRoomPresenterTest { @Test fun `present - leaving a room leaves the room`() = runTest { - val roomMembershipObserver = RoomMembershipObserver() + val leaveRoomLambda = lambdaRecorder> { Result.success(Unit) } val presenter = createLeaveRoomPresenter( client = FakeMatrixClient().apply { givenGetRoomResult( roomId = A_ROOM_ID, result = FakeMatrixRoom( - leaveRoomLambda = { Result.success(Unit) } + leaveRoomLambda = leaveRoomLambda ), ) }, - roomMembershipObserver = roomMembershipObserver ) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { val initialState = awaitItem() initialState.eventSink(LeaveRoomEvent.LeaveRoom(A_ROOM_ID)) - // Membership observer should receive a 'left room' change - assertThat(roomMembershipObserver.updates.first().change).isEqualTo(MembershipChange.LEFT) + advanceUntilIdle() cancelAndIgnoreRemainingEvents() + assert(leaveRoomLambda) + .isCalledOnce() + .withNoParameter() } } @@ -227,9 +228,7 @@ class LeaveRoomPresenterTest { private fun TestScope.createLeaveRoomPresenter( client: MatrixClient = FakeMatrixClient(), - roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(), ): LeaveRoomPresenter = LeaveRoomPresenter( client = client, - roomMembershipObserver = roomMembershipObserver, dispatchers = testCoroutineDispatchers(false), ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 3c3498da48..193cbd5350 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -178,6 +178,8 @@ class RustMatrixClient( sessionCoroutineScope = sessionCoroutineScope, ) + private val roomMembershipObserver = RoomMembershipObserver() + private val roomFactory = RustRoomFactory( roomListService = roomListService, innerRoomListService = innerRoomListService, @@ -191,6 +193,7 @@ class RustMatrixClient( roomSyncSubscriber = roomSyncSubscriber, timelineEventTypeFilterFactory = timelineEventTypeFilterFactory, featureFlagService = featureFlagService, + roomMembershipObserver = roomMembershipObserver, ) override val mediaLoader: MatrixMediaLoader = RustMediaLoader( @@ -199,8 +202,6 @@ class RustMatrixClient( innerClient = client, ) - private val roomMembershipObserver = RoomMembershipObserver() - private var clientDelegateTaskHandle: TaskHandle? = client.setDelegate(sessionDelegate) private val _userProfile: MutableStateFlow = MutableStateFlow( diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 8b72282cd5..523364683b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MatrixRoomNotificationSettingsState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.location.AssetType @@ -58,7 +59,6 @@ import io.element.android.libraries.matrix.impl.widget.RustWidgetDriver import io.element.android.libraries.matrix.impl.widget.generateWidgetWebViewUrl import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -90,7 +90,6 @@ import org.matrix.rustcomponents.sdk.IdentityStatusChange as RustIdentityStateCh import org.matrix.rustcomponents.sdk.Room as InnerRoom import org.matrix.rustcomponents.sdk.Timeline as InnerTimeline -@OptIn(ExperimentalCoroutinesApi::class) class RustMatrixRoom( override val sessionId: SessionId, private val deviceId: DeviceId, @@ -105,6 +104,7 @@ class RustMatrixRoom( private val roomSyncSubscriber: RoomSyncSubscriber, private val matrixRoomInfoMapper: MatrixRoomInfoMapper, private val featureFlagService: FeatureFlagService, + private val roomMembershipObserver: RoomMembershipObserver, ) : MatrixRoom { override val roomId = RoomId(innerRoom.id()) @@ -374,6 +374,8 @@ class RustMatrixRoom( override suspend fun leave(): Result = withContext(roomDispatcher) { runCatching { innerRoom.leave() + }.onSuccess { + roomMembershipObserver.notifyUserLeftRoom(roomId) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustPendingRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustPendingRoom.kt index 635d362365..6e230b7ef7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustPendingRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustPendingRoom.kt @@ -10,15 +10,19 @@ package io.element.android.libraries.matrix.impl.room 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.room.PendingRoom +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import org.matrix.rustcomponents.sdk.RoomPreview class RustPendingRoom( override val sessionId: SessionId, override val roomId: RoomId, private val inner: RoomPreview, + private val roomMembershipObserver: RoomMembershipObserver, ) : PendingRoom { override suspend fun leave(): Result = runCatching { inner.leave() + }.onSuccess { + roomMembershipObserver.notifyUserLeftRoom(roomId) } override fun close() { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt index 487c4d1496..84f34ae9bf 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt @@ -17,13 +17,13 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.PendingRoom +import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.awaitLoaded import io.element.android.libraries.matrix.impl.roomlist.fullRoomWithTimeline import io.element.android.libraries.matrix.impl.roomlist.roomOrNull import io.element.android.services.toolbox.api.systemclock.SystemClock import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock @@ -51,8 +51,8 @@ class RustRoomFactory( private val roomSyncSubscriber: RoomSyncSubscriber, private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory, private val featureFlagService: FeatureFlagService, + private val roomMembershipObserver: RoomMembershipObserver, ) { - @OptIn(ExperimentalCoroutinesApi::class) private val dispatcher = dispatchers.io.limitedParallelism(1) private val mutex = Mutex() private var isDestroyed: Boolean = false @@ -120,6 +120,7 @@ class RustRoomFactory( roomSyncSubscriber = roomSyncSubscriber, matrixRoomInfoMapper = matrixRoomInfoMapper, featureFlagService = featureFlagService, + roomMembershipObserver = roomMembershipObserver, ) } } @@ -148,6 +149,7 @@ class RustRoomFactory( sessionId = sessionId, roomId = roomId, inner = innerRoom, + roomMembershipObserver = roomMembershipObserver, ) } From fe45005a855d0bca75a6fb441e9084135b596673 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 01:07:35 +0000 Subject: [PATCH 46/47] Update dependency org.robolectric:robolectric to v4.14.1 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 262bd97f77..9946504d20 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -154,7 +154,7 @@ test_konsist = "com.lemonappdev:konsist:0.16.1" test_turbine = "app.cash.turbine:turbine:1.2.0" test_truth = "com.google.truth:truth:1.4.4" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.18" -test_robolectric = "org.robolectric:robolectric:4.14" +test_robolectric = "org.robolectric:robolectric:4.14.1" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } test_composable_preview_scanner = "com.github.sergio-sastre.ComposablePreviewScanner:android:0.1.2" From 01ee3ee6fe01e2d2846fb1c3423b4c638255356f Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 22 Nov 2024 07:01:59 +0000 Subject: [PATCH 47/47] Update screenshots --- ...tures.createroom.impl.addpeople_AddPeopleView_Day_2_en.png | 2 +- ...res.createroom.impl.addpeople_AddPeopleView_Night_2_en.png | 2 +- ...tures.createroom.impl.components_UserListView_Day_2_en.png | 4 ++-- ...tures.createroom.impl.components_UserListView_Day_3_en.png | 2 +- ...tures.createroom.impl.components_UserListView_Day_4_en.png | 2 +- ...tures.createroom.impl.components_UserListView_Day_5_en.png | 4 ++-- ...tures.createroom.impl.components_UserListView_Day_6_en.png | 2 +- ...tures.createroom.impl.components_UserListView_Day_7_en.png | 4 ++-- ...tures.createroom.impl.components_UserListView_Day_8_en.png | 2 +- ...res.createroom.impl.components_UserListView_Night_2_en.png | 4 ++-- ...res.createroom.impl.components_UserListView_Night_3_en.png | 4 ++-- ...res.createroom.impl.components_UserListView_Night_4_en.png | 4 ++-- ...res.createroom.impl.components_UserListView_Night_5_en.png | 4 ++-- ...res.createroom.impl.components_UserListView_Night_6_en.png | 2 +- ...res.createroom.impl.components_UserListView_Night_7_en.png | 2 +- ...res.createroom.impl.components_UserListView_Night_8_en.png | 4 ++-- ...tures.createroom.impl.root_CreateRoomRootView_Day_1_en.png | 4 ++-- ...tures.createroom.impl.root_CreateRoomRootView_Day_2_en.png | 4 ++-- ...res.createroom.impl.root_CreateRoomRootView_Night_1_en.png | 4 ++-- ...res.createroom.impl.root_CreateRoomRootView_Night_2_en.png | 4 ++-- ...atures.messages.impl.report_ReportMessageView_Day_0_en.png | 4 ++-- ...atures.messages.impl.report_ReportMessageView_Day_1_en.png | 4 ++-- ...ures.messages.impl.report_ReportMessageView_Night_0_en.png | 4 ++-- ...ures.messages.impl.report_ReportMessageView_Night_1_en.png | 4 ++-- ...roomdetails.impl.invite_RoomInviteMembersView_Day_2_en.png | 2 +- ...roomdetails.impl.invite_RoomInviteMembersView_Day_3_en.png | 4 ++-- ...roomdetails.impl.invite_RoomInviteMembersView_Day_4_en.png | 2 +- ...roomdetails.impl.invite_RoomInviteMembersView_Day_5_en.png | 2 +- ...roomdetails.impl.invite_RoomInviteMembersView_Day_6_en.png | 4 ++-- ...roomdetails.impl.invite_RoomInviteMembersView_Day_7_en.png | 2 +- ...omdetails.impl.invite_RoomInviteMembersView_Night_2_en.png | 2 +- ...omdetails.impl.invite_RoomInviteMembersView_Night_3_en.png | 4 ++-- ...omdetails.impl.invite_RoomInviteMembersView_Night_4_en.png | 4 ++-- ...omdetails.impl.invite_RoomInviteMembersView_Night_5_en.png | 2 +- ...omdetails.impl.invite_RoomInviteMembersView_Night_6_en.png | 4 ++-- ...omdetails.impl.invite_RoomInviteMembersView_Night_7_en.png | 2 +- ...s.roomdetails.impl.members_RoomMemberListView_Day_4_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_5_en.png | 2 +- ...s.roomdetails.impl.members_RoomMemberListView_Day_6_en.png | 2 +- ...s.roomdetails.impl.members_RoomMemberListView_Day_7_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_4_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_5_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_6_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_7_en.png | 2 +- ...lesandpermissions.changeroles_ChangeRolesView_Day_5_en.png | 2 +- ...sandpermissions.changeroles_ChangeRolesView_Night_5_en.png | 2 +- ...components_DefaultRoomListTopBarWithIndicator_Day_0_en.png | 4 ++-- ...mponents_DefaultRoomListTopBarWithIndicator_Night_0_en.png | 4 ++-- ...oomlist.impl.components_DefaultRoomListTopBar_Day_0_en.png | 4 ++-- ...mlist.impl.components_DefaultRoomListTopBar_Night_0_en.png | 4 ++-- ...res.roomlist.impl.filters_RoomListFiltersView_Day_0_en.png | 4 ++-- ...s.roomlist.impl.filters_RoomListFiltersView_Night_0_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_0_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_10_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_1_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_2_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_3_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_4_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_5_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Day_6_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_0_en.png | 4 ++-- .../features.roomlist.impl_RoomListView_Night_10_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_1_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_2_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_3_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_4_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_5_en.png | 4 ++-- .../images/features.roomlist.impl_RoomListView_Night_6_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_0_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_1_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_2_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_3_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_4_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Day_5_en.png | 3 +++ .../libraries.designsystem.icons_IconsCompound_Night_0_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Night_1_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Night_2_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Night_3_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Night_4_en.png | 4 ++-- .../libraries.designsystem.icons_IconsCompound_Night_5_en.png | 3 +++ ...ents.previews_TimePickerHorizontal_DateTime_pickers_en.png | 4 ++-- ...ts.previews_TimePickerVerticalDark_DateTime_pickers_en.png | 4 ++-- ...s.previews_TimePickerVerticalLight_DateTime_pickers_en.png | 4 ++-- ...me.components_SearchBarActiveNoneQuery_Search_views_en.png | 2 +- ....components_SearchBarActiveWithContent_Search_views_en.png | 4 ++-- ...omponents_SearchBarActiveWithNoResults_Search_views_en.png | 4 ++-- ...s_SearchBarActiveWithQueryNoBackButton_Search_views_en.png | 4 ++-- ...me.components_SearchBarActiveWithQuery_Search_views_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_1_en.png | 2 +- .../libraries.roomselect.impl_RoomSelectView_Day_3_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Day_4_en.png | 2 +- .../libraries.roomselect.impl_RoomSelectView_Night_1_en.png | 4 ++-- .../libraries.roomselect.impl_RoomSelectView_Night_3_en.png | 2 +- .../libraries.roomselect.impl_RoomSelectView_Night_4_en.png | 2 +- 94 files changed, 165 insertions(+), 159 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_5_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Day_2_en.png index 6a4c0ada32..62e19018c4 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94ee32aad0979cbc11d1ef7dbb23fbed8425778a9e28f8742a7d219d8bdab379 +oid sha256:480dcf4628c371f8df8b6a26f73f0a5ed45e9ca89baf9f4ab52bd896ed1cc4d7 size 77593 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Night_2_en.png index b5298e08af..26be59c3da 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.addpeople_AddPeopleView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e85f874e950c2ae755a31bc2dac2115ef30e052a1183112badd50e7066d861c +oid sha256:96333cfda74bc44b7f9f95eab383ab26857b07d68ed30255ccb1ef3ae1558a4c size 78110 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_2_en.png index 92d9db2f11..9cbd2e472b 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d175ae95fed4ac24e9b506678c4ee1e235c3c8405915498f7f97db0764e5470c -size 7571 +oid sha256:adb68fcd10b66e37f774560e59991bf6488043d4e1b66e6b1f19a648c90a6333 +size 7572 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_3_en.png index fdb10220a2..c10cc18a37 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0db80941c8c981d3f66bc6cd9364f0f8fd5b1e7033f81da46cdffe478f97c748 +oid sha256:72dbe69b1952d3c2e00509bb1a5e0493baa30c0ef4e444f652f3fd7f81a8eccd size 6528 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_4_en.png index fdb10220a2..c10cc18a37 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0db80941c8c981d3f66bc6cd9364f0f8fd5b1e7033f81da46cdffe478f97c748 +oid sha256:72dbe69b1952d3c2e00509bb1a5e0493baa30c0ef4e444f652f3fd7f81a8eccd size 6528 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_5_en.png index c562f2cabd..d52aba896f 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f49822ac3f9a328dcbc9747e49ab3b3af74de42f81f833640232199d85d8d961 -size 38428 +oid sha256:1ae3884c6bfded545fda8dfadfc94cb4c17bf2df9556c4d33a931c3509b8a885 +size 38429 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_6_en.png index e0413b796a..cba838d82c 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c2187b3eb917901c6d9fac36ae44c28c7c3946a055cbf156aab3063c8981e4e +oid sha256:daba14ee51067d64e9098815b1d187a89b405b0f11b22f7fa888106cfb388fa9 size 52055 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_7_en.png index 3c8281a03c..86a85de950 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57ee28833b587ec86f93c685d716f0cce94b60e0752de3fc1a1a3d7ac05cbdb6 -size 11013 +oid sha256:878d81472018964e1217c36708e31469a62486e1a913da26fc5a209731c4f9a1 +size 11014 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_8_en.png index fdb10220a2..c10cc18a37 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0db80941c8c981d3f66bc6cd9364f0f8fd5b1e7033f81da46cdffe478f97c748 +oid sha256:72dbe69b1952d3c2e00509bb1a5e0493baa30c0ef4e444f652f3fd7f81a8eccd size 6528 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_2_en.png index 0fbe95ff70..f0f400e37a 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d174f1f8e77c9cd02506b487e410a7bcbf4d571f048f739d4f10582c72e682d0 -size 7501 +oid sha256:e8638e7c07500bddc9c67480685d2548f0b50772977fee7565fb92ae72eaefcb +size 7504 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_3_en.png index 228b02c0a9..acb4061713 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:000c36468af4793e4956a4a2a2be1867afefa13140219e2dd8b17b1f7670b6de -size 6299 +oid sha256:000dbaa58af2f75293be0a3fed993447275582abaa33088b3f9c533ac4e0fec6 +size 6298 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_4_en.png index 228b02c0a9..acb4061713 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:000c36468af4793e4956a4a2a2be1867afefa13140219e2dd8b17b1f7670b6de -size 6299 +oid sha256:000dbaa58af2f75293be0a3fed993447275582abaa33088b3f9c533ac4e0fec6 +size 6298 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_5_en.png index 5ed5ad8a29..6e3f7c983b 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed09d7879d10d22bc90bf0757bc649436f90428347cc8df2780c05e4c1c95fe5 -size 39183 +oid sha256:375315a6a917f013079bfaa0d96bb3b90f72d485c3c4ed7b30c3f86dd9277793 +size 39184 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_6_en.png index dd905d53ce..2fa7ccc26b 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8cec0dc2a2b0870c7ee43a0329f9e8b67b42e7e4f26f349543e8c5d5841830fd +oid sha256:618164f424e1b2d334051d7d55dac014d77ea00ac8f15ae0f62fdd0fa77705fe size 53161 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_7_en.png index 39750c36e6..605d9d0907 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5694d2ee8d939aa3cc5107b7601ff251481fc8226981208b603507d407dcb12a +oid sha256:b81f55a04ecf3d4c3f266d5e0b67413be226933816195307e830d081a2bbc286 size 10637 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_8_en.png index 228b02c0a9..acb4061713 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.components_UserListView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:000c36468af4793e4956a4a2a2be1867afefa13140219e2dd8b17b1f7670b6de -size 6299 +oid sha256:000dbaa58af2f75293be0a3fed993447275582abaa33088b3f9c533ac4e0fec6 +size 6298 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_1_en.png index ea896a093d..169ee5ef02 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:208e9d9f42a929c0bdb280c4442faf0211f43d3d350c48246b20ca3256a11690 -size 19846 +oid sha256:0838f9b076ed75cb55ea1119aa097401314bf175ead2c34ee84d7cefb65f38c6 +size 19851 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_2_en.png index beb2aca740..c23fdfb978 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5524fdbc6570b90bb1d8296670631259b3fd7b3b8908b7622165d658ac7d1e60 -size 26324 +oid sha256:5567d4fb0e1595b6383b6bf5a8e34e276443f288bd8b9ed8ffc04f459260510f +size 26329 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_1_en.png index ac30088346..055b332106 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa26d53e0373f886180c38c7398597737dd808ef98e658a5f98e0fc74f150f36 -size 18764 +oid sha256:1b96b798e72a139710e318a2eb5203078654a1b39126bc07eb46bc0cf5d65114 +size 18783 diff --git a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_2_en.png index b8fb57b908..48c38ccba1 100644 --- a/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.createroom.impl.root_CreateRoomRootView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0fc065ed57fc706c81e04fb527ed4ba25deb5b5366d4c67cb902ead6bac83d5 -size 24772 +oid sha256:2c1270e74e3a6d52b6665922c1efc940c42d5b5d7b05943e7f0604e217fac57e +size 24788 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_0_en.png index faac664042..d1e243898f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fb068f011864a5045c7bd65ffba67bd4b9234f42f40960c1eba1408328f5b3e -size 43782 +oid sha256:94d5c829de7020a80f0ce3a89b731febc4a1636834adb2d831650756f3b12ab2 +size 43728 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_1_en.png index 4c690b2ad6..c555bbb3c2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:741ad1b881c9598c42c91603e84166768b5dc5a713ec191dc1c34c05360dbb92 -size 44908 +oid sha256:a59f101c511d6b3ce269edf80cf961a7ef637cc14d36879e79a6af46bf0f1fd6 +size 44853 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_0_en.png index a8c5947ca0..f6f120f536 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0e8cdaa2d979c68923e554754a6b5e5d9b31040988c2d4e6fc8248a28a8aa8dc -size 42409 +oid sha256:43a6fd18c7957df16e71645df99796d922e5f4b530047b366ae9c8d41260d8b7 +size 42445 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_1_en.png index 7b65db25b3..424d924e89 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.report_ReportMessageView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ca3973d21ea5575ab0921f78c4443c69c21f1f3f07ca78612c57bfe58b261002 -size 43748 +oid sha256:6f61dc062ae0f2cbbbb1001f6a7dc85c5c1f453a72757ef56e0c931354eb7f56 +size 43785 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en.png index e45a56abe0..87e561ebdb 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96292b1a98c2d9a7f034cbde25d03a4c1ee0debf6e8a7b5114eccf0d6c7b68bb +oid sha256:130f2892cfebfc0b679669e8eab88706aa7fa35bf9e24d88c62448625aaf0904 size 11125 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en.png index 8b05387403..06c93027e3 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:73cf6be0bd55e6c83888708176af33b9975fbe0721c4cce86799c547b9118593 -size 22408 +oid sha256:d58405ce69b7823d7f5c2da021b3f9cffc39335e1beabe543452e606179f9a8b +size 22409 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en.png index 67a16d35b5..47362fb9c9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be4cf1bfbe051f838a3469309bc2bbf29d7c3b07be92d52c7b77f94268a02c3c +oid sha256:9e339b7d5286e4793b781a6edf8e7b1059d0b90d3998314057eaf0b40d9a7149 size 13060 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en.png index a54a62e2ae..117efe3950 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2bd2bfdc6c1c597d6f9963eb657ab66f0d9c0ea42dc7d48cbb93d21b2933a8b0 +oid sha256:53b649b6aa79b687aa1a57d564e0fb7c2786dc62e5854a8cbba1e8a60704008c size 42451 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en.png index 068035ff74..d53f6a1ee4 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e3e15dff6a041cab272fba75089bc8f373605630709e6120625ccb81b52be6a -size 37510 +oid sha256:53ad1edda2a1b0f3355f471a87a92ed9e4490af30a7f927d6b88d1bf54e8e4dd +size 37509 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en.png index 9c3a9fe439..3d00319245 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48351de48d44af2e1d22d72e6e3fc7511a3d9ec7af3a0bbaadc2928e822795b0 +oid sha256:dff355ad91d6e7d81dbd3a11822e57b28aca8dd87db79ad76e18d2295f9b7a7d size 29660 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en.png index b47b425017..80e14e8129 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ff9a4ca8777f52c24fe86979790c7f2fedf8becce0c0a5c6d896bfef926a33f4 +oid sha256:c18aa05e130d7e5d2d33ea3eb78a096656dd8625719a2f16bb39406c5319ee76 size 10745 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en.png index 38e0cf9d7a..7813ea21b8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3ea5702dbc2487125dd3ce6c382a10cd67dff580240cc81f510a4bc7d06bfbb -size 22833 +oid sha256:f886766fdefc45c8738658d3851b973bc12f703576dd213c717e3990a7fedc9c +size 22832 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en.png index 54824070cf..ec5bce7d58 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ca09d0870d394875ec86e3e9b1077e64408cc86310ff50dc8943ff31762d9b8 -size 12666 +oid sha256:93deeff0e991b3384f582e65e5729856b7bed4195a5a0329535c616bc5c15b9f +size 12665 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en.png index 4070ccfd7f..bdcd76b709 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:693bc737b9fcc36a745cb816bfbedfd1fc69793bbd45a1bbd8a4fcf4ca9080cf +oid sha256:e815198898cfd091260650f301121e26a70d3943abc4ef2cc0bc95394395c2e2 size 43080 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en.png index 9900befc1d..0aa06f43bd 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:efcd5a2fdd381c599e143d0bcae5fa75d46814de4b48900170a03abe38219905 -size 37448 +oid sha256:0da7a01de4fd1623c4acfd771f74e4a01b38e8227dffbe2c0076c56d617c0916 +size 37447 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en.png index 7849027ddf..87ec7712b6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.invite_RoomInviteMembersView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29f1fa7d90f26cf8e4a6ec4d0228673f3a5e7d2067910b6bf1e2a44f74d3d6de +oid sha256:ec72db9bd920c237d4919fa9c09245efe02019a789d4c3c7cf1c9d3a9a76aa5b size 29028 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png index 92d9db2f11..9cbd2e472b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d175ae95fed4ac24e9b506678c4ee1e235c3c8405915498f7f97db0764e5470c -size 7571 +oid sha256:adb68fcd10b66e37f774560e59991bf6488043d4e1b66e6b1f19a648c90a6333 +size 7572 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png index fdb10220a2..c10cc18a37 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0db80941c8c981d3f66bc6cd9364f0f8fd5b1e7033f81da46cdffe478f97c748 +oid sha256:72dbe69b1952d3c2e00509bb1a5e0493baa30c0ef4e444f652f3fd7f81a8eccd size 6528 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png index 942808435a..06aa5f723f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ddb463eff5c3174663e6543726671708cef04bb11c9194b20373435e1441323a +oid sha256:6c2c9f8dc95c5ccf4836621ea4546fdad30091495b00d8207db8aeed9d0f5a1f size 24543 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png index 3c8281a03c..86a85de950 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57ee28833b587ec86f93c685d716f0cce94b60e0752de3fc1a1a3d7ac05cbdb6 -size 11013 +oid sha256:878d81472018964e1217c36708e31469a62486e1a913da26fc5a209731c4f9a1 +size 11014 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png index 0fbe95ff70..f0f400e37a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d174f1f8e77c9cd02506b487e410a7bcbf4d571f048f739d4f10582c72e682d0 -size 7501 +oid sha256:e8638e7c07500bddc9c67480685d2548f0b50772977fee7565fb92ae72eaefcb +size 7504 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png index 228b02c0a9..acb4061713 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:000c36468af4793e4956a4a2a2be1867afefa13140219e2dd8b17b1f7670b6de -size 6299 +oid sha256:000dbaa58af2f75293be0a3fed993447275582abaa33088b3f9c533ac4e0fec6 +size 6298 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png index 3473f077b5..ab59f1d629 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a6bb04b4dc4dfb43adb8ae45670f20232e8a3ba50c409c50a86feb96dfb00d56 -size 24486 +oid sha256:cfcb60ce2e343530c5344d9dfb70a6a562fe2fae942054afa033e9052de998fa +size 24485 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png index 39750c36e6..605d9d0907 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5694d2ee8d939aa3cc5107b7601ff251481fc8226981208b603507d407dcb12a +oid sha256:b81f55a04ecf3d4c3f266d5e0b67413be226933816195307e830d081a2bbc286 size 10637 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en.png index 85bd84bb10..8cf65f96b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:13c8b71ef7331e86d15200b8b1979688b21337237bcccd309ce70d866f9304f4 +oid sha256:d40487761c37e8ffd1e9ab268f27c15db6b9f3e60e4e419e561d22ee2af49e91 size 12932 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en.png index 31bb7dad85..0e2092abb6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.rolesandpermissions.changeroles_ChangeRolesView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:562dc9be79006376346ab1b2635890615eecc381e82c15b16a9ebf1855741e24 +oid sha256:41801b45373848016f408b2a91a4261bc5af86f5c53c97a6932bb9393e9754f9 size 12817 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en.png index c528154bfb..b91b6d767f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e94bf908067fbea798749b67aae88f26867bc1633a73d0f6b96ab085a4ccbb6c -size 41080 +oid sha256:874bb723f65bf35d328d55659c3bb8292823646466b140bc32474c080065a58b +size 41289 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en.png index 510fccb59e..f03e85e94e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBarWithIndicator_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:febe2f1b89d81289ec248f61f3c0058136143dadc43763ebc074b23be36ad5ea -size 49305 +oid sha256:3ae4345c1037edcccf383e7b24361ff0714823be1b9bc183ba71b1f64efb5d0c +size 49624 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en.png index fa86c41af4..63bcd16fdf 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1210e30466e2561333261762640db7b29339034f6b9bd8b371ebde43d2118e7d -size 40788 +oid sha256:9971b939e3b5ee51ae59dedef4d2a4cf4a2c95411c686fcfb9f1c7a41a738f03 +size 40998 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en.png index ff5cad9907..3df0a0197a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.components_DefaultRoomListTopBar_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aac26520f2e8e9ca823958191d4e51abc31072fb4cb1d2914b20a6ecc7456c71 -size 48964 +oid sha256:4c47f2f6f2ffca0a2c761f0b98b4154c3bc35a096a16c7093cddffea42d60dcb +size 49288 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Day_0_en.png index af751577e4..01368fb6f0 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49109a5fe23e3e103f9d8aee9f312cee45480269f1150d5aa84ddd4339d815fd -size 14235 +oid sha256:564970ecfeb0a57378b521baa9c16b830b91770c38e1b0acc79f67a45d13833c +size 14405 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Night_0_en.png index 4bb5a36f0f..c3e53a8a0f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl.filters_RoomListFiltersView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72924ce1e3173a9fd8acdbca8725f8f3711851840fd4713729959632a96f5524 -size 13922 +oid sha256:fbb769252ca3727a0e632425d1d59c45305deb22064b89eadcd406849a3ec7b0 +size 14165 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png index 81446e80a5..b53245dabe 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:604ac96927bdd49547fd39d2c9313ecd87b59ed7c8bbf9f5e5973cdb3f948b5e -size 82277 +oid sha256:3eee11c39a4fa103ff73c08586b13ed53617a6f6d588e13946d660d49f03e55d +size 82442 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png index 01655ac6c0..b358f95da0 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2f1c32f860df198a084dc1570dde8f94cedf304d5f21036cfbc39c0dc43e603 -size 106169 +oid sha256:36aa042d914cbe6eab8539fe50926fa2f524854f7cf6525540d9ddcb11315a2b +size 106358 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png index 81446e80a5..b53245dabe 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:604ac96927bdd49547fd39d2c9313ecd87b59ed7c8bbf9f5e5973cdb3f948b5e -size 82277 +oid sha256:3eee11c39a4fa103ff73c08586b13ed53617a6f6d588e13946d660d49f03e55d +size 82442 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png index bdff50ac76..2cc7aa172f 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3b73e6363372ac7e23fec07eaed7332cbd4436b57b58292fd02a1c6736470431 -size 82728 +oid sha256:126a41eb38a23dac27d5ecb21bbb3c2c60506d53a9857f609dd9a4edf2165010 +size 82978 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_3_en.png index 81c3cd3b4c..a0fb04b4d6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce301d1fa711ea2f00193cd808580da80cb3eb9024824aacb17e764e775986fa -size 61590 +oid sha256:6f7c759196214be21c701f1dcca980a94c70bbfcdaea7e5bee5e6f9cb9685b59 +size 61772 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_4_en.png index a8de70c034..52fdca3f3b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:611016bb64174fe744cc34b427c8ac6216a326cd3ffb514ab511615e4cffe4d2 -size 61343 +oid sha256:02ea20fc4bb1c80295d9dee76b0629eb273e0f0c899b8739806ae71a470df391 +size 61525 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_5_en.png index 522b5b859c..b86c5dcee2 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c983fbda82828a169957e6d37b867e98eef6d2807707fd736b20b6a758317f21 -size 59593 +oid sha256:5ff01dd9185bac406e54b357a2cdc144ca3e069e2b23d81d731f554c54fdad7c +size 59771 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png index bd0c3984d7..b49d429d00 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b5e578b50b6e5b4e06bd45cb16064ff425736ab1e5db12db8ffac1fc19a2d9f -size 100683 +oid sha256:81969735c40780f6577dae015d7ea77aaa9e262fea6192659c2fdcad048408ed +size 100839 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png index b80a127217..a53ceb31a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80702a8d97a3d178f8d4b8c7cd91f34e5b2d05da5babcdb148d347820633df72 -size 88608 +oid sha256:ca9c29b0723068c5e2f9b864b0b41b042c78361dbeef04708154021003c5d883 +size 88838 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png index d6fcf4c50b..ad561fa348 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:212e99c8bf79e5465c73305b9941f5b99fe27feb0e98a0b436e72288e5d3f2f1 -size 111946 +oid sha256:b3ff9a2bb0567787034d016522af9f6cf278c46f8cd4145979e82f80f82b99d4 +size 112195 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png index b80a127217..a53ceb31a6 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80702a8d97a3d178f8d4b8c7cd91f34e5b2d05da5babcdb148d347820633df72 -size 88608 +oid sha256:ca9c29b0723068c5e2f9b864b0b41b042c78361dbeef04708154021003c5d883 +size 88838 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png index d2b85d8dca..3ace91441c 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd8ab022ccecdff2350e6d2f58c7437dfe8a587f5cda6276a415b6c737538d6c -size 88589 +oid sha256:b69f49e553071e6ced4a3ba549c968cc2e23ce51384d318fb6f7c2872111fb4f +size 88792 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_3_en.png index 0993af003d..3652311d0e 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6649a87c37110a6820802a6fddf51250bd05f3b6b1ad4cfcf79bbcb20058d74e -size 70000 +oid sha256:4ef9f94c9b74fdfb1c4ed97e5a1be1d74ca974d33e510046fce58fcfd00e6b5e +size 70278 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_4_en.png index f02609d7dd..8cb8f3e738 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be1919432e860b977e841ce4d2d0bb3452e680a3575433707f4f9cef39860815 -size 69758 +oid sha256:0f9281bd18215852ad02ccd4e4a96bf06b2d536b491527712e1a0d45972ea95c +size 70037 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_5_en.png index ad1d7b2e48..cc03a0a8dd 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:22220f563256a794ea94d7e594c06e36ca26a0427ebcb8d1e838089453217af4 -size 67952 +oid sha256:e550b8d70599b8a9ea9281ad353c2caed7b22764d968604e0939076be7b4cdef +size 68249 diff --git a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png index 7cc568c6e6..a6a84c9564 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomlist.impl_RoomListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44520745df70fbcfb7a1e6cdc309dfc931e3afd55843431ba43b4e9aec21cbfc -size 106144 +oid sha256:e162854ac387df26e4c96bd88ede81972dc3048716865037e30e1c93221e4a36 +size 106400 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_0_en.png index ec31263806..b3f9dda381 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b9e9eaf86150f82e4374e61423a9796a7d042bbd208382df00520fb97649ffa -size 65271 +oid sha256:174958b24ca5c9d1cb465444d8b869e03252c24d203d308b5bdb0681908d86cb +size 67766 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_1_en.png index e8f5407443..9f7de0cccc 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4548f9368187b2f702f96a3b49fc2b828bfcf7fcb07825630e20987fcd9bbafd -size 62912 +oid sha256:378e2d8a4f8bacbd1b7937ffaf54078c95213d867d7a0ddb85c3ca2a367e06c5 +size 62938 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_2_en.png index 8edba5334d..447f7390bd 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a137bba61a56335e399117108efef010dd21ee0ebcd3054b278e7aac0cc778b -size 76778 +oid sha256:81ae404a24a37d8b86e61b1341d9fc4666d87dec99be6553a18037a22c3f8179 +size 72732 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_3_en.png index db94aef1dd..37fafa3eba 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ddaba3cda9a7fcd0f33a55b9141ee4dd5f1f2f6865a6f004798bb07b803413f -size 67986 +oid sha256:c87f241efd4cdc2c983674dd19fecc368b1aacc70f65360b69df7d7442341eba +size 74310 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_4_en.png index 29aaf73681..c9a507344e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6c95186a53ef178306d2b75406e908a89ce5ea18f644fb99ed877a6ba889808 -size 68123 +oid sha256:7f4b8fcee15f760864f66375a77dabf79150dabf2b7e589e2f855d94241fe4ac +size 79002 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_5_en.png new file mode 100644 index 0000000000..cfb421873e --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Day_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91e9736a94f3ee5c82b7bef2a939503e878910abff0c930e0edc2d6f61631e19 +size 22134 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_0_en.png index 13ecdc58dd..3fee6d2856 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb474e919cbd45e0e3e33d235915d4f47853b664ec9ee89427faac57cfe1b08b -size 62661 +oid sha256:fb59beed103cd60897d2b837d09c441d9a7eab44daa3061863274556619e7b1e +size 64862 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_1_en.png index 5dfc7c53af..0199f2ebf0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a088440355f1731341fdf8868c83a7491b5b0cfdcea89fc93a1932a950ad334b -size 60003 +oid sha256:55f3de8981fc43f7c674200304a0da0b30ea0562c6bebf9ce2997b50fe680d1c +size 60295 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_2_en.png index ed3de2c969..399f07d303 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87d592fd512c71d48f7f5ff7f5d9d8661b5bd698f31f1e1ac92c67bd845d485c -size 73773 +oid sha256:f935a0511a16dba0b2aa974334f84a50ceed06a82ecb13b911c8419aca4407fb +size 69558 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_3_en.png index 1f6dd5a021..064d35c1b1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b1e802f8ed6410fe90f02342d8de77e14c80fc7b12ee1608b96e5e30b16f25e -size 64941 +oid sha256:e0be6bcfe4f8b6df47a314c82411c1625c71605f257f5bc4cfb1ccfbf638f445 +size 71267 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_4_en.png index be37cc6ff3..9a76db8606 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3e85bfb40a17b393c113a907f1ec468a354b78dcffa057ab2e7ae40beef4aab5 -size 64907 +oid sha256:2a3732d0ed75d211bf0827f5433acdaf64c3915b96c03343c76018fff7f88dc6 +size 76111 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_5_en.png new file mode 100644 index 0000000000..627bb3b7aa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.icons_IconsCompound_Night_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc64e2dd35081ef8dbec7bbeb0a904e2556fa2dcd753acf73c16af06e55b77a6 +size 21524 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png index 01e6f56033..d5639c42b1 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:134b6c98eb0fa9513a50d1c272901b2881a7b1b1b4303b299f36d6dff832e9dd -size 33504 +oid sha256:0171a8269216d3d1d43e9f78d9616473e357127db7d1452f29aed8b2614ca350 +size 33478 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en.png index f528f58de4..2206653e60 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a78c77da5eb9c5706bbaf306fba85e311757990b81ad5d5714a4a8ccf72adc92 -size 24411 +oid sha256:15e3d8f6a686349045f5101490b18b9323ce114a9b2ffba492495c88e50d9be4 +size 24415 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en.png index 2dc142ad75..74503b2706 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0328504a77a8d9c1f5500b2d2b8f9504352c238cdded9fc82f6bac2c995293df -size 23940 +oid sha256:c12fbe16c8103e201ed682eb3dd01c680ce2c97fa2166dbd04ceb1627db08fda +size 23957 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png index 78b2174e58..d517ece48d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5117f03b47d430e9a9373ad0fd90534288010745500e21e007b5b3836f10df49 +oid sha256:0a69f4b7add1abaadd967c96693d14dfff62f73705a9edeb3d1a9c32b68a01ce size 7500 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png index 9d79031705..4ede7b2351 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:40416d4e67f10d0399af1de88e8a4785a645475021c97c51e4888ec51746bd76 -size 23707 +oid sha256:18d0edd9ffe6749b524a454bfb74373bbef52b1d0fe6e503b73523f2b84f8bea +size 23704 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png index 0b416da9f6..2b0f5e477d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25390b86c8ee47707f99e43bf566ca91a289781be2969e2aaf8b5e1ad0f36c96 -size 9113 +oid sha256:e37ec1481f04822c9784f3610444e36f9e2189c41aad878bb83b4570a033ac07 +size 9107 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png index d78df1fa15..16509084c8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:342c3d1af1d44b912e7516de3a6aa4a25affb25bc02d0c36d0c93c90f97a96b8 -size 6839 +oid sha256:014273f9262a31f01596e883dd8779b2bf8ac4ac2f609abbe582814b8eabe07b +size 6837 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png index 05f6e3ac88..b4a50169ec 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da44fbadab421c9a055fd835ccc1ec67966ec3e52940b00b5ab607f85d050684 -size 7173 +oid sha256:584f8c7eaf99a6b9bf3ff6faf65a188d23b27ce2f1888fb4c78ab166b77dddd5 +size 7169 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png index 79539cc2ba..cc1f51b3c9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e8fbaa10be1d09931f7e74502a7badc15f331040da89d4dbdce97211ac7bbba1 +oid sha256:05712f7aee243827568680e2e911640bb058f2a3b5500740054d72eb47bb97c1 size 11085 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png index 6d265d0892..1eb2ec85b4 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d1a17ed95a976a813b541eb373e2eb1f50388f6a994da7b65a586d31be8e0d23 -size 29199 +oid sha256:c6139f1037a5c09425121ddddac37ab0d006f3441467329715fd53dd3d27f24b +size 29200 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png index 734ee090db..f0656f971f 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a6a80bd4372c69ee97a857bf2a03bd90fe011b3703649b171bbc168f08c92be +oid sha256:1034df9a9d3404f00658b1bb0e4f939f5e9cb00d8966761d9089bb3cb9bab86a size 33643 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png index 187f6011a1..55763a2741 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f99464f3f16b7304ed1a6a99b864a30ad874d4ada5d9960ef41dc8557c9f4061 -size 10794 +oid sha256:f41a72ee1adb7fb72720c2c4323a1049b5a2c77e88372aec4b51c1e32251f6f3 +size 10796 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png index 4ef4a97357..7a29490bb0 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:594841dd922deceeee60da8bdd7228f9c685f2aa700a2ccbe0dd03bd4b9e4b98 +oid sha256:a479ad5ccdfd947730465010cf21503c0e7a22857537cd7d8f727a45beec58cd size 28739 diff --git a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png index 5ce058ef3e..a1820a3132 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.roomselect.impl_RoomSelectView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79224876e9c3e44f30f08c1e1d4050d8c909d8f290c4267f29eea15ae4f7f2d2 +oid sha256:df25628681cdf2bee33230069ae84210c3dda185d1e009fe646cb1cd30bf1ed5 size 33186