From 6f4335bd022e0f96ec53d34fd7143a3ba0cf1dc1 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Oct 2023 10:32:38 +0200 Subject: [PATCH 01/11] Add RedIndicatorAtom --- .../atomic/atoms/RedIndicatorAtom.kt | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RedIndicatorAtom.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RedIndicatorAtom.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RedIndicatorAtom.kt new file mode 100644 index 0000000000..c14f961a8f --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/RedIndicatorAtom.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.atomic.atoms + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.theme.ElementTheme + +@Composable +fun RedIndicatorAtom( + modifier: Modifier = Modifier, + size: Dp = 10.dp, + borderSize: Dp = 1.dp, + color: Color = ElementTheme.colors.bgCriticalPrimary, +) { + Box( + modifier = modifier + .size(size) + .border(borderSize, ElementTheme.materialColors.background, CircleShape) + .padding(borderSize / 2) + .clip(CircleShape) + .background(color) + ) +} + +@PreviewsDayNight +@Composable +internal fun RedIndicatorAtomPreview() = ElementPreview { + RedIndicatorAtom() +} From 1af4bfb1d812a938c0542bde9496339d55b14541 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Oct 2023 16:23:14 +0200 Subject: [PATCH 02/11] Design kit: add destructive buttons. --- .../designsystem/theme/components/Button.kt | 120 ++++++++++++------ 1 file changed, 84 insertions(+), 36 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt index fce2cb3eff..b3bc9a01bd 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt @@ -64,6 +64,7 @@ fun Button( enabled: Boolean = true, size: ButtonSize = ButtonSize.Large, showProgress: Boolean = false, + destructive: Boolean = false, leadingIcon: IconSource? = null, ) = ButtonInternal( text = text, @@ -73,6 +74,7 @@ fun Button( enabled = enabled, size = size, showProgress = showProgress, + destructive = destructive, leadingIcon = leadingIcon ) @@ -84,6 +86,7 @@ fun OutlinedButton( enabled: Boolean = true, size: ButtonSize = ButtonSize.Large, showProgress: Boolean = false, + destructive: Boolean = false, leadingIcon: IconSource? = null, ) = ButtonInternal( text = text, @@ -93,6 +96,7 @@ fun OutlinedButton( enabled = enabled, size = size, showProgress = showProgress, + destructive = destructive, leadingIcon = leadingIcon ) @@ -104,6 +108,7 @@ fun TextButton( enabled: Boolean = true, size: ButtonSize = ButtonSize.Large, showProgress: Boolean = false, + destructive: Boolean = false, leadingIcon: IconSource? = null, ) = ButtonInternal( text = text, @@ -113,6 +118,7 @@ fun TextButton( enabled = enabled, size = size, showProgress = showProgress, + destructive = destructive, leadingIcon = leadingIcon ) @@ -122,7 +128,8 @@ private fun ButtonInternal( onClick: () -> Unit, style: ButtonStyle, modifier: Modifier = Modifier, - colors: ButtonColors = style.getColors(), + destructive: Boolean = false, + colors: ButtonColors = style.getColors(destructive), enabled: Boolean = true, size: ButtonSize = ButtonSize.Large, showProgress: Boolean = false, @@ -170,7 +177,12 @@ private fun ButtonInternal( ButtonStyle.Filled -> null ButtonStyle.Outlined -> BorderStroke( width = 1.dp, - color = ElementTheme.colors.borderInteractiveSecondary + color = if (destructive) + ElementTheme.colors.borderCriticalPrimary.copy( + alpha = if (enabled) 1f else 0.5f + ) + else + ElementTheme.colors.borderInteractiveSecondary ) ButtonStyle.Text -> null } @@ -246,26 +258,52 @@ internal enum class ButtonStyle { Filled, Outlined, Text; @Composable - fun getColors(): ButtonColors = when (this) { + fun getColors(destructive: Boolean): ButtonColors = when (this) { Filled -> ButtonDefaults.buttonColors( - containerColor = ElementTheme.materialColors.primary, + containerColor = getPrimaryColor(destructive), contentColor = ElementTheme.materialColors.onPrimary, - disabledContainerColor = ElementTheme.colors.bgActionPrimaryDisabled, + disabledContainerColor = if (destructive) { + ElementTheme.colors.bgCriticalPrimary.copy(alpha = 0.5f) + } else { + ElementTheme.colors.bgActionPrimaryDisabled + }, disabledContentColor = ElementTheme.colors.textOnSolidPrimary ) Outlined -> ButtonDefaults.buttonColors( containerColor = Color.Transparent, - contentColor = ElementTheme.materialColors.primary, + contentColor = getPrimaryColor(destructive), disabledContainerColor = Color.Transparent, - disabledContentColor = ElementTheme.colors.textDisabled, + disabledContentColor = getDisabledContentColor(destructive), ) Text -> ButtonDefaults.buttonColors( containerColor = Color.Transparent, - contentColor = if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary, + contentColor = if (destructive) { + ElementTheme.colors.textCriticalPrimary + } else { + if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary + }, disabledContainerColor = Color.Transparent, - disabledContentColor = ElementTheme.colors.textDisabled, + disabledContentColor = getDisabledContentColor(destructive), ) } + + @Composable + private fun getPrimaryColor(destructive: Boolean): Color { + return if (destructive) { + ElementTheme.colors.bgCriticalPrimary + } else { + ElementTheme.materialColors.primary + } + } + + @Composable + private fun getDisabledContentColor(destructive: Boolean): Color { + return if (destructive) { + ElementTheme.colors.textCriticalPrimary.copy(alpha = 0.5f) + } else { + ElementTheme.colors.textDisabled + } + } } @Preview(group = PreviewGroup.Buttons) @@ -326,7 +364,6 @@ internal fun TextButtonLargePreview() { private fun ButtonCombinationPreview( style: ButtonStyle, size: ButtonSize, - modifier: Modifier = Modifier, ) { ElementThemedPreview { Column( @@ -335,59 +372,70 @@ private fun ButtonCombinationPreview( .padding(16.dp) .width(IntrinsicSize.Max), ) { - // Normal - ButtonRowPreview( - modifier = Modifier.then(modifier), - style = style, - size = size, - ) - - // With icon - ButtonRowPreview( - modifier = Modifier.then(modifier), - leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android), - style = style, - size = size, - ) - - // With progress - ButtonRowPreview( - modifier = Modifier.then(modifier), - showProgress = true, - style = style, - size = size, - ) + ButtonMatrixPreview(style = style, size = size, destructive = false) + ButtonMatrixPreview(style = style, size = size, destructive = true) } } } +@Composable +private fun ButtonMatrixPreview( + style: ButtonStyle, + size: ButtonSize, + destructive: Boolean, +) { + // Normal + ButtonRowPreview( + style = style, + size = size, + destructive = destructive, + ) + // With icon + ButtonRowPreview( + leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android), + style = style, + size = size, + destructive = destructive, + ) + // With progress + ButtonRowPreview( + showProgress = true, + style = style, + size = size, + destructive = destructive, + ) +} + @Composable private fun ButtonRowPreview( style: ButtonStyle, size: ButtonSize, - modifier: Modifier = Modifier, leadingIcon: IconSource? = null, showProgress: Boolean = false, + destructive: Boolean = false, ) { - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally), + ) { ButtonInternal( text = "A button", showProgress = showProgress, + destructive = destructive, onClick = {}, style = style, size = size, leadingIcon = leadingIcon, - modifier = Modifier.then(modifier), ) ButtonInternal( text = "A button", showProgress = showProgress, + destructive = destructive, enabled = false, onClick = {}, style = style, size = size, leadingIcon = leadingIcon, - modifier = Modifier.then(modifier), ) } } From f34fdcc87b168d4a8ae58658af5b4f2497524d60 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 4 Oct 2023 16:31:34 +0200 Subject: [PATCH 03/11] Design kit: add destructive dialog action --- .../components/dialogs/ConfirmationDialog.kt | 4 +++ .../theme/components/AlertDialogContent.kt | 36 +++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt index 0c2fca84d5..801575fe56 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt @@ -38,6 +38,7 @@ fun ConfirmationDialog( title: String? = null, submitText: String = stringResource(id = CommonStrings.action_ok), cancelText: String = stringResource(id = CommonStrings.action_cancel), + destructiveSubmit: Boolean = false, thirdButtonText: String? = null, onCancelClicked: () -> Unit = onDismiss, onThirdButtonClicked: () -> Unit = {}, @@ -49,6 +50,7 @@ fun ConfirmationDialog( submitText = submitText, cancelText = cancelText, thirdButtonText = thirdButtonText, + destructiveSubmit = destructiveSubmit, onSubmitClicked = onSubmitClicked, onCancelClicked = onCancelClicked, onThirdButtonClicked = onThirdButtonClicked, @@ -67,6 +69,7 @@ private fun ConfirmationDialogContent( title: String? = null, thirdButtonText: String? = null, onThirdButtonClicked: () -> Unit = {}, + destructiveSubmit: Boolean = false, icon: @Composable (() -> Unit)? = null, ) { SimpleAlertDialogContent( @@ -79,6 +82,7 @@ private fun ConfirmationDialogContent( onCancelClicked = onCancelClicked, thirdButtonText = thirdButtonText, onThirdButtonClicked = onThirdButtonClicked, + destructiveSubmit = destructiveSubmit, icon = icon, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt index 2eb290dd4e..bdeceb2ac8 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/AlertDialogContent.kt @@ -57,6 +57,7 @@ internal fun SimpleAlertDialogContent( title: String? = null, subtitle: @Composable (() -> Unit)? = null, submitText: String? = null, + destructiveSubmit: Boolean = false, onSubmitClicked: () -> Unit = {}, thirdButtonText: String? = null, onThirdButtonClicked: () -> Unit = {}, @@ -76,6 +77,7 @@ internal fun SimpleAlertDialogContent( title = title, subtitle = subtitle, submitText = submitText, + destructiveSubmit = destructiveSubmit, onSubmitClicked = onSubmitClicked, thirdButtonText = thirdButtonText, onThirdButtonClicked = onThirdButtonClicked, @@ -92,6 +94,7 @@ internal fun SimpleAlertDialogContent( title: String? = null, subtitle: @Composable (() -> Unit)? = null, submitText: String? = null, + destructiveSubmit: Boolean = false, onSubmitClicked: () -> Unit = {}, thirdButtonText: String? = null, onThirdButtonClicked: () -> Unit = {}, @@ -126,6 +129,7 @@ internal fun SimpleAlertDialogContent( enabled = enabled, size = ButtonSize.Medium, onClick = onSubmitClicked, + destructive = destructiveSubmit, ) } } @@ -345,8 +349,10 @@ private fun AlertDialogFlowRow( val arrangement = Arrangement.End val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 } with(arrangement) { - arrange(mainAxisLayoutSize, childrenMainAxisSizes, - layoutDirection, mainAxisPositions) + arrange( + mainAxisLayoutSize, childrenMainAxisSizes, + layoutDirection, mainAxisPositions + ) } placeables.forEachIndexed { j, placeable -> placeable.place( @@ -385,22 +391,22 @@ internal object DialogContentDefaults { val containerColor: Color @Composable @ReadOnlyComposable - get()= ElementTheme.colors.bgCanvasDefault + get() = ElementTheme.colors.bgCanvasDefault val textContentColor: Color @Composable @ReadOnlyComposable - get()= ElementTheme.materialColors.onSurfaceVariant + get() = ElementTheme.materialColors.onSurfaceVariant val titleContentColor: Color @Composable @ReadOnlyComposable - get()= ElementTheme.materialColors.onSurface + get() = ElementTheme.materialColors.onSurface val iconContentColor: Color @Composable @ReadOnlyComposable - get()= ElementTheme.materialColors.primary + get() = ElementTheme.materialColors.primary } // Paddings for each of the dialog's parts. Taken from M3 source code. @@ -462,3 +468,21 @@ internal fun DialogWithOnlyMessageAndOkButtonPreview() { } } } + +@Preview(group = PreviewGroup.Dialogs, name = "Dialog with destructive button") +@Composable +@Suppress("MaxLineLength") +internal fun DialogWithDestructiveButtonPreview() { + ElementThemedPreview(showBackground = false) { + DialogPreview { + SimpleAlertDialogContent( + title = "Dialog Title", + content = "A dialog with a destructive action", + cancelText = "Cancel", + submitText = "Delete", + destructiveSubmit = true, + onCancelClicked = {}, + ) + } + } +} From c6ddc33be769919a1fb03f49b17535435adc88b8 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 3 Oct 2023 13:44:06 +0200 Subject: [PATCH 04/11] Preference: Add badge to the icon preference. --- .../components/preferences/PreferenceText.kt | 2 + .../preferences/components/PreferenceIcon.kt | 49 ++++++++++++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt index d4bc627802..e0b8ea7926 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt @@ -57,6 +57,7 @@ fun PreferenceText( icon: ImageVector? = null, @DrawableRes iconResourceId: Int? = null, showIconAreaIfNoIcon: Boolean = false, + showIconBadge: Boolean = false, tintColor: Color? = null, onClick: () -> Unit = {}, ) { @@ -73,6 +74,7 @@ fun PreferenceText( PreferenceIcon( icon = icon, iconResourceId = iconResourceId, + showIconBadge = showIconBadge, enabled = enabled, isVisible = showIconAreaIfNoIcon, tintColor = tintColor ?: enabled.toSecondaryEnabledColor(), diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt index d1c1281ee9..c29b46f3c3 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/components/PreferenceIcon.kt @@ -17,17 +17,20 @@ package io.element.android.libraries.designsystem.components.preferences.components import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Box 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.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.theme.components.Icon @@ -38,20 +41,30 @@ fun PreferenceIcon( modifier: Modifier = Modifier, icon: ImageVector? = null, @DrawableRes iconResourceId: Int? = null, + showIconBadge: Boolean = false, tintColor: Color? = null, enabled: Boolean = true, isVisible: Boolean = true, ) { if (icon != null || iconResourceId != null) { - Icon( - imageVector = icon, - resourceId = iconResourceId, - contentDescription = "", - tint = tintColor ?: enabled.toSecondaryEnabledColor(), - modifier = modifier - .padding(end = 16.dp) - .size(24.dp), - ) + Box(modifier = modifier) { + Icon( + imageVector = icon, + resourceId = iconResourceId, + contentDescription = "", + tint = tintColor ?: enabled.toSecondaryEnabledColor(), + modifier = Modifier + .padding(end = 16.dp) + .size(24.dp), + ) + if (showIconBadge) { + RedIndicatorAtom( + modifier = Modifier + .align(Alignment.TopEnd) + .padding(end = 16.dp) + ) + } + } } else if (isVisible) { Spacer(modifier = modifier.width(40.dp)) } @@ -60,9 +73,19 @@ fun PreferenceIcon( @Preview(group = PreviewGroup.Preferences) @Composable internal fun PreferenceIconPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) = - ElementThemedPreview { ContentToPreview(content) } + ElementThemedPreview { + PreferenceIcon( + icon = content, + showIconBadge = false, + ) + } +@Preview(group = PreviewGroup.Preferences) @Composable -private fun ContentToPreview(content: ImageVector?) { - PreferenceIcon(icon = content) -} +internal fun PreferenceIconWithBadgePreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) = + ElementThemedPreview { + PreferenceIcon( + icon = content, + showIconBadge = true, + ) + } From 243c47682fe97a4c35467b65ce662e3359c0e8a5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Oct 2023 17:15:10 +0200 Subject: [PATCH 05/11] Design: extract DialogLikeBannerMolecule from RequestVerificationHeader --- .../components/RequestVerificationHeader.kt | 74 +++---------- .../atomic/molecules/HomeBannerMolecule.kt | 103 ++++++++++++++++++ 2 files changed, 116 insertions(+), 61 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt index 991be692a0..d3ad6db206 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RequestVerificationHeader.kt @@ -16,31 +16,13 @@ package io.element.android.features.roomlist.impl.components -import androidx.compose.foundation.clickable -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.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp import io.element.android.features.roomlist.impl.R -import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.ButtonSize -import io.element.android.libraries.designsystem.theme.components.Icon -import io.element.android.libraries.designsystem.theme.components.Surface -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.designsystem.utils.CommonDrawables -import io.element.android.libraries.theme.ElementTheme -import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.libraries.designsystem.preview.PreviewsDayNight @Composable internal fun RequestVerificationHeader( @@ -48,50 +30,20 @@ internal fun RequestVerificationHeader( onDismissClicked: () -> Unit, modifier: Modifier = Modifier, ) { - Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { - Surface( - Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.small, - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Column( - Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp) - ) { - Row { - Text( - stringResource(R.string.session_verification_banner_title), - modifier = Modifier.weight(1f), - style = ElementTheme.typography.fontBodyLgMedium, - color = MaterialTheme.colorScheme.primary, - textAlign = TextAlign.Start, - ) - Icon( - modifier = Modifier.clickable(onClick = onDismissClicked), - resourceId = CommonDrawables.ic_compound_close, - contentDescription = stringResource(CommonStrings.action_close) - ) - } - Spacer(modifier = Modifier.height(4.dp)) - Text( - stringResource(R.string.session_verification_banner_message), - style = ElementTheme.typography.fontBodyMdRegular, - ) - Spacer(modifier = Modifier.height(12.dp)) - Button( - text = stringResource(CommonStrings.action_continue), - size = ButtonSize.Medium, - modifier = Modifier.fillMaxWidth(), - onClick = onVerifyClicked, - ) - } - } - } + DialogLikeBannerMolecule( + modifier = modifier, + title = stringResource(R.string.session_verification_banner_title), + content = stringResource(R.string.session_verification_banner_message), + onSubmitClicked = onVerifyClicked, + onDismissClicked = onDismissClicked, + ) } @PreviewsDayNight @Composable internal fun RequestVerificationHeaderPreview() = ElementPreview { - RequestVerificationHeader(onVerifyClicked = {}, onDismissClicked = {}) + RequestVerificationHeader( + onVerifyClicked = {}, + onDismissClicked = {}, + ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt new file mode 100644 index 0000000000..dd33cd1b79 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.atomic.molecules + +import androidx.compose.foundation.clickable +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.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Button +import io.element.android.libraries.designsystem.theme.components.ButtonSize +import io.element.android.libraries.designsystem.theme.components.Icon +import io.element.android.libraries.designsystem.theme.components.Surface +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.utils.CommonDrawables +import io.element.android.libraries.theme.ElementTheme +import io.element.android.libraries.ui.strings.CommonStrings + +@Composable +fun DialogLikeBannerMolecule( + title: String, + content: String, + onSubmitClicked: () -> Unit, + onDismissClicked: () -> Unit, + modifier: Modifier = Modifier, +) { + Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { + Surface( + Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.small, + color = MaterialTheme.colorScheme.surfaceVariant + ) { + Column( + Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp) + ) { + Row { + Text( + text = title, + modifier = Modifier.weight(1f), + style = ElementTheme.typography.fontBodyLgMedium, + color = MaterialTheme.colorScheme.primary, + textAlign = TextAlign.Start, + ) + Icon( + modifier = Modifier.clickable(onClick = onDismissClicked), + resourceId = CommonDrawables.ic_compound_close, + contentDescription = stringResource(CommonStrings.action_close) + ) + } + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = content, + style = ElementTheme.typography.fontBodyMdRegular, + ) + Spacer(modifier = Modifier.height(12.dp)) + Button( + text = stringResource(CommonStrings.action_continue), + size = ButtonSize.Medium, + modifier = Modifier.fillMaxWidth(), + onClick = onSubmitClicked, + ) + } + } + } +} + +@PreviewsDayNight +@Composable +internal fun DialogLikeBannerMoleculePreview() = ElementPreview { + DialogLikeBannerMolecule( + title = "Title", + content = "Content", + onSubmitClicked = {}, + onDismissClicked = {} + ) +} From b12f9ff3a8b7ba59fb2b277ecb0eac4766e44084 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 26 Oct 2023 17:09:57 +0200 Subject: [PATCH 06/11] Use DialogLikeBannerMolecule in NotificationSettingsView. --- .../notifications/NotificationSettingsView.kt | 63 ++++--------------- .../atomic/molecules/HomeBannerMolecule.kt | 14 +++-- 2 files changed, 19 insertions(+), 58 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt index 223107226e..a1d248c1fd 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt @@ -16,41 +16,27 @@ package io.element.android.features.preferences.impl.notifications -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.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent import io.element.android.libraries.architecture.Async +import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule import io.element.android.libraries.designsystem.components.ProgressDialog import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferencePage import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch import io.element.android.libraries.designsystem.components.preferences.PreferenceText -import io.element.android.libraries.designsystem.components.preferences.PreferencePage -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.theme.components.Button -import io.element.android.libraries.designsystem.theme.components.ButtonSize -import io.element.android.libraries.designsystem.theme.components.Surface -import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.designsystem.utils.OnLifecycleEvent import io.element.android.libraries.matrix.api.room.RoomNotificationMode -import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings /** @@ -197,41 +183,14 @@ private fun InvalidNotificationSettingsView( onDismissError: () -> Unit, modifier: Modifier = Modifier ) { - Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { - Surface( - Modifier.fillMaxWidth(), - shape = MaterialTheme.shapes.small, - color = MaterialTheme.colorScheme.surfaceVariant - ) { - Column( - Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 12.dp) - ) { - Row { - Text( - stringResource(CommonStrings.screen_notification_settings_configuration_mismatch), - modifier = Modifier.weight(1f), - style = ElementTheme.typography.fontBodyLgMedium, - color = MaterialTheme.colorScheme.primary, - textAlign = TextAlign.Start, - ) - } - Spacer(modifier = Modifier.height(4.dp)) - Text( - stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description), - style = ElementTheme.typography.fontBodyMdRegular, - ) - Spacer(modifier = Modifier.height(12.dp)) - Button( - text = stringResource(CommonStrings.action_continue), - size = ButtonSize.Medium, - modifier = Modifier.fillMaxWidth(), - onClick = onContinueClicked, - ) - } - } - } + DialogLikeBannerMolecule( + modifier = modifier, + title = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch), + content = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description), + onSubmitClicked = onContinueClicked, + onDismissClicked = null, + ) + if (showError) { ErrorDialog( title = stringResource(id = CommonStrings.dialog_title_error), diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt index dd33cd1b79..1be5f12b0f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt @@ -46,7 +46,7 @@ fun DialogLikeBannerMolecule( title: String, content: String, onSubmitClicked: () -> Unit, - onDismissClicked: () -> Unit, + onDismissClicked: (() -> Unit)?, modifier: Modifier = Modifier, ) { Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) { @@ -68,11 +68,13 @@ fun DialogLikeBannerMolecule( color = MaterialTheme.colorScheme.primary, textAlign = TextAlign.Start, ) - Icon( - modifier = Modifier.clickable(onClick = onDismissClicked), - resourceId = CommonDrawables.ic_compound_close, - contentDescription = stringResource(CommonStrings.action_close) - ) + if (onDismissClicked != null) { + Icon( + modifier = Modifier.clickable(onClick = onDismissClicked), + resourceId = CommonDrawables.ic_compound_close, + contentDescription = stringResource(CommonStrings.action_close) + ) + } } Spacer(modifier = Modifier.height(4.dp)) Text( From 6a96d6e00b5f06b173f7057db8d0c53f68c52744 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 26 Oct 2023 15:25:07 +0000 Subject: [PATCH 07/11] Update screenshots --- ...c.atoms_null_RedIndicatorAtom-D_0_null,NEXUS_5,1.0,en].png | 3 +++ ...c.atoms_null_RedIndicatorAtom-N_1_null,NEXUS_5,1.0,en].png | 3 +++ ...null_DialogLikeBannerMolecule-D_0_null,NEXUS_5,1.0,en].png | 3 +++ ...null_DialogLikeBannerMolecule-N_1_null,NEXUS_5,1.0,en].png | 3 +++ ...ences_PreferenceIconWithBadge_0_null_0,NEXUS_5,1.0,en].png | 3 +++ ...ences_PreferenceIconWithBadge_0_null_1,NEXUS_5,1.0,en].png | 3 +++ ..._null_Buttons_FilledButtonLarge_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...null_Buttons_FilledButtonMedium_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ull_Buttons_OutlinedButtonLarge_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ll_Buttons_OutlinedButtonMedium_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ts_null_Buttons_TextButtonLarge_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...s_null_Buttons_TextButtonMedium_0_null,NEXUS_5,1.0,en].png | 4 ++-- ...ogs_Dialogwithdestructivebutton_0_null,NEXUS_5,1.0,en].png | 3 +++ 13 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-D_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-N_1_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-D_0_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-N_1_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_0,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_1,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Dialogs_Dialogwithdestructivebutton_0_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-D_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-D_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7593c75aaf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-D_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f54912dfb9235aa915025d496f280de362286997f746481da41deb02a1ec67e3 +size 4768 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-N_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-N_1_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..f1ff44eecf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.atoms_null_RedIndicatorAtom-N_1_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae078e1bb55967e9e583a588b4fb410eb0417d944b20911158b24f3824ee6dca +size 4752 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-D_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-D_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..9315297856 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-D_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45736b242f9bf1a50fb14af9b340633f0fdc348ed7a846c4c57c3a56a4b2a48c +size 11429 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-N_1_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-N_1_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..7defe86721 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.atomic.molecules_null_DialogLikeBannerMolecule-N_1_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f9989dadb7c68cf705683997689f48595be9283eb939d934819399ec3c6805f +size 11209 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..e62a06473c --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6d2243cb6bedd4b7a2f1c8c9b5aeac8356642271061c1439e591ce07c55c822 +size 6390 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3c228b96a0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.preferences.components_null_Preferences_PreferenceIconWithBadge_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2d302d58c1faec3c3f0aa3286977b2698cd642c1e6dbcb9632510c6a4a922eb +size 4501 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonLarge_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonLarge_0_null,NEXUS_5,1.0,en].png index a82b9c0a1c..1ef44d7b1d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonLarge_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonLarge_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0f2dc7bfcf59bf26362775625ddc9dedf53f400057997560628614136e2880b -size 44144 +oid sha256:222795141c044e5bd7929cb9b894535124a176fd88347eea83037116f4ba6e8b +size 68192 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonMedium_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonMedium_0_null,NEXUS_5,1.0,en].png index 322c44b61f..4d5c49c7a8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonMedium_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_FilledButtonMedium_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e240c572aab6db77995c93787a7b0aaba76060861c45934eb87d4ba48c5675c -size 42789 +oid sha256:b2d816dac6d468ede766719ec854cd575c89f454346ddd6ef8048c836bd04c14 +size 66223 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonLarge_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonLarge_0_null,NEXUS_5,1.0,en].png index 47ca9e7c31..d34a8c1d62 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonLarge_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonLarge_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54497bfab92c6ed850f753df61a31366ca68d41c7d90e322e7cc7eceb6dd4277 -size 48139 +oid sha256:a8d423b71168b3bd5dab8da01376fa3f114865aa0d4eb48d41fccfb4640367e3 +size 77867 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonMedium_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonMedium_0_null,NEXUS_5,1.0,en].png index 916f75d13e..be25d4cf37 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonMedium_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_OutlinedButtonMedium_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e7d3f2e50b395f86ed7c78146d5a428b099c672d763c278c1b2899d915abf717 -size 47615 +oid sha256:5381c6f070f2c81019ce39af5902f6f2c683c7ce4db4636b3b3259fdca270cdf +size 75884 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonLarge_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonLarge_0_null,NEXUS_5,1.0,en].png index 996018bf70..2fa4c52ecb 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonLarge_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonLarge_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:876eba4a9f8214aa2d33dad84ccbbb95994c615f25f158cb6596fd4512241bd9 -size 31582 +oid sha256:093a5bd68ebca0a9eaf8cac3cf748514cc0f3165c1079016d54d40762c7c0287 +size 46434 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonMedium_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonMedium_0_null,NEXUS_5,1.0,en].png index 021f9c9358..89b4df8c93 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonMedium_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Buttons_TextButtonMedium_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3dd7259e0b14b9ad5e9a6aed46383f91822ee11f1e77b0f2cdc5d2e0b38f7abd -size 29702 +oid sha256:dfa423f2008049e54046449c19615eb66f28e7e66645eff76e80e33062b5c59a +size 43655 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Dialogs_Dialogwithdestructivebutton_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Dialogs_Dialogwithdestructivebutton_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8bc5d4dfb5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.theme.components_null_Dialogs_Dialogwithdestructivebutton_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3079a82a70fc20feac8c694a8571eac5dac9e2dea800bd7ca01628fe7c90d29 +size 33019 From c93470b6e485ccf1ce28b3a865186716edb45dff Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 26 Oct 2023 17:21:19 +0200 Subject: [PATCH 08/11] Rename file. --- .../{HomeBannerMolecule.kt => DialogLikeBannerMolecule.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/{HomeBannerMolecule.kt => DialogLikeBannerMolecule.kt} (100%) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/DialogLikeBannerMolecule.kt similarity index 100% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/HomeBannerMolecule.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/molecules/DialogLikeBannerMolecule.kt From f9cf3c814da4b5fd4fddc8971dbb06d11c020b24 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 26 Oct 2023 17:49:13 +0200 Subject: [PATCH 09/11] Fix warning: Composable functions should only be emitting content into the composition from one source at their top level. --- .../android/libraries/designsystem/theme/components/Button.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt index b3bc9a01bd..5ce528c814 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/Button.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -379,7 +380,7 @@ private fun ButtonCombinationPreview( } @Composable -private fun ButtonMatrixPreview( +private fun ColumnScope.ButtonMatrixPreview( style: ButtonStyle, size: ButtonSize, destructive: Boolean, From d7ce326612958c1761ee96db832519b070892512 Mon Sep 17 00:00:00 2001 From: Marco Romano Date: Fri, 27 Oct 2023 11:30:57 +0200 Subject: [PATCH 10/11] Show correct UI when replying to a voice message (#1658) Shows voice messages in the room summary. Shows voice messages in the reply context menu and composer. Show replies to voice messages in the timeline. (before this PR voice messages were shown the same as audio messages) Story: https://github.com/vector-im/element-meta/issues/2106 --- .../messages/impl/MessagesPresenter.kt | 5 ++++- .../actionlist/ActionListStateProvider.kt | 18 +++++++++++++++ .../impl/actionlist/ActionListView.kt | 13 ++++++++++- .../components/TimelineItemEventRow.kt | 16 ++++++++++---- .../main/res/drawable/ic_voice_attachment.xml | 9 ++++++++ .../impl/DefaultRoomLastMessageFormatter.kt | 6 ++++- .../DefaultRoomLastMessageFormatterTest.kt | 22 ++++++++++++++++--- .../ui/components/AttachmentThumbnail.kt | 8 ++++++- ...tContent-D-1_1_null_10,NEXUS_5,1.0,en].png | 3 +++ ...etContent-D-1_1_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-D-1_1_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-D-1_1_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-D-1_1_null_9,NEXUS_5,1.0,en].png | 3 +++ ...tContent-N-1_2_null_10,NEXUS_5,1.0,en].png | 3 +++ ...etContent-N-1_2_null_6,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-N-1_2_null_7,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-N-1_2_null_8,NEXUS_5,1.0,en].png | 4 ++-- ...etContent-N-1_2_null_9,NEXUS_5,1.0,en].png | 3 +++ 18 files changed, 110 insertions(+), 23 deletions(-) create mode 100644 libraries/designsystem/src/main/res/drawable/ic_voice_attachment.xml create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_10,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_9,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_10,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_9,NEXUS_5,1.0,en].png 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 ea9eade4b3..f924e7f716 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 @@ -331,11 +331,14 @@ class MessagesPresenter @AssistedInject constructor( textContent = targetEvent.content.body, type = AttachmentThumbnailType.Audio, ) + is TimelineItemVoiceContent -> AttachmentThumbnailInfo( + textContent = targetEvent.content.body, + type = AttachmentThumbnailType.Voice, + ) is TimelineItemLocationContent -> AttachmentThumbnailInfo( type = AttachmentThumbnailType.Location, ) is TimelineItemPollContent, // TODO Polls: handle reply to - is TimelineItemVoiceContent, // TODO Voice messages: handle reply to is TimelineItemTextBasedContent, is TimelineItemRedactedContent, is TimelineItemStateContent, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt index 44736bc076..3ea99aaede 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListStateProvider.kt @@ -20,11 +20,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction import io.element.android.features.messages.impl.timeline.aTimelineItemEvent import io.element.android.features.messages.impl.timeline.aTimelineItemReactions +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemLocationContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVideoContent +import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVoiceContent import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -67,6 +69,22 @@ open class ActionListStateProvider : PreviewParameterProvider { actions = aTimelineItemActionList(), ) ), + anActionListState().copy( + target = ActionListState.Target.Success( + event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy( + reactionsState = reactionsState + ), + actions = aTimelineItemActionList(), + ) + ), + anActionListState().copy( + target = ActionListState.Target.Success( + event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy( + reactionsState = reactionsState + ), + actions = aTimelineItemActionList(), + ) + ), anActionListState().copy( target = ActionListState.Target.Success( event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt index c5e6e5facd..bed3af59bd 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListView.kt @@ -238,7 +238,6 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif when (event.content) { is TimelineItemPollContent, // TODO Polls: handle summary - is TimelineItemVoiceContent, // TODO Voice messages: handle reply summary is TimelineItemTextBasedContent, is TimelineItemStateContent, is TimelineItemEncryptedContent, @@ -309,6 +308,18 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif } content = { ContentForBody(event.content.body) } } + is TimelineItemVoiceContent -> { + icon = { + AttachmentThumbnail( + modifier = imageModifier, + info = AttachmentThumbnailInfo( + textContent = textContent, + type = AttachmentThumbnailType.Voice, + ) + ) + } + content = { ContentForBody(event.content.body) } + } } Row(modifier = modifier) { icon() 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 0ef1c9bc67..304ff88662 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 @@ -612,10 +612,18 @@ private fun attachmentThumbnailInfoForInReplyTo(inReplyTo: InReplyTo.Ready): Att textContent = messageContent.body, type = AttachmentThumbnailType.Location, ) - is AudioMessageType -> AttachmentThumbnailInfo( - textContent = messageContent.body, - type = AttachmentThumbnailType.Audio, - ) + is AudioMessageType -> { + when (type.isVoiceMessage) { + true -> AttachmentThumbnailInfo( + textContent = messageContent.body, + type = AttachmentThumbnailType.Voice, + ) + false -> AttachmentThumbnailInfo( + textContent = messageContent.body, + type = AttachmentThumbnailType.Audio, + ) + } + } else -> null } } diff --git a/libraries/designsystem/src/main/res/drawable/ic_voice_attachment.xml b/libraries/designsystem/src/main/res/drawable/ic_voice_attachment.xml new file mode 100644 index 0000000000..d8986e206d --- /dev/null +++ b/libraries/designsystem/src/main/res/drawable/ic_voice_attachment.xml @@ -0,0 +1,9 @@ + + + diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt index 80e7a7155b..99b06401d9 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt @@ -128,7 +128,11 @@ class DefaultRoomLastMessageFormatter @Inject constructor( sp.getString(CommonStrings.common_file) } is AudioMessageType -> { - sp.getString(CommonStrings.common_audio) + if (messageType.isVoiceMessage) { + sp.getString(CommonStrings.common_voice_message) + } else { + sp.getString(CommonStrings.common_audio) + } } is OtherMessageType -> { messageType.body diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt index bc58aa1d48..48c498c3d8 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt @@ -163,6 +163,7 @@ class DefaultRoomLastMessageFormatterTest { TextMessageType(body, null), VideoMessageType(body, MediaSource("url"), null), AudioMessageType(body, MediaSource("url"), null, null, false), + AudioMessageType(body, MediaSource("url"), null, null, true), ImageMessageType(body, MediaSource("url"), null), FileMessageType(body, MediaSource("url"), null), LocationMessageType(body, "geo:1,2", null), @@ -198,7 +199,12 @@ class DefaultRoomLastMessageFormatterTest { for ((type, result) in resultsInDm) { val expectedResult = when (type) { is VideoMessageType -> "Video" - is AudioMessageType -> "Audio" + is AudioMessageType -> { + when (type.isVoiceMessage) { + true -> "Voice message" + false -> "Audio" + } + } is ImageMessageType -> "Image" is FileMessageType -> "File" is LocationMessageType -> "Shared location" @@ -216,7 +222,12 @@ class DefaultRoomLastMessageFormatterTest { val string = result.toString() val expectedResult = when (type) { is VideoMessageType -> "$senderName: Video" - is AudioMessageType -> "$senderName: Audio" + is AudioMessageType -> { + when (type.isVoiceMessage) { + true -> "$senderName: Voice message" + false -> "$senderName: Audio" + } + } is ImageMessageType -> "$senderName: Image" is FileMessageType -> "$senderName: File" is LocationMessageType -> "$senderName: Shared location" @@ -228,7 +239,12 @@ class DefaultRoomLastMessageFormatterTest { } val shouldCreateAnnotatedString = when (type) { is VideoMessageType -> true - is AudioMessageType -> true + is AudioMessageType -> { + when (type.isVoiceMessage) { + true -> true + false -> true + } + } is ImageMessageType -> true is FileMessageType -> true is LocationMessageType -> false diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt index cafbdd04c0..c1fa34a764 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/AttachmentThumbnail.kt @@ -75,6 +75,12 @@ fun AttachmentThumbnail( contentDescription = info.textContent, ) } + AttachmentThumbnailType.Voice -> { + Icon( + resourceId = CommonDrawables.ic_voice_attachment, + contentDescription = info.textContent, + ) + } AttachmentThumbnailType.File -> { Icon( resourceId = CommonDrawables.ic_september_attachment, @@ -95,7 +101,7 @@ fun AttachmentThumbnail( @Parcelize enum class AttachmentThumbnailType : Parcelable { - Image, Video, File, Audio, Location + Image, Video, File, Audio, Location, Voice } @Parcelize diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_10,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..af7782f5d7 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_10,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85692ea3847fe5a79f955bb71153ccb6e5b24cf451292c7b9d56f26e2eff95b7 +size 28840 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_6,NEXUS_5,1.0,en].png index 74448d6967..c458b9a7b8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:979138753000ada021a67f4bc14a89b912430c4331ac69aa702b2e50c050d7cb -size 41200 +oid sha256:d32becec465a3f01e35aac9ebbeb8f48507cc2146f35b8e6c6393bbd410cca3e +size 39370 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_7,NEXUS_5,1.0,en].png index 3cb12c4c94..0ed5c052a6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e06e1a32d8c9d06a307a5116a396a03308d5e5486f911d34002139485e7d9ffe -size 28176 +oid sha256:a1f8750e66aa2a60198fe68d2e3185bcf5a8708df81502f33c394d72f7b20a30 +size 42765 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_8,NEXUS_5,1.0,en].png index af7782f5d7..74448d6967 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85692ea3847fe5a79f955bb71153ccb6e5b24cf451292c7b9d56f26e2eff95b7 -size 28840 +oid sha256:979138753000ada021a67f4bc14a89b912430c4331ac69aa702b2e50c050d7cb +size 41200 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_9,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3cb12c4c94 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-D-1_1_null_9,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e06e1a32d8c9d06a307a5116a396a03308d5e5486f911d34002139485e7d9ffe +size 28176 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_10,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..ee2fa7b46f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_10,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5df2d3b6e4698867277712214fa526e08a9bf790140cd000cfe2bf94c70e77f4 +size 27525 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_6,NEXUS_5,1.0,en].png index 8d45efac8c..dbe1f4d267 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:752abe37a810cc8e4b36ae5f4c4aa38c9f22757b6458f272ba991050c69aee53 -size 39409 +oid sha256:a99566280864e66ec327d2d6d8016c74b12f1c62ff27fd0d2d4ba0109ae9756a +size 37747 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_7,NEXUS_5,1.0,en].png index 811cb7e4cd..8ee1838413 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0c53fdbe427ddb7088d9bd8f9b46a1281d145fd6f9ccc3a7de339750e3079075 -size 26498 +oid sha256:fbb1233cf288e6ffc1aaa7136b56c412699897d7edd20bef82784562e302bf40 +size 41215 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_8,NEXUS_5,1.0,en].png index ee2fa7b46f..8d45efac8c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5df2d3b6e4698867277712214fa526e08a9bf790140cd000cfe2bf94c70e77f4 -size 27525 +oid sha256:752abe37a810cc8e4b36ae5f4c4aa38c9f22757b6458f272ba991050c69aee53 +size 39409 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_9,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..811cb7e4cd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.actionlist_null_SheetContent-N-1_2_null_9,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c53fdbe427ddb7088d9bd8f9b46a1281d145fd6f9ccc3a7de339750e3079075 +size 26498 From 0bd9c788360c8a065d77f66c09ba26c8c0289008 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 27 Oct 2023 12:26:40 +0200 Subject: [PATCH 11/11] Initial support for member suggestions (#1631) * Initial support for member suggestion (search and UI) * Add custom `BottomSheetScaffold` implementation to workaround several scrolling bugs * Start searching as soon as `@` is typed, add UI following initial designs * Extract suggestion processing code * Extract component, add previews, fix tests * Add tests * Add exception from kover to the forked bottom sheet code * Add a feature flag for mentions - Extract composer & mention suggestions to their composable. - Extract mentions suggestions processing to its own class. - Add `MatrixRoom.canTriggerRoomNotification` function. - Update strings and conditions for displaying the `@room` mention. --------- Co-authored-by: ElementBot --- build.gradle.kts | 4 +- changelog.d/1452.feature | 1 + .../location/impl/send/SendLocationView.kt | 8 +- .../impl/ExpandableBottomSheetScaffold.kt | 13 +- .../features/messages/impl/MessagesView.kt | 70 ++- .../mentions/MentionSuggestionsPickerView.kt | 169 ++++++ .../mentions/MentionSuggestionsProcessor.kt | 111 ++++ .../messagecomposer/MessageComposerEvents.kt | 2 + .../MessageComposerPresenter.kt | 58 ++ .../messagecomposer/MessageComposerState.kt | 1 + .../MessageComposerStateProvider.kt | 4 + .../messagecomposer/MessageComposerView.kt | 10 +- .../impl/src/main/res/values/localazy.xml | 2 + .../messages/MessagesPresenterTest.kt | 3 + .../MessageComposerPresenterTest.kt | 113 ++++ .../theme/components/BottomSheetScaffold.kt | 7 +- .../bottomsheet/CustomBottomSheetScaffold.kt | 519 ++++++++++++++++++ .../bottomsheet/CustomSheetState.kt | 309 +++++++++++ .../libraries/featureflag/api/FeatureFlags.kt | 6 + .../impl/StaticFeatureFlagProvider.kt | 1 + .../libraries/matrix/api/room/MatrixRoom.kt | 2 + .../matrix/api/user/CurrentSessionIdHolder.kt | 30 + .../matrix/impl/room/RustMatrixRoom.kt | 6 + .../matrix/test/room/FakeMatrixRoom.kt | 10 + .../libraries/textcomposer/TextComposer.kt | 56 +- .../textcomposer/model/Suggestion.kt | 50 ++ .../tests/konsist/KonsistArchitectureTest.kt | 1 + ...PickerView_-D-3_3_null,NEXUS_5,1.0,en].png | 3 + ...PickerView_-N-3_4_null,NEXUS_5,1.0,en].png | 3 + ...PickerMenu-D-4_4_null,NEXUS_5,1.0,en].png} | 0 ...PickerMenu-N-4_5_null,NEXUS_5,1.0,en].png} | 0 ...oserView-D-5_5_null_0,NEXUS_5,1.0,en].png} | 0 ...oserView-N-5_6_null_0,NEXUS_5,1.0,en].png} | 0 ...iewVoice-D-6_6_null_0,NEXUS_5,1.0,en].png} | 0 ...iewVoice-N-6_7_null_0,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_0,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_1,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_2,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_3,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_4,NEXUS_5,1.0,en].png} | 0 ...sageView-D-7_7_null_5,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_0,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_1,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_2,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_3,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_4,NEXUS_5,1.0,en].png} | 0 ...sageView-N-7_8_null_5,NEXUS_5,1.0,en].png} | 0 ...mojiItem-D-26_26_null,NEXUS_5,1.0,en].png} | 0 ...mojiItem-N-26_27_null,NEXUS_5,1.0,en].png} | 0 ...jiPicker-D-27_27_null,NEXUS_5,1.0,en].png} | 0 ...jiPicker-N-27_28_null,NEXUS_5,1.0,en].png} | 0 ...ioView-D-28_28_null_0,NEXUS_5,1.0,en].png} | 0 ...ioView-D-28_28_null_1,NEXUS_5,1.0,en].png} | 0 ...ioView-D-28_28_null_2,NEXUS_5,1.0,en].png} | 0 ...ioView-N-28_29_null_0,NEXUS_5,1.0,en].png} | 0 ...ioView-N-28_29_null_1,NEXUS_5,1.0,en].png} | 0 ...ioView-N-28_29_null_2,NEXUS_5,1.0,en].png} | 0 ...ptedView-D-29_29_null,NEXUS_5,1.0,en].png} | 0 ...ptedView-N-29_30_null,NEXUS_5,1.0,en].png} | 0 ...leView-D-30_30_null_0,NEXUS_5,1.0,en].png} | 0 ...leView-D-30_30_null_1,NEXUS_5,1.0,en].png} | 0 ...leView-D-30_30_null_2,NEXUS_5,1.0,en].png} | 0 ...leView-N-30_31_null_0,NEXUS_5,1.0,en].png} | 0 ...leView-N-30_31_null_1,NEXUS_5,1.0,en].png} | 0 ...leView-N-30_31_null_2,NEXUS_5,1.0,en].png} | 0 ...geView-D-31_31_null_0,NEXUS_5,1.0,en].png} | 0 ...geView-D-31_31_null_1,NEXUS_5,1.0,en].png} | 0 ...geView-D-31_31_null_2,NEXUS_5,1.0,en].png} | 0 ...geView-N-31_32_null_0,NEXUS_5,1.0,en].png} | 0 ...geView-N-31_32_null_1,NEXUS_5,1.0,en].png} | 0 ...geView-N-31_32_null_2,NEXUS_5,1.0,en].png} | 0 ...tiveView-D-32_32_null,NEXUS_5,1.0,en].png} | 0 ...tiveView-N-32_33_null,NEXUS_5,1.0,en].png} | 0 ...onView-D-33_33_null_0,NEXUS_5,1.0,en].png} | 0 ...onView-D-33_33_null_1,NEXUS_5,1.0,en].png} | 0 ...onView-N-33_34_null_0,NEXUS_5,1.0,en].png} | 0 ...onView-N-33_34_null_1,NEXUS_5,1.0,en].png} | 0 ...orView-D-35_35_null_0,NEXUS_5,1.0,en].png} | 0 ...orView-D-35_35_null_1,NEXUS_5,1.0,en].png} | 0 ...orView-N-35_36_null_0,NEXUS_5,1.0,en].png} | 0 ...orView-N-35_36_null_1,NEXUS_5,1.0,en].png} | 0 ...llView-D-34_34_null_0,NEXUS_5,1.0,en].png} | 0 ...llView-D-34_34_null_1,NEXUS_5,1.0,en].png} | 0 ...llView-N-34_35_null_0,NEXUS_5,1.0,en].png} | 0 ...llView-N-34_35_null_1,NEXUS_5,1.0,en].png} | 0 ...ctedView-D-36_36_null,NEXUS_5,1.0,en].png} | 0 ...ctedView-N-36_37_null,NEXUS_5,1.0,en].png} | 0 ...tateView-D-37_37_null,NEXUS_5,1.0,en].png} | 0 ...tateView-N-37_38_null,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_0,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_1,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_2,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_3,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_4,NEXUS_5,1.0,en].png} | 0 ...xtView-D-38_38_null_5,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_0,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_1,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_2,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_3,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_4,NEXUS_5,1.0,en].png} | 0 ...xtView-N-38_39_null_5,NEXUS_5,1.0,en].png} | 0 ...nownView-D-39_39_null,NEXUS_5,1.0,en].png} | 0 ...nownView-N-39_40_null,NEXUS_5,1.0,en].png} | 0 ...eoView-D-40_40_null_0,NEXUS_5,1.0,en].png} | 0 ...eoView-D-40_40_null_1,NEXUS_5,1.0,en].png} | 0 ...eoView-D-40_40_null_2,NEXUS_5,1.0,en].png} | 0 ...eoView-N-40_41_null_0,NEXUS_5,1.0,en].png} | 0 ...eoView-N-40_41_null_1,NEXUS_5,1.0,en].png} | 0 ...eoView-N-40_41_null_2,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_0,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_1,NEXUS_5,1.0,en].png} | 0 ...eView-D-41_41_null_10,NEXUS_5,1.0,en].png} | 0 ...eView-D-41_41_null_11,NEXUS_5,1.0,en].png} | 0 ...eView-D-41_41_null_12,NEXUS_5,1.0,en].png} | 0 ...eView-D-41_41_null_13,NEXUS_5,1.0,en].png} | 0 ...eView-D-41_41_null_14,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_2,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_3,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_4,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_5,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_6,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_7,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_8,NEXUS_5,1.0,en].png} | 0 ...ceView-D-41_41_null_9,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_0,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_1,NEXUS_5,1.0,en].png} | 0 ...eView-N-41_42_null_10,NEXUS_5,1.0,en].png} | 0 ...eView-N-41_42_null_11,NEXUS_5,1.0,en].png} | 0 ...eView-N-41_42_null_12,NEXUS_5,1.0,en].png} | 0 ...eView-N-41_42_null_13,NEXUS_5,1.0,en].png} | 0 ...eView-N-41_42_null_14,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_2,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_3,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_4,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_5,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_6,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_7,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_8,NEXUS_5,1.0,en].png} | 0 ...ceView-N-41_42_null_9,NEXUS_5,1.0,en].png} | 0 ...wUnified-D-42_42_null,NEXUS_5,1.0,en].png} | 0 ...wUnified-N-42_43_null,NEXUS_5,1.0,en].png} | 0 ...aderView-D-43_43_null,NEXUS_5,1.0,en].png} | 0 ...aderView-N-43_44_null,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_0,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_1,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_10,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_11,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_12,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_13,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_14,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_15,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_16,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_17,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_18,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_19,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_2,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_20,NEXUS_5,1.0,en].png} | 0 ...ument-D-44_44_null_21,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_3,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_4,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_5,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_6,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_7,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_8,NEXUS_5,1.0,en].png} | 0 ...cument-D-44_44_null_9,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_0,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_1,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_10,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_11,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_12,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_13,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_14,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_15,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_16,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_17,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_18,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_19,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_2,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_20,NEXUS_5,1.0,en].png} | 0 ...ument-N-44_45_null_21,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_3,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_4,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_5,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_6,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_7,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_8,NEXUS_5,1.0,en].png} | 0 ...cument-N-44_45_null_9,NEXUS_5,1.0,en].png} | 0 ...ontent-D-45_45_null_0,NEXUS_5,1.0,en].png} | 0 ...ontent-N-45_46_null_0,NEXUS_5,1.0,en].png} | 0 ...geMenu-D-46_46_null_0,NEXUS_5,1.0,en].png} | 0 ...geMenu-D-46_46_null_1,NEXUS_5,1.0,en].png} | 0 ...geMenu-N-46_47_null_0,NEXUS_5,1.0,en].png} | 0 ...geMenu-N-46_47_null_1,NEXUS_5,1.0,en].png} | 0 ...nnerView-D-47_47_null,NEXUS_5,1.0,en].png} | 0 ...nnerView-N-47_48_null,NEXUS_5,1.0,en].png} | 0 ...orView-D-48_48_null_0,NEXUS_5,1.0,en].png} | 0 ...orView-D-48_48_null_1,NEXUS_5,1.0,en].png} | 0 ...orView-N-48_49_null_0,NEXUS_5,1.0,en].png} | 0 ...orView-N-48_49_null_1,NEXUS_5,1.0,en].png} | 0 ...ndicator-D-49_49_null,NEXUS_5,1.0,en].png} | 0 ...ndicator-N-49_50_null,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_0,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_1,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_10,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_11,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_12,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_13,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_14,NEXUS_5,1.0,en].png} | 0 ...tBubble-D-9_9_null_15,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_2,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_3,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_4,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_5,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_6,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_7,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_8,NEXUS_5,1.0,en].png} | 0 ...ntBubble-D-9_9_null_9,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_0,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_1,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_10,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_11,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_12,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_13,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_14,NEXUS_5,1.0,en].png} | 0 ...Bubble-N-9_10_null_15,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_2,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_3,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_4,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_5,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_6,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_7,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_8,NEXUS_5,1.0,en].png} | 0 ...tBubble-N-9_10_null_9,NEXUS_5,1.0,en].png} | 0 ...ontainer-D-10_10_null,NEXUS_5,1.0,en].png} | 0 ...ontainer-N-10_11_null,NEXUS_5,1.0,en].png} | 0 ...onButton-D-12_12_null,NEXUS_5,1.0,en].png} | 0 ...onButton-N-12_13_null,NEXUS_5,1.0,en].png} | 0 ...Button-D-11_11_null_0,NEXUS_5,1.0,en].png} | 0 ...Button-D-11_11_null_1,NEXUS_5,1.0,en].png} | 0 ...Button-D-11_11_null_2,NEXUS_5,1.0,en].png} | 0 ...Button-D-11_11_null_3,NEXUS_5,1.0,en].png} | 0 ...Button-N-11_12_null_0,NEXUS_5,1.0,en].png} | 0 ...Button-N-11_12_null_1,NEXUS_5,1.0,en].png} | 0 ...Button-N-11_12_null_2,NEXUS_5,1.0,en].png} | 0 ...Button-N-11_12_null_3,NEXUS_5,1.0,en].png} | 0 ...aButtons-D-13_13_null,NEXUS_5,1.0,en].png} | 0 ...aButtons-N-13_14_null,NEXUS_5,1.0,en].png} | 0 ...ndicator-D-14_14_null,NEXUS_5,1.0,en].png} | 0 ...ndicator-N-14_15_null,NEXUS_5,1.0,en].png} | 0 ...mpView-D-15_15_null_0,NEXUS_5,1.0,en].png} | 0 ...mpView-D-15_15_null_1,NEXUS_5,1.0,en].png} | 0 ...mpView-D-15_15_null_2,NEXUS_5,1.0,en].png} | 0 ...mpView-D-15_15_null_3,NEXUS_5,1.0,en].png} | 0 ...mpView-N-15_16_null_0,NEXUS_5,1.0,en].png} | 0 ...mpView-N-15_16_null_1,NEXUS_5,1.0,en].png} | 0 ...mpView-N-15_16_null_2,NEXUS_5,1.0,en].png} | 0 ...mpView-N-15_16_null_3,NEXUS_5,1.0,en].png} | 0 ...EventRow-D-16_16_null,NEXUS_5,1.0,en].png} | 0 ...EventRow-N-16_17_null,NEXUS_5,1.0,en].png} | 0 ...estamp-D-18_18_null_0,NEXUS_5,1.0,en].png} | 0 ...estamp-D-18_18_null_1,NEXUS_5,1.0,en].png} | 0 ...estamp-D-18_18_null_2,NEXUS_5,1.0,en].png} | 0 ...estamp-D-18_18_null_3,NEXUS_5,1.0,en].png} | 0 ...estamp-N-18_19_null_0,NEXUS_5,1.0,en].png} | 0 ...estamp-N-18_19_null_1,NEXUS_5,1.0,en].png} | 0 ...estamp-N-18_19_null_2,NEXUS_5,1.0,en].png} | 0 ...estamp-N-18_19_null_3,NEXUS_5,1.0,en].png} | 0 ...eactions-D-19_19_null,NEXUS_5,1.0,en].png} | 0 ...eactions-N-19_20_null,NEXUS_5,1.0,en].png} | 0 ...ithReply-D-17_17_null,NEXUS_5,1.0,en].png} | 0 ...ithReply-N-17_18_null,NEXUS_5,1.0,en].png} | 0 ...nsLayout-D-20_20_null,NEXUS_5,1.0,en].png} | 0 ...nsLayout-N-20_21_null,NEXUS_5,1.0,en].png} | 0 ...ionsView-D-21_21_null,NEXUS_5,1.0,en].png} | 0 ...ionsView-N-21_22_null,NEXUS_5,1.0,en].png} | 0 ...sViewFew-D-22_22_null,NEXUS_5,1.0,en].png} | 0 ...sViewFew-N-22_23_null,NEXUS_5,1.0,en].png} | 0 ...Incoming-D-23_23_null,NEXUS_5,1.0,en].png} | 0 ...Incoming-N-23_24_null,NEXUS_5,1.0,en].png} | 0 ...Outgoing-D-24_24_null,NEXUS_5,1.0,en].png} | 0 ...Outgoing-N-24_25_null,NEXUS_5,1.0,en].png} | 0 ...EventRow-D-25_25_null,NEXUS_5,1.0,en].png} | 0 ...EventRow-N-25_26_null,NEXUS_5,1.0,en].png} | 0 ...InfoView-D-50_50_null,NEXUS_5,1.0,en].png} | 0 ...InfoView-N-50_51_null,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_0,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_1,NEXUS_5,1.0,en].png} | 0 ...ineView-D-8_8_null_10,NEXUS_5,1.0,en].png} | 0 ...ineView-D-8_8_null_11,NEXUS_5,1.0,en].png} | 0 ...ineView-D-8_8_null_12,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_2,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_3,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_4,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_5,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_6,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_7,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_8,NEXUS_5,1.0,en].png} | 0 ...lineView-D-8_8_null_9,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_0,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_1,NEXUS_5,1.0,en].png} | 0 ...ineView-N-8_9_null_10,NEXUS_5,1.0,en].png} | 0 ...ineView-N-8_9_null_11,NEXUS_5,1.0,en].png} | 0 ...ineView-N-8_9_null_12,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_2,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_3,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_4,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_5,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_6,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_7,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_8,NEXUS_5,1.0,en].png} | 0 ...lineView-N-8_9_null_9,NEXUS_5,1.0,en].png} | 0 tools/localazy/config.json | 1 + 312 files changed, 1522 insertions(+), 51 deletions(-) create mode 100644 changelog.d/1452.feature create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt create mode 100644 features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsProcessor.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomBottomSheetScaffold.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentSessionIdHolder.kt create mode 100644 libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/Suggestion.kt create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-D-3_3_null,NEXUS_5,1.0,en].png create mode 100644 tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-N-3_4_null,NEXUS_5,1.0,en].png rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-3_3_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-4_4_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-3_4_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-4_5_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-4_4_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-5_5_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-4_5_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-5_6_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-5_5_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-6_6_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-5_6_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-6_7_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-25_25_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-26_26_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-25_26_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-26_27_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-26_26_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-27_27_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-26_27_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-27_28_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-28_28_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-29_29_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-28_29_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-29_30_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-31_31_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-32_32_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-31_32_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-32_33_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-35_35_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-36_36_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-35_36_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-36_37_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-36_36_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-37_37_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-36_37_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-37_38_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-38_38_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-39_39_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-38_39_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-39_40_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-41_41_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-42_42_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-41_42_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-42_43_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-42_42_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-43_43_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-42_43_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-43_44_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_15,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_15,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_16,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_16,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_17,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_17,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_18,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_18,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_19,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_19,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_20,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_20,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_21,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_21,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_15,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_15,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_16,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_16,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_17,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_17,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_18,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_18,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_19,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_19,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_20,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_20,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_21,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_21,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-44_44_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-45_45_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-44_45_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-45_46_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-46_46_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-47_47_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-46_47_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-47_48_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-48_48_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-49_49_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-48_49_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-49_50_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_15,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_15,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_13,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_13,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_14,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_14,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_15,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_15,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-9_9_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-10_10_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-9_10_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-10_11_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-11_11_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-12_12_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-11_12_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-12_13_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-12_12_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-13_13_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-12_13_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-13_14_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-13_13_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-14_14_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-13_14_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-14_15_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-15_15_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-16_16_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-15_16_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-16_17_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-18_18_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-19_19_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-18_19_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-19_20_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-16_16_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-17_17_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-16_17_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-17_18_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-19_19_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-20_20_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-19_20_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-20_21_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-20_20_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-21_21_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-20_21_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-21_22_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-21_21_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-22_22_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-21_22_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-22_23_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-22_22_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-23_23_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-22_23_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-23_24_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-23_23_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-24_24_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-23_24_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-24_25_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-24_24_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-25_25_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-24_25_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-25_26_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-49_49_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-50_50_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-49_50_null,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-50_51_null,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_9,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_0,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_0,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_1,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_1,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_10,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_10,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_11,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_11,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_12,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_12,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_2,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_2,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_3,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_3,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_4,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_4,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_5,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_5,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_6,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_6,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_7,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_7,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_8,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_8,NEXUS_5,1.0,en].png} (100%) rename tests/uitests/src/test/snapshots/images/{ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_9,NEXUS_5,1.0,en].png => ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_9,NEXUS_5,1.0,en].png} (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 9cbf6cd3cc..598d4aab43 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -200,7 +200,9 @@ koverMerged { "*Node$*", // Exclude `:libraries:matrix:impl` module, it contains only wrappers to access the Rust Matrix SDK api, so it is not really relevant to unit test it: there is no logic to test. "io.element.android.libraries.matrix.impl.*", - "*Presenter\$present\$*" + "*Presenter\$present\$*", + // Forked from compose + "io.element.android.libraries.designsystem.theme.components.bottomsheet.*", ) ) } diff --git a/changelog.d/1452.feature b/changelog.d/1452.feature new file mode 100644 index 0000000000..acdee4039e --- /dev/null +++ b/changelog.d/1452.feature @@ -0,0 +1 @@ +Mentions: add mentions suggestion view in RTE diff --git a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt index e70fe79fdf..124f30e9f4 100644 --- a/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt +++ b/features/location/impl/src/main/kotlin/io/element/android/features/location/impl/send/SendLocationView.kt @@ -33,8 +33,6 @@ import androidx.compose.material.icons.filled.MyLocation import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ListItem import androidx.compose.material3.SheetValue -import androidx.compose.material3.rememberBottomSheetScaffoldState -import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment @@ -47,19 +45,21 @@ import com.mapbox.mapboxsdk.camera.CameraPosition import io.element.android.features.location.api.Location import io.element.android.features.location.api.internal.centerBottomEdge import io.element.android.features.location.api.internal.rememberTileStyleUrl -import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.R +import io.element.android.features.location.impl.common.MapDefaults import io.element.android.features.location.impl.common.PermissionDeniedDialog import io.element.android.features.location.impl.common.PermissionRationaleDialog import io.element.android.libraries.designsystem.components.button.BackButton -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.aliasScreenTitle import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold import io.element.android.libraries.designsystem.theme.components.FloatingActionButton import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TopAppBar +import io.element.android.libraries.designsystem.theme.components.bottomsheet.rememberBottomSheetScaffoldState +import io.element.android.libraries.designsystem.theme.components.bottomsheet.rememberStandardBottomSheetState import io.element.android.libraries.designsystem.utils.CommonDrawables import io.element.android.libraries.maplibre.compose.CameraMode import io.element.android.libraries.maplibre.compose.CameraMoveStartedReason diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt index 8b28a216b0..215559b334 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt @@ -20,12 +20,8 @@ package io.element.android.features.messages.impl import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue -import androidx.compose.material3.rememberBottomSheetScaffoldState -import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf @@ -42,6 +38,10 @@ import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.min +import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold +import io.element.android.libraries.designsystem.theme.components.bottomsheet.CustomSheetState +import io.element.android.libraries.designsystem.theme.components.bottomsheet.rememberBottomSheetScaffoldState +import io.element.android.libraries.designsystem.theme.components.bottomsheet.rememberStandardBottomSheetState import kotlin.math.roundToInt /** @@ -58,6 +58,7 @@ import kotlin.math.roundToInt * @param modifier The modifier for the layout. * @param sheetContentKey The key for the sheet content. If the key changes, the sheet will be remeasured. */ +@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun ExpandableBottomSheetScaffold( content: @Composable (padding: PaddingValues) -> Unit, @@ -139,7 +140,7 @@ internal fun ExpandableBottomSheetScaffold( modifier = Modifier.fillMaxHeight(), measurePolicy = { measurables, constraints -> val constraintHeight = constraints.maxHeight - val offset = scaffoldState.bottomSheetState.getOffset() ?: 0 + val offset = scaffoldState.bottomSheetState.getIntOffset() ?: 0 val height = Integer.max(0, constraintHeight - offset) val top = measurables[0].measure( constraints.copy( @@ -163,7 +164,7 @@ internal fun ExpandableBottomSheetScaffold( }) } -private fun SheetState.getOffset(): Int? = try { +private fun CustomSheetState.getIntOffset(): Int? = try { requireOffset().roundToInt() } catch (e: IllegalStateException) { null 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 9ecf63dd29..5c08c62849 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 @@ -43,7 +43,11 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontStyle @@ -55,6 +59,7 @@ 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.mentions.MentionSuggestionsPickerView 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 @@ -338,7 +343,11 @@ private fun MessagesViewContent( @Composable {} }, sheetSwipeEnabled = state.composerState.showTextFormatting, - sheetShape = if (state.composerState.showTextFormatting) MaterialTheme.shapes.large else RectangleShape, + sheetShape = if (state.composerState.showTextFormatting || state.composerState.memberSuggestions.isNotEmpty()) { + MaterialTheme.shapes.large + } else { + RectangleShape + }, content = { paddingValues -> TimelineView( modifier = Modifier.padding(paddingValues), @@ -354,27 +363,56 @@ private fun MessagesViewContent( ) }, sheetContent = { subcomposing: Boolean -> - if (state.userHasPermissionToSendMessage) { - MessageComposerView( - state = state.composerState, - voiceMessageState = state.voiceMessageComposerState, - subcomposing = subcomposing, - enableTextFormatting = state.enableTextFormatting, - enableVoiceMessages = state.enableVoiceMessages, - modifier = Modifier - .fillMaxWidth(), - ) - } else { - CantSendMessageBanner() - } + MessagesViewComposerBottomSheetContents( + subcomposing = subcomposing, + state = state, + ) }, - sheetContentKey = state.composerState.richTextEditorState.lineCount, + sheetContentKey = state.composerState.richTextEditorState.lineCount + state.composerState.memberSuggestions.size, sheetTonalElevation = 0.dp, - sheetShadowElevation = 0.dp, + sheetShadowElevation = if (state.composerState.memberSuggestions.isNotEmpty()) 16.dp else 0.dp, ) } } +@Composable +private fun MessagesViewComposerBottomSheetContents( + subcomposing: Boolean, + state: MessagesState, + modifier: Modifier = Modifier, +) { + if (state.userHasPermissionToSendMessage) { + Column(modifier = modifier.fillMaxWidth()) { + MentionSuggestionsPickerView( + modifier = Modifier.heightIn(max = 230.dp) + // Consume all scrolling, preventing the bottom sheet from being dragged when interacting with the list of suggestions + .nestedScroll(object : NestedScrollConnection { + override fun onPostScroll(consumed: Offset, available: Offset, source: NestedScrollSource): Offset { + return available + } + }), + roomId = state.roomId, + roomName = state.roomName.dataOrNull(), + roomAvatarData = state.roomAvatar.dataOrNull(), + memberSuggestions = state.composerState.memberSuggestions, + onSuggestionSelected = { + // TODO pass the selected suggestion to the RTE so it can be inserted as a pill + } + ) + MessageComposerView( + state = state.composerState, + voiceMessageState = state.voiceMessageComposerState, + subcomposing = subcomposing, + enableTextFormatting = state.enableTextFormatting, + enableVoiceMessages = state.enableVoiceMessages, + modifier = Modifier.fillMaxWidth(), + ) + } + } else { + CantSendMessageBanner(modifier = modifier) + } +} + @OptIn(ExperimentalMaterial3Api::class) @Composable private fun MessagesViewTopBar( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt new file mode 100644 index 0000000000..6b937a872e --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsPickerView.kt @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.messages.impl.mentions + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import io.element.android.features.messages.impl.R +import io.element.android.features.messages.impl.messagecomposer.RoomMemberSuggestion +import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.HorizontalDivider +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.theme.ElementTheme +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +@Composable +fun MentionSuggestionsPickerView( + roomId: RoomId, + roomName: String?, + roomAvatarData: AvatarData?, + memberSuggestions: ImmutableList, + onSuggestionSelected: (RoomMemberSuggestion) -> Unit, + modifier: Modifier = Modifier, +) { + LazyColumn( + modifier = modifier.fillMaxWidth(), + ) { + items( + memberSuggestions, + key = { suggestion -> + when (suggestion) { + is RoomMemberSuggestion.Room -> "@room" + is RoomMemberSuggestion.Member -> suggestion.roomMember.userId.value + } + } + ) { + Column(modifier = Modifier.fillParentMaxWidth()) { + RoomMemberSuggestionItemView( + memberSuggestion = it, + roomId = roomId.value, + roomName = roomName, + roomAvatar = roomAvatarData, + onSuggestionSelected = onSuggestionSelected, + modifier = Modifier.fillMaxWidth() + ) + HorizontalDivider(modifier = Modifier.fillMaxWidth()) + } + } + } +} + +@Composable +private fun RoomMemberSuggestionItemView( + memberSuggestion: RoomMemberSuggestion, + roomId: String, + roomName: String?, + roomAvatar: AvatarData?, + onSuggestionSelected: (RoomMemberSuggestion) -> Unit, + modifier: Modifier = Modifier, +) { + Row(modifier = modifier.clickable { onSuggestionSelected(memberSuggestion) }, horizontalArrangement = Arrangement.spacedBy(16.dp)) { + val avatarSize = AvatarSize.TimelineRoom + val avatarData = when (memberSuggestion) { + is RoomMemberSuggestion.Room -> roomAvatar?.copy(size = avatarSize) ?: AvatarData(roomId, roomName, null, avatarSize) + is RoomMemberSuggestion.Member -> AvatarData( + memberSuggestion.roomMember.userId.value, + memberSuggestion.roomMember.displayName, + memberSuggestion.roomMember.avatarUrl, + avatarSize, + ) + } + val title = when (memberSuggestion) { + is RoomMemberSuggestion.Room -> stringResource(R.string.screen_room_mentions_at_room_title) + is RoomMemberSuggestion.Member -> memberSuggestion.roomMember.displayName + } + + val subtitle = when (memberSuggestion) { + is RoomMemberSuggestion.Room -> "@room" + is RoomMemberSuggestion.Member -> memberSuggestion.roomMember.userId.value + } + + Avatar(avatarData = avatarData, modifier = Modifier.padding(start = 16.dp, top = 12.dp, bottom = 12.dp)) + + Column( + modifier = Modifier + .fillMaxWidth() + .padding(end = 16.dp, top = 8.dp, bottom = 8.dp) + .align(Alignment.CenterVertically), + ) { + title?.let { + Text( + text = it, + style = ElementTheme.typography.fontBodyLgRegular, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + Text( + text = subtitle, + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } +} + +@PreviewsDayNight +@Composable +internal fun MentionSuggestionsPickerView_Preview() { + ElementPreview { + val roomMember = RoomMember( + userId = UserId("@alice:server.org"), + displayName = null, + avatarUrl = null, + membership = RoomMembershipState.JOIN, + isNameAmbiguous = false, + powerLevel = 0L, + normalizedPowerLevel = 0L, + isIgnored = false, + ) + MentionSuggestionsPickerView( + roomId = RoomId("!room:matrix.org"), + roomName = "Room", + roomAvatarData = null, + memberSuggestions = persistentListOf( + RoomMemberSuggestion.Room, + RoomMemberSuggestion.Member(roomMember), + RoomMemberSuggestion.Member(roomMember.copy(userId = UserId("@bob:server.org"), displayName = "Bob")), + ), + onSuggestionSelected = {} + ) + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsProcessor.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsProcessor.kt new file mode 100644 index 0000000000..1f4e2b5376 --- /dev/null +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/mentions/MentionSuggestionsProcessor.kt @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.messages.impl.mentions + +import io.element.android.features.messages.impl.messagecomposer.RoomMemberSuggestion +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState +import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.roomMembers +import io.element.android.libraries.textcomposer.model.Suggestion +import io.element.android.libraries.textcomposer.model.SuggestionType + +/** + * This class is responsible for processing mention suggestions when `@`, `/` or `#` are type in the composer. + */ +object MentionSuggestionsProcessor { + + // We don't want to retrieve thousands of members + private const val MAX_BATCH_ITEMS = 100 + + /** + * Process the mention suggestions. + * @param suggestion The current suggestion input + * @param roomMembersState The room members state, it contains the current users in the room + * @param currentUserId The current user id + * @param canSendRoomMention Should return true if the current user can send room mentions + * @return The list of mentions to display + */ + suspend fun process( + suggestion: Suggestion?, + roomMembersState: MatrixRoomMembersState, + currentUserId: UserId, + canSendRoomMention: suspend () -> Boolean, + ): List { + val members = roomMembersState.roomMembers() + // Take the first MAX_BATCH_ITEMS only + ?.take(MAX_BATCH_ITEMS) + return when { + members.isNullOrEmpty() || suggestion == null -> { + // Clear suggestions + emptyList() + } + else -> { + when (suggestion.type) { + SuggestionType.Mention -> { + // Replace suggestions + val matchingMembers = getMemberSuggestions( + query = suggestion.text, + roomMembers = roomMembersState.roomMembers(), + currentUserId = currentUserId, + canSendRoomMention = canSendRoomMention() + ) + matchingMembers + } + else -> { + // Clear suggestions + emptyList() + } + } + } + } + } + + private fun getMemberSuggestions( + query: String, + roomMembers: List?, + currentUserId: UserId, + canSendRoomMention: Boolean, + ): List { + return if (roomMembers.isNullOrEmpty()) { + emptyList() + } else { + fun isJoinedMemberAndNotSelf(member: RoomMember): Boolean { + return member.membership == RoomMembershipState.JOIN && currentUserId != member.userId + } + + fun memberMatchesQuery(member: RoomMember, query: String): Boolean { + return member.userId.value.contains(query, ignoreCase = true) + || member.displayName?.contains(query, ignoreCase = true) == true + } + + val matchingMembers = roomMembers + // Search only in joined members, exclude the current user + .filter { member -> + isJoinedMemberAndNotSelf(member) && memberMatchesQuery(member, query) + } + .map(RoomMemberSuggestion::Member) + + if ("room".contains(query) && canSendRoomMention) { + listOf(RoomMemberSuggestion.Room) + matchingMembers + } else { + matchingMembers + } + } + } +} 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 cd03c52e1e..97c2e7015d 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 @@ -19,6 +19,7 @@ package io.element.android.features.messages.impl.messagecomposer import androidx.compose.runtime.Immutable import io.element.android.libraries.textcomposer.model.Message import io.element.android.libraries.textcomposer.model.MessageComposerMode +import io.element.android.libraries.textcomposer.model.Suggestion @Immutable sealed interface MessageComposerEvents { @@ -39,4 +40,5 @@ sealed interface MessageComposerEvents { data class ToggleTextFormatting(val enabled: Boolean) : MessageComposerEvents data object CancelSendAttachment : MessageComposerEvents data class Error(val error: Throwable) : 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 3857600e58..b66decd81e 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 @@ -23,6 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -34,6 +35,7 @@ import im.vector.app.features.analytics.plan.Composer 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.media.local.LocalMediaFactory +import io.element.android.features.messages.impl.mentions.MentionSuggestionsProcessor 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 @@ -43,22 +45,32 @@ 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.room.MatrixRoom +import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaSender import io.element.android.libraries.permissions.api.PermissionsEvents import io.element.android.libraries.permissions.api.PermissionsPresenter import io.element.android.libraries.textcomposer.model.Message import io.element.android.libraries.textcomposer.model.MessageComposerMode +import io.element.android.libraries.textcomposer.model.Suggestion import io.element.android.services.analytics.api.AnalyticsService import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.isActive import kotlinx.coroutines.launch 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 @SingleIn(RoomScope::class) @@ -73,17 +85,26 @@ class MessageComposerPresenter @Inject constructor( private val analyticsService: AnalyticsService, private val messageComposerContext: MessageComposerContextImpl, private val richTextEditorStateFactory: RichTextEditorStateFactory, + private val currentSessionIdHolder: CurrentSessionIdHolder, permissionsPresenterFactory: PermissionsPresenter.Factory ) : Presenter { private val cameraPermissionPresenter = permissionsPresenterFactory.create(Manifest.permission.CAMERA) private var pendingEvent: MessageComposerEvents? = null + private val suggestionSearchTrigger = MutableStateFlow(null) + + @OptIn(FlowPreview::class) @SuppressLint("UnsafeOptInUsageError") @Composable override fun present(): MessageComposerState { val localCoroutineScope = rememberCoroutineScope() + var isMentionsEnabled by remember { mutableStateOf(false) } + LaunchedEffect(Unit) { + isMentionsEnabled = featureFlagService.isFeatureEnabled(FeatureFlags.Mentions) + } + val cameraPermissionState = cameraPermissionPresenter.present() val attachmentsState = remember { mutableStateOf(AttachmentsState.None) @@ -151,6 +172,34 @@ class MessageComposerPresenter @Inject constructor( } } + val memberSuggestions = remember { mutableStateListOf() } + LaunchedEffect(isMentionsEnabled) { + if (!isMentionsEnabled) return@LaunchedEffect + val currentUserId = currentSessionIdHolder.current + + suspend fun canSendRoomMention(): Boolean { + val roomIsDm = room.isDirect && room.isOneToOne + val userCanSendAtRoom = room.canUserTriggerRoomNotification(currentUserId).getOrDefault(false) + return !roomIsDm && userCanSendAtRoom + } + + suggestionSearchTrigger + .debounce(0.5.seconds) + .combine(room.membersStateFlow) { suggestion, roomMembersState -> + memberSuggestions.clear() + val result = MentionSuggestionsProcessor.process( + suggestion = suggestion, + roomMembersState = roomMembersState, + currentUserId = currentUserId, + canSendRoomMention = ::canSendRoomMention, + ) + if (result.isNotEmpty()) { + memberSuggestions.addAll(result) + } + } + .collect() + } + fun handleEvents(event: MessageComposerEvents) { when (event) { MessageComposerEvents.ToggleFullScreenState -> isFullScreen.value = !isFullScreen.value @@ -231,6 +280,9 @@ class MessageComposerPresenter @Inject constructor( is MessageComposerEvents.Error -> { analyticsService.trackError(event.error) } + is MessageComposerEvents.SuggestionReceived -> { + suggestionSearchTrigger.value = event.suggestion + } } } @@ -243,6 +295,7 @@ class MessageComposerPresenter @Inject constructor( canShareLocation = canShareLocation.value, canCreatePoll = canCreatePoll.value, attachmentsState = attachmentsState.value, + memberSuggestions = memberSuggestions.toPersistentList(), eventSink = { handleEvents(it) } ) } @@ -355,3 +408,8 @@ class MessageComposerPresenter @Inject constructor( } } } + +sealed interface RoomMemberSuggestion { + data object Room : RoomMemberSuggestion + data class Member(val roomMember: RoomMember) : RoomMemberSuggestion +} 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 3e8f171626..6a9d963d18 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 @@ -33,6 +33,7 @@ data class MessageComposerState( val canShareLocation: Boolean, val canCreatePoll: Boolean, val attachmentsState: AttachmentsState, + val memberSuggestions: ImmutableList, val eventSink: (MessageComposerEvents) -> Unit, ) { val hasFocus: Boolean = richTextEditorState.hasFocus 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 76f40a1969..ac936b2118 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 @@ -19,6 +19,8 @@ package io.element.android.features.messages.impl.messagecomposer import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.wysiwyg.compose.RichTextEditorState +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf open class MessageComposerStateProvider : PreviewParameterProvider { override val values: Sequence @@ -36,6 +38,7 @@ fun aMessageComposerState( canShareLocation: Boolean = true, canCreatePoll: Boolean = true, attachmentsState: AttachmentsState = AttachmentsState.None, + memberSuggestions: ImmutableList = persistentListOf(), ) = MessageComposerState( richTextEditorState = composerState, isFullScreen = isFullScreen, @@ -45,5 +48,6 @@ fun aMessageComposerState( canShareLocation = canShareLocation, canCreatePoll = canCreatePoll, attachmentsState = attachmentsState, + memberSuggestions = memberSuggestions, eventSink = {}, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt index 0c71bdbec1..e34a22eedc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt @@ -28,11 +28,12 @@ import io.element.android.features.messages.impl.voicemessages.composer.VoiceMes import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerStateProvider import io.element.android.features.messages.impl.voicemessages.composer.aVoiceMessageComposerState -import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.textcomposer.model.Message +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.textcomposer.TextComposer +import io.element.android.libraries.textcomposer.model.Message import io.element.android.libraries.textcomposer.model.PressEvent +import io.element.android.libraries.textcomposer.model.Suggestion import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent import kotlinx.coroutines.launch @@ -61,6 +62,10 @@ internal fun MessageComposerView( state.eventSink(MessageComposerEvents.ToggleTextFormatting(enabled = false)) } + fun onSuggestionReceived(suggestion: Suggestion?) { + state.eventSink(MessageComposerEvents.SuggestionReceived(suggestion)) + } + fun onError(error: Throwable) { state.eventSink(MessageComposerEvents.Error(error)) } @@ -106,6 +111,7 @@ internal fun MessageComposerView( onVoicePlayerEvent = onVoicePlayerEvent, onSendVoiceMessage = onSendVoiceMessage, onDeleteVoiceMessage = onDeleteVoiceMessage, + onSuggestionReceived = ::onSuggestionReceived, onError = ::onError, ) } diff --git a/features/messages/impl/src/main/res/values/localazy.xml b/features/messages/impl/src/main/res/values/localazy.xml index 233a9ecbf4..12b3ec04a1 100644 --- a/features/messages/impl/src/main/res/values/localazy.xml +++ b/features/messages/impl/src/main/res/values/localazy.xml @@ -4,6 +4,8 @@ "%1$d room change" "%1$d room changes" + "Notify the whole room" + "Everyone" "Camera" "Take photo" "Record video" diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt index 9709dde50e..3dde2a984f 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/MessagesPresenterTest.kt @@ -63,11 +63,13 @@ 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.user.CurrentSessionIdHolder 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_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.FakeMatrixClient import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.room.FakeMatrixRoom import io.element.android.libraries.matrix.test.room.aRoomInfo @@ -629,6 +631,7 @@ class MessagesPresenterTest { messageComposerContext = MessageComposerContextImpl(), richTextEditorStateFactory = TestRichTextEditorStateFactory(), permissionsPresenterFactory = permissionsPresenterFactory, + currentSessionIdHolder = CurrentSessionIdHolder(FakeMatrixClient(A_SESSION_ID)), ) val voiceMessageComposerPresenter = VoiceMessageComposerPresenter( this, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index 2ae34d018f..f05c209085 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.messagecomposer.MessageComposer 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.messagecomposer.MessageComposerState +import io.element.android.features.messages.impl.messagecomposer.RoomMemberSuggestion import io.element.android.features.messages.media.FakeLocalMediaFactory import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher @@ -42,13 +43,23 @@ import io.element.android.libraries.matrix.api.core.TransactionId 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.room.MatrixRoom +import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState +import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder 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_MESSAGE import io.element.android.libraries.matrix.test.A_REPLY +import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_TRANSACTION_ID +import io.element.android.libraries.matrix.test.A_USER_ID +import io.element.android.libraries.matrix.test.A_USER_ID_2 +import io.element.android.libraries.matrix.test.A_USER_ID_3 +import io.element.android.libraries.matrix.test.A_USER_ID_4 import io.element.android.libraries.matrix.test.A_USER_NAME +import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.libraries.matrix.test.room.aRoomMember import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediapickers.test.FakePickerProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor @@ -60,6 +71,8 @@ import io.element.android.libraries.permissions.test.FakePermissionsPresenter import io.element.android.libraries.permissions.test.FakePermissionsPresenterFactory import io.element.android.libraries.textcomposer.model.Message import io.element.android.libraries.textcomposer.model.MessageComposerMode +import io.element.android.libraries.textcomposer.model.Suggestion +import io.element.android.libraries.textcomposer.model.SuggestionType import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.waitForPredicate @@ -67,6 +80,7 @@ import io.mockk.mockk import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest +import okhttp3.internal.immutableListOf import org.junit.Rule import org.junit.Test import java.io.File @@ -706,6 +720,104 @@ class MessageComposerPresenterTest { } } + @Test + fun `present - room member mention suggestions`() = runTest { + val currentUser = aRoomMember(userId = A_USER_ID, membership = RoomMembershipState.JOIN) + val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) + val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) + val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) + val room = FakeMatrixRoom( + isDirect = false, + isOneToOne = false, + ).apply { + givenRoomMembersState(MatrixRoomMembersState.Ready( + immutableListOf(currentUser, invitedUser, bob, david), + )) + givenCanTriggerRoomNotification(Result.success(true)) + } + val flagsService = FakeFeatureFlagService( + mapOf( + FeatureFlags.Mentions.key to true, + ) + ) + val presenter = createPresenter(this, room, featureFlagService = flagsService) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + + // A null suggestion (no suggestion was received) returns nothing + initialState.eventSink(MessageComposerEvents.SuggestionReceived(null)) + assertThat(awaitItem().memberSuggestions).isEmpty() + + // An empty suggestion returns the room and joined members that are not the current user + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) + assertThat(awaitItem().memberSuggestions) + .containsExactly(RoomMemberSuggestion.Room, RoomMemberSuggestion.Member(bob), RoomMemberSuggestion.Member(david)) + + // A suggestion containing a part of "room" will also return the room mention + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "roo"))) + assertThat(awaitItem().memberSuggestions).containsExactly(RoomMemberSuggestion.Room) + + // A non-empty suggestion will return those joined members whose user id matches it + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "bob"))) + assertThat(awaitItem().memberSuggestions).containsExactly(RoomMemberSuggestion.Member(bob)) + + // A non-empty suggestion will return those joined members whose display name matches it + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, "dave"))) + assertThat(awaitItem().memberSuggestions).containsExactly(RoomMemberSuggestion.Member(david)) + + // If the suggestion isn't a mention, no suggestions are returned + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Command, ""))) + assertThat(awaitItem().memberSuggestions).isEmpty() + + // If user has no permission to send `@room` mentions, `RoomMemberSuggestion.Room` is not returned + room.givenCanTriggerRoomNotification(Result.success(false)) + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) + assertThat(awaitItem().memberSuggestions) + .containsExactly(RoomMemberSuggestion.Member(bob), RoomMemberSuggestion.Member(david)) + + // If room is a DM, `RoomMemberSuggestion.Room` is not returned + room.givenCanTriggerRoomNotification(Result.success(true)) + room.isDirect + } + } + + @Test + fun `present - room member mention suggestions in a DM`() = runTest { + val currentUser = aRoomMember(userId = A_USER_ID, membership = RoomMembershipState.JOIN) + val invitedUser = aRoomMember(userId = A_USER_ID_3, membership = RoomMembershipState.INVITE) + val bob = aRoomMember(userId = A_USER_ID_2, membership = RoomMembershipState.JOIN) + val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) + val room = FakeMatrixRoom( + isDirect = true, + isOneToOne = true, + ).apply { + givenRoomMembersState(MatrixRoomMembersState.Ready( + immutableListOf(currentUser, invitedUser, bob, david), + )) + givenCanTriggerRoomNotification(Result.success(true)) + } + val flagsService = FakeFeatureFlagService( + mapOf( + FeatureFlags.Mentions.key to true, + ) + ) + val presenter = createPresenter(this, room, featureFlagService = flagsService) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + skipItems(1) + val initialState = awaitItem() + + // An empty suggestion returns the joined members that are not the current user, but not the room + initialState.eventSink(MessageComposerEvents.SuggestionReceived(Suggestion(0, 0, SuggestionType.Mention, ""))) + assertThat(awaitItem().memberSuggestions) + .containsExactly(RoomMemberSuggestion.Member(bob), RoomMemberSuggestion.Member(david)) + } + } + private suspend fun ReceiveTurbine.backToNormalMode(state: MessageComposerState, skipCount: Int = 0): MessageComposerState { state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode) skipItems(skipCount) @@ -733,6 +845,7 @@ class MessageComposerPresenterTest { analyticsService, MessageComposerContextImpl(), TestRichTextEditorStateFactory(), + currentSessionIdHolder = CurrentSessionIdHolder(FakeMatrixClient(A_SESSION_ID)), permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionPresenter), ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/BottomSheetScaffold.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/BottomSheetScaffold.kt index 6d3487b3a2..a9f7de4efe 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/BottomSheetScaffold.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/BottomSheetScaffold.kt @@ -19,18 +19,19 @@ package io.element.android.libraries.designsystem.theme.components import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.material3.BottomSheetDefaults -import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.contentColorFor -import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.Dp +import io.element.android.libraries.designsystem.theme.components.bottomsheet.BottomSheetScaffoldState +import io.element.android.libraries.designsystem.theme.components.bottomsheet.CustomBottomSheetScaffold +import io.element.android.libraries.designsystem.theme.components.bottomsheet.rememberBottomSheetScaffoldState @Composable @ExperimentalMaterial3Api @@ -52,7 +53,7 @@ fun BottomSheetScaffold( contentColor: Color = contentColorFor(containerColor), content: @Composable (PaddingValues) -> Unit ) { - androidx.compose.material3.BottomSheetScaffold( + CustomBottomSheetScaffold( sheetContent = sheetContent, modifier = modifier, scaffoldState = scaffoldState, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomBottomSheetScaffold.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomBottomSheetScaffold.kt new file mode 100644 index 0000000000..22b55c19af --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomBottomSheetScaffold.kt @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:OptIn(ExperimentalFoundationApi::class) + +package io.element.android.libraries.designsystem.theme.components.bottomsheet + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.gestures.DraggableAnchors +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.gestures.anchoredDraggable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.requiredHeightIn +import androidx.compose.foundation.layout.widthIn +import androidx.compose.material3.BottomSheetDefaults +import androidx.compose.material3.BottomSheetScaffold +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SheetState +import androidx.compose.material3.SheetValue +import androidx.compose.material3.SheetValue.Expanded +import androidx.compose.material3.SheetValue.PartiallyExpanded +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.Surface +import androidx.compose.material3.contentColorFor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.layout.SubcomposeLayout +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.semantics.collapse +import androidx.compose.ui.semantics.dismiss +import androidx.compose.ui.semantics.expand +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.Velocity +import kotlinx.coroutines.launch +import kotlin.math.abs +import kotlin.math.roundToInt + +// These are needed until https://issuetracker.google.com/issues/306464779 is fixed + +@Composable +@ExperimentalMaterial3Api +fun CustomBottomSheetScaffold( + sheetContent: @Composable ColumnScope.() -> Unit, + modifier: Modifier = Modifier, + scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(), + sheetPeekHeight: Dp = BottomSheetDefaults.SheetPeekHeight, + sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth, + sheetShape: Shape = BottomSheetDefaults.ExpandedShape, + sheetContainerColor: Color = BottomSheetDefaults.ContainerColor, + sheetContentColor: Color = contentColorFor(sheetContainerColor), + sheetTonalElevation: Dp = BottomSheetDefaults.Elevation, + sheetShadowElevation: Dp = BottomSheetDefaults.Elevation, + sheetDragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() }, + sheetSwipeEnabled: Boolean = true, + topBar: @Composable (() -> Unit)? = null, + snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) }, + containerColor: Color = MaterialTheme.colorScheme.surface, + contentColor: Color = contentColorFor(containerColor), + content: @Composable (PaddingValues) -> Unit +) { + val peekHeightPx = with(LocalDensity.current) { + sheetPeekHeight.roundToPx() + } + CustomBottomSheetScaffoldLayout( + modifier = modifier, + topBar = topBar, + body = content, + snackbarHost = { + snackbarHost(scaffoldState.snackbarHostState) + }, + sheetPeekHeight = sheetPeekHeight, + sheetOffset = { scaffoldState.bottomSheetState.requireOffset() }, + sheetState = scaffoldState.bottomSheetState, + containerColor = containerColor, + contentColor = contentColor, + bottomSheet = { layoutHeight -> + CustomStandardBottomSheet( + state = scaffoldState.bottomSheetState, + peekHeight = sheetPeekHeight, + sheetMaxWidth = sheetMaxWidth, + sheetSwipeEnabled = sheetSwipeEnabled, + calculateAnchors = { sheetSize -> + val sheetHeight = sheetSize.height + io.element.android.libraries.designsystem.theme.components.bottomsheet.DraggableAnchors { + if (!scaffoldState.bottomSheetState.skipPartiallyExpanded) { + PartiallyExpanded at (layoutHeight - peekHeightPx).toFloat() + } + if (sheetHeight != peekHeightPx) { + Expanded at maxOf(layoutHeight - sheetHeight, 0).toFloat() + } + if (!scaffoldState.bottomSheetState.skipHiddenState) { + SheetValue.Hidden at layoutHeight.toFloat() + } + } + }, + shape = sheetShape, + containerColor = sheetContainerColor, + contentColor = sheetContentColor, + tonalElevation = sheetTonalElevation, + shadowElevation = sheetShadowElevation, + dragHandle = sheetDragHandle, + content = sheetContent + ) + } + ) +} + +@SuppressWarnings("ModifierWithoutDefault") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun CustomBottomSheetScaffoldLayout( + modifier: Modifier, + topBar: @Composable (() -> Unit)?, + body: @Composable (innerPadding: PaddingValues) -> Unit, + bottomSheet: @Composable (layoutHeight: Int) -> Unit, + snackbarHost: @Composable () -> Unit, + sheetPeekHeight: Dp, + sheetOffset: () -> Float, + sheetState: CustomSheetState, + containerColor: Color, + contentColor: Color, +) { + // b/291735717 Remove this once deprecated methods without density are removed + val density = LocalDensity.current + SideEffect { + sheetState.density = density + } + SubcomposeLayout { constraints -> + val layoutWidth = constraints.maxWidth + val layoutHeight = constraints.maxHeight + val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0) + + val sheetPlaceable = subcompose(BottomSheetScaffoldLayoutSlot.Sheet) { + bottomSheet(layoutHeight) + }[0].measure(looseConstraints) + + val topBarPlaceable = topBar?.let { + subcompose(BottomSheetScaffoldLayoutSlot.TopBar) { topBar() }[0] + .measure(looseConstraints) + } + val topBarHeight = topBarPlaceable?.height ?: 0 + + val bodyConstraints = looseConstraints.copy(maxHeight = layoutHeight - topBarHeight) + val bodyPlaceable = subcompose(BottomSheetScaffoldLayoutSlot.Body) { + Surface( + modifier = modifier, + color = containerColor, + contentColor = contentColor, + ) { body(PaddingValues(bottom = sheetPeekHeight)) } + }[0].measure(bodyConstraints) + + val snackbarPlaceable = subcompose(BottomSheetScaffoldLayoutSlot.Snackbar, snackbarHost)[0] + .measure(looseConstraints) + + layout(layoutWidth, layoutHeight) { + val sheetOffsetY = sheetOffset().roundToInt() + val sheetOffsetX = Integer.max(0, (layoutWidth - sheetPlaceable.width) / 2) + + val snackbarOffsetX = (layoutWidth - snackbarPlaceable.width) / 2 + val snackbarOffsetY = when (sheetState.currentValue) { + SheetValue.PartiallyExpanded -> sheetOffsetY - snackbarPlaceable.height + SheetValue.Expanded, SheetValue.Hidden -> layoutHeight - snackbarPlaceable.height + } + + // Placement order is important for elevation + bodyPlaceable.placeRelative(0, topBarHeight) + topBarPlaceable?.placeRelative(0, 0) + sheetPlaceable.placeRelative(sheetOffsetX, sheetOffsetY) + snackbarPlaceable.placeRelative(snackbarOffsetX, snackbarOffsetY) + } + } +} + +private enum class BottomSheetScaffoldLayoutSlot { TopBar, Body, Sheet, Snackbar } + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@Composable +private fun CustomStandardBottomSheet( + state: CustomSheetState, + @Suppress("PrimitiveInLambda") + calculateAnchors: (sheetSize: IntSize) -> DraggableAnchors, + peekHeight: Dp, + sheetMaxWidth: Dp, + sheetSwipeEnabled: Boolean, + shape: Shape, + containerColor: Color, + contentColor: Color, + tonalElevation: Dp, + shadowElevation: Dp, + dragHandle: @Composable (() -> Unit)?, + content: @Composable ColumnScope.() -> Unit +) { + val scope = rememberCoroutineScope() + + val orientation = Orientation.Vertical + + Surface( + modifier = Modifier + .widthIn(max = sheetMaxWidth) + .fillMaxWidth() + .requiredHeightIn(min = peekHeight) + .apply { + if (sheetSwipeEnabled) { + nestedScroll( + remember(state.anchoredDraggableState) { + ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection( + sheetState = state, + orientation = orientation, + onFling = { scope.launch { state.settle(it) } } + ) + } + ) + } + } + .anchoredDraggable( + state = state.anchoredDraggableState, + orientation = orientation, + enabled = sheetSwipeEnabled + ) + .onSizeChanged { layoutSize -> + val newAnchors = calculateAnchors(layoutSize) + val newTarget = when (state.anchoredDraggableState.targetValue) { + SheetValue.Hidden, SheetValue.PartiallyExpanded -> SheetValue.PartiallyExpanded + SheetValue.Expanded -> { + if (newAnchors.hasAnchorFor(SheetValue.Expanded)) SheetValue.Expanded else SheetValue.PartiallyExpanded + } + } + state.anchoredDraggableState.updateAnchors(newAnchors, newTarget) + }, + shape = shape, + color = containerColor, + contentColor = contentColor, + tonalElevation = tonalElevation, + shadowElevation = shadowElevation, + ) { + Column(Modifier.fillMaxWidth()) { + if (dragHandle != null) { + val partialExpandActionLabel = + "Partial Expand" + val dismissActionLabel = "Dismiss" + val expandActionLabel = "Expand" + Box( + Modifier + .align(Alignment.CenterHorizontally) + .semantics(mergeDescendants = true) { + with(state) { + // Provides semantics to interact with the bottomsheet if there is more + // than one anchor to swipe to and swiping is enabled. + if (anchoredDraggableState.anchors.size > 1 && sheetSwipeEnabled) { + if (currentValue == SheetValue.PartiallyExpanded) { + expand(expandActionLabel) { + scope.launch { expand() }; true + } + } else { + collapse(partialExpandActionLabel) { + scope.launch { partialExpand() }; true + } + } + if (!state.skipHiddenState) { + dismiss(dismissActionLabel) { + scope.launch { hide() } + true + } + } + } + } + }, + ) { + dragHandle() + } + } + content() + } + } +} + +/** + * [DraggableAnchorsConfig] stores a mutable configuration anchors, comprised of values of [T] and + * corresponding [Float] positions. This [DraggableAnchorsConfig] is used to construct an immutable + * [DraggableAnchors] instance later on. + */ +@ExperimentalFoundationApi +class DraggableAnchorsConfig { + + internal val anchors = mutableMapOf() + + /** + * Set the anchor position for [this] anchor. + * + * @param position The anchor position. + */ + @Suppress("BuilderSetStyle") + infix fun T.at(position: Float) { + anchors[this] = position + } +} + +/** + * Create a new [DraggableAnchors] instance using a builder function. + * + * @param T The type of the anchor values. + * @param builder A function with a [DraggableAnchorsConfig] that offers APIs to configure anchors + * @return A new [DraggableAnchors] instance with the anchor positions set by the `builder` + * function. + */ +@OptIn(ExperimentalFoundationApi::class) +@ExperimentalMaterial3Api +@SuppressWarnings("FunctionName") +internal fun DraggableAnchors( + builder: DraggableAnchorsConfig.() -> Unit +): DraggableAnchors = MapDraggableAnchors(DraggableAnchorsConfig().apply(builder).anchors) + +private class MapDraggableAnchors(private val anchors: Map) : DraggableAnchors { + + override fun positionOf(value: T): Float = anchors[value] ?: Float.NaN + override fun hasAnchorFor(value: T) = anchors.containsKey(value) + + override fun closestAnchor(position: Float): T? = anchors.minByOrNull { + abs(position - it.value) + }?.key + + override fun closestAnchor( + position: Float, + searchUpwards: Boolean + ): T? { + return anchors.minByOrNull { (_, anchor) -> + val delta = if (searchUpwards) anchor - position else position - anchor + if (delta < 0) Float.POSITIVE_INFINITY else delta + }?.key + } + + override fun minAnchor() = anchors.values.minOrNull() ?: Float.NaN + + override fun maxAnchor() = anchors.values.maxOrNull() ?: Float.NaN + + override val size: Int + get() = anchors.size + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is MapDraggableAnchors<*>) return false + + return anchors == other.anchors + } + + override fun hashCode() = 31 * anchors.hashCode() + + override fun toString() = "MapDraggableAnchors($anchors)" +} + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@SuppressWarnings("FunctionName") +internal fun ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection( + sheetState: CustomSheetState, + orientation: Orientation, + onFling: (velocity: Float) -> Unit +): NestedScrollConnection = object : NestedScrollConnection { + override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { + val delta = available.toFloat() + return if (delta < 0 && source == NestedScrollSource.Drag) { + sheetState.anchoredDraggableState.dispatchRawDelta(delta).toOffset() + } else { + Offset.Zero + } + } + + override fun onPostScroll( + consumed: Offset, + available: Offset, + source: NestedScrollSource + ): Offset { + return if (source == NestedScrollSource.Drag) { + sheetState.anchoredDraggableState.dispatchRawDelta(available.toFloat()).toOffset() + } else { + Offset.Zero + } + } + + override suspend fun onPreFling(available: Velocity): Velocity { + val toFling = available.toFloat() + val currentOffset = sheetState.requireOffset() + val minAnchor = sheetState.anchoredDraggableState.anchors.minAnchor() + return if (toFling < 0 && currentOffset > minAnchor) { + onFling(toFling) + // since we go to the anchor with tween settling, consume all for the best UX + available + } else { + Velocity.Zero + } + } + + override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity { + onFling(available.toFloat()) + return available + } + + private fun Float.toOffset(): Offset = Offset( + x = if (orientation == Orientation.Horizontal) this else 0f, + y = if (orientation == Orientation.Vertical) this else 0f + ) + + @JvmName("velocityToFloat") + private fun Velocity.toFloat() = if (orientation == Orientation.Horizontal) x else y + + @JvmName("offsetToFloat") + private fun Offset.toFloat(): Float = if (orientation == Orientation.Horizontal) x else y +} + +/** + * State of the [BottomSheetScaffold] composable. + * + * @param bottomSheetState the state of the persistent bottom sheet + * @param snackbarHostState the [SnackbarHostState] used to show snackbars inside the scaffold + */ +@ExperimentalMaterial3Api +@Stable +@SuppressWarnings("UseDataClass") +class BottomSheetScaffoldState( + val bottomSheetState: CustomSheetState, + val snackbarHostState: SnackbarHostState +) + +/** + * Create and [remember] a [BottomSheetScaffoldState]. + * + * @param bottomSheetState the state of the standard bottom sheet. See + * [rememberStandardBottomSheetState] + * @param snackbarHostState the [SnackbarHostState] used to show snackbars inside the scaffold + */ +@Composable +@ExperimentalMaterial3Api +fun rememberBottomSheetScaffoldState( + bottomSheetState: CustomSheetState = rememberStandardBottomSheetState(), + snackbarHostState: SnackbarHostState = remember { SnackbarHostState() } +): BottomSheetScaffoldState { + return remember(bottomSheetState, snackbarHostState) { + BottomSheetScaffoldState( + bottomSheetState = bottomSheetState, + snackbarHostState = snackbarHostState + ) + } +} + +/** + * Create and [remember] a [SheetState] for [BottomSheetScaffold]. + * + * @param initialValue the initial value of the state. Should be either [PartiallyExpanded] or + * [Expanded] if [skipHiddenState] is true + * @param confirmValueChange optional callback invoked to confirm or veto a pending state change + * @param [skipHiddenState] whether Hidden state is skipped for [BottomSheetScaffold] + */ +@Composable +@ExperimentalMaterial3Api +fun rememberStandardBottomSheetState( + initialValue: SheetValue = PartiallyExpanded, + confirmValueChange: (SheetValue) -> Boolean = { true }, + skipHiddenState: Boolean = true, +) = rememberSheetState(false, confirmValueChange, initialValue, skipHiddenState) + +@Composable +@ExperimentalMaterial3Api +internal fun rememberSheetState( + skipPartiallyExpanded: Boolean = false, + confirmValueChange: (SheetValue) -> Boolean = { true }, + initialValue: SheetValue = SheetValue.Hidden, + skipHiddenState: Boolean = false, +): CustomSheetState { + + val density = LocalDensity.current + return rememberSaveable( + skipPartiallyExpanded, confirmValueChange, + saver = CustomSheetState.Saver( + skipPartiallyExpanded = skipPartiallyExpanded, + confirmValueChange = confirmValueChange, + density = density + ) + ) { + CustomSheetState( + skipPartiallyExpanded, + density, + initialValue, + confirmValueChange, + skipHiddenState + ) + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt new file mode 100644 index 0000000000..9a2ff713db --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/bottomsheet/CustomSheetState.kt @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components.bottomsheet + +import androidx.compose.animation.core.SpringSpec +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.gestures.animateTo +import androidx.compose.foundation.gestures.snapTo +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetValue +import androidx.compose.material3.SheetValue.Expanded +import androidx.compose.material3.SheetValue.Hidden +import androidx.compose.material3.SheetValue.PartiallyExpanded +import androidx.compose.runtime.Stable +import androidx.compose.runtime.saveable.Saver +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.CancellationException + +@OptIn(ExperimentalFoundationApi::class) +@Stable +@ExperimentalMaterial3Api +class CustomSheetState @Deprecated( + message = "This constructor is deprecated. " + + "Please use the constructor that provides a [Density]", + replaceWith = ReplaceWith( + "SheetState(" + + "skipPartiallyExpanded, LocalDensity.current, initialValue, " + + "confirmValueChange, skipHiddenState)" + ) +) constructor( + internal val skipPartiallyExpanded: Boolean, + initialValue: SheetValue = Hidden, + confirmValueChange: (SheetValue) -> Boolean = { true }, + internal val skipHiddenState: Boolean = false, +) { + + /** + * State of a sheet composable, such as [ModalBottomSheet] + * + * Contains states relating to its swipe position as well as animations between state values. + * + * @param skipPartiallyExpanded Whether the partially expanded state, if the sheet is large + * enough, should be skipped. If true, the sheet will always expand to the [Expanded] state and move + * to the [Hidden] state if available when hiding the sheet, either programmatically or by user + * interaction. + * @param density The density that this state can use to convert values to and from dp. + * @param initialValue The initial value of the state. + * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change. + * @param skipHiddenState Whether the hidden state should be skipped. If true, the sheet will always + * expand to the [Expanded] state and move to the [PartiallyExpanded] if available, either + * programmatically or by user interaction. + */ + @ExperimentalMaterial3Api + @Suppress("Deprecation") + constructor( + skipPartiallyExpanded: Boolean, + density: Density, + initialValue: SheetValue = Hidden, + confirmValueChange: (SheetValue) -> Boolean = { true }, + skipHiddenState: Boolean = false, + ) : this(skipPartiallyExpanded, initialValue, confirmValueChange, skipHiddenState) { + this.density = density + } + init { + if (skipPartiallyExpanded) { + require(initialValue != PartiallyExpanded) { + "The initial value must not be set to PartiallyExpanded if skipPartiallyExpanded " + + "is set to true." + } + } + if (skipHiddenState) { + require(initialValue != Hidden) { + "The initial value must not be set to Hidden if skipHiddenState is set to true." + } + } + } + + /** + * The current value of the state. + * + * If no swipe or animation is in progress, this corresponds to the state the bottom sheet is + * currently in. If a swipe or an animation is in progress, this corresponds the state the sheet + * was in before the swipe or animation started. + */ + + val currentValue: SheetValue get() = anchoredDraggableState.currentValue + + /** + * The target value of the bottom sheet state. + * + * If a swipe is in progress, this is the value that the sheet would animate to if the + * swipe finishes. If an animation is running, this is the target value of that animation. + * Finally, if no swipe or animation is in progress, this is the same as the [currentValue]. + */ + val targetValue: SheetValue get() = anchoredDraggableState.targetValue + + /** + * Whether the modal bottom sheet is visible. + */ + val isVisible: Boolean + get() = anchoredDraggableState.currentValue != Hidden + + /** + * Require the current offset (in pixels) of the bottom sheet. + * + * The offset will be initialized during the first measurement phase of the provided sheet + * content. + * + * These are the phases: + * Composition { -> Effects } -> Layout { Measurement -> Placement } -> Drawing + * + * During the first composition, an [IllegalStateException] is thrown. In subsequent + * compositions, the offset will be derived from the anchors of the previous pass. Always prefer + * accessing the offset from a LaunchedEffect as it will be scheduled to be executed the next + * frame, after layout. + * + * @throws IllegalStateException If the offset has not been initialized yet + */ + fun requireOffset(): Float = anchoredDraggableState.requireOffset() + + fun getOffset(): Float? = anchoredDraggableState.offset.takeIf { !it.isNaN() } + + /** + * Whether the sheet has an expanded state defined. + */ + + val hasExpandedState: Boolean + get() = anchoredDraggableState.anchors.hasAnchorFor(Expanded) + + /** + * Whether the modal bottom sheet has a partially expanded state defined. + */ + val hasPartiallyExpandedState: Boolean + get() = anchoredDraggableState.anchors.hasAnchorFor(PartiallyExpanded) + + /** + * Fully expand the bottom sheet with animation and suspend until it is fully expanded or + * animation has been cancelled. + * * + * @throws [CancellationException] if the animation is interrupted + */ + suspend fun expand() { + anchoredDraggableState.animateTo(Expanded) + } + + /** + * Animate the bottom sheet and suspend until it is partially expanded or animation has been + * cancelled. + * @throws [CancellationException] if the animation is interrupted + * @throws [IllegalStateException] if [skipPartiallyExpanded] is set to true + */ + suspend fun partialExpand() { + check(!skipPartiallyExpanded) { + "Attempted to animate to partial expanded when skipPartiallyExpanded was enabled. Set" + + " skipPartiallyExpanded to false to use this function." + } + animateTo(PartiallyExpanded) + } + + /** + * Expand the bottom sheet with animation and suspend until it is [PartiallyExpanded] if defined + * else [Expanded]. + * @throws [CancellationException] if the animation is interrupted + */ + suspend fun show() { + val targetValue = when { + hasPartiallyExpandedState -> PartiallyExpanded + else -> Expanded + } + animateTo(targetValue) + } + + /** + * Hide the bottom sheet with animation and suspend until it is fully hidden or animation has + * been cancelled. + * @throws [CancellationException] if the animation is interrupted + */ + suspend fun hide() { + check(!skipHiddenState) { + "Attempted to animate to hidden when skipHiddenState was enabled. Set skipHiddenState" + + " to false to use this function." + } + animateTo(Hidden) + } + + /** + * Animate to a [targetValue]. + * If the [targetValue] is not in the set of anchors, the [currentValue] will be updated to the + * [targetValue] without updating the offset. + * + * @throws CancellationException if the interaction interrupted by another interaction like a + * gesture interaction or another programmatic interaction like a [animateTo] or [snapTo] call. + * + * @param targetValue The target value of the animation + * @param velocity The velocity of the animation + */ + @OptIn(ExperimentalFoundationApi::class) + internal suspend fun animateTo( + targetValue: SheetValue, + velocity: Float = anchoredDraggableState.lastVelocity + ) { + anchoredDraggableState.animateTo(targetValue, velocity) + } + + /** + * Snap to a [targetValue] without any animation. + * + * @throws CancellationException if the interaction interrupted by another interaction like a + * gesture interaction or another programmatic interaction like a [animateTo] or [snapTo] call. + * + * @param targetValue The target value of the animation + */ + @OptIn(ExperimentalFoundationApi::class) + internal suspend fun snapTo(targetValue: SheetValue) { + anchoredDraggableState.snapTo(targetValue) + } + + /** + * Find the closest anchor taking into account the velocity and settle at it with an animation. + */ + @OptIn(ExperimentalFoundationApi::class) + internal suspend fun settle(velocity: Float) { + anchoredDraggableState.settle(velocity) + } + + @OptIn(ExperimentalFoundationApi::class) + internal var anchoredDraggableState = androidx.compose.foundation.gestures.AnchoredDraggableState( + initialValue = initialValue, + animationSpec = AnchoredDraggableDefaults.AnimationSpec, + confirmValueChange = confirmValueChange, + positionalThreshold = { with(requireDensity()) { 56.dp.toPx() } }, + velocityThreshold = { with(requireDensity()) { 125.dp.toPx() } } + ) + + @OptIn(ExperimentalFoundationApi::class) + internal val offset: Float? get() = anchoredDraggableState.offset + + internal var density: Density? = null + private fun requireDensity() = requireNotNull(density) { + "SheetState did not have a density attached. Are you using SheetState with " + + "BottomSheetScaffold or ModalBottomSheet component?" + } + + companion object { + /** + * The default [Saver] implementation for [SheetState]. + */ + @SuppressWarnings("FunctionName") + fun Saver( + skipPartiallyExpanded: Boolean, + confirmValueChange: (SheetValue) -> Boolean, + density: Density + ) = Saver( + save = { it.currentValue }, + restore = { savedValue -> + CustomSheetState(skipPartiallyExpanded, density, savedValue, confirmValueChange) + } + ) + + /** + * The default [Saver] implementation for [SheetState]. + */ + @Deprecated( + message = "This function is deprecated. Please use the overload where Density is" + + " provided.", + replaceWith = ReplaceWith( + "Saver(skipPartiallyExpanded, confirmValueChange, LocalDensity.current)" + ) + ) + @Suppress("Deprecation", "FunctionName") + fun Saver( + skipPartiallyExpanded: Boolean, + confirmValueChange: (SheetValue) -> Boolean + ) = Saver( + save = { it.currentValue }, + restore = { savedValue -> + CustomSheetState(skipPartiallyExpanded, savedValue, confirmValueChange) + } + ) + } +} + +@Stable +@ExperimentalMaterial3Api +internal object AnchoredDraggableDefaults { + /** + * The default animation used by [AnchoredDraggableState]. + */ + @get:ExperimentalMaterial3Api + @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET") + @ExperimentalMaterial3Api + val AnimationSpec = SpringSpec() +} diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index e078b634d1..819679082b 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -60,5 +60,11 @@ enum class FeatureFlags( title = "Element call in rooms", description = "Allow user to start or join a call in a room", defaultValue = false, + ), + Mentions( + key = "feature.mentions", + title = "Mentions", + description = "Type `@` to get mention suggestions and insert them", + defaultValue = false, ) } diff --git a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt index 87a797d13a..7ff59c7512 100644 --- a/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt +++ b/libraries/featureflag/impl/src/main/kotlin/io/element/android/libraries/featureflag/impl/StaticFeatureFlagProvider.kt @@ -38,6 +38,7 @@ class StaticFeatureFlagProvider @Inject constructor() : FeatureFlags.VoiceMessages -> false FeatureFlags.PinUnlock -> false FeatureFlags.InRoomCalls -> false + FeatureFlags.Mentions -> false } } else { false 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 1cce3f03b7..23db1ef00f 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 @@ -130,6 +130,8 @@ interface MatrixRoom : Closeable { suspend fun canUserSendMessage(userId: UserId, type: MessageEventType): Result + suspend fun canUserTriggerRoomNotification(userId: UserId): Result + suspend fun updateAvatar(mimeType: String, data: ByteArray): Result suspend fun removeAvatar(): Result diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentSessionIdHolder.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentSessionIdHolder.kt new file mode 100644 index 0000000000..64e618ccdf --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/CurrentSessionIdHolder.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.api.user + +import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.di.SingleIn +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.matrix.api.core.SessionId +import javax.inject.Inject + +@SingleIn(SessionScope::class) +class CurrentSessionIdHolder @Inject constructor(matrixClient: MatrixClient) { + val current = matrixClient.sessionId + + fun isCurrentSession(sessionId: SessionId?): Boolean = current == sessionId +} 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 d45508e424..44f095a38c 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 @@ -349,6 +349,12 @@ class RustMatrixRoom( } } + override suspend fun canUserTriggerRoomNotification(userId: UserId): Result { + return runCatching { + innerRoom.canUserTriggerRoomNotification(userId.value) + } + } + override suspend fun sendImage(file: File, thumbnailFile: File, imageInfo: ImageInfo, progressCallback: ProgressCallback?): Result { return sendAttachment(listOf(file, thumbnailFile)) { innerRoom.sendImage(file.path, thumbnailFile.path, imageInfo.map(), 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 844a049a40..a2adf0b0bb 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 @@ -71,6 +71,7 @@ class FakeMatrixRoom( override val alternativeAliases: List = emptyList(), override val isPublic: Boolean = true, override val isDirect: Boolean = false, + override val isOneToOne: Boolean = false, override val joinedMemberCount: Long = 123L, override val activeMemberCount: Long = 234L, val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(), @@ -106,6 +107,7 @@ class FakeMatrixRoom( private var progressCallbackValues = emptyList>() private var generateWidgetWebViewUrlResult = Result.success("https://call.element.io") private var getWidgetDriverResult: Result = Result.success(FakeWidgetDriver()) + private var canUserTriggerRoomNotificationResult: Result = Result.success(true) val editMessageCalls = mutableListOf>() var sendMediaCount = 0 @@ -270,6 +272,10 @@ class FakeMatrixRoom( return canSendEventResults[type] ?: Result.failure(IllegalStateException("No fake answer")) } + override suspend fun canUserTriggerRoomNotification(userId: UserId): Result { + return canUserTriggerRoomNotificationResult + } + override suspend fun sendImage( file: File, thumbnailFile: File, @@ -434,6 +440,10 @@ class FakeMatrixRoom( canSendEventResults[type] = result } + fun givenCanTriggerRoomNotification(result: Result) { + canUserTriggerRoomNotificationResult = result + } + fun givenIgnoreResult(result: Result) { ignoreResult = result } 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 73c1764de2..adb81019d6 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 @@ -37,6 +37,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -75,6 +76,7 @@ import io.element.android.libraries.textcomposer.model.Message import io.element.android.libraries.textcomposer.model.MessageComposerMode import io.element.android.libraries.textcomposer.model.PressEvent import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent +import io.element.android.libraries.textcomposer.model.Suggestion import io.element.android.libraries.textcomposer.model.VoiceMessageState import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.ui.strings.CommonStrings @@ -83,6 +85,7 @@ import io.element.android.wysiwyg.compose.RichTextEditorState import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlin.time.Duration.Companion.seconds +import uniffi.wysiwyg_composer.MenuAction @Composable fun TextComposer( @@ -104,6 +107,7 @@ fun TextComposer( onSendVoiceMessage: () -> Unit = {}, onDeleteVoiceMessage: () -> Unit = {}, onError: (Throwable) -> Unit = {}, + onSuggestionReceived: (Suggestion?) -> Unit = {}, ) { val onSendClicked = { val html = if (enableTextFormatting) state.messageHtml else null @@ -122,27 +126,31 @@ fun TextComposer( .fillMaxSize() .height(IntrinsicSize.Min) - val composerOptionsButton = @Composable { - ComposerOptionsButton( - modifier = Modifier - .size(48.dp), - onClick = onAddAttachment - ) + val composerOptionsButton: @Composable () -> Unit = remember { + @Composable { + ComposerOptionsButton( + modifier = Modifier + .size(48.dp), + onClick = onAddAttachment + ) + } } - val textInput = @Composable { - TextInput( - state = state, - subcomposing = subcomposing, - placeholder = if (composerMode.inThread) { - stringResource(id = CommonStrings.action_reply_in_thread) - } else { - stringResource(id = R.string.rich_text_editor_composer_placeholder) - }, - composerMode = composerMode, - onResetComposerMode = onResetComposerMode, - onError = onError, - ) + val textInput: @Composable () -> Unit = remember(state, subcomposing, composerMode, onResetComposerMode, onError) { + @Composable { + TextInput( + state = state, + subcomposing = subcomposing, + placeholder = if (composerMode.inThread) { + stringResource(id = CommonStrings.action_reply_in_thread) + } else { + stringResource(id = R.string.rich_text_editor_composer_placeholder) + }, + composerMode = composerMode, + onResetComposerMode = onResetComposerMode, + onError = onError, + ) + } } val canSendMessage by remember { derivedStateOf { state.messageHtml.isNotEmpty() } } @@ -249,6 +257,16 @@ fun TextComposer( SoftKeyboardEffect(showTextFormatting, onRequestFocus) { it } } + + val menuAction = state.menuAction + LaunchedEffect(menuAction) { + if (menuAction is MenuAction.Suggestion) { + val suggestion = Suggestion(menuAction.suggestionPattern) + onSuggestionReceived(suggestion) + } else { + onSuggestionReceived(null) + } + } } @Composable diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/Suggestion.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/Suggestion.kt new file mode 100644 index 0000000000..e3174f74d0 --- /dev/null +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/model/Suggestion.kt @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.textcomposer.model + +import uniffi.wysiwyg_composer.PatternKey +import uniffi.wysiwyg_composer.SuggestionPattern + +data class Suggestion( + val start: Int, + val end: Int, + val type: SuggestionType, + val text: String, +) { + constructor(suggestion: SuggestionPattern): this( + suggestion.start.toInt(), + suggestion.end.toInt(), + SuggestionType.fromPatternKey(suggestion.key), + suggestion.text, + ) +} + +enum class SuggestionType { + Mention, + Command, + Room; + + companion object { + fun fromPatternKey(key: PatternKey): SuggestionType { + return when (key) { + PatternKey.AT -> Mention + PatternKey.SLASH -> Command + PatternKey.HASH -> Room + } + } + } +} diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt index f4bd7175fd..6ed58b61e8 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistArchitectureTest.kt @@ -35,6 +35,7 @@ class KonsistArchitectureTest { .withNameEndingWith("State") .withoutName( "CameraPositionState", + "CustomSheetState", ) .constructors .parameters diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-D-3_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-D-3_3_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..6a628f5fea --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-D-3_3_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9a2c753096d4b2a363e5e0811e3017e3a20fd1c23d2ad26133434c651c4c4cb +size 18686 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-N-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-N-3_4_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..fc371b38fd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.mentions_null_MentionSuggestionsPickerView_-N-3_4_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e52de245ef2c4a423849ab0ff592109e51c2c25e0cbc1335812a37986c27b06 +size 18411 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-3_3_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-4_4_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-3_3_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-D-4_4_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-3_4_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-4_5_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-3_4_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_AttachmentSourcePickerMenu-N-4_5_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-4_4_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-5_5_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-4_4_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-D-5_5_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-4_5_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-5_6_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-4_5_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerView-N-5_6_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-5_5_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-6_6_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-5_5_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-D-6_6_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-5_6_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-6_7_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-5_6_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.messagecomposer_null_MessageComposerViewVoice-N-6_7_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-6_6_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-D-7_7_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-6_7_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.report_null_ReportMessageView-N-7_8_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-25_25_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-26_26_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-25_25_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-D-26_26_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-25_26_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-26_27_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-25_26_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiItem-N-26_27_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-26_26_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-27_27_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-26_26_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-D-27_27_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-26_27_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-27_28_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-26_27_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.customreaction_null_EmojiPicker-N-27_28_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-27_27_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-D-28_28_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-27_28_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemAudioView-N-28_29_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-28_28_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-29_29_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-28_28_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-D-29_29_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-28_29_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-29_30_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-28_29_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemEncryptedView-N-29_30_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-29_29_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-D-30_30_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-29_30_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemFileView-N-30_31_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-30_30_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-D-31_31_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-30_31_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemImageView-N-31_32_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-31_31_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-32_32_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-31_31_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-D-32_32_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-31_32_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-32_33_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-31_32_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemInformativeView-N-32_33_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-32_32_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-D-33_33_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-32_33_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemLocationView-N-33_34_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-34_34_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-D-35_35_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-34_35_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollCreatorView-N-35_36_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-33_33_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-D-34_34_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-33_34_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemPollView-N-34_35_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-35_35_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-36_36_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-35_35_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-D-36_36_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-35_36_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-36_37_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-35_36_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemRedactedView-N-36_37_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-36_36_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-37_37_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-36_36_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-D-37_37_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-36_37_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-37_38_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-36_37_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemStateView-N-37_38_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-37_37_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-D-38_38_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-37_38_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemTextView-N-38_39_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-38_38_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-39_39_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-38_38_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-D-39_39_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-38_39_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-39_40_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-38_39_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemUnknownView-N-39_40_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-39_39_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-D-40_40_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-39_40_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVideoView-N-40_41_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-40_40_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-D-41_41_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-40_41_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceView-N-41_42_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-41_41_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-42_42_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-41_41_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-D-42_42_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-41_42_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-42_43_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-41_42_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.event_null_TimelineItemVoiceViewUnified-N-42_43_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-42_42_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-43_43_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-42_42_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-D-43_43_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-42_43_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-43_44_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-42_43_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.group_null_GroupHeaderView-N-43_44_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_15,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_15,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_15,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_16,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_16,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_16,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_17,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_17,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_17,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_17,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_18,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_18,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_18,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_18,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_19,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_19,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_19,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_19,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_20,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_20,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_20,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_20,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_21,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_21,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_21,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_21,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-43_43_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-D-44_44_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_15,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_15,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_15,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_16,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_16,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_16,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_17,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_17,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_17,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_17,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_18,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_18,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_18,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_18,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_19,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_19,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_19,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_19,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_20,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_20,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_20,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_20,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_21,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_21,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_21,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_21,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-43_44_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.html_null_HtmlDocument-N-44_45_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-44_44_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-45_45_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-44_44_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-D-45_45_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-44_45_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-45_46_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-44_45_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.reactionsummary_null_SheetContent-N-45_46_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-45_45_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-D-46_46_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-45_46_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_null_RetrySendMessageMenu-N-46_47_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-46_46_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-47_47_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-46_46_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-D-47_47_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-46_47_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-47_48_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-46_47_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineEncryptedHistoryBannerView-N-47_48_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-47_47_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-D-48_48_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-47_48_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineItemDaySeparatorView-N-48_49_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-48_48_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-49_49_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-48_48_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-D-49_49_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-48_49_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-49_50_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-48_49_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_null_TimelineLoadingMoreIndicator-N-49_50_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_15,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_15,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_15,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-8_8_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-D-9_9_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_13,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_13,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_13,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_14,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_14,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_14,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_15,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_15,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_15,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-8_9_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageEventBubble-N-9_10_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-9_9_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-10_10_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-9_9_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-D-10_10_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-9_10_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-10_11_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-9_10_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessageStateEventContainer-N-10_11_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-11_11_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-12_12_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-11_11_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-D-12_12_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-11_12_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-12_13_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-11_12_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesAddReactionButton-N-12_13_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-10_10_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-D-11_11_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-10_11_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionButton-N-11_12_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-12_12_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-13_13_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-12_12_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-D-13_13_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-12_13_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-13_14_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-12_13_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_MessagesReactionExtraButtons-N-13_14_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-13_13_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-14_14_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-13_13_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-D-14_14_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-13_14_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-14_15_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-13_14_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_ReplySwipeIndicator-N-14_15_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-14_14_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-D-15_15_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-14_15_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineEventTimestampView-N-15_16_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-15_15_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-16_16_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-15_15_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-D-16_16_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-15_16_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-16_17_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-15_16_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRow-N-16_17_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-17_17_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-D-18_18_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-17_18_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowTimestamp-N-18_19_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-18_18_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-19_19_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-18_18_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-D-19_19_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-18_19_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-19_20_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-18_19_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithManyReactions-N-19_20_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-16_16_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-17_17_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-16_16_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-D-17_17_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-16_17_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-17_18_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-16_17_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemEventRowWithReply-N-17_18_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-19_19_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-20_20_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-19_19_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-D-20_20_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-19_20_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-20_21_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-19_20_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsLayout-N-20_21_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-20_20_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-21_21_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-20_20_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-D-21_21_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-20_21_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-21_22_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-20_21_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsView-N-21_22_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-21_21_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-22_22_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-21_21_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-D-22_22_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-21_22_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-22_23_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-21_22_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewFew-N-22_23_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-22_22_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-23_23_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-22_22_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-D-23_23_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-22_23_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-23_24_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-22_23_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewIncoming-N-23_24_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-23_23_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-24_24_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-23_23_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-D-24_24_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-23_24_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-24_25_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-23_24_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemReactionsViewOutgoing-N-24_25_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-24_24_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-25_25_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-24_24_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-D-25_25_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-24_25_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-25_26_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-24_25_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_null_TimelineItemStateEventRow-N-25_26_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-49_49_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-50_50_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-49_49_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-D-50_50_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-49_50_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-50_51_null,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-49_50_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_null_EventDebugInfoView-N-50_51_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-7_7_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-D-8_8_null_9,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_0,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_1,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_10,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_10,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_10,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_11,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_11,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_11,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_12,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_12,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_12,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_2,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_3,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_4,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_5,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_6,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_7,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_8,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_9,NEXUS_5,1.0,en].png similarity index 100% rename from tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-7_8_null_9,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_null_TimelineView-N-8_9_null_9,NEXUS_5,1.0,en].png diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 5144dc191d..547dfc2d0b 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -112,6 +112,7 @@ "name": ":features:messages:impl", "includeRegex": [ "screen_room_.*", + "screen\\.room\\..*", "screen_dm_details_.*", "room_timeline_state_changes" ],