diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 06643f616c..219ec2167a 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -41,6 +41,7 @@ import dagger.assisted.AssistedInject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.anvilannotations.ContributesNode import io.element.android.appnav.loggedin.LoggedInNode +import io.element.android.appnav.loggedin.SendQueues import io.element.android.appnav.room.RoomFlowNode import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode @@ -102,6 +103,7 @@ class LoggedInFlowNode @AssistedInject constructor( private val roomDirectoryEntryPoint: RoomDirectoryEntryPoint, private val shareEntryPoint: ShareEntryPoint, private val matrixClient: MatrixClient, + private val sendingQueue: SendQueues, snackbarDispatcher: SnackbarDispatcher, ) : BaseFlowNode( backstack = BackStack( @@ -157,6 +159,11 @@ class LoggedInFlowNode @AssistedInject constructor( } ) observeSyncStateAndNetworkStatus() + setupSendingQueue() + } + + private fun setupSendingQueue() { + sendingQueue.launchIn(lifecycleScope) } @OptIn(FlowPreview::class) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendQueues.kt b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendQueues.kt new file mode 100644 index 0000000000..c03ce947f8 --- /dev/null +++ b/appnav/src/main/kotlin/io/element/android/appnav/loggedin/SendQueues.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 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.appnav.loggedin + +import androidx.annotation.VisibleForTesting +import io.element.android.features.networkmonitor.api.NetworkMonitor +import io.element.android.features.networkmonitor.api.NetworkStatus +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.RoomId +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import javax.inject.Inject + +@VisibleForTesting +const val SEND_QUEUES_RETRY_DELAY_MILLIS = 1500L + +@SingleIn(SessionScope::class) +class SendQueues @Inject constructor( + private val matrixClient: MatrixClient, + private val networkMonitor: NetworkMonitor, +) { + fun launchIn(coroutineScope: CoroutineScope) { + networkMonitor.connectivity + .onEach { networkStatus -> + matrixClient.setAllSendQueuesEnabled(enabled = networkStatus == NetworkStatus.Online) + } + .launchIn(coroutineScope) + + matrixClient.sendQueueDisabledFlow() + .onEach { roomId: RoomId -> + Timber.d("Send queue disabled for room $roomId") + if (networkMonitor.connectivity.value == NetworkStatus.Online) { + delay(SEND_QUEUES_RETRY_DELAY_MILLIS) + matrixClient.getRoom(roomId)?.use { room -> + room.setSendQueueEnabled(enabled = true) + } + } + } + .launchIn(coroutineScope) + } +} diff --git a/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendQueuesTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendQueuesTest.kt new file mode 100644 index 0000000000..c2521827fe --- /dev/null +++ b/appnav/src/test/kotlin/io/element/android/appnav/loggedin/SendQueuesTest.kt @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 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.appnav.loggedin + +import io.element.android.features.networkmonitor.api.NetworkStatus +import io.element.android.features.networkmonitor.test.FakeNetworkMonitor +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.test.FakeMatrixClient +import io.element.android.libraries.matrix.test.room.FakeMatrixRoom +import io.element.android.tests.testutils.lambda.assert +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.test.advanceTimeBy +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) class SendQueuesTest { + private val matrixClient = FakeMatrixClient() + private val room = FakeMatrixRoom() + private val networkMonitor = FakeNetworkMonitor() + private val sut = SendQueues(matrixClient, networkMonitor) + + @Test + fun `test network status online and sending queue failed`() = runTest { + val sendQueueDisabledFlow = MutableSharedFlow(replay = 1) + val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> } + matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow + matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda + matrixClient.givenGetRoomResult(room.roomId, room) + + val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> } + room.setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda + + sut.launchIn(backgroundScope) + + sendQueueDisabledFlow.emit(room.roomId) + advanceTimeBy(SEND_QUEUES_RETRY_DELAY_MILLIS) + runCurrent() + + assert(setAllSendQueuesEnabledLambda) + .isCalledOnce() + .with(value(true)) + + assert(setRoomSendQueueEnabledLambda) + .isCalledOnce() + .with(value(true)) + } + + @Test + fun `test network status offline and sending queue failed`() = runTest { + val sendQueueDisabledFlow = MutableSharedFlow(replay = 1) + + val setAllSendQueuesEnabledLambda = lambdaRecorder { _: Boolean -> } + matrixClient.sendQueueDisabledFlow = sendQueueDisabledFlow + matrixClient.setAllSendQueuesEnabledLambda = setAllSendQueuesEnabledLambda + networkMonitor.connectivity.value = NetworkStatus.Offline + matrixClient.givenGetRoomResult(room.roomId, room) + + val setRoomSendQueueEnabledLambda = lambdaRecorder { _: Boolean -> } + room.setSendQueueEnabledLambda = setRoomSendQueueEnabledLambda + + sut.launchIn(backgroundScope) + + sendQueueDisabledFlow.emit(room.roomId) + advanceTimeBy(SEND_QUEUES_RETRY_DELAY_MILLIS) + runCurrent() + + assert(setAllSendQueuesEnabledLambda) + .isCalledOnce() + .with(value(false)) + + assert(setRoomSendQueueEnabledLambda) + .isNeverCalled() + } + + @Test + fun `test network status getting offline and online`() = runTest { + val setEnableSendingQueueLambda = lambdaRecorder { _: Boolean -> } + matrixClient.setAllSendQueuesEnabledLambda = setEnableSendingQueueLambda + + sut.launchIn(backgroundScope) + advanceTimeBy(SEND_QUEUES_RETRY_DELAY_MILLIS) + networkMonitor.connectivity.value = NetworkStatus.Offline + advanceTimeBy(SEND_QUEUES_RETRY_DELAY_MILLIS) + networkMonitor.connectivity.value = NetworkStatus.Online + advanceTimeBy(SEND_QUEUES_RETRY_DELAY_MILLIS) + + assert(setEnableSendingQueueLambda) + .isCalledExactly(3) + .withSequence( + listOf(value(true)), + listOf(value(false)), + listOf(value(true)), + ) + } +} 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 72b05a62cc..065c81e407 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 @@ -46,7 +46,6 @@ import io.element.android.features.messages.impl.timeline.TimelineState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionPresenter import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryPresenter import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetPresenter -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuPresenter import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent @@ -107,7 +106,6 @@ class MessagesPresenter @AssistedInject constructor( private val actionListPresenter: ActionListPresenter, private val customReactionPresenter: CustomReactionPresenter, private val reactionSummaryPresenter: ReactionSummaryPresenter, - private val retrySendMenuPresenter: RetrySendMenuPresenter, private val readReceiptBottomSheetPresenter: ReadReceiptBottomSheetPresenter, private val networkMonitor: NetworkMonitor, private val snackbarDispatcher: SnackbarDispatcher, @@ -140,7 +138,6 @@ class MessagesPresenter @AssistedInject constructor( val actionListState = actionListPresenter.present() val customReactionState = customReactionPresenter.present() val reactionSummaryState = reactionSummaryPresenter.present() - val retryState = retrySendMenuPresenter.present() val readReceiptBottomSheetState = readReceiptBottomSheetPresenter.present() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() @@ -231,7 +228,6 @@ class MessagesPresenter @AssistedInject constructor( actionListState = actionListState, customReactionState = customReactionState, reactionSummaryState = reactionSummaryState, - retrySendMenuState = retryState, readReceiptBottomSheetState = readReceiptBottomSheetState, hasNetworkConnection = networkConnectionStatus == NetworkStatus.Online, snackbarMessage = snackbarMessage, @@ -309,11 +305,9 @@ class MessagesPresenter @AssistedInject constructor( } private suspend fun handleActionRedact(event: TimelineItem.Event) { - if (event.failedToSend) { - // If the message hasn't been sent yet, just cancel it - event.transactionId?.let { room.cancelSend(it) } - } else if (event.eventId != null) { - room.redactEvent(event.eventId) + timelineController.invokeOnCurrentTimeline { + redactEvent(eventId = event.eventId, transactionId = event.transactionId, reason = null) + .onFailure { Timber.e(it) } } } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt index 5c6e1c7ffa..752aa94a9f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt @@ -23,7 +23,6 @@ import io.element.android.features.messages.impl.timeline.TimelineState import io.element.android.features.messages.impl.timeline.components.customreaction.CustomReactionState import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState import io.element.android.features.messages.impl.typing.TypingNotificationState import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState import io.element.android.libraries.architecture.AsyncData @@ -47,7 +46,6 @@ data class MessagesState( val actionListState: ActionListState, val customReactionState: CustomReactionState, val reactionSummaryState: ReactionSummaryState, - val retrySendMenuState: RetrySendMenuState, val readReceiptBottomSheetState: ReadReceiptBottomSheetState, val hasNetworkConnection: Boolean, val snackbarMessage: SnackbarMessage?, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt index fd00eba04b..526edfb1e7 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt @@ -31,8 +31,6 @@ import io.element.android.features.messages.impl.timeline.components.reactionsum import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryState import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.typing.aTypingNotificationState @@ -110,7 +108,6 @@ fun aMessagesState( // Render a focused event for an event with sender information displayed focusedEventIndex = 2, ), - retrySendMenuState: RetrySendMenuState = aRetrySendMenuState(), readReceiptBottomSheetState: ReadReceiptBottomSheetState = aReadReceiptBottomSheetState(), actionListState: ActionListState = anActionListState(), customReactionState: CustomReactionState = aCustomReactionState(), @@ -132,7 +129,6 @@ fun aMessagesState( voiceMessageComposerState = voiceMessageComposerState, typingNotificationState = aTypingNotificationState(), timelineState = timelineState, - retrySendMenuState = retrySendMenuState, readReceiptBottomSheetState = readReceiptBottomSheetState, actionListState = actionListState, customReactionState = customReactionState, 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 702dffd607..b9b9e7e4a7 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 @@ -74,8 +74,6 @@ import io.element.android.features.messages.impl.timeline.components.reactionsum import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryView import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheet import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuEvents -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMessageMenu import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerEvents import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessagePermissionRationaleDialog @@ -103,7 +101,6 @@ import io.element.android.libraries.designsystem.utils.OnLifecycleEvent import io.element.android.libraries.designsystem.utils.snackbar.SnackbarHost import io.element.android.libraries.designsystem.utils.snackbar.rememberSnackbarHostState import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import timber.log.Timber @@ -212,11 +209,6 @@ fun MessagesView( onMessageLongClick = ::onMessageLongClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onTimestampClick = { event -> - if (event.localSendState is LocalEventSendState.SendingFailed) { - state.retrySendMenuState.eventSink(RetrySendMenuEvents.EventSelected(event)) - } - }, onReactionClick = ::onEmojiReactionClick, onReactionLongClick = ::onEmojiReactionLongClick, onMoreReactionsClick = ::onMoreReactionsClick, @@ -258,7 +250,6 @@ fun MessagesView( ) ReactionSummaryView(state = state.reactionSummaryState) - RetrySendMessageMenu(state = state.retrySendMenuState) ReadReceiptBottomSheet( state = state.readReceiptBottomSheetState, onUserDataClick = onUserDataClick, @@ -319,7 +310,6 @@ private fun MessagesViewContent( onMoreReactionsClick: (TimelineItem.Event) -> Unit, onReadReceiptClick: (TimelineItem.Event) -> Unit, onMessageLongClick: (TimelineItem.Event) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onSendLocationClick: () -> Unit, onCreatePollClick: () -> Unit, onJoinCallClick: () -> Unit, @@ -387,7 +377,6 @@ private fun MessagesViewContent( onLinkClick = onLinkClick, onMessageClick = onMessageClick, onMessageLongClick = onMessageLongClick, - onTimestampClick = onTimestampClick, onSwipeToReply = onSwipeToReply, onReactionClick = onReactionClick, onReactionLongClick = onReactionLongClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index 609ab5c3b3..a3452d4422 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -181,7 +181,7 @@ class ActionListPresenter @Inject constructor( add(TimelineItemAction.Forward) } } - if (timelineItem.isMine && timelineItem.isTextMessage) { + if (timelineItem.isEditable) { add(TimelineItemAction.Edit) } if (timelineItem.content.canBeCopied()) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt index 19df330c54..370d7bc517 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelineView.kt @@ -83,7 +83,6 @@ fun TimelineView( onLinkClick: (String) -> Unit, onMessageClick: (TimelineItem.Event) -> Unit, onMessageLongClick: (TimelineItem.Event) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onSwipeToReply: (TimelineItem.Event) -> Unit, onReactionClick: (emoji: String, TimelineItem.Event) -> Unit, onReactionLongClick: (emoji: String, TimelineItem.Event) -> Unit, @@ -148,7 +147,6 @@ fun TimelineView( onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, - onTimestampClick = onTimestampClick, eventSink = state.eventSink, onSwipeToReply = onSwipeToReply, onJoinCallClick = onJoinCallClick, @@ -245,8 +243,8 @@ private fun BoxScope.TimelineScrollHelper( // Use inverse of canAutoScroll otherwise we might briefly see the before the scroll animation is triggered isVisible = !canAutoScroll || forceJumpToBottomVisibility || !isLive, modifier = Modifier - .align(Alignment.BottomEnd) - .padding(end = 24.dp, bottom = 12.dp), + .align(Alignment.BottomEnd) + .padding(end = 24.dp, bottom = 12.dp), onClick = { jumpToBottom() }, ) } @@ -273,8 +271,8 @@ private fun JumpToBottomButton( ) { Icon( modifier = Modifier - .size(24.dp) - .rotate(90f), + .size(24.dp) + .rotate(90f), imageVector = CompoundIcons.ArrowRight(), contentDescription = stringResource(id = CommonStrings.a11y_jump_to_bottom) ) @@ -301,7 +299,6 @@ internal fun TimelineViewPreview( onLinkClick = {}, onMessageClick = {}, onMessageLongClick = {}, - onTimestampClick = {}, onSwipeToReply = {}, onReactionClick = { _, _ -> }, onReactionLongClick = { _, _ -> }, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt index b6e6646c1e..8e482c020f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/ATimelineItemEventRow.kt @@ -45,6 +45,5 @@ internal fun ATimelineItemEventRow( onMoreReactionsClick = {}, onReadReceiptClick = {}, onSwipeToReply = {}, - onTimestampClick = {}, eventSink = {}, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt index 9206369a1e..5ec0262205 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineEventTimestampView.kt @@ -16,61 +16,34 @@ package io.element.android.features.messages.impl.timeline.components -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.material.ripple.rememberRipple import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.isEdited import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.ui.strings.CommonStrings -@OptIn(ExperimentalFoundationApi::class) @Composable fun TimelineEventTimestampView( - event: TimelineItem.Event, - onClick: () -> Unit, - onLongClick: () -> Unit, + formattedTime: String, + isMessageEdited: Boolean, modifier: Modifier = Modifier, ) { - val formattedTime = event.sentTime - val hasMessageSendingFailed = event.localSendState is LocalEventSendState.SendingFailed - val isMessageEdited = event.content.isEdited() - val tint = if (hasMessageSendingFailed) MaterialTheme.colorScheme.error else null - val clickModifier = if (hasMessageSendingFailed) { - Modifier.combinedClickable( - onClick = onClick, - onLongClick = onLongClick, - indication = rememberRipple(bounded = false), - interactionSource = remember { MutableInteractionSource() } - ) - } else { - Modifier - } Row( modifier = Modifier - .then(clickModifier) - // Add extra padding for touch target size .padding(PaddingValues(start = TimelineEventTimestampViewDefaults.spacing)) .then(modifier), verticalAlignment = Alignment.CenterVertically, @@ -79,35 +52,22 @@ fun TimelineEventTimestampView( Text( stringResource(CommonStrings.common_edited_suffix), style = ElementTheme.typography.fontBodyXsRegular, - color = tint ?: MaterialTheme.colorScheme.secondary, + color = MaterialTheme.colorScheme.secondary, ) Spacer(modifier = Modifier.width(4.dp)) } Text( formattedTime, style = ElementTheme.typography.fontBodyXsRegular, - color = tint ?: MaterialTheme.colorScheme.secondary, + color = MaterialTheme.colorScheme.secondary, ) - if (hasMessageSendingFailed && tint != null) { - Spacer(modifier = Modifier.width(2.dp)) - Icon( - imageVector = CompoundIcons.Error(), - contentDescription = stringResource(id = CommonStrings.common_sending_failed), - tint = tint, - modifier = Modifier.size(15.dp, 18.dp), - ) - } } } @PreviewsDayNight @Composable internal fun TimelineEventTimestampViewPreview(@PreviewParameter(TimelineItemEventForTimestampViewProvider::class) event: TimelineItem.Event) = ElementPreview { - TimelineEventTimestampView( - event = event, - onClick = {}, - onLongClick = {}, - ) + TimelineEventTimestampView(formattedTime = event.sentTime, isMessageEdited = event.content.isEdited()) } object TimelineEventTimestampViewDefaults { 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 993d872852..0c5dec2553 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 @@ -92,6 +92,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.features.messages.impl.timeline.model.event.canBeRepliedTo +import io.element.android.features.messages.impl.timeline.model.event.isEdited import io.element.android.features.messages.impl.timeline.model.eventId import io.element.android.features.messages.impl.timeline.model.metadata import io.element.android.libraries.designsystem.atomic.atoms.PlaceholderAtom @@ -130,7 +131,6 @@ fun TimelineItemEventRow( onLinkClick: (String) -> Unit, onUserDataClick: (UserId) -> Unit, inReplyToClick: (EventId) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onReactionClick: (emoji: String, eventId: TimelineItem.Event) -> Unit, onReactionLongClick: (emoji: String, eventId: TimelineItem.Event) -> Unit, onMoreReactionsClick: (eventId: TimelineItem.Event) -> Unit, @@ -190,7 +190,6 @@ fun TimelineItemEventRow( interactionSource = interactionSource, onClick = onClick, onLongClick = onLongClick, - onTimestampClick = onTimestampClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, onReactionClick = { emoji -> onReactionClick(emoji, event) }, @@ -209,7 +208,6 @@ fun TimelineItemEventRow( interactionSource = interactionSource, onClick = onClick, onLongClick = onLongClick, - onTimestampClick = onTimestampClick, inReplyToClick = ::inReplyToClick, onUserDataClick = ::onUserDataClick, onReactionClick = { emoji -> onReactionClick(emoji, event) }, @@ -265,7 +263,6 @@ private fun TimelineItemEventRowContent( interactionSource: MutableInteractionSource, onClick: () -> Unit, onLongClick: () -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, inReplyToClick: () -> Unit, onUserDataClick: () -> Unit, onReactionClick: (emoji: String) -> Unit, @@ -337,9 +334,6 @@ private fun TimelineItemEventRowContent( event = event, onMessageLongClick = onLongClick, inReplyToClick = inReplyToClick, - onTimestampClick = { - onTimestampClick(event) - }, onLinkClick = onLinkClick, eventSink = eventSink, ) @@ -419,7 +413,6 @@ private fun MessageEventBubbleContent( event: TimelineItem.Event, onMessageLongClick: () -> Unit, inReplyToClick: () -> Unit, - onTimestampClick: () -> Unit, onLinkClick: (String) -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, @SuppressLint("ModifierParameter") @@ -467,9 +460,8 @@ private fun MessageEventBubbleContent( Box(modifier, contentAlignment = Alignment.Center) { content {} TimelineEventTimestampView( - event = event, - onClick = onTimestampClick, - onLongClick = ::onTimestampLongClick, + formattedTime = event.sentTime, + isMessageEdited = event.content.isEdited(), modifier = Modifier // Outer padding .padding(horizontal = 4.dp, vertical = 4.dp) @@ -489,9 +481,8 @@ private fun MessageEventBubbleContent( content = { content(this::onContentLayoutChange) }, overlay = { TimelineEventTimestampView( - event = event, - onClick = onTimestampClick, - onLongClick = ::onTimestampLongClick, + formattedTime = event.sentTime, + isMessageEdited = event.content.isEdited(), modifier = Modifier .padding(horizontal = 8.dp, vertical = 4.dp) ) @@ -501,9 +492,8 @@ private fun MessageEventBubbleContent( Column(modifier) { content {} TimelineEventTimestampView( - event = event, - onClick = onTimestampClick, - onLongClick = ::onTimestampLongClick, + formattedTime = event.sentTime, + isMessageEdited = event.content.isEdited(), modifier = Modifier .align(Alignment.End) .padding(horizontal = 8.dp, vertical = 4.dp) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt index e50ea0ee8c..4dd4d4e356 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemGroupedEventsRow.kt @@ -49,7 +49,6 @@ fun TimelineItemGroupedEventsRow( inReplyToClick: (EventId) -> Unit, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onReactionClick: (key: String, TimelineItem.Event) -> Unit, onReactionLongClick: (key: String, TimelineItem.Event) -> Unit, onMoreReactionsClick: (TimelineItem.Event) -> Unit, @@ -76,7 +75,6 @@ fun TimelineItemGroupedEventsRow( inReplyToClick = inReplyToClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onTimestampClick = onTimestampClick, onReactionClick = onReactionClick, onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, @@ -100,7 +98,6 @@ private fun TimelineItemGroupedEventsRowContent( inReplyToClick: (EventId) -> Unit, onUserDataClick: (UserId) -> Unit, onLinkClick: (String) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onReactionClick: (key: String, TimelineItem.Event) -> Unit, onReactionLongClick: (key: String, TimelineItem.Event) -> Unit, onMoreReactionsClick: (TimelineItem.Event) -> Unit, @@ -133,7 +130,6 @@ private fun TimelineItemGroupedEventsRowContent( inReplyToClick = inReplyToClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onTimestampClick = onTimestampClick, onReactionClick = onReactionClick, onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, @@ -175,7 +171,6 @@ internal fun TimelineItemGroupedEventsRowContentExpandedPreview() = ElementPrevi inReplyToClick = {}, onUserDataClick = {}, onLinkClick = {}, - onTimestampClick = {}, onReactionClick = { _, _ -> }, onReactionLongClick = { _, _ -> }, onMoreReactionsClick = {}, @@ -200,7 +195,6 @@ internal fun TimelineItemGroupedEventsRowContentCollapsePreview() = ElementPrevi inReplyToClick = {}, onUserDataClick = {}, onLinkClick = {}, - onTimestampClick = {}, onReactionClick = { _, _ -> }, onReactionLongClick = { _, _ -> }, onMoreReactionsClick = {}, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt index 06683d3569..2a3a0305c2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemRow.kt @@ -54,7 +54,6 @@ internal fun TimelineItemRow( onReactionLongClick: (key: String, TimelineItem.Event) -> Unit, onMoreReactionsClick: (TimelineItem.Event) -> Unit, onReadReceiptClick: (TimelineItem.Event) -> Unit, - onTimestampClick: (TimelineItem.Event) -> Unit, onSwipeToReply: (TimelineItem.Event) -> Unit, onJoinCallClick: () -> Unit, eventSink: (TimelineEvents.EventFromTimelineItem) -> Unit, @@ -118,7 +117,6 @@ internal fun TimelineItemRow( onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, onReadReceiptClick = onReadReceiptClick, - onTimestampClick = onTimestampClick, onSwipeToReply = { onSwipeToReply(timelineItem) }, eventSink = eventSink, ) @@ -137,7 +135,6 @@ internal fun TimelineItemRow( inReplyToClick = inReplyToClick, onUserDataClick = onUserDataClick, onLinkClick = onLinkClick, - onTimestampClick = onTimestampClick, onReactionClick = onReactionClick, onReactionLongClick = onReactionLongClick, onMoreReactionsClick = onMoreReactionsClick, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt index 3bce2b389b..84f619341c 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/TimelineItemReadReceiptView.kt @@ -81,7 +81,8 @@ fun TimelineItemReadReceiptView( } } else { when (state.sendState) { - LocalEventSendState.NotSentYet -> { + is LocalEventSendState.SendingFailed, + is LocalEventSendState.NotSentYet -> { ReadReceiptsRow(modifier) { Icon( modifier = Modifier.padding(2.dp), @@ -91,10 +92,6 @@ fun TimelineItemReadReceiptView( ) } } - LocalEventSendState.Canceled -> Unit - is LocalEventSendState.SendingFailed -> { - // Error? The timestamp is already displayed in red - } null, is LocalEventSendState.Sent -> { if (state.isLastOutgoingMessage) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheet.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheet.kt index 1062e11977..d54d48eeab 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheet.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/receipt/bottomsheet/ReadReceiptBottomSheet.kt @@ -123,7 +123,6 @@ private fun ReadReceiptBottomSheetContent( @PreviewsDayNight @Composable internal fun ReadReceiptBottomSheetPreview(@PreviewParameter(ReadReceiptBottomSheetStateProvider::class) state: ReadReceiptBottomSheetState) = ElementPreview { - // TODO restore RetrySendMessageMenuBottomSheet once the issue with bottom sheet not being previewable is fixed Column { ReadReceiptBottomSheetContent( state = state, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuEvents.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuEvents.kt deleted file mode 100644 index 77854773c4..0000000000 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuEvents.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import io.element.android.features.messages.impl.timeline.model.TimelineItem - -sealed interface RetrySendMenuEvents { - data class EventSelected(val event: TimelineItem.Event) : RetrySendMenuEvents - data object Retry : RetrySendMenuEvents - data object Remove : RetrySendMenuEvents - data object Dismiss : RetrySendMenuEvents -} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt deleted file mode 100644 index 8745df9e53..0000000000 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenter.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import io.element.android.features.messages.impl.timeline.model.TimelineItem -import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.room.MatrixRoom -import kotlinx.coroutines.launch -import javax.inject.Inject - -class RetrySendMenuPresenter @Inject constructor( - private val room: MatrixRoom, -) : Presenter { - @Composable - override fun present(): RetrySendMenuState { - val coroutineScope = rememberCoroutineScope() - var selectedEvent: TimelineItem.Event? by remember { mutableStateOf(null) } - - fun handleEvent(event: RetrySendMenuEvents) { - when (event) { - is RetrySendMenuEvents.EventSelected -> { - selectedEvent = event.event - } - RetrySendMenuEvents.Retry -> { - coroutineScope.launch { - selectedEvent?.transactionId?.let { transactionId -> - room.retrySendMessage(transactionId) - } - selectedEvent = null - } - } - RetrySendMenuEvents.Remove -> { - coroutineScope.launch { - selectedEvent?.transactionId?.let { transactionId -> - room.cancelSend(transactionId) - } - selectedEvent = null - } - } - RetrySendMenuEvents.Dismiss -> { - selectedEvent = null - } - } - } - - return RetrySendMenuState( - selectedEvent = selectedEvent, - eventSink = { handleEvent(it) }, - ) - } -} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuState.kt deleted file mode 100644 index e10e9c752c..0000000000 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuState.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import androidx.compose.runtime.Immutable -import io.element.android.features.messages.impl.timeline.model.TimelineItem - -@Immutable -data class RetrySendMenuState( - val selectedEvent: TimelineItem.Event?, - val eventSink: (RetrySendMenuEvents) -> Unit, -) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuStateProvider.kt deleted file mode 100644 index 14353ddd09..0000000000 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuStateProvider.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.messages.impl.timeline.aTimelineItemEvent -import io.element.android.features.messages.impl.timeline.model.TimelineItem - -class RetrySendMenuStateProvider : PreviewParameterProvider { - override val values: Sequence = sequenceOf( - aRetrySendMenuState(), - aRetrySendMenuState(event = aTimelineItemEvent()), - ) -} - -fun aRetrySendMenuState( - event: TimelineItem.Event? = null, - eventSink: (RetrySendMenuEvents) -> Unit = {}, -) = RetrySendMenuState( - selectedEvent = event, - eventSink = eventSink, -) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenu.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenu.kt deleted file mode 100644 index ce01c18dfa..0000000000 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenu.kt +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.ListItem -import androidx.compose.material3.ListItemDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SheetState -import androidx.compose.material3.rememberModalBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.unit.dp -import io.element.android.compound.theme.ElementTheme -import io.element.android.features.messages.impl.R -import io.element.android.libraries.designsystem.preview.ElementPreview -import io.element.android.libraries.designsystem.preview.PreviewsDayNight -import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet -import io.element.android.libraries.designsystem.theme.components.Text -import io.element.android.libraries.ui.strings.CommonStrings -import kotlinx.coroutines.launch - -@Composable -internal fun RetrySendMessageMenu( - state: RetrySendMenuState, - modifier: Modifier = Modifier, -) { - val isVisible = state.selectedEvent != null - - fun onDismiss() { - state.eventSink(RetrySendMenuEvents.Dismiss) - } - - fun onRetry() { - state.eventSink(RetrySendMenuEvents.Retry) - } - - fun onRemove() { - state.eventSink(RetrySendMenuEvents.Remove) - } - - RetrySendMessageMenuBottomSheet( - modifier = modifier, - isVisible = isVisible, - onRetry = ::onRetry, - onRemove = ::onRemove, - onDismiss = ::onDismiss - ) -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun RetrySendMessageMenuBottomSheet( - isVisible: Boolean, - onRetry: () -> Unit, - onRemove: () -> Unit, - onDismiss: () -> Unit, - modifier: Modifier = Modifier, -) { - val sheetState = rememberModalBottomSheetState() - val coroutineScope = rememberCoroutineScope() - - if (isVisible) { - ModalBottomSheet( - modifier = modifier, -// modifier = modifier.navigationBarsPadding() - FIXME after https://issuetracker.google.com/issues/275849044 -// .imePadding() - sheetState = sheetState, - onDismissRequest = { - coroutineScope.launch { - sheetState.hide() - onDismiss() - } - } - ) { - RetrySendMenuContents( - onRetry = onRetry, - onRemove = onRemove, - ) - // FIXME remove after https://issuetracker.google.com/issues/275849044 - Spacer(modifier = Modifier.height(32.dp)) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun ColumnScope.RetrySendMenuContents( - onRetry: () -> Unit, - onRemove: () -> Unit, - sheetState: SheetState = rememberModalBottomSheetState(), -) { - val coroutineScope = rememberCoroutineScope() - - ListItem(headlineContent = { - Text( - text = stringResource(R.string.screen_room_retry_send_menu_title), - style = ElementTheme.typography.fontBodyLgMedium, - ) - }) - ListItem( - headlineContent = { - Text( - text = stringResource(R.string.screen_room_retry_send_menu_send_again_action), - style = ElementTheme.typography.fontBodyLgRegular, - ) - }, - modifier = Modifier.clickable { - coroutineScope.launch { - sheetState.hide() - onRetry() - } - } - ) - ListItem( - headlineContent = { - Text( - text = stringResource(CommonStrings.action_remove), - style = ElementTheme.typography.fontBodyLgRegular, - ) - }, - colors = ListItemDefaults.colors(headlineColor = MaterialTheme.colorScheme.error), - modifier = Modifier.clickable { - coroutineScope.launch { - sheetState.hide() - onRemove() - } - } - ) -} - -@PreviewsDayNight -@Composable -internal fun RetrySendMessageMenuPreview(@PreviewParameter(RetrySendMenuStateProvider::class) state: RetrySendMenuState) = ElementPreview { - RetrySendMessageMenu( - state = state, - ) -} diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 1732087814..b0f7fd5a48 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -38,7 +38,6 @@ import io.element.android.features.messages.impl.timeline.components.customreact import io.element.android.features.messages.impl.timeline.components.customreaction.FakeEmojibaseProvider import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryPresenter import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetPresenter -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuPresenter import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent @@ -64,19 +63,18 @@ import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatch import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.TransactionId import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.RoomMembershipState -import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState 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.A_TRANSACTION_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.core.aBuildMeta import io.element.android.libraries.matrix.test.permalink.FakePermalinkBuilder @@ -445,41 +443,25 @@ class MessagesPresenterTest { @Test fun `present - handle action redact`() = runTest { val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true) - val matrixRoom = FakeMatrixRoom() - val presenter = createMessagesPresenter(matrixRoom = matrixRoom, coroutineDispatchers = coroutineDispatchers) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - val initialState = awaitItem() - initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Redact, aMessageEvent())) - assertThat(matrixRoom.redactEventEventIdParam).isEqualTo(AN_EVENT_ID) - assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) - } - } - @Test - fun `present - handle action redact message in error, in this case the message is just cancelled`() = runTest { - val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true) - val matrixRoom = FakeMatrixRoom() + val liveTimeline = FakeTimeline() + val matrixRoom = FakeMatrixRoom(liveTimeline = liveTimeline) + + val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) } + liveTimeline.redactEventLambda = redactEventLambda + val presenter = createMessagesPresenter(matrixRoom = matrixRoom, coroutineDispatchers = coroutineDispatchers) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { skipItems(1) val initialState = awaitItem() - initialState.eventSink.invoke( - MessagesEvents.HandleAction( - action = TimelineItemAction.Redact, - event = aMessageEvent( - transactionId = A_TRANSACTION_ID, - sendState = LocalEventSendState.SendingFailed("Failed to send message") - ) - ) - ) - assertThat(matrixRoom.cancelSendCount).isEqualTo(1) - assertThat(matrixRoom.redactEventEventIdParam).isNull() + val messageEvent = aMessageEvent() + initialState.eventSink.invoke(MessagesEvents.HandleAction(TimelineItemAction.Redact, messageEvent)) assertThat(awaitItem().actionListState.target).isEqualTo(ActionListState.Target.None) + assert(redactEventLambda) + .isCalledOnce() + .with(value(messageEvent.eventId), value(messageEvent.transactionId), value(null)) } } @@ -839,7 +821,6 @@ class MessagesPresenterTest { val readReceiptBottomSheetPresenter = ReadReceiptBottomSheetPresenter() val customReactionPresenter = CustomReactionPresenter(emojibaseProvider = FakeEmojibaseProvider()) val reactionSummaryPresenter = ReactionSummaryPresenter(room = matrixRoom) - val retrySendMenuPresenter = RetrySendMenuPresenter(room = matrixRoom) return MessagesPresenter( room = matrixRoom, composerPresenter = messageComposerPresenter, @@ -849,7 +830,6 @@ class MessagesPresenterTest { actionListPresenter = actionListPresenter, customReactionPresenter = customReactionPresenter, reactionSummaryPresenter = reactionSummaryPresenter, - retrySendMenuPresenter = retrySendMenuPresenter, readReceiptBottomSheetPresenter = readReceiptBottomSheetPresenter, networkMonitor = FakeNetworkMonitor(), snackbarDispatcher = SnackbarDispatcher(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt index dd64f0b967..54af738466 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesViewTest.kt @@ -52,8 +52,6 @@ import io.element.android.features.messages.impl.timeline.components.customreact import io.element.android.features.messages.impl.timeline.components.reactionsummary.ReactionSummaryEvents import io.element.android.features.messages.impl.timeline.components.receipt.aReadReceiptData import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetEvents -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuEvents -import io.element.android.features.messages.impl.timeline.components.retrysendmenu.aRetrySendMenuState import io.element.android.features.messages.impl.timeline.model.TimelineItem import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent import io.element.android.libraries.matrix.api.core.UserId @@ -74,6 +72,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.junit.runner.RunWith +import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) class MessagesViewTest { @@ -145,22 +144,6 @@ class MessagesViewTest { callback.assertSuccess() } - @Test - fun `clicking on an Event timestamp in error emits the expected Event`() { - val eventsRecorder = EventsRecorder() - val state = aMessagesState( - retrySendMenuState = aRetrySendMenuState( - eventSink = eventsRecorder - ), - ) - val timelineItem = state.timelineState.timelineItems[1] as TimelineItem.Event - rule.setMessagesView( - state = state, - ) - rule.onAllNodesWithText(timelineItem.sentTime)[1].performClick() - eventsRecorder.assertSingle(RetrySendMenuEvents.EventSelected(timelineItem)) - } - @Test fun `long clicking on an Event emits the expected Event userHasPermissionToSendMessage`() { `long clicking on an Event emits the expected Event`(userHasPermissionToSendMessage = true) @@ -313,6 +296,7 @@ class MessagesViewTest { } @Test + @Config(qualifiers = "h1024dp") fun `clicking on the sender of an Event invoke expected callback`() { val eventsRecorder = EventsRecorder(expectEvents = false) val state = aMessagesState( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt index 99b266dd82..ea18c0af39 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenterTest.kt @@ -62,7 +62,7 @@ class ActionListPresenterTest { presenter.present() }.test { val initialState = awaitItem() - val messageEvent = aMessageEvent(isMine = true, content = TimelineItemRedactedContent) + val messageEvent = aMessageEvent(isMine = true, isEditable = false, content = TimelineItemRedactedContent) initialState.eventSink.invoke( ActionListEvents.ComputeForMessage( event = messageEvent, @@ -96,7 +96,11 @@ class ActionListPresenterTest { presenter.present() }.test { val initialState = awaitItem() - val messageEvent = aMessageEvent(isMine = false, content = TimelineItemRedactedContent) + val messageEvent = aMessageEvent( + isMine = false, + isEditable = false, + content = TimelineItemRedactedContent + ) initialState.eventSink.invoke( ActionListEvents.ComputeForMessage( event = messageEvent, @@ -132,6 +136,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = false, + isEditable = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) ) initialState.eventSink.invoke( @@ -174,6 +179,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = false, + isEditable = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) ) initialState.eventSink.invoke( @@ -215,6 +221,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = false, + isEditable = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) ) initialState.eventSink.invoke( @@ -256,6 +263,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = false, + isEditable = false, content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null) ) initialState.eventSink.invoke( @@ -382,6 +390,7 @@ class ActionListPresenterTest { val initialState = awaitItem() val messageEvent = aMessageEvent( isMine = true, + isEditable = false, content = aTimelineItemImageContent(), ) initialState.eventSink.invoke( diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt index 9ae6453a4f..e66bd4c7a1 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelineViewTest.kt @@ -106,7 +106,6 @@ private fun AndroidComposeTestRule.setTimel onLinkClick: (String) -> Unit = EnsureNeverCalledWithParam(), onMessageClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), onMessageLongClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), - onTimestampClick: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), onSwipeToReply: (TimelineItem.Event) -> Unit = EnsureNeverCalledWithParam(), onReactionClick: (emoji: String, TimelineItem.Event) -> Unit = EnsureNeverCalledWithTwoParams(), onReactionLongClick: (emoji: String, TimelineItem.Event) -> Unit = EnsureNeverCalledWithTwoParams(), @@ -123,7 +122,6 @@ private fun AndroidComposeTestRule.setTimel onLinkClick = onLinkClick, onMessageClick = onMessageClick, onMessageLongClick = onMessageLongClick, - onTimestampClick = onTimestampClick, onSwipeToReply = onSwipeToReply, onReactionClick = onReactionClick, onReactionLongClick = onReactionLongClick, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenterTest.kt deleted file mode 100644 index 7881cba6aa..0000000000 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMenuPresenterTest.kt +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.features.messages.impl.timeline.components.retrysendmenu - -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test -import com.google.common.truth.Truth.assertThat -import io.element.android.features.messages.impl.timeline.aTimelineItemEvent -import io.element.android.libraries.matrix.test.A_TRANSACTION_ID -import io.element.android.libraries.matrix.test.room.FakeMatrixRoom -import io.element.android.tests.testutils.WarmUpRule -import kotlinx.coroutines.test.runTest -import org.junit.Rule -import org.junit.Test - -class RetrySendMenuPresenterTest { - @get:Rule - val warmUpRule = WarmUpRule() - - private val room = FakeMatrixRoom() - private val presenter = RetrySendMenuPresenter(room) - - @Test - fun `present - handle event selected`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent() - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - assertThat(awaitItem().selectedEvent).isSameInstanceAs(selectedEvent) - } - } - - @Test - fun `present - handle dismiss`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent() - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Dismiss) - assertThat(room.cancelSendCount).isEqualTo(0) - assertThat(room.retrySendMessageCount).isEqualTo(0) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle resend with transactionId`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = A_TRANSACTION_ID) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Retry) - assertThat(room.cancelSendCount).isEqualTo(0) - assertThat(room.retrySendMessageCount).isEqualTo(1) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle resend without transactionId`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = null) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Retry) - assertThat(room.cancelSendCount).isEqualTo(0) - assertThat(room.retrySendMessageCount).isEqualTo(0) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle resend with error`() = runTest { - room.givenRetrySendMessageResult(Result.failure(IllegalStateException("An error"))) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = A_TRANSACTION_ID) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Retry) - assertThat(room.cancelSendCount).isEqualTo(0) - assertThat(room.retrySendMessageCount).isEqualTo(1) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle remove failed message with transactionId`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = A_TRANSACTION_ID) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Remove) - assertThat(room.cancelSendCount).isEqualTo(1) - assertThat(room.retrySendMessageCount).isEqualTo(0) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle remove failed message without transactionId`() = runTest { - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = null) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Remove) - assertThat(room.cancelSendCount).isEqualTo(0) - assertThat(room.retrySendMessageCount).isEqualTo(0) - assertThat(awaitItem().selectedEvent).isNull() - } - } - - @Test - fun `present - handle remove failed message with error`() = runTest { - room.givenRetrySendMessageResult(Result.failure(IllegalStateException("An error"))) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - val initialState = awaitItem() - val selectedEvent = aTimelineItemEvent(transactionId = A_TRANSACTION_ID) - initialState.eventSink(RetrySendMenuEvents.EventSelected(selectedEvent)) - skipItems(1) - initialState.eventSink(RetrySendMenuEvents.Remove) - assertThat(room.cancelSendCount).isEqualTo(1) - assertThat(room.retrySendMessageCount).isEqualTo(0) - assertThat(awaitItem().selectedEvent).isNull() - } - } -} diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenuTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenuTest.kt deleted file mode 100644 index 41d6d5610f..0000000000 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/components/retrysendmenu/RetrySendMessageMenuTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2024 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.timeline.components.retrysendmenu - -import androidx.activity.ComponentActivity -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.element.android.features.messages.impl.R -import io.element.android.features.messages.impl.timeline.aTimelineItemEvent -import io.element.android.libraries.ui.strings.CommonStrings -import io.element.android.tests.testutils.EventsRecorder -import io.element.android.tests.testutils.clickOn -import io.element.android.tests.testutils.pressBackKey -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.robolectric.annotation.Config - -@RunWith(AndroidJUnit4::class) -class RetrySendMessageMenuTest { - @get:Rule val rule = createAndroidComposeRule() - - @Test - fun `dismiss the bottom sheet emits the expected event`() { - val eventsRecorder = EventsRecorder() - rule.setRetrySendMessageMenu( - aRetrySendMenuState( - event = aTimelineItemEvent(), - eventSink = eventsRecorder - ), - ) - rule.pressBackKey() - // Cannot test this for now. - // eventsRecorder.assertSingle(RetrySendMenuEvents.Dismiss) - } - - @Config(qualifiers = "h1024dp") - @Test - fun `retry to send the event emits the expected event`() { - val eventsRecorder = EventsRecorder() - rule.setRetrySendMessageMenu( - aRetrySendMenuState( - event = aTimelineItemEvent(), - eventSink = eventsRecorder - ), - ) - rule.clickOn(R.string.screen_room_retry_send_menu_send_again_action) - eventsRecorder.assertSingle(RetrySendMenuEvents.Retry) - } - - @Config(qualifiers = "h1024dp") - @Test - fun `remove the event emits the expected event`() { - val eventsRecorder = EventsRecorder() - rule.setRetrySendMessageMenu( - aRetrySendMenuState( - event = aTimelineItemEvent(), - eventSink = eventsRecorder - ), - ) - rule.clickOn(CommonStrings.action_remove) - eventsRecorder.assertSingle(RetrySendMenuEvents.Remove) - } -} - -private fun AndroidComposeTestRule.setRetrySendMessageMenu( - state: RetrySendMenuState, -) { - setContent { - RetrySendMessageMenu( - state = state, - ) - } -} diff --git a/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt new file mode 100644 index 0000000000..3a2f15e5c9 --- /dev/null +++ b/features/migration/impl/src/main/kotlin/io/element/android/features/migration/impl/migrations/AppMigration05.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 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.migration.impl.migrations + +import com.squareup.anvil.annotations.ContributesMultibinding +import io.element.android.libraries.di.AppScope +import io.element.android.libraries.sessionstorage.api.SessionStore +import java.io.File +import javax.inject.Inject + +@ContributesMultibinding(AppScope::class) +class AppMigration05 @Inject constructor( + private val sessionStore: SessionStore, + private val baseDirectory: File, +) : AppMigration { + override val order: Int = 5 + + override suspend fun migrate() { + val allSessions = sessionStore.getAllSessions() + for (session in allSessions) { + if (session.sessionPath.isEmpty()) { + val sessionPath = File(baseDirectory, session.userId.replace(':', '_')).absolutePath + sessionStore.updateData(session.copy(sessionPath = sessionPath)) + } + } + } +} diff --git a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/data/PollRepository.kt b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/data/PollRepository.kt index e8d2506408..d1902facb7 100644 --- a/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/data/PollRepository.kt +++ b/features/poll/impl/src/main/kotlin/io/element/android/features/poll/impl/data/PollRepository.kt @@ -68,8 +68,12 @@ class PollRepository @Inject constructor( suspend fun deletePoll( pollStartId: EventId, - ): Result = - room.redactEvent( - eventId = pollStartId, - ) + ): Result = + timelineProvider + .getActiveTimeline() + .redactEvent( + eventId = pollStartId, + transactionId = null, + reason = null, + ) } diff --git a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt index 2dbc612a0b..89536deaec 100644 --- a/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt +++ b/features/poll/impl/src/test/kotlin/io/element/android/features/poll/impl/create/CreatePollPresenterTest.kt @@ -29,6 +29,7 @@ import io.element.android.features.poll.impl.aPollTimelineItems import io.element.android.features.poll.impl.anOngoingPollContent import io.element.android.features.poll.impl.data.PollRepository import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.TransactionId import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.timeline.item.event.PollContent @@ -39,6 +40,7 @@ import io.element.android.libraries.matrix.test.timeline.FakeTimeline import io.element.android.libraries.matrix.test.timeline.LiveTimelineProvider import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule +import io.element.android.tests.testutils.lambda.any import io.element.android.tests.testutils.lambda.assert import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value @@ -455,47 +457,53 @@ import org.junit.Test @Test fun `delete confirms`() = runTest { val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId)) + val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) } + timeline.redactEventLambda = redactEventLambda moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { awaitDefaultItem() awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) awaitDeleteConfirmation() - assertThat(fakeMatrixRoom.redactEventEventIdParam).isNull() + assert(redactEventLambda).isNeverCalled() } } @Test fun `delete can be cancelled`() = runTest { val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId)) + val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) } + timeline.redactEventLambda = redactEventLambda moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { awaitDefaultItem() awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) - assertThat(fakeMatrixRoom.redactEventEventIdParam).isNull() awaitDeleteConfirmation().eventSink(CreatePollEvents.HideConfirmation) awaitPollLoaded().apply { assertThat(showDeleteConfirmation).isFalse() } - assertThat(fakeMatrixRoom.redactEventEventIdParam).isNull() + assert(redactEventLambda).isNeverCalled() } } @Test fun `delete can be confirmed`() = runTest { val presenter = createCreatePollPresenter(mode = CreatePollMode.EditPoll(pollEventId)) + val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) } + timeline.redactEventLambda = redactEventLambda moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { awaitDefaultItem() awaitPollLoaded().eventSink(CreatePollEvents.Delete(confirmed = false)) - assertThat(fakeMatrixRoom.redactEventEventIdParam).isNull() awaitDeleteConfirmation().eventSink(CreatePollEvents.Delete(confirmed = true)) awaitPollLoaded().apply { assertThat(showDeleteConfirmation).isFalse() } - assertThat(fakeMatrixRoom.redactEventEventIdParam).isEqualTo(pollEventId) + assert(redactEventLambda) + .isCalledOnce() + .with(value(pollEventId), value(null), any()) } } diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt index ad7f6b76e7..fa78a164b1 100755 --- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt +++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt @@ -287,7 +287,8 @@ class DefaultBugReporterTest { oidcData = null, refreshToken = null, slidingSyncProxy = null, - passphrase = null + passphrase = null, + sessionPath = "session", ) @Test fun `test sendBugReport error`() = runTest { diff --git a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt index df3549b0f8..bd303f7945 100644 --- a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt +++ b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutStateProvider.kt @@ -51,5 +51,6 @@ fun aSessionData( isTokenValid = isTokenValid, loginType = LoginType.UNKNOWN, passphrase = null, + sessionPath = "/a/path/to/a/session", ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bb704f6ab9..8ba98e0e06 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -162,7 +162,7 @@ jsoup = "org.jsoup:jsoup:1.17.2" appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" } molecule-runtime = "app.cash.molecule:molecule-runtime:2.0.0" timber = "com.jakewharton.timber:timber:5.0.1" -matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.24" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:0.2.25" matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" } matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" } sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt index a4b808d653..4dd00984f1 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt @@ -105,4 +105,20 @@ interface MatrixClient : Closeable { suspend fun getRecentlyVisitedRooms(): Result> suspend fun resolveRoomAlias(roomAlias: RoomAlias): Result suspend fun getRoomPreviewFromRoomId(roomId: RoomId, serverNames: List): Result + + /** + * Enables or disables the sending queue, according to the given parameter. + * + * The sending queue automatically disables itself whenever sending an + * event with it failed (e.g. sending an event via the Timeline), + * so it's required to manually re-enable it as soon as + * connectivity is back on the device. + */ + suspend fun setAllSendQueuesEnabled(enabled: Boolean) + + /** + * Returns a flow of room IDs that have send queue being disabled. + * This flow will emit a new value whenever the send queue is disabled for a room. + */ + fun sendQueueDisabledFlow(): Flow } 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 7ca6080f11..4cfc303974 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,8 +130,6 @@ interface MatrixRoom : Closeable { suspend fun sendMessage(body: String, htmlBody: String?, mentions: List): Result - suspend fun redactEvent(eventId: EventId, reason: String? = null): Result - suspend fun sendImage( file: File, thumbnailFile: File?, @@ -160,7 +158,7 @@ interface MatrixRoom : Closeable { suspend fun retrySendMessage(transactionId: TransactionId): Result - suspend fun cancelSend(transactionId: TransactionId): Result + suspend fun cancelSend(transactionId: TransactionId): Result suspend fun leave(): Result @@ -337,5 +335,7 @@ interface MatrixRoom : Closeable { */ suspend fun sendCallNotificationIfNeeded(): Result + suspend fun setSendQueueEnabled(enabled: Boolean) + override fun close() = destroy() } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt index 5c1da08b65..ee745ea59d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/Timeline.kt @@ -83,6 +83,8 @@ interface Timeline : AutoCloseable { progressCallback: ProgressCallback? ): Result + suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result + suspend fun sendAudio(file: File, audioInfo: AudioInfo, progressCallback: ProgressCallback?): Result suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result @@ -91,9 +93,7 @@ interface Timeline : AutoCloseable { suspend fun forwardEvent(eventId: EventId, roomIds: List): Result - suspend fun retrySendMessage(transactionId: TransactionId): Result - - suspend fun cancelSend(transactionId: TransactionId): Result + suspend fun cancelSend(transactionId: TransactionId): Result /** * Share a location message in the room. diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/LocalEventSendState.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/LocalEventSendState.kt index f74ddca3a8..e68ca3fedb 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/LocalEventSendState.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/LocalEventSendState.kt @@ -22,7 +22,6 @@ import io.element.android.libraries.matrix.api.core.EventId @Immutable sealed interface LocalEventSendState { data object NotSentYet : LocalEventSendState - data object Canceled : LocalEventSendState data class SendingFailed( val error: String diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 4319077946..ebb871541d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -63,7 +63,7 @@ import io.element.android.libraries.matrix.impl.roomlist.RustRoomListService import io.element.android.libraries.matrix.impl.sync.RustSyncService import io.element.android.libraries.matrix.impl.usersearch.UserProfileMapper import io.element.android.libraries.matrix.impl.usersearch.UserSearchResultMapper -import io.element.android.libraries.matrix.impl.util.SessionDirectoryNameProvider +import io.element.android.libraries.matrix.impl.util.SessionDirectoryProvider import io.element.android.libraries.matrix.impl.util.cancelAndDestroy import io.element.android.libraries.matrix.impl.util.mxCallbackFlow import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService @@ -95,9 +95,11 @@ import kotlinx.coroutines.withTimeout import org.matrix.rustcomponents.sdk.BackupState import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.ClientDelegate +import org.matrix.rustcomponents.sdk.ClientException import org.matrix.rustcomponents.sdk.IgnoredUsersListener import org.matrix.rustcomponents.sdk.NotificationProcessSetup import org.matrix.rustcomponents.sdk.PowerLevels +import org.matrix.rustcomponents.sdk.SendQueueRoomErrorListener import org.matrix.rustcomponents.sdk.TaskHandle import org.matrix.rustcomponents.sdk.use import timber.log.Timber @@ -151,7 +153,7 @@ class RustMatrixClient( sessionDispatcher = sessionDispatcher, ) - private val sessionDirectoryNameProvider = SessionDirectoryNameProvider() + private val sessionDirectoryProvider = SessionDirectoryProvider(sessionStore) private val isLoggingOut = AtomicBoolean(false) @@ -171,6 +173,7 @@ class RustMatrixClient( isTokenValid = false, loginType = existingData.loginType, passphrase = existingData.passphrase, + sessionPath = existingData.sessionPath, ) sessionStore.updateData(newData) Timber.d("Removed session data with token: '...$anonymizedToken'.") @@ -198,6 +201,7 @@ class RustMatrixClient( isTokenValid = true, loginType = existingData.loginType, passphrase = existingData.passphrase, + sessionPath = existingData.sessionPath, ) sessionStore.updateData(newData) Timber.d("Saved new session data with token: '...$anonymizedToken'.") @@ -482,7 +486,7 @@ class RustMatrixClient( override suspend fun clearCache() { close() - baseDirectory.deleteSessionDirectory(deleteCryptoDb = false) + deleteSessionDirectory(deleteCryptoDb = false) } override suspend fun logout(ignoreSdkError: Boolean): String? = doLogout( @@ -512,7 +516,7 @@ class RustMatrixClient( } } close() - baseDirectory.deleteSessionDirectory(deleteCryptoDb = true) + deleteSessionDirectory(deleteCryptoDb = true) if (removeSession) { sessionStore.removeSession(sessionId.value) } @@ -551,11 +555,23 @@ class RustMatrixClient( }.distinctUntilChanged() } + override suspend fun setAllSendQueuesEnabled(enabled: Boolean) = withContext(sessionDispatcher) { + Timber.i("setAllSendQueuesEnabled($enabled)") + client.enableAllSendQueues(enabled) + } + + override fun sendQueueDisabledFlow(): Flow = mxCallbackFlow { + client.subscribeToSendQueueStatus(object : SendQueueRoomErrorListener { + override fun onError(roomId: String, error: ClientException) { + trySend(RoomId(roomId)) + } + }) + }.buffer(Channel.UNLIMITED) + private suspend fun File.getCacheSize( includeCryptoDb: Boolean = false, ): Long = withContext(sessionDispatcher) { - val sessionDirectoryName = sessionDirectoryNameProvider.provides(sessionId) - val sessionDirectory = File(this@getCacheSize, sessionDirectoryName) + val sessionDirectory = sessionDirectoryProvider.provides(sessionId) ?: return@withContext 0L if (includeCryptoDb) { sessionDirectory.getSizeOfFiles() } else { @@ -571,11 +587,10 @@ class RustMatrixClient( } } - private suspend fun File.deleteSessionDirectory( + private suspend fun deleteSessionDirectory( deleteCryptoDb: Boolean = false, ): Boolean = withContext(sessionDispatcher) { - val sessionDirectoryName = sessionDirectoryNameProvider.provides(sessionId) - val sessionDirectory = File(this@deleteSessionDirectory, sessionDirectoryName) + val sessionDirectory = sessionDirectoryProvider.provides(sessionId) ?: return@withContext false if (deleteCryptoDb) { // Delete the folder and all its content sessionDirectory.deleteRecursively() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt index cb0fbbefa4..4b3d89baac 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactory.kt @@ -46,7 +46,7 @@ class RustMatrixClientFactory @Inject constructor( private val utdTracker: UtdTracker, ) { suspend fun create(sessionData: SessionData): RustMatrixClient = withContext(coroutineDispatchers.io) { - val client = getBaseClientBuilder() + val client = getBaseClientBuilder(sessionData.sessionPath) .homeserverUrl(sessionData.homeserverUrl) .username(sessionData.userId) .passphrase(sessionData.passphrase) @@ -71,9 +71,9 @@ class RustMatrixClientFactory @Inject constructor( ) } - internal fun getBaseClientBuilder(): ClientBuilder { + internal fun getBaseClientBuilder(sessionPath: String): ClientBuilder { return ClientBuilder() - .basePath(baseDirectory.absolutePath) + .sessionPath(sessionPath) .userAgent(userAgentProvider.provide()) .addRootCertificates(userCertificatesProvider.provides()) .serverVersions(listOf("v1.0", "v1.1", "v1.2", "v1.3", "v1.4", "v1.5")) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfiguration.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfiguration.kt deleted file mode 100644 index 2f9a6e3bb8..0000000000 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfiguration.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.libraries.matrix.impl.auth - -import io.element.android.libraries.matrix.api.auth.OidcConfig -import org.matrix.rustcomponents.sdk.OidcConfiguration - -val oidcConfiguration: OidcConfiguration = OidcConfiguration( - clientName = "Element", - redirectUri = OidcConfig.REDIRECT_URI, - clientUri = "https://element.io", - logoUri = "https://element.io/mobile-icon.png", - tosUri = "https://element.io/acceptable-use-policy-terms", - policyUri = "https://element.io/privacy", - contacts = listOf( - "support@element.io", - ), - // Some homeservers/auth issuers don't support dynamic client registration, and have to be registered manually - staticRegistrations = mapOf( - "https://id.thirdroom.io/realms/thirdroom" to "elementx", - ), -) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfigurationProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfigurationProvider.kt new file mode 100644 index 0000000000..e55f0bd227 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/OidcConfigurationProvider.kt @@ -0,0 +1,43 @@ +/* + * 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.impl.auth + +import io.element.android.libraries.matrix.api.auth.OidcConfig +import org.matrix.rustcomponents.sdk.OidcConfiguration +import java.io.File +import javax.inject.Inject + +class OidcConfigurationProvider @Inject constructor( + private val baseDirectory: File, +) { + fun get(): OidcConfiguration = OidcConfiguration( + clientName = "Element", + redirectUri = OidcConfig.REDIRECT_URI, + clientUri = "https://element.io", + logoUri = "https://element.io/mobile-icon.png", + tosUri = "https://element.io/acceptable-use-policy-terms", + policyUri = "https://element.io/privacy", + contacts = listOf( + "support@element.io", + ), + // Some homeservers/auth issuers don't support dynamic client registration, and have to be registered manually + staticRegistrations = mapOf( + "https://id.thirdroom.io/realms/thirdroom" to "elementx", + ), + dynamicRegistrationsFile = File(baseDirectory, "oidc/registrations.json").absolutePath, + ) +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt index d992c7fc1c..bb65a5a442 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt @@ -54,6 +54,7 @@ import org.matrix.rustcomponents.sdk.QrLoginProgressListener import org.matrix.rustcomponents.sdk.use import timber.log.Timber import java.io.File +import java.util.UUID import javax.inject.Inject import org.matrix.rustcomponents.sdk.AuthenticationService as RustAuthenticationService @@ -68,17 +69,19 @@ class RustMatrixAuthenticationService @Inject constructor( private val passphraseGenerator: PassphraseGenerator, userCertificatesProvider: UserCertificatesProvider, proxyProvider: ProxyProvider, + private val oidcConfigurationProvider: OidcConfigurationProvider, ) : MatrixAuthenticationService { // Passphrase which will be used for new sessions. Existing sessions will use the passphrase // stored in the SessionData. private val pendingPassphrase = getDatabasePassphrase() + private val sessionPath = File(baseDirectory, UUID.randomUUID().toString()).absolutePath private val authService: RustAuthenticationService = RustAuthenticationService( - basePath = baseDirectory.absolutePath, + sessionPath = sessionPath, passphrase = pendingPassphrase, proxy = proxyProvider.provides(), userAgent = userAgentProvider.provide(), additionalRootCertificates = userCertificatesProvider.provides(), - oidcConfiguration = oidcConfiguration, + oidcConfiguration = oidcConfigurationProvider.get(), customSlidingSyncProxy = null, sessionDelegate = null, crossProcessRefreshLockId = null, @@ -148,6 +151,7 @@ class RustMatrixAuthenticationService @Inject constructor( isTokenValid = true, loginType = LoginType.PASSWORD, passphrase = pendingPassphrase, + sessionPath = sessionPath, ) } sessionStore.storeData(sessionData) @@ -196,6 +200,7 @@ class RustMatrixAuthenticationService @Inject constructor( isTokenValid = true, loginType = LoginType.OIDC, passphrase = pendingPassphrase, + sessionPath = sessionPath, ) } pendingOidcAuthenticationData?.close() @@ -211,11 +216,11 @@ class RustMatrixAuthenticationService @Inject constructor( override suspend fun loginWithQrCode(qrCodeData: MatrixQrCodeLoginData, progress: (QrCodeLoginStep) -> Unit) = withContext(coroutineDispatchers.io) { runCatching { - val client = rustMatrixClientFactory.getBaseClientBuilder() + val client = rustMatrixClientFactory.getBaseClientBuilder(sessionPath) .passphrase(pendingPassphrase) .buildWithQrCode( qrCodeData = (qrCodeData as SdkQrCodeLoginData).rustQrCodeData, - oidcConfiguration = oidcConfiguration, + oidcConfiguration = oidcConfigurationProvider.get(), progressListener = object : QrLoginProgressListener { override fun onUpdate(state: QrLoginProgress) { Timber.d("QR Code login progress: $state") @@ -229,6 +234,7 @@ class RustMatrixAuthenticationService @Inject constructor( isTokenValid = true, loginType = LoginType.QR, passphrase = pendingPassphrase, + sessionPath = sessionPath, ) sessionStore.storeData(sessionData) SessionId(sessionData.userId) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt index aea838b705..e7f9199a34 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/mapper/Session.kt @@ -25,6 +25,7 @@ internal fun Session.toSessionData( isTokenValid: Boolean, loginType: LoginType, passphrase: String?, + sessionPath: String, ) = SessionData( userId = userId, deviceId = deviceId, @@ -37,4 +38,5 @@ internal fun Session.toSessionData( isTokenValid = isTokenValid, loginType = loginType, passphrase = passphrase, + sessionPath = sessionPath, ) 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 aa7a90c540..28318540ce 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 @@ -84,6 +84,7 @@ import org.matrix.rustcomponents.sdk.WidgetCapabilities import org.matrix.rustcomponents.sdk.WidgetCapabilitiesProvider import org.matrix.rustcomponents.sdk.getElementCallRequiredPermissions import org.matrix.rustcomponents.sdk.use +import timber.log.Timber import uniffi.matrix_sdk.RoomPowerLevelChanges import java.io.File import org.matrix.rustcomponents.sdk.Room as InnerRoom @@ -324,12 +325,6 @@ class RustMatrixRoom( return liveTimeline.sendMessage(body, htmlBody, mentions) } - override suspend fun redactEvent(eventId: EventId, reason: String?) = withContext(roomDispatcher) { - runCatching { - innerRoom.redact(eventId.value, reason) - } - } - override suspend fun leave(): Result = withContext(roomDispatcher) { runCatching { innerRoom.leave() @@ -435,10 +430,10 @@ class RustMatrixRoom( } override suspend fun retrySendMessage(transactionId: TransactionId): Result { - return liveTimeline.retrySendMessage(transactionId) + return Result.failure(UnsupportedOperationException("Not supported")) } - override suspend fun cancelSend(transactionId: TransactionId): Result { + override suspend fun cancelSend(transactionId: TransactionId): Result { return liveTimeline.cancelSend(transactionId) } @@ -600,6 +595,11 @@ class RustMatrixRoom( innerRoom.sendCallNotificationIfNeeded() } + override suspend fun setSendQueueEnabled(enabled: Boolean) = withContext(roomDispatcher) { + Timber.d("setSendQueuesEnabled: $enabled") + innerRoom.enableSendQueue(enabled) + } + private fun createTimeline( timeline: InnerTimeline, isLive: Boolean, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 0a7e67bcf6..593b41deea 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -279,12 +279,32 @@ class RustTimeline( override suspend fun sendMessage(body: String, htmlBody: String?, mentions: List): Result = withContext(dispatcher) { messageEventContentFromParts(body, htmlBody).withMentions(mentions.map()).use { content -> - runCatching { + runCatching { inner.send(content) } } } + override suspend fun redactEvent(eventId: EventId?, transactionId: TransactionId?, reason: String?): Result = withContext(dispatcher) { + runCatching { + when { + eventId != null -> { + inner.getEventTimelineItemByEventId(eventId.value).use { + inner.redactEvent(item = it, reason = reason) + } + } + transactionId != null -> { + inner.getEventTimelineItemByTransactionId(transactionId.value).use { + inner.redactEvent(item = it, reason = reason) + } + } + else -> { + error("Either eventId or transactionId must be non-null") + } + } + } + } + override suspend fun editMessage( originalEventId: EventId?, transactionId: TransactionId?, @@ -293,21 +313,24 @@ class RustTimeline( mentions: List, ): Result = withContext(dispatcher) { - if (originalEventId != null) { - runCatching { - val editedEvent = specialModeEventTimelineItem ?: inner.getEventTimelineItemByEventId(originalEventId.value) - editedEvent.use { - inner.edit( - newContent = messageEventContentFromParts(body, htmlBody).withMentions(mentions.map()), - editItem = it, - ) + runCatching { + when { + originalEventId != null -> { + val editedEvent = specialModeEventTimelineItem ?: inner.getEventTimelineItemByEventId(originalEventId.value) + editedEvent.use { + inner.edit( + newContent = messageEventContentFromParts(body, htmlBody).withMentions(mentions.map()), + editItem = it, + ) + } + specialModeEventTimelineItem = null + } + transactionId != null -> { + error("Editing local echo is not supported yet.") + } + else -> { + error("Either originalEventId or transactionId must be non null") } - specialModeEventTimelineItem = null - } - } else { - runCatching { - transactionId?.let { cancelSend(it) } - inner.send(messageEventContentFromParts(body, htmlBody)) } } } @@ -426,17 +449,7 @@ class RustTimeline( } } - override suspend fun retrySendMessage(transactionId: TransactionId): Result = withContext(dispatcher) { - runCatching { - inner.retrySend(transactionId.value) - } - } - - override suspend fun cancelSend(transactionId: TransactionId): Result = withContext(dispatcher) { - runCatching { - inner.cancelSend(transactionId.value) - } - } + override suspend fun cancelSend(transactionId: TransactionId): Result = redactEvent(eventId = null, transactionId = transactionId, reason = null) override suspend fun sendLocation( body: String, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt index ed56d4a8d0..a603d354e5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt @@ -79,7 +79,6 @@ fun RustEventSendState?.map(): LocalEventSendState? { RustEventSendState.NotSentYet -> LocalEventSendState.NotSentYet is RustEventSendState.SendingFailed -> LocalEventSendState.SendingFailed(error) is RustEventSendState.Sent -> LocalEventSendState.Sent(EventId(eventId)) - RustEventSendState.Cancelled -> LocalEventSendState.Canceled } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryNameProvider.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt similarity index 65% rename from libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryNameProvider.kt rename to libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt index de9d6c1520..f9b8edbd8e 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryNameProvider.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/SessionDirectoryProvider.kt @@ -17,10 +17,15 @@ package io.element.android.libraries.matrix.impl.util import io.element.android.libraries.matrix.api.core.SessionId +import io.element.android.libraries.sessionstorage.api.SessionStore +import java.io.File +import javax.inject.Inject -class SessionDirectoryNameProvider { - // Rust sanitises the user ID replacing invalid characters with an _ - fun provides(sessionId: SessionId): String { - return sessionId.value.replace(":", "_") +class SessionDirectoryProvider @Inject constructor( + private val sessionStore: SessionStore, +) { + suspend fun provides(sessionId: SessionId): File? { + val path = sessionStore.getSession(sessionId.value)?.sessionPath ?: return null + return File(path) } } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt index be029705fb..8f17c3547d 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/FakeMatrixClient.kt @@ -48,13 +48,16 @@ import io.element.android.libraries.matrix.test.roomdirectory.FakeRoomDirectoryS import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService import io.element.android.libraries.matrix.test.sync.FakeSyncService import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService +import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.simulateLongTask import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestScope import java.util.Optional @@ -298,4 +301,13 @@ class FakeMatrixClient( } override fun getRoomInfoFlow(roomId: RoomId) = getRoomInfoFlowLambda(roomId) + + var setAllSendQueuesEnabledLambda = lambdaRecorder(ensureNeverCalled = true) { _: Boolean -> + // no-op + } + + override suspend fun setAllSendQueuesEnabled(enabled: Boolean) = setAllSendQueuesEnabledLambda(enabled) + + var sendQueueDisabledFlow = emptyFlow() + override fun sendQueueDisabledFlow(): Flow = sendQueueDisabledFlow } 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 f220144485..d5dddf3b7e 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 @@ -113,7 +113,7 @@ class FakeMatrixRoom( private var updateUserRoleResult = Result.success(Unit) private var toggleReactionResult = Result.success(Unit) private var retrySendMessageResult = Result.success(Unit) - private var cancelSendResult = Result.success(Unit) + private var cancelSendResult = Result.success(true) private var forwardEventResult = Result.success(Unit) private var reportContentResult = Result.success(Unit) private var kickUserResult = Result.success(Unit) @@ -282,7 +282,7 @@ class FakeMatrixRoom( return retrySendMessageResult } - override suspend fun cancelSend(transactionId: TransactionId): Result { + override suspend fun cancelSend(transactionId: TransactionId): Result { cancelSendCount++ return cancelSendResult } @@ -295,14 +295,6 @@ class FakeMatrixRoom( return eventPermalinkResult(eventId) } - var redactEventEventIdParam: EventId? = null - private set - - override suspend fun redactEvent(eventId: EventId, reason: String?): Result { - redactEventEventIdParam = eventId - return Result.success(Unit) - } - override suspend fun leave(): Result { return leaveRoomLambda() } @@ -533,6 +525,9 @@ class FakeMatrixRoom( return sendCallNotificationIfNeededResult() } + var setSendQueueEnabledLambda = { _: Boolean -> } + override suspend fun setSendQueueEnabled(enabled: Boolean) = setSendQueueEnabledLambda(enabled) + override fun getWidgetDriver(widgetSettings: MatrixWidgetSettings): Result = getWidgetDriverResult fun givenRoomMembersState(state: MatrixRoomMembersState) { @@ -631,7 +626,7 @@ class FakeMatrixRoom( retrySendMessageResult = result } - fun givenCancelSendResult(result: Result) { + fun givenCancelSendResult(result: Result) { cancelSendResult = result } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt index 1cb4a3c3eb..9f62df2ca6 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimeline.kt @@ -69,6 +69,16 @@ class FakeTimeline( mentions: List, ): Result = sendMessageLambda(body, htmlBody, mentions) + var redactEventLambda: (eventId: EventId?, transactionId: TransactionId?, reason: String?) -> Result = { _, _, _ -> + Result.success(true) + } + + override suspend fun redactEvent( + eventId: EventId?, + transactionId: TransactionId?, + reason: String? + ): Result = redactEventLambda(eventId, transactionId, reason) + var editMessageLambda: ( originalEventId: EventId?, transactionId: TransactionId?, @@ -219,11 +229,7 @@ class FakeTimeline( var forwardEventLambda: (eventId: EventId, roomIds: List) -> Result = { _, _ -> Result.success(Unit) } override suspend fun forwardEvent(eventId: EventId, roomIds: List): Result = forwardEventLambda(eventId, roomIds) - var retrySendMessageLambda: (transactionId: TransactionId) -> Result = { Result.success(Unit) } - override suspend fun retrySendMessage(transactionId: TransactionId): Result = retrySendMessageLambda(transactionId) - - var cancelSendLambda: (transactionId: TransactionId) -> Result = { Result.success(Unit) } - override suspend fun cancelSend(transactionId: TransactionId): Result = cancelSendLambda(transactionId) + override suspend fun cancelSend(transactionId: TransactionId): Result = redactEvent(null, transactionId, null) var sendLocationLambda: ( body: String, diff --git a/libraries/pushproviders/firebase/build.gradle.kts b/libraries/pushproviders/firebase/build.gradle.kts index 58d3b882d9..d1c9f62ef0 100644 --- a/libraries/pushproviders/firebase/build.gradle.kts +++ b/libraries/pushproviders/firebase/build.gradle.kts @@ -63,6 +63,7 @@ dependencies { testImplementation(projects.libraries.push.test) testImplementation(projects.libraries.pushstore.test) testImplementation(projects.libraries.sessionStorage.implMemory) + testImplementation(projects.libraries.sessionStorage.test) testImplementation(projects.tests.testutils) testImplementation(projects.services.toolbox.test) } diff --git a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt index 585a5e2a08..aca3ccf054 100644 --- a/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt +++ b/libraries/pushproviders/firebase/src/test/kotlin/io/element/android/libraries/pushproviders/firebase/DefaultFirebaseNewTokenHandlerTest.kt @@ -19,7 +19,6 @@ package io.element.android.libraries.pushproviders.firebase import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService -import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 @@ -31,11 +30,10 @@ import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStore import io.element.android.libraries.pushstore.test.userpushstore.FakeUserPushStoreFactory -import io.element.android.libraries.sessionstorage.api.LoginType -import io.element.android.libraries.sessionstorage.api.SessionData import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.impl.memory.InMemoryMultiSessionsStore import io.element.android.libraries.sessionstorage.impl.memory.InMemorySessionStore +import io.element.android.libraries.sessionstorage.test.aSessionData import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import kotlinx.coroutines.test.runTest @@ -165,22 +163,4 @@ class DefaultFirebaseNewTokenHandlerTest { firebaseStore = firebaseStore ) } - - private fun aSessionData( - sessionId: SessionId, - ): SessionData { - return SessionData( - userId = sessionId.value, - deviceId = "aDeviceId", - accessToken = "anAccessToken", - refreshToken = "aRefreshToken", - homeserverUrl = "aHomeserverUrl", - oidcData = null, - slidingSyncProxy = null, - loginTimestamp = null, - isTokenValid = true, - loginType = LoginType.UNKNOWN, - passphrase = null, - ) - } } diff --git a/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt b/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt index 76bd7f743a..30f721d68a 100644 --- a/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt +++ b/libraries/session-storage/api/src/main/kotlin/io/element/android/libraries/sessionstorage/api/SessionData.kt @@ -44,4 +44,6 @@ data class SessionData( val loginType: LoginType, /** The optional passphrase used to encrypt data in the SDK local store. */ val passphrase: String?, + /** The path to the session data stored in the filesystem. */ + val sessionPath: String, ) diff --git a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt index 3824def48c..026c13eadc 100644 --- a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt +++ b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/SessionDataMapper.kt @@ -34,6 +34,7 @@ internal fun SessionData.toDbModel(): DbSessionData { isTokenValid = if (isTokenValid) 1L else 0L, loginType = loginType.name, passphrase = passphrase, + sessionPath = sessionPath, ) } @@ -50,5 +51,6 @@ internal fun DbSessionData.toApiModel(): SessionData { isTokenValid = isTokenValid == 1L, loginType = LoginType.fromName(loginType ?: LoginType.UNKNOWN.name), passphrase = passphrase, + sessionPath = sessionPath, ) } diff --git a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/di/SessionStorageModule.kt b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/di/SessionStorageModule.kt index 8d22dcfa61..3df49bfb1f 100644 --- a/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/di/SessionStorageModule.kt +++ b/libraries/session-storage/impl/src/main/kotlin/io/element/android/libraries/sessionstorage/impl/di/SessionStorageModule.kt @@ -32,7 +32,9 @@ import io.element.encrypteddb.passphrase.RandomSecretPassphraseProvider object SessionStorageModule { @Provides @SingleIn(AppScope::class) - fun provideMatrixDatabase(@ApplicationContext context: Context): SessionDatabase { + fun provideMatrixDatabase( + @ApplicationContext context: Context, + ): SessionDatabase { val name = "session_database" val secretFile = context.getDatabasePath("$name.key") diff --git a/libraries/session-storage/impl/src/main/sqldelight/databases/8.db b/libraries/session-storage/impl/src/main/sqldelight/databases/8.db new file mode 100644 index 0000000000..f2870ba857 Binary files /dev/null and b/libraries/session-storage/impl/src/main/sqldelight/databases/8.db differ diff --git a/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq b/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq index c33b4d7c7e..74f268606a 100644 --- a/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq +++ b/libraries/session-storage/impl/src/main/sqldelight/io/element/android/libraries/matrix/session/SessionData.sq @@ -23,7 +23,9 @@ CREATE TABLE SessionData ( isTokenValid INTEGER NOT NULL DEFAULT 1, loginType TEXT, -- added in version 5 - passphrase TEXT + passphrase TEXT, + -- added in version 6 + sessionPath TEXT NOT NULL DEFAULT "" ); diff --git a/libraries/session-storage/impl/src/main/sqldelight/migrations/7.sqm b/libraries/session-storage/impl/src/main/sqldelight/migrations/7.sqm new file mode 100644 index 0000000000..5814d23914 --- /dev/null +++ b/libraries/session-storage/impl/src/main/sqldelight/migrations/7.sqm @@ -0,0 +1,4 @@ +-- Migrate DB from version 7 +-- Add sessionPath so we can track the anonymized path for the session files dir + +ALTER TABLE SessionData ADD COLUMN sessionPath TEXT NOT NULL DEFAULT ""; diff --git a/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/DatabaseSessionStoreTest.kt b/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/DatabaseSessionStoreTest.kt index 8df46f708d..2b7aa371f8 100644 --- a/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/DatabaseSessionStoreTest.kt +++ b/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/DatabaseSessionStoreTest.kt @@ -144,6 +144,7 @@ class DatabaseSessionStoreTest { isTokenValid = 1, loginType = null, passphrase = "aPassphrase", + sessionPath = "sessionPath", ) val secondSessionData = SessionData( userId = "userId", @@ -157,6 +158,7 @@ class DatabaseSessionStoreTest { isTokenValid = 1, loginType = null, passphrase = "aPassphraseAltered", + sessionPath = "sessionPath", ) assertThat(firstSessionData.userId).isEqualTo(secondSessionData.userId) assertThat(firstSessionData.loginTimestamp).isNotEqualTo(secondSessionData.loginTimestamp) @@ -193,6 +195,7 @@ class DatabaseSessionStoreTest { isTokenValid = 1, loginType = null, passphrase = "aPassphrase", + sessionPath = "sessionPath", ) val secondSessionData = SessionData( userId = "userIdUnknown", @@ -206,6 +209,7 @@ class DatabaseSessionStoreTest { isTokenValid = 1, loginType = null, passphrase = "aPassphraseAltered", + sessionPath = "sessionPath", ) assertThat(firstSessionData.userId).isNotEqualTo(secondSessionData.userId) diff --git a/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/Fixtures.kt b/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/Fixtures.kt index 341e5e0e92..37ff2c82b3 100644 --- a/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/Fixtures.kt +++ b/libraries/session-storage/impl/src/test/kotlin/io/element/android/libraries/sessionstorage/impl/Fixtures.kt @@ -31,4 +31,5 @@ internal fun aSessionData() = SessionData( isTokenValid = 1, loginType = LoginType.UNKNOWN.name, passphrase = null, + sessionPath = "sessionPath", ) diff --git a/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/SessionData.kt b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/SessionData.kt index 84c1142193..9ae6100ca1 100644 --- a/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/SessionData.kt +++ b/libraries/session-storage/test/src/main/kotlin/io/element/android/libraries/sessionstorage/test/SessionData.kt @@ -36,5 +36,6 @@ fun aSessionData( isTokenValid = isTokenValid, loginType = LoginType.UNKNOWN, passphrase = null, + sessionPath = "/a/path/to/a/session", ) } diff --git a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt index 6945e5084f..45321a6eb3 100644 --- a/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt +++ b/samples/minimal/src/main/kotlin/io/element/android/samples/minimal/MainActivity.kt @@ -30,6 +30,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.impl.RustMatrixClientFactory import io.element.android.libraries.matrix.impl.analytics.UtdTracker +import io.element.android.libraries.matrix.impl.auth.OidcConfigurationProvider import io.element.android.libraries.matrix.impl.auth.RustMatrixAuthenticationService import io.element.android.libraries.network.useragent.SimpleUserAgentProvider import io.element.android.libraries.sessionstorage.api.LoggedInState @@ -66,6 +67,7 @@ class MainActivity : ComponentActivity() { passphraseGenerator = NullPassphraseGenerator(), userCertificatesProvider = userCertificatesProvider, proxyProvider = proxyProvider, + oidcConfigurationProvider = OidcConfigurationProvider(baseDirectory), ) } diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Day-60_60_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Day-60_60_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index 1539503dc8..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Day-60_60_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94dca1fe2f633ff25724bfc287718f506dee8a18710518fd682de67d9d3d2350 -size 14742 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Night-60_61_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Night-60_61_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index da350147ba..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Night-60_61_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e2588aa42d2fd215f4019e823c8aae87b9ca44b5164b382cc6015f726945168c -size 13478 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Day-61_61_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Day-60_60_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_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Day-61_61_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Day-60_60_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_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Night-61_62_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Night-60_61_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_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Night-61_62_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_EncryptedHistoryBannerView_null_EncryptedHistoryBannerView-Night-60_61_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-62_62_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-61_61_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-62_62_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-61_61_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-62_62_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-61_61_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-62_62_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Day-61_61_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-62_63_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-61_62_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-62_63_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-61_62_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-62_63_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-61_62_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-62_63_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_TimelineItemDaySeparatorView_null_TimelineItemDaySeparatorView-Night-61_62_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_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Day-63_63_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Day-62_62_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_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Day-63_63_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Day-62_62_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_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Night-63_64_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Night-62_63_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_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Night-63_64_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_null_TimelineItemReadMarkerView-Night-62_63_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_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Day-64_64_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Day-63_63_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_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Day-64_64_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Day-63_63_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_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Night-64_65_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Night-63_64_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_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Night-64_65_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_null_TimelineItemRoomBeginningView-Night-63_64_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_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Day-65_65_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Day-64_64_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_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Day-65_65_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Day-64_64_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_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Night-65_66_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Night-64_65_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_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Night-65_66_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_null_TimelineLoadingMoreIndicator-Night-64_65_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_1,NEXUS_5,1.0,en].png index 8b2f180453..5396163fb1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e924c2fc2dc6b66146364d999b77874c883fae2abac9390a1a48c90f61ebf3f7 -size 4928 +oid sha256:de9876d82b13a220cd296f6117bedf7c1a260d9560978701065ce068e22b1c8b +size 4485 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_3,NEXUS_5,1.0,en].png index 2d422864fa..7fd6bf228b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Day-16_16_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8a4dd7d2d6607135bb9e18f684a34df17e0ef1fd2b48fb85bbc6ba82b82e09c5 -size 6213 +oid sha256:cce57f0b6d304c9871fdb3f8a13e1dd787493d95d5edde9631a18e45b9756acc +size 5704 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_1,NEXUS_5,1.0,en].png index f703f2dd98..7148c0371e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ee2232b7d0feb4c7310a695f3b1e58ddb466970a8cef4051e35f7d83dbb1629 -size 4863 +oid sha256:5dc95cafaeda3d0cd45ce37408de0858543f1de07a29b18d165cf2c9a438e9c6 +size 4465 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_3,NEXUS_5,1.0,en].png index 37f721d4c4..ab62303abe 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineEventTimestampView_null_TimelineEventTimestampView-Night-16_17_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bfa1209e3c4c97dffe0f633643a8e4da3509d57998cb047651a7e18daeddb566 -size 6080 +oid sha256:e7d670f258934a3b9b016464f74739a0eff902ec9a184bfb166b116e01de36da +size 5698 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_1,NEXUS_5,1.0,en].png index 1e8199b046..1594e91e0f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f5503888d07219df789c5394553491ad4fe142e7f806d92d2aad95d626d343bd -size 30501 +oid sha256:29cceba22078f6b7791bd5785c7654b68114a7858d043aa5e3b71764089c8ab7 +size 31482 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_3,NEXUS_5,1.0,en].png index bd9d2a86b4..aa9b6c7812 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Day-21_21_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45309834e68ab0b6c6efbb5bfe26cc61f2b9fc171df8734df69dd9c9b2fd9b06 -size 34219 +oid sha256:00e60c9996b9f76848eaa6178aa50ecc4aedd880536800bd307fb68db9c17011 +size 35177 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_1,NEXUS_5,1.0,en].png index b40cb858f3..4efd44ace2 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:724c3407a1b62b22549081165b40faaf26d151e8901209f58dc09465586e6c3c -size 30971 +oid sha256:c3bb375b7a5e3e1566c73693cb19e9a38a33b9f40148ffd219a2e0c2037d7a97 +size 32137 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_3,NEXUS_5,1.0,en].png index 6a90530247..0bc3924405 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components_TimelineItemEventRowTimestamp_null_TimelineItemEventRowTimestamp-Night-21_22_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1675d944150065d33f6b375ae7bc617385099a4bcb76e55a213f322146788d0f -size 34402 +oid sha256:57c3265ca6432efdc69ed45acdb719a10a72544c520b32008c203294bd92f18d +size 35571 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Day-66_66_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Day-65_65_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_EventDebugInfoView_null_EventDebugInfoView-Day-66_66_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Day-65_65_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Night-66_67_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Night-65_66_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_EventDebugInfoView_null_EventDebugInfoView-Night-66_67_null,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.debug_EventDebugInfoView_null_EventDebugInfoView-Night-65_66_null,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_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.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_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.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_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.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_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.focus_FocusRequestStateView_null_FocusRequestStateView-Day-67_67_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Day-66_66_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_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.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_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.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_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.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_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.focus_FocusRequestStateView_null_FocusRequestStateView-Night-67_68_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.focus_FocusRequestStateView_null_FocusRequestStateView-Night-66_67_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_0,NEXUS_5,1.0,en].png index fadf211509..0781ebf8a0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a90813041638a500f77ea67b7d2bd5eda67340aa3167694dd056b3d3b335170 -size 49858 +oid sha256:af29bab33aa3acd1cf0141d339c54764b76ef79978519ad33078dadb2bab39b5 +size 50347 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_1,NEXUS_5,1.0,en].png index d4a72e1d10..cd6ec0918f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b7234d292e54eda42bce2d3ebf5077d663c18e15f5d4fd40d8fedd05696fcab7 -size 70828 +oid sha256:d45f5492470427b578e9a89147114df46b8e97669aa821356ffcb1b13669c360 +size 71317 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_10,NEXUS_5,1.0,en].png index 54272f39d6..4b6810b5b3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28b52a5faf15fed991aff80f2dc7f4da19d3a8eb5f274d880debfd99f502b3d5 -size 328963 +oid sha256:90d6e29da0c6e203b5337496aef692f579f3754c3709735c98d650fe4e519b5b +size 310747 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_11,NEXUS_5,1.0,en].png index fefddddd17..4d88097a8b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8cd185f8149044a4254d418ff5ee670ad85c8d8f2ce235a15045d170c02b8f5 -size 85699 +oid sha256:b3534ec458fa98111819b74453086b203dbd69cbc9aee70141203444f56b01f2 +size 84090 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_12,NEXUS_5,1.0,en].png index 42e04ef916..3ff9c8ca52 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f7aa599537bff4a9db1cf532eab36fc20c823cebb86fded64b53d9084693467b -size 51322 +oid sha256:fa1157e50a67d9fbb25dcb2fba467a684709a329ed2dc6aca9178ccd66e654b7 +size 51816 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_13,NEXUS_5,1.0,en].png index 76316ddb44..2c8958ad02 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_13,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_13,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:566646a9a50e33618141ad6c36291b6e4b620f36d7735723adcca6adf9fbf935 -size 63060 +oid sha256:66ef24a752440232d199c490b3d75db9f9348b5f9665e1f3a668f9496634fd34 +size 63525 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_14,NEXUS_5,1.0,en].png index 6b0c29a0e6..c19eda08f4 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_14,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_14,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c02c2ab99e4b678281272cda0cd0bc851a7e0befd2d6e485b7b76c35abf050b3 -size 47565 +oid sha256:54933b4baf189f65341b3d0d38712de2cca05626df279e9f31b454edf76ba17a +size 47926 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_15,NEXUS_5,1.0,en].png index 3a7f0740f1..768ffe3a70 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_15,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_15,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de8660212fd423769edad29d66d23e0cca408f2ffb4bf23353ab5adafcec26e4 -size 64153 +oid sha256:fb4c57a9fabbd79fb9fd9e2b151c45ac4b72b95f809b67aa0197915172477527 +size 64546 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_16,NEXUS_5,1.0,en].png index 70f9d3cee9..2583076db6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_16,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_16,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:50dbce54adab9c1adc55223568bdbdbf70a5e0b5e08fb3694e30154ac528f34e -size 54824 +oid sha256:27a0bba84f8641eeb7dc0945a66da0d595569afd8a7dd89efabc884989fbc4a8 +size 55233 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_2,NEXUS_5,1.0,en].png index 2d443dc632..536d316361 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6cea814cb38d53b38212faf8932ef57dcb84049d6bb7118021a596bd8448cea8 -size 199469 +oid sha256:2dc3a3b111f837ad42c2d0e5e2ea3292cfdb3b70c8b46340ef4c3171468103b3 +size 193757 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_3,NEXUS_5,1.0,en].png index 990a8c659e..016aa7bdd5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b28a586281470e477a4a5a1fc1d8c0ca269a746d9a48369f6d08dbb8dc63c74 -size 200528 +oid sha256:7084d16f74914bdc62fd23a00dffc866f5e478d9c849e45453f692df2d4449d8 +size 194242 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_4,NEXUS_5,1.0,en].png index 487f74d5db..0431d96d3c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d5728a7c246984c1e8ee2ce070f18222965dad2146955d6bd5efb5d80ae1454 -size 69881 +oid sha256:50e8c9686df4ab245041eef15207f77c18dc183796469e4c6a269e4b1939ffc5 +size 67083 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_5,NEXUS_5,1.0,en].png index 1396dde0b3..0fb0e33a31 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8add799b9c3b94a7194c646eda06e253ac04adb6b6c1ea7d5ca31d5701d2bfa3 -size 84930 +oid sha256:bf1b21d0356f70811ca05b7878db88d7778f83545c47ae05e91b6c687606247e +size 77775 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_6,NEXUS_5,1.0,en].png index 2ac327f131..c311a4d1e3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed1f409ccb67d37447db67191d73486dd86135c9f0332da8e6c1cef01d60dfec -size 72429 +oid sha256:91da42863dc70c8c1c260928af7844d3923df47040716ee195c944eaefedcbb0 +size 69564 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_7,NEXUS_5,1.0,en].png index f5f0015bfb..49f190baa8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:069e35e29631bca1ac0fb815678c38e22eee10c60d8dc65a7196671317a3dbb3 -size 103020 +oid sha256:303dbf1c5c464a915fbda1d88b98a1ea987d10728f6e65f25920ac549c583ca3 +size 94549 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_8,NEXUS_5,1.0,en].png index 7228f25e7d..203ad7fa9b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f0ccb4a3ef7224e0c2068872dfbba9af8c55229005abb22b7387b205983a84d -size 52795 +oid sha256:95df044e19bd5471c7b8eabd813816eef73968e790ff510a72336cdb49c5370d +size 51139 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_9,NEXUS_5,1.0,en].png index d9030d7c3a..7377e60892 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Day-9_9_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:63ff34a6dd748054cb6b48bc08939d8e45f94396a5661206d3aff6d393183ff8 -size 371251 +oid sha256:bb876f78f2e2ebecafbb58095817ad01a220ccb9a70965e7a508183c214d8df6 +size 354592 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_0,NEXUS_5,1.0,en].png index 8a4882b202..1db4d0f25c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:159bc4f7b1865fd14f3efbb4c937ff3f963f56b3f815f91597d79dd9b58fe3e8 -size 48981 +oid sha256:c36e4582167745c80628ef8526dc68906bbff53de097b4c36aa1f4f592d4d9ea +size 50047 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_1,NEXUS_5,1.0,en].png index f1b50f7c06..4c62f9bb73 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44a2192704d4bdbdfbb0537aafc7f230115765adfd4c2b6755ef3961f727de76 -size 69082 +oid sha256:789a326a3af5180bda7dad9d9d77ca79b62812a8f6e24d84a6f3c83abd64e99b +size 69242 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_10,NEXUS_5,1.0,en].png index c4019d6a28..26749a6429 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f8f6344e856b2458045810b00de63781f97baf5310ad484de7434cb4c959b49 -size 148105 +oid sha256:b73ee19ebcf4cb6799a67c80427b7a25e64183b0b52ab1af812e5851847b830e +size 144140 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_11,NEXUS_5,1.0,en].png index 1d60b3c078..828c920437 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e3ab2e2ccdf7803343f934db088d8630398d9b96e92706ad74e322f4ca4425e -size 86729 +oid sha256:118d94c8b41b679847bd91cf01d11f897c65a2521aafd24ffa48a63091c84bc8 +size 85089 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_12,NEXUS_5,1.0,en].png index c6cb236720..b119cc55d6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c97b3c62a1ce328401f9075facf22d9dbef87265f241a601e35939ca4728fd3e -size 50680 +oid sha256:c4149e8fd1203da0ab5a545c3f67094dd737918e57502aa0796697ca72d0c106 +size 51505 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_13,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_13,NEXUS_5,1.0,en].png index 56e137cbc4..5d79c36d11 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_13,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_13,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:474e501b8f1dc9d1a771fda23962396d6c5e5c75e7e61b62bffc4de6f002fba0 -size 61674 +oid sha256:086940e0370602326a9bf5ea997580fd4de5e80de4c0341e3d8fc1578ce6ce0f +size 61864 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_14,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_14,NEXUS_5,1.0,en].png index 9bc445dfa9..540a782147 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_14,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_14,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62259e3aad62ed70fa75fffe7e4caded9f7196210012b780c9fd4e5a8eb54e19 -size 46916 +oid sha256:8b663f20fcb93302d8fe1225a87232ec4e41f743f9242a7efc623e8da7643dd5 +size 47894 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_15,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_15,NEXUS_5,1.0,en].png index 625ba25042..e79fa00980 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_15,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_15,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:53d2b406262b11d2d2106a068f9959a8b7fb58ab32599fdf9a57e0bef0482856 -size 62609 +oid sha256:4668a3a7ac3765532d9e051ed2fe11a9a2c239030d6769649615f1b550f6c9e7 +size 62912 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_16,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_16,NEXUS_5,1.0,en].png index f85222285e..1a757b5aa7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_16,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_16,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3759c91169a805e7521d75d2e17ac0a3efbfa4a08fe62788fd63b5a8af186ff0 -size 53628 +oid sha256:c2ebe0178839e23c368387366120fb8260ff508036b9d5934f377d82e9b9c120 +size 54674 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_2,NEXUS_5,1.0,en].png index b2ca7c2cd4..25a026b9a6 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_2,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_2,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:440efc8cb28716551595ca34eb87e272c451ccc55964a15114a8239d2cc9426e -size 199220 +oid sha256:0e6480a796cd00662a3e14e4c1d4188f7a52c83c29d7efcde2f433e646d1b948 +size 192615 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_3,NEXUS_5,1.0,en].png index d913833434..dea21b6398 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aff74e3869b69e1c04c58487a5f1465092fdc1a729c8f101a67d365b6dc1297a -size 200008 +oid sha256:67e0d7a2b395a791cae4a4498d7b7ba05f999fd07d5103771bf69c58bc4dffab +size 193004 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_4,NEXUS_5,1.0,en].png index 7a7dcce49c..f17d9dec1e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c13fdb271b5131c10c9dba2e8ddb1d7f1fb6b01d7a45957e0c60560d6db3aeb -size 68570 +oid sha256:2901dc01b47ac30f456390b09fdb65bde848f4e02f56faceafefbe7706dcd764 +size 65680 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_5,NEXUS_5,1.0,en].png index 06b3cb7a4b..88d306cd6d 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5a738c3890caf80364c8b76ae83a85942fadc8ca069eb5339dd5b7a66553b26b -size 82988 +oid sha256:d5032b5c43157e218668c78856c1ab4a0e7fd429d8161b919cb8a41be135e53c +size 75958 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_6,NEXUS_5,1.0,en].png index 881987f394..4d5ada1737 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89152c5b043e8ac5eb479c851432fe713992cede85f7d90b072758583e727dc0 -size 71466 +oid sha256:5eb6c2e7b5b6ce965ed1aa2d3aa47deb62946f79d2b0282e87dbb412ed23c4cc +size 68508 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_7,NEXUS_5,1.0,en].png index c622e90b84..8e2590c21e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3846c5c09b5942e51bd19ec5e4183263c89e88dbcd35dc07245c2d2e483fe459 -size 100770 +oid sha256:844fa90309a83dd43b3d4028ae79d48d1c0bdef1a7944b2a4e865d9cf77dcec5 +size 92567 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_8,NEXUS_5,1.0,en].png index aa3e2e6d6b..d95c9dc8f3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a039f9361f2bab38367c29eafe99e61b0026e899213fca0fb6f2f658d8f1bb02 -size 52544 +oid sha256:5505c9f63fff3452d9fc896c943b646b3086669bef40881fde0c77ccbe7fa156 +size 50785 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_9,NEXUS_5,1.0,en].png index be6dd4d1eb..ae1f7c0cdc 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline_TimelineView_null_TimelineView-Night-9_10_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4f7e7cce0cc67dad4c6c8a12f2ea64d1a666fc6145a48a69087a7b09b435ba8 -size 152564 +oid sha256:3cae1244e4454bd92040ba2583aed5980742825f95a00baa843c1a711a408728 +size 149639 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..c314a4c9ab --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19de73540ba48d5ca65b64e5d194e52a977a21592c29dcea6ff45f3f36ea1a3b +size 52261 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..d4b5ac5a93 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a7fe5302b43c78202b4028134ed4df8f6e9558643f4bf8178ff273bee941816 +size 53095 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..db091d9591 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-67_67_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13ff670c0b97e1274d6afb7202fec7bb622be86814315997a79f957e898bee75 +size 49202 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index 834a97a7b2..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d551fd050cc7a439733e4b3125d8c35fc36d640b1fb2e684286da1fcec2ab6ad -size 53861 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index f2674f85f9..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b622f8988d154c5cd053f4014dd75369b2e583ba73032d910a0c3253d2e0a4d0 -size 54727 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_2,NEXUS_5,1.0,en].png deleted file mode 100644 index e7f3bd1499..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Day-68_68_null_2,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f5c9a728f1a642f00b3892e9737a2f2737719958c657cd039b005092445e155 -size 50781 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..3bef28c102 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9db737b3288fcb08871daa469f93bef6ea95070661d3dae02426f7c199f41f5d +size 53004 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..29202c56b6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:891b7b9e40990e87417495261f241c3b477dd206297ee1d357ea8fcdd90159f6 +size 53840 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..c76a3720a6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-67_68_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:428579cbd7ec1f61a89938f2150cf261676fb2fc6658a7917661842efc28020f +size 49986 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index 8aa29792dd..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:249118f1a42822362e978bcf53c9334444e20cd43ad63a547e788bdd1f042899 -size 54666 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index a1a9906792..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:19cb3b5406f9ea7294878bc5f95f3d19c554ed10a9f91e42871206e7406041bb -size 55526 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_2,NEXUS_5,1.0,en].png deleted file mode 100644 index 09d13c6a72..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_MessagesViewWithTyping_null_MessagesViewWithTyping-Night-68_69_null_2,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c8b962ff9ef5e49706ca82d81751469371e56e3ce337df68427803839c40790 -size 51628 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Day-60_60_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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_RetrySendMessageMenu_null_RetrySendMessageMenu-Day-60_60_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_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.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-68_68_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index 1b6fb4bab8..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Day-69_69_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:96a867cb12498cbdc97957bee07855dfaa13602baddaf933aff2b666ef4c7650 -size 3642 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.timeline.components.retrysendmenu_RetrySendMessageMenu_null_RetrySendMessageMenu-Night-60_61_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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_RetrySendMessageMenu_null_RetrySendMessageMenu-Night-60_61_null_0,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_0,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_1,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_1,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_2,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_2,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_3,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_3,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_4,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_4,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_5,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_5,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_6,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_6,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_7,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_7,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_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.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_8,NEXUS_5,1.0,en].png rename to tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-68_69_null_8,NEXUS_5,1.0,en].png diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index d6fd8eeb70..0000000000 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl.typing_TypingNotificationView_null_TypingNotificationView-Night-69_70_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5bb36ccd718f3fec5b04f1bc812dc7718b5ea7fa4619c8b031466297a8d016fd -size 3659 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_0,NEXUS_5,1.0,en].png index da5db5b863..3251147c47 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:276c362b7f0e866a320426d0b03211d28656941b62cc1f2bbf61c03f5e1383d9 -size 55438 +oid sha256:9a9f75213d353879e58f44c677e8624103d7f481ab699a5df53dd774c5a31e5b +size 52658 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_1,NEXUS_5,1.0,en].png index 197d3b4f01..8cf3ac1926 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8f632be800da91e3d4febb62df698fa41df8cedc30b64b3f89fb48ab48479f88 -size 54998 +oid sha256:8831c74f330178283e105bc52732421c9b16119d0bd2bed763df9ed7238bbeed +size 51614 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_10,NEXUS_5,1.0,en].png index fdfcf05e54..a04206308c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e62849a1c0d4293538dccee2b21258999bc0ddbc1b29c499eaf87dff4bb3f00 -size 57099 +oid sha256:4c844567d2284b1ceb1cf990fa480219b444cd7e5a228e076118af3f60330060 +size 54327 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_11,NEXUS_5,1.0,en].png index ac0cfb404b..7d9837e64f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:381bdce7e0862619badd7aa7badf02048fb6f2d38c1ebd18dbfe18f1c76a1415 -size 47138 +oid sha256:9ea468e739fcba66cc8c942738ff657fc2d0d801c52a9dfc93bd0dc425647aa2 +size 44407 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_12,NEXUS_5,1.0,en].png index 7a387dfdae..5ce64e308f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4b5c4bf91c536d5015e4306cbbca6ddf4452a5d01ae7bcb4cfe5fac2a702734 -size 55477 +oid sha256:8b2ad537992b4e99232d660f04823e850b0dbe993370a77da41701a03775355b +size 52662 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_3,NEXUS_5,1.0,en].png index d3f04ca755..5aa8895565 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad89550e4d21912968a99f9cb03b33eb6716b8768ad16448c0e89d50ed96e0cc -size 57957 +oid sha256:e8dbbc5b6b2d017a0bf95cbd11a74abb8ba7883dc203108fbf3af952ea984b52 +size 55655 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_4,NEXUS_5,1.0,en].png index cce0b4edf1..0942fdde3e 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f59f361cdf705b85a09588cf3a34b328f853c15f730e5494fc430457415d3c5a -size 53238 +oid sha256:034deeac70a9226f1e205dcd159506062007118b0fb4e8a6a802d4bb4b34ca2a +size 50335 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_5,NEXUS_5,1.0,en].png index 6f7c26ee8d..1ed84f67ce 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d9d34bf92d440f1b7dd87e803de38b85b63c31e35fcb5f8d13f4c3aedb34dc3 -size 53304 +oid sha256:562d614859a7e299701903096d01566efbc5e69a34cd52b8aaae14131d27be8f +size 50674 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_6,NEXUS_5,1.0,en].png index 2e4c184fa6..84d36014f0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45bc2833a2574cd87ad68e40a629a91d32b6e095bc9b7ab058eb0e903ccccf40 -size 53863 +oid sha256:00d7de2a5361fa33b455ebe3b5763315d00ff779039d01b08211952421dacd8e +size 50053 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_7,NEXUS_5,1.0,en].png index 773942d736..e920a85eb1 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d25804e9ecf8edba92ce806cec52276edf9650495e1cdde4c191464a37272d7 -size 56412 +oid sha256:05411d4eb0d11263d43b57a7c67e8ac2bec1ebadc1220d635a4ae66f65274485 +size 53992 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_8,NEXUS_5,1.0,en].png index 88b005827f..11692cb0a8 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:140aab98b13e6f4564969f0cf0ece72263250d88658f7ddeef21266173ca5626 -size 38300 +oid sha256:5ba8eff7b71d995d22a48aeb2e739fceec6d1a6908f15b04b37a694d5116bf56 +size 37165 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_9,NEXUS_5,1.0,en].png index ff6685622e..0ca16daad3 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Day-0_0_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fce4f7175f66c28ebdfa0a79322078d3685899fb655194cb9a063e2dcf9f175 -size 37579 +oid sha256:be97b0dba2e8203a7fbf101c3ae59f600059b1fb62d951eca21442deeaf31566 +size 36443 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_0,NEXUS_5,1.0,en].png index 6e094b4f5e..e8b3b3e18b 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:72c2f686ce683912ec9fd7a8e1a76ae30abf887c0f379d5581a19f912c1e2812 -size 55325 +oid sha256:294da45aa0eb92dcc09ec4398e5c08ee67d5aa8fb4a28c2bbfc218719e695216 +size 52803 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_1,NEXUS_5,1.0,en].png index a2546e000b..502e8bfeed 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f29a1f0046e3d5484888b7b3dbb86678f60ce57c456e85935c25f243ae1762d1 -size 54778 +oid sha256:d485b0a5eb23a4757a9e18498924fa1d95293b3aacb83f8c7e536d7504767819 +size 51496 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_10,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_10,NEXUS_5,1.0,en].png index 6aa830e4de..15384fb85f 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_10,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_10,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:425147764f554eae83eae0cefa75aefa5b1b91e7b9e47b7238919fced7edb25c -size 56857 +oid sha256:a4cb9e671219a2c448c007b702b6ada9f91bf3dcfc80e42fecf75b7d07d59934 +size 54366 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_11,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_11,NEXUS_5,1.0,en].png index 47a64a934f..31adf1e477 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_11,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_11,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5025e928d2fae2152c77f379f5486faaa27fc585f4b6128ef6d2d97e72593b3 -size 43387 +oid sha256:b11805c536c004d3f22ffefff4c07fc80ff106073f9ab67a879af1f770c9eafb +size 40952 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_12,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_12,NEXUS_5,1.0,en].png index 7b747ae0ce..f38b4974c7 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_12,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_12,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d206813aeb44f8f4832cd11c52f50069e3465150f81df300fe8ebebebff34670 -size 55351 +oid sha256:87c1063cbb57541b02338ef0d09681f2f6b6ba035af7e2ea44a0e15e0d263b34 +size 52818 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_3,NEXUS_5,1.0,en].png index ac4da1c08e..1027e6a30c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_3,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_3,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:babaca465d57957d87eb5650c9e45488f611c50f74a5572e890ac68064fa3b44 -size 57547 +oid sha256:28be632b07cdcb9fa560cf51276a8aa2e42afc47ce35f5292b40ef037aaea407 +size 55766 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_4,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_4,NEXUS_5,1.0,en].png index 46395aea03..6596824545 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_4,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_4,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2e519343e6f2358dc3c0ef9adb2082852847226eb2638c04f68ecc5b2096bb1 -size 49628 +oid sha256:c194e458f638acd1a9a3f99023bd1d22a492f955abf4766e792556a70ccf89fa +size 47152 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_5,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_5,NEXUS_5,1.0,en].png index bb79c05a3a..b50dc9d5d5 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_5,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_5,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bac890895decb6b51c230268aa5509bfa9f90e299f746c605580e7d0b0ce4faf -size 52920 +oid sha256:6d9a167883fd1bfa98a062c2d88215356193d497ad8a8d48b58a33c876957d1a +size 50618 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_6,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_6,NEXUS_5,1.0,en].png index adc9b190e0..108a5324ad 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_6,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_6,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae14459c3689c7a4f76a981ae52f630abb7543417673da0fdc5049ac474ad7ae -size 53649 +oid sha256:1e05626759cc33c599e27f9b6f8720f99a5e03cc7210581321e3f2dba349fbed +size 49992 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_7,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_7,NEXUS_5,1.0,en].png index ef33927a23..5da9af327c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_7,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_7,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ba8f03c80e41b5ac83a16c843d33876b8a864dd8618676d74cd35b8179349b3 -size 52430 +oid sha256:07a828f80adaef6bb1329252248cc21f530818e5173d302ccbd8b10a9d814ff8 +size 50285 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_8,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_8,NEXUS_5,1.0,en].png index ec6bb59600..ff93a71ff0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_8,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_8,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38d61512aedeab57b0ad69aa56aa8d3180aacb89fbc37ddeb6de54840de679ca -size 36184 +oid sha256:7ae2dc28e342ae38be1157306f8cc4d6bc0ff6f70e58dc42ca396232c15e69f1 +size 35190 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_9,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_9,NEXUS_5,1.0,en].png index 96a9346176..6d459fb0e0 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_9,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.messages.impl_MessagesView_null_MessagesView-Night-0_1_null_9,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f621aedbc67d7d6e1e4d09afde978b048943d71851b82fd71e16559513f7ccc1 -size 35452 +oid sha256:5dd1a559e607794d71bda4bc3ff032e5fd365f47ed8a01a29a582d65adcdd64b +size 34452