From 1f0aa23bff695ab8224eb725a9ef12858c786dcd Mon Sep 17 00:00:00 2001 From: Florian Date: Thu, 9 Oct 2025 21:43:47 +0200 Subject: [PATCH 01/13] Add variable playback speed feature for voice messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add playback speed control for voice messages with support for 0.5×, 1×, 1.5×, and 2× playback speeds. The speed button is displayed above the timestamp and cycles through the available speeds when tapped. --- .../components/event/TimelineItemVoiceView.kt | 71 ++++++++++++++++--- .../libraries/mediaplayer/api/MediaPlayer.kt | 6 ++ .../mediaplayer/impl/DefaultMediaPlayer.kt | 4 ++ .../mediaplayer/impl/SimplePlayer.kt | 5 ++ .../mediaplayer/impl/FakeSimplePlayer.kt | 2 + .../mediaplayer/test/FakeMediaPlayer.kt | 4 ++ .../impl/gallery/ui/VoiceItemView.kt | 66 +++++++++++++++-- .../voiceplayer/api/VoiceMessageEvents.kt | 1 + .../voiceplayer/api/VoiceMessageState.kt | 1 + .../api/VoiceMessageStateProvider.kt | 2 + .../voiceplayer/impl/VoiceMessagePlayer.kt | 11 +++ .../voiceplayer/impl/VoiceMessagePresenter.kt | 11 +++ .../impl/VoiceMessagePresenterTest.kt | 34 +++++++++ 13 files changed, 203 insertions(+), 15 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 02d08a8f43..e12887eab1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -8,6 +8,8 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -16,6 +18,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -109,19 +112,30 @@ fun TimelineItemVoiceView( } } Spacer(Modifier.width(8.dp)) - Text( - text = state.time, - color = ElementTheme.colors.textSecondary, - style = ElementTheme.typography.fontBodySmMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + PlaybackSpeedButton( + speed = state.playbackSpeed, + onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + ) + Text( + text = state.time, + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodySmMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } Spacer(Modifier.width(8.dp)) WaveformPlaybackView( showCursor = state.showCursor, playbackProgress = state.progress, waveform = content.waveform, - modifier = Modifier.height(34.dp), + modifier = Modifier + .weight(1f) + .height(34.dp), seekEnabled = !isTalkbackActive(), onSeek = { state.eventSink(VoiceMessageEvents.Seek(it)) }, ) @@ -172,6 +186,36 @@ private fun RetryButton( } } +@Composable +private fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + androidx.compose.foundation.layout.Box( + modifier = Modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .padding(horizontal = 8.dp, vertical = 4.dp) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + @Composable private fun ControlIcon( imageVector: ImageVector, @@ -295,3 +339,14 @@ internal fun ProgressButtonPreview() = ElementPreview { ProgressButton(displayImmediately = false) } } + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt b/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt index 0834323f90..b10dd44b7f 100644 --- a/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt +++ b/libraries/mediaplayer/api/src/main/kotlin/io/element/android/libraries/mediaplayer/api/MediaPlayer.kt @@ -46,6 +46,12 @@ interface MediaPlayer : AutoCloseable { */ fun seekTo(positionMs: Long) + /** + * Sets the playback speed. + * @param speed The playback speed (e.g., 0.5f for half speed, 1.0f for normal, 2.0f for double speed) + */ + fun setPlaybackSpeed(speed: Float) + /** * Releases any resources associated with this player. */ diff --git a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt index 5aad37779c..0767aea3ef 100644 --- a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt +++ b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/DefaultMediaPlayer.kt @@ -160,6 +160,10 @@ class DefaultMediaPlayer( } } + override fun setPlaybackSpeed(speed: Float) { + player.setPlaybackSpeed(speed) + } + override fun close() { player.release() } diff --git a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt index c8e42b8abf..b6aff2570a 100644 --- a/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt +++ b/libraries/mediaplayer/impl/src/main/kotlin/io/element/android/libraries/mediaplayer/impl/SimplePlayer.kt @@ -33,6 +33,7 @@ interface SimplePlayer { fun isPlaying(): Boolean fun pause() fun seekTo(positionMs: Long) + fun setPlaybackSpeed(speed: Float) fun release() interface Listener { fun onIsPlayingChanged(isPlaying: Boolean) @@ -87,5 +88,9 @@ class DefaultSimplePlayer( override fun seekTo(positionMs: Long) = p.seekTo(positionMs) + override fun setPlaybackSpeed(speed: Float) { + p.setPlaybackParameters(p.playbackParameters.withSpeed(speed)) + } + override fun release() = p.release() } diff --git a/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt b/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt index 94c880a862..34078ab4e8 100644 --- a/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt +++ b/libraries/mediaplayer/impl/src/test/kotlin/io/element/android/libraries/mediaplayer/impl/FakeSimplePlayer.kt @@ -19,6 +19,7 @@ class FakeSimplePlayer( private val isPlayingLambda: () -> Boolean = { lambdaError() }, private val pauseLambda: () -> Unit = { lambdaError() }, private val seekToLambda: (Long) -> Unit = { lambdaError() }, + private val setPlaybackSpeedLambda: (Float) -> Unit = { lambdaError() }, private val releaseLambda: () -> Unit = { lambdaError() }, ) : SimplePlayer { private val listeners = mutableListOf() @@ -44,6 +45,7 @@ class FakeSimplePlayer( override fun isPlaying() = isPlayingLambda() override fun pause() = pauseLambda() override fun seekTo(positionMs: Long) = seekToLambda(positionMs) + override fun setPlaybackSpeed(speed: Float) = setPlaybackSpeedLambda(speed) override fun release() = releaseLambda() fun simulateIsPlayingChanged(isPlaying: Boolean) { diff --git a/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt b/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt index 1e670d4675..0dcd655424 100644 --- a/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt +++ b/libraries/mediaplayer/test/src/main/kotlin/io/element/android/libraries/mediaplayer/test/FakeMediaPlayer.kt @@ -95,6 +95,10 @@ class FakeMediaPlayer( } } + override fun setPlaybackSpeed(speed: Float) { + // no-op + } + override fun close() { // no-op } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 6d5fdd9612..bd8daa69e1 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -9,7 +9,9 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -119,13 +121,22 @@ private fun VoiceInfoRow( VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) } Spacer(Modifier.width(8.dp)) - Text( - text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, - color = ElementTheme.colors.textSecondary, - style = ElementTheme.typography.fontBodyMdMedium, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + PlaybackSpeedButton( + speed = state.playbackSpeed, + onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + ) + Text( + text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodyMdMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } Spacer(modifier = Modifier.width(8.dp)) WaveformPlaybackView( modifier = Modifier @@ -223,6 +234,36 @@ private fun RetryButton( } } +@Composable +private fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + androidx.compose.foundation.layout.Box( + modifier = Modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .padding(horizontal = 8.dp, vertical = 4.dp) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + @Composable private fun ControlIcon( imageVector: ImageVector, @@ -283,3 +324,14 @@ internal fun VoiceItemViewPlayPreview( onLongClick = {}, ) } + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt index db97331b6f..7e5430a566 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt @@ -10,4 +10,5 @@ package io.element.android.libraries.voiceplayer.api sealed interface VoiceMessageEvents { data object PlayPause : VoiceMessageEvents data class Seek(val percentage: Float) : VoiceMessageEvents + data object ChangePlaybackSpeed : VoiceMessageEvents } diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index f14bf690cc..522b5cfbe2 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -12,6 +12,7 @@ data class VoiceMessageState( val progress: Float, val time: String, val showCursor: Boolean, + val playbackSpeed: Float, val eventSink: (event: VoiceMessageEvents) -> Unit, ) { enum class Button { diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt index 0ff510a485..bfc2f144ab 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt @@ -47,10 +47,12 @@ fun aVoiceMessageState( progress: Float = 0f, time: String = "1:00", showCursor: Boolean = false, + playbackSpeed: Float = 1.0f, ) = VoiceMessageState( button = button, progress = progress, time = time, showCursor = showCursor, + playbackSpeed = playbackSpeed, eventSink = {}, ) diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt index 64a479105d..51a1163e36 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePlayer.kt @@ -79,6 +79,13 @@ interface VoiceMessagePlayer { */ fun seekTo(positionMs: Long) + /** + * Set the playback speed. + * + * @param speed The playback speed (e.g., 0.5f for half speed, 1.0f for normal, 2.0f for double speed) + */ + fun setPlaybackSpeed(speed: Float) + data class State( /** * Whether the player is ready to play. @@ -218,6 +225,10 @@ class Factory( } } + override fun setPlaybackSpeed(speed: Float) { + mediaPlayer.setPlaybackSpeed(speed) + } + private val MediaPlayer.State.isMyTrack: Boolean get() = if (eventId == null) false else this.mediaId == eventId.value diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index c7811f6d17..9637c5e587 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -37,6 +37,9 @@ class VoiceMessagePresenter( private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) + private val playbackSpeed = mutableStateOf(1.0f) + + private val availablePlaybackSpeeds = listOf(0.5f, 1.0f, 1.5f, 2.0f) @Composable override fun present(): VoiceMessageState { @@ -111,6 +114,13 @@ class VoiceMessagePresenter( is VoiceMessageEvents.Seek -> { player.seekTo((event.percentage * duration).toLong()) } + is VoiceMessageEvents.ChangePlaybackSpeed -> { + val currentIndex = availablePlaybackSpeeds.indexOf(playbackSpeed.value) + val nextIndex = (currentIndex + 1) % availablePlaybackSpeeds.size + val newSpeed = availablePlaybackSpeeds[nextIndex] + playbackSpeed.value = newSpeed + player.setPlaybackSpeed(newSpeed) + } } } @@ -119,6 +129,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, + playbackSpeed = playbackSpeed.value, eventSink = { eventSink(it) }, ) } diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 9d16cd6bcc..5f0b34b45e 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -222,6 +222,40 @@ class VoiceMessagePresenterTest { } } } + + @Test + fun `changing playback speed cycles through available speeds`() = runTest { + val presenter = createVoiceMessagePresenter( + duration = 10_000.milliseconds, + ) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.5f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(2.0f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(0.5f) + } + + initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + } + } + } } fun TestScope.createVoiceMessagePresenter( From 32d2d312e98495f9333624322f3749c897a656bd Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 30 Dec 2025 21:24:41 +0100 Subject: [PATCH 02/13] Increase clickable area of playback speed button --- .../impl/timeline/components/event/TimelineItemVoiceView.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index e12887eab1..f231988f90 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -204,8 +204,8 @@ private fun PlaybackSpeedButton( color = ElementTheme.colors.bgCanvasDefault, shape = RoundedCornerShape(12.dp) ) - .padding(horizontal = 8.dp, vertical = 4.dp) - .clickable(onClick = onClick), + .clickable(onClick = onClick) + .padding(horizontal = 8.dp, vertical = 4.dp), contentAlignment = Alignment.Center, ) { Text( From bbe8e112cd48856ce02c014c952f9cf4aad47d37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:17:40 +0100 Subject: [PATCH 03/13] Extract PlaybackSpeedButton as an Atom. --- .../components/event/TimelineItemVoiceView.kt | 44 +------------ .../atomic/atoms/PlaybackSpeedButton.kt | 65 +++++++++++++++++++ .../impl/gallery/ui/VoiceItemView.kt | 43 +----------- 3 files changed, 67 insertions(+), 85 deletions(-) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 1010075803..45534e9591 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -19,7 +18,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -45,6 +43,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContentProvider +import io.element.android.libraries.designsystem.atomic.atoms.PlaybackSpeedButton import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -187,36 +186,6 @@ private fun RetryButton( } } -@Composable -private fun PlaybackSpeedButton( - speed: Float, - onClick: () -> Unit, -) { - val speedText = when (speed) { - 0.5f -> "0.5×" - 1.0f -> "1×" - 1.5f -> "1.5×" - 2.0f -> "2×" - else -> "${speed}×" - } - androidx.compose.foundation.layout.Box( - modifier = Modifier - .background( - color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) - ) - .clickable(onClick = onClick) - .padding(horizontal = 8.dp, vertical = 4.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = speedText, - color = ElementTheme.colors.iconSecondary, - style = ElementTheme.typography.fontBodyXsMedium, - ) - } -} - @Composable private fun ControlIcon( imageVector: ImageVector, @@ -340,14 +309,3 @@ internal fun ProgressButtonPreview() = ElementPreview { ProgressButton(displayImmediately = false) } } - -@PreviewsDayNight -@Composable -internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) - } -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt new file mode 100644 index 0000000000..bfc876d13a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.atomic.atoms + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.designsystem.theme.components.Text + +@Composable +fun PlaybackSpeedButton( + speed: Float, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + val speedText = when (speed) { + 0.5f -> "0.5×" + 1.0f -> "1×" + 1.5f -> "1.5×" + 2.0f -> "2×" + else -> "${speed}×" + } + Box( + modifier = modifier + .background( + color = ElementTheme.colors.bgCanvasDefault, + shape = RoundedCornerShape(12.dp) + ) + .clickable(onClick = onClick) + .padding(horizontal = 8.dp, vertical = 4.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = speedText, + color = ElementTheme.colors.iconSecondary, + style = ElementTheme.typography.fontBodyXsMedium, + ) + } +} + +@PreviewsDayNight +@Composable +internal fun PlaybackSpeedButtonPreview() = ElementPreview { + Row { + PlaybackSpeedButton(speed = 0.5f, onClick = {}) + PlaybackSpeedButton(speed = 1.0f, onClick = {}) + PlaybackSpeedButton(speed = 1.5f, onClick = {}) + PlaybackSpeedButton(speed = 2.0f, onClick = {}) + } +} diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 878c8ffd3a..9b2eaa2b32 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -10,7 +10,6 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -40,6 +39,7 @@ 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.libraries.designsystem.atomic.atoms.PlaybackSpeedButton import io.element.android.libraries.designsystem.components.media.WaveformPlaybackView import io.element.android.libraries.designsystem.modifiers.onKeyboardContextMenuAction import io.element.android.libraries.designsystem.preview.ElementPreview @@ -235,36 +235,6 @@ private fun RetryButton( } } -@Composable -private fun PlaybackSpeedButton( - speed: Float, - onClick: () -> Unit, -) { - val speedText = when (speed) { - 0.5f -> "0.5×" - 1.0f -> "1×" - 1.5f -> "1.5×" - 2.0f -> "2×" - else -> "${speed}×" - } - androidx.compose.foundation.layout.Box( - modifier = Modifier - .background( - color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) - ) - .padding(horizontal = 8.dp, vertical = 4.dp) - .clickable(onClick = onClick), - contentAlignment = Alignment.Center, - ) { - Text( - text = speedText, - color = ElementTheme.colors.iconSecondary, - style = ElementTheme.typography.fontBodyXsMedium, - ) - } -} - @Composable private fun ControlIcon( imageVector: ImageVector, @@ -325,14 +295,3 @@ internal fun VoiceItemViewPlayPreview( onLongClick = {}, ) } - -@PreviewsDayNight -@Composable -internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) - } -} From 8a52d2b8ce9252f909e2f4b16ab3cc24f1696928 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:23:08 +0100 Subject: [PATCH 04/13] Improve preview. --- .../atomic/atoms/PlaybackSpeedButton.kt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index bfc876d13a..66bdf6505d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.designsystem.atomic.atoms import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding @@ -21,6 +22,7 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.designsystem.theme.messageFromMeBackground @Composable fun PlaybackSpeedButton( @@ -56,10 +58,17 @@ fun PlaybackSpeedButton( @PreviewsDayNight @Composable internal fun PlaybackSpeedButtonPreview() = ElementPreview { - Row { - PlaybackSpeedButton(speed = 0.5f, onClick = {}) - PlaybackSpeedButton(speed = 1.0f, onClick = {}) - PlaybackSpeedButton(speed = 1.5f, onClick = {}) - PlaybackSpeedButton(speed = 2.0f, onClick = {}) + Row( + modifier = Modifier + .background(ElementTheme.colors.messageFromMeBackground) + .padding(4.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + listOf(0.5f, 1.0f, 1.5f, 2.0f, 3.0f).forEach { speed -> + PlaybackSpeedButton( + speed = speed, + onClick = {}, + ) + } } } From f59e979aab63200caa863b392465a5d9956047a5 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:43:25 +0100 Subject: [PATCH 05/13] Create VoicePlayerConfig. --- .../voiceplayer/impl/VoiceMessagePresenter.kt | 14 +++++--------- .../voiceplayer/impl/VoicePlayerConfig.kt | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 089e7fa533..95c9554731 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import io.element.android.libraries.architecture.AsyncData @@ -38,9 +39,7 @@ class VoiceMessagePresenter( private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) - private val playbackSpeed = mutableStateOf(1.0f) - - private val availablePlaybackSpeeds = listOf(0.5f, 1.0f, 1.5f, 2.0f) + private val playbackSpeedIndex = mutableIntStateOf(0) @Composable override fun present(): VoiceMessageState { @@ -116,11 +115,8 @@ class VoiceMessagePresenter( player.seekTo((event.percentage * duration).toLong()) } is VoiceMessageEvents.ChangePlaybackSpeed -> { - val currentIndex = availablePlaybackSpeeds.indexOf(playbackSpeed.value) - val nextIndex = (currentIndex + 1) % availablePlaybackSpeeds.size - val newSpeed = availablePlaybackSpeeds[nextIndex] - playbackSpeed.value = newSpeed - player.setPlaybackSpeed(newSpeed) + playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size + player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) } } } @@ -130,7 +126,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, - playbackSpeed = playbackSpeed.value, + playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue], eventSink = ::handleEvent, ) } diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt new file mode 100644 index 0000000000..3ade34d99f --- /dev/null +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerConfig.kt @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.voiceplayer.impl + +object VoicePlayerConfig { + // Available playback speeds for voice messages, the first one is the default speed, and + // the UI will allow to change to the next speed in the list, in loop. + val availablePlaybackSpeeds = listOf(1.0f, 1.5f, 2.0f, 0.5f) +} From 7e4b4e4076cd00bb96d0a231b132e0c8db4bb86e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:46:44 +0100 Subject: [PATCH 06/13] Avoid reusing the initialState to send event. --- .../impl/VoiceMessagePresenterTest.kt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index fe680422f6..ac35e77ee4 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -212,10 +212,9 @@ class VoiceMessagePresenterTest { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") + it.eventSink(VoiceMessageEvents.Seek(0.5f)) } - initialState.eventSink(VoiceMessageEvents.Seek(0.5f)) - awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.5f) @@ -232,26 +231,22 @@ class VoiceMessagePresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitItem().also { + awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.5f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(2.0f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(0.5f) + it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) } - - initialState.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) } From 9e25db97f744a5db3fa49a6fcbbefb41b3e6a7fc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:47:45 +0100 Subject: [PATCH 07/13] Use test extension --- .../impl/VoiceMessagePresenterTest.kt | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index ac35e77ee4..87f7ffbc34 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -8,9 +8,6 @@ package io.element.android.libraries.voiceplayer.impl -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.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.core.EventId @@ -21,6 +18,7 @@ import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.test import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Test @@ -31,9 +29,7 @@ class VoiceMessagePresenterTest { @Test fun `initial state has proper default values`() = runTest { val presenter = createVoiceMessagePresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().let { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -48,9 +44,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -86,9 +80,7 @@ class VoiceMessagePresenterTest { analyticsService = analyticsService, duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -122,9 +114,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 2_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -154,9 +144,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( eventId = null, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Disabled) assertThat(it.progress).isEqualTo(0f) @@ -171,9 +159,7 @@ class VoiceMessagePresenterTest { mediaPlayer = FakeMediaPlayer(fakeTotalDurationMs = 2_000), duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -195,9 +181,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0f) @@ -228,9 +212,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter( duration = 10_000.milliseconds, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) From 4f44edf6af14cf2577f1864832704905c4b0c875 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:48:46 +0100 Subject: [PATCH 08/13] VoiceMessageEvents -> VoiceMessageEvent --- .../components/event/TimelineItemVoiceView.kt | 8 +++---- .../impl/gallery/ui/VoiceItemView.kt | 8 +++---- ...eMessageEvents.kt => VoiceMessageEvent.kt} | 8 +++---- .../voiceplayer/api/VoiceMessageState.kt | 2 +- .../voiceplayer/impl/VoiceMessagePresenter.kt | 10 ++++---- .../impl/VoiceMessagePresenterTest.kt | 24 +++++++++---------- 6 files changed, 30 insertions(+), 30 deletions(-) rename libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/{VoiceMessageEvents.kt => VoiceMessageEvent.kt} (58%) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 45534e9591..203fd8f1da 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -53,7 +53,7 @@ import io.element.android.libraries.designsystem.theme.components.IconButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.utils.time.isTalkbackActive -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider import kotlinx.coroutines.delay @@ -66,7 +66,7 @@ fun TimelineItemVoiceView( modifier: Modifier = Modifier, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } val a11y = stringResource(CommonStrings.common_voice_message) @@ -118,7 +118,7 @@ fun TimelineItemVoiceView( ) { PlaybackSpeedButton( speed = state.playbackSpeed, - onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + onClick = { state.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) }, ) Text( text = state.time, @@ -137,7 +137,7 @@ fun TimelineItemVoiceView( .weight(1f) .height(34.dp), seekEnabled = !isTalkbackActive(), - onSeek = { state.eventSink(VoiceMessageEvents.Seek(it)) }, + onSeek = { state.eventSink(VoiceMessageEvent.Seek(it)) }, ) } } diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index 9b2eaa2b32..f608236e49 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -52,7 +52,7 @@ import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.mediaviewer.impl.model.MediaItem import io.element.android.libraries.mediaviewer.impl.model.aMediaItemVoice import io.element.android.libraries.ui.strings.CommonStrings -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageStateProvider import io.element.android.libraries.voiceplayer.api.aVoiceMessageState @@ -94,7 +94,7 @@ private fun VoiceInfoRow( onLongClick: () -> Unit, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } Row( @@ -128,7 +128,7 @@ private fun VoiceInfoRow( ) { PlaybackSpeedButton( speed = state.playbackSpeed, - onClick = { state.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) }, + onClick = { state.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) }, ) Text( text = if (state.progress > 0f) state.time else voice.mediaInfo.duration ?: state.time, @@ -147,7 +147,7 @@ private fun VoiceInfoRow( playbackProgress = state.progress, waveform = voice.mediaInfo.waveform.orEmpty().toImmutableList(), onSeek = { - state.eventSink(VoiceMessageEvents.Seek(it)) + state.eventSink(VoiceMessageEvent.Seek(it)) }, seekEnabled = true, ) diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt similarity index 58% rename from libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt rename to libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt index 01910ddcd6..bec03f3943 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvents.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageEvent.kt @@ -8,8 +8,8 @@ package io.element.android.libraries.voiceplayer.api -sealed interface VoiceMessageEvents { - data object PlayPause : VoiceMessageEvents - data class Seek(val percentage: Float) : VoiceMessageEvents - data object ChangePlaybackSpeed : VoiceMessageEvents +sealed interface VoiceMessageEvent { + data object PlayPause : VoiceMessageEvent + data class Seek(val percentage: Float) : VoiceMessageEvent + data object ChangePlaybackSpeed : VoiceMessageEvent } diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index a66209c5db..36fa13a268 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -14,7 +14,7 @@ data class VoiceMessageState( val time: String, val showCursor: Boolean, val playbackSpeed: Float, - val eventSink: (event: VoiceMessageEvents) -> Unit, + val eventSink: (event: VoiceMessageEvent) -> Unit, ) { enum class Button { Play, diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 95c9554731..c58838963a 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -22,7 +22,7 @@ import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.ui.utils.time.formatShort -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService @@ -87,9 +87,9 @@ class VoiceMessagePresenter( } } - fun handleEvent(event: VoiceMessageEvents) { + fun handleEvent(event: VoiceMessageEvent) { when (event) { - is VoiceMessageEvents.PlayPause -> { + is VoiceMessageEvent.PlayPause -> { if (playerState.isPlaying) { player.pause() } else if (playerState.isReady) { @@ -111,10 +111,10 @@ class VoiceMessagePresenter( } } } - is VoiceMessageEvents.Seek -> { + is VoiceMessageEvent.Seek -> { player.seekTo((event.percentage * duration).toLong()) } - is VoiceMessageEvents.ChangePlaybackSpeed -> { + is VoiceMessageEvent.ChangePlaybackSpeed -> { playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) } diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 87f7ffbc34..3d9c452c2a 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -13,7 +13,7 @@ import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.media.MediaSource import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer -import io.element.android.libraries.voiceplayer.api.VoiceMessageEvents +import io.element.android.libraries.voiceplayer.api.VoiceMessageEvent import io.element.android.libraries.voiceplayer.api.VoiceMessageException import io.element.android.libraries.voiceplayer.api.VoiceMessageState import io.element.android.services.analytics.api.AnalyticsService @@ -51,7 +51,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) @@ -87,7 +87,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) @@ -121,7 +121,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) skipItems(2) // skip downloading states val playingState = awaitItem().also { @@ -130,7 +130,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:01") } - playingState.eventSink(VoiceMessageEvents.PlayPause) + playingState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) assertThat(it.progress).isEqualTo(0.5f) @@ -166,7 +166,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:10") } - initialState.eventSink(VoiceMessageEvents.Seek(0.5f)) + initialState.eventSink(VoiceMessageEvent.Seek(0.5f)) awaitItem().also { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) @@ -188,7 +188,7 @@ class VoiceMessagePresenterTest { assertThat(it.time).isEqualTo("0:10") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) skipItems(2) // skip downloading states @@ -196,7 +196,7 @@ class VoiceMessagePresenterTest { assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") - it.eventSink(VoiceMessageEvents.Seek(0.5f)) + it.eventSink(VoiceMessageEvent.Seek(0.5f)) } awaitItem().also { @@ -215,19 +215,19 @@ class VoiceMessagePresenterTest { presenter.test { awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.5f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(2.0f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(0.5f) - it.eventSink(VoiceMessageEvents.ChangePlaybackSpeed) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) } awaitItem().also { assertThat(it.playbackSpeed).isEqualTo(1.0f) From 4c0b02ce23a389e319ac384b5967b1388022650b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 09:51:38 +0100 Subject: [PATCH 09/13] Rename Button to ButtonType to avoid confusion. --- .../components/event/TimelineItemVoiceView.kt | 28 +++++++-------- .../impl/gallery/ui/VoiceItemView.kt | 12 +++---- .../voiceplayer/api/VoiceMessageState.kt | 4 +-- .../api/VoiceMessageStateProvider.kt | 14 ++++---- .../voiceplayer/impl/VoiceMessagePresenter.kt | 14 ++++---- .../impl/VoiceMessagePresenterTest.kt | 34 +++++++++---------- 6 files changed, 53 insertions(+), 53 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt index 203fd8f1da..5dbd0c478f 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/event/TimelineItemVoiceView.kt @@ -71,21 +71,21 @@ fun TimelineItemVoiceView( val a11y = stringResource(CommonStrings.common_voice_message) val a11yActionLabel = stringResource( - when (state.button) { - VoiceMessageState.Button.Play -> CommonStrings.a11y_play - VoiceMessageState.Button.Pause -> CommonStrings.a11y_pause - VoiceMessageState.Button.Downloading -> CommonStrings.common_downloading - VoiceMessageState.Button.Retry -> CommonStrings.action_retry - VoiceMessageState.Button.Disabled -> CommonStrings.error_unknown + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> CommonStrings.a11y_play + VoiceMessageState.ButtonType.Pause -> CommonStrings.a11y_pause + VoiceMessageState.ButtonType.Downloading -> CommonStrings.common_downloading + VoiceMessageState.ButtonType.Retry -> CommonStrings.action_retry + VoiceMessageState.ButtonType.Disabled -> CommonStrings.error_unknown } ) Row( modifier = modifier .clearAndSetSemantics { contentDescription = a11y - if (state.button == VoiceMessageState.Button.Disabled) { + if (state.buttonType == VoiceMessageState.ButtonType.Disabled) { disabled() - } else if (state.button in listOf(VoiceMessageState.Button.Play, VoiceMessageState.Button.Pause)) { + } else if (state.buttonType in listOf(VoiceMessageState.ButtonType.Play, VoiceMessageState.ButtonType.Pause)) { onClick(label = a11yActionLabel) { playPause() true @@ -103,12 +103,12 @@ fun TimelineItemVoiceView( verticalAlignment = Alignment.CenterVertically, ) { if (!isTalkbackActive()) { - when (state.button) { - VoiceMessageState.Button.Play -> PlayButton(onClick = ::playPause) - VoiceMessageState.Button.Pause -> PauseButton(onClick = ::playPause) - VoiceMessageState.Button.Downloading -> ProgressButton() - VoiceMessageState.Button.Retry -> RetryButton(onClick = ::playPause) - VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> PlayButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Pause -> PauseButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Downloading -> ProgressButton() + VoiceMessageState.ButtonType.Retry -> RetryButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Disabled -> PlayButton(onClick = {}, enabled = false) } } Spacer(Modifier.width(8.dp)) diff --git a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt index f608236e49..dbbeb28b80 100644 --- a/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt +++ b/libraries/mediaviewer/impl/src/main/kotlin/io/element/android/libraries/mediaviewer/impl/gallery/ui/VoiceItemView.kt @@ -114,12 +114,12 @@ private fun VoiceInfoRow( .padding(start = 12.dp, end = 36.dp, top = 8.dp, bottom = 8.dp), verticalAlignment = Alignment.CenterVertically, ) { - when (state.button) { - VoiceMessageState.Button.Play -> PlayButton(onClick = ::playPause) - VoiceMessageState.Button.Pause -> PauseButton(onClick = ::playPause) - VoiceMessageState.Button.Downloading -> ProgressButton() - VoiceMessageState.Button.Retry -> RetryButton(onClick = ::playPause) - VoiceMessageState.Button.Disabled -> PlayButton(onClick = {}, enabled = false) + when (state.buttonType) { + VoiceMessageState.ButtonType.Play -> PlayButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Pause -> PauseButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Downloading -> ProgressButton() + VoiceMessageState.ButtonType.Retry -> RetryButton(onClick = ::playPause) + VoiceMessageState.ButtonType.Disabled -> PlayButton(onClick = {}, enabled = false) } Spacer(Modifier.width(8.dp)) Column( diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt index 36fa13a268..2faf35f91f 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageState.kt @@ -9,14 +9,14 @@ package io.element.android.libraries.voiceplayer.api data class VoiceMessageState( - val button: Button, + val buttonType: ButtonType, val progress: Float, val time: String, val showCursor: Boolean, val playbackSpeed: Float, val eventSink: (event: VoiceMessageEvent) -> Unit, ) { - enum class Button { + enum class ButtonType { Play, Pause, Downloading, diff --git a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt index d8ccb85832..dd8d222e69 100644 --- a/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt +++ b/libraries/voiceplayer/api/src/main/kotlin/io/element/android/libraries/voiceplayer/api/VoiceMessageStateProvider.kt @@ -14,29 +14,29 @@ open class VoiceMessageStateProvider : PreviewParameterProvider get() = sequenceOf( aVoiceMessageState( - VoiceMessageState.Button.Downloading, + VoiceMessageState.ButtonType.Downloading, progress = 0f, time = "0:00", ), aVoiceMessageState( - VoiceMessageState.Button.Retry, + VoiceMessageState.ButtonType.Retry, progress = 0.5f, time = "0:01", ), aVoiceMessageState( - VoiceMessageState.Button.Play, + VoiceMessageState.ButtonType.Play, progress = 1f, time = "1:00", showCursor = true, ), aVoiceMessageState( - VoiceMessageState.Button.Pause, + VoiceMessageState.ButtonType.Pause, progress = 0.2f, time = "10:00", showCursor = true, ), aVoiceMessageState( - VoiceMessageState.Button.Disabled, + VoiceMessageState.ButtonType.Disabled, progress = 0.2f, time = "30:00", ), @@ -44,13 +44,13 @@ open class VoiceMessageStateProvider : PreviewParameterProvider VoiceMessageState.Button.Disabled - playerState.isPlaying -> VoiceMessageState.Button.Pause - play.value is AsyncData.Loading -> VoiceMessageState.Button.Downloading - play.value is AsyncData.Failure -> VoiceMessageState.Button.Retry - else -> VoiceMessageState.Button.Play + eventId == null -> VoiceMessageState.ButtonType.Disabled + playerState.isPlaying -> VoiceMessageState.ButtonType.Pause + play.value is AsyncData.Loading -> VoiceMessageState.ButtonType.Downloading + play.value is AsyncData.Failure -> VoiceMessageState.ButtonType.Retry + else -> VoiceMessageState.ButtonType.Play } } } @@ -122,7 +122,7 @@ class VoiceMessagePresenter( } return VoiceMessageState( - button = button, + buttonType = buttonType, progress = progress, time = time, showCursor = showCursor, diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index 3d9c452c2a..e6ae760b53 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -31,7 +31,7 @@ class VoiceMessagePresenterTest { val presenter = createVoiceMessagePresenter() presenter.test { awaitItem().let { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -46,7 +46,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -54,17 +54,17 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:00") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } @@ -82,7 +82,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -90,12 +90,12 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Downloading) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Downloading) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Retry) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Retry) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -116,7 +116,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } @@ -125,14 +125,14 @@ class VoiceMessagePresenterTest { skipItems(2) // skip downloading states val playingState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } playingState.eventSink(VoiceMessageEvent.PlayPause) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:01") } @@ -146,7 +146,7 @@ class VoiceMessagePresenterTest { ) presenter.test { awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Disabled) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Disabled) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -161,7 +161,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:10") } @@ -169,7 +169,7 @@ class VoiceMessagePresenterTest { initialState.eventSink(VoiceMessageEvent.Seek(0.5f)) awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:05") } @@ -183,7 +183,7 @@ class VoiceMessagePresenterTest { ) presenter.test { val initialState = awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Play) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:10") } @@ -193,14 +193,14 @@ class VoiceMessagePresenterTest { skipItems(2) // skip downloading states awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.1f) assertThat(it.time).isEqualTo("0:01") it.eventSink(VoiceMessageEvent.Seek(0.5f)) } awaitItem().also { - assertThat(it.button).isEqualTo(VoiceMessageState.Button.Pause) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Pause) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:05") } From c9b3a19a90d96125e9fb4d1154c5c1455192e22f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 10:02:58 +0100 Subject: [PATCH 10/13] Improve click effect. --- .../libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index 66bdf6505d..e00d0c92d7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -17,6 +17,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.libraries.designsystem.preview.ElementPreview @@ -39,9 +40,9 @@ fun PlaybackSpeedButton( } Box( modifier = modifier + .clip(RoundedCornerShape(12.dp)) .background( color = ElementTheme.colors.bgCanvasDefault, - shape = RoundedCornerShape(12.dp) ) .clickable(onClick = onClick) .padding(horizontal = 8.dp, vertical = 4.dp), From 325d7d5fdea14c3bc0897a68723f9db9e2f21a47 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 11:24:49 +0100 Subject: [PATCH 11/13] Remove useless curly braces --- .../libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt index e00d0c92d7..dfd98dd5da 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -36,7 +36,7 @@ fun PlaybackSpeedButton( 1.0f -> "1×" 1.5f -> "1.5×" 2.0f -> "2×" - else -> "${speed}×" + else -> "$speed×" } Box( modifier = modifier From 152b351bf3bb5d8c4864a08db7484955c56163f0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 31 Dec 2025 11:28:26 +0100 Subject: [PATCH 12/13] Store voice player playback index in a datastore. --- libraries/voiceplayer/impl/build.gradle.kts | 2 + .../DefaultVoiceMessagePresenterFactory.kt | 2 + .../voiceplayer/impl/VoiceMessagePresenter.kt | 21 +++++++--- .../voiceplayer/impl/VoicePlayerStore.kt | 41 +++++++++++++++++++ .../impl/InMemoryVoicePlayerStore.kt | 26 ++++++++++++ .../impl/VoiceMessagePresenterTest.kt | 2 + 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt create mode 100644 libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt diff --git a/libraries/voiceplayer/impl/build.gradle.kts b/libraries/voiceplayer/impl/build.gradle.kts index 679e8206d9..4aa00e188b 100644 --- a/libraries/voiceplayer/impl/build.gradle.kts +++ b/libraries/voiceplayer/impl/build.gradle.kts @@ -26,10 +26,12 @@ dependencies { implementation(projects.libraries.di) implementation(projects.libraries.matrix.api) implementation(projects.libraries.mediaplayer.api) + implementation(projects.libraries.preferences.api) implementation(projects.libraries.uiUtils) implementation(projects.services.analytics.api) implementation(libs.androidx.annotationjvm) + implementation(libs.androidx.datastore.preferences) implementation(libs.coroutines.core) testCommonDependencies(libs) diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt index b2518eaca0..0a262b8145 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/DefaultVoiceMessagePresenterFactory.kt @@ -26,6 +26,7 @@ class DefaultVoiceMessagePresenterFactory( @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val voiceMessagePlayerFactory: VoiceMessagePlayer.Factory, + private val voicePlayerStore: VoicePlayerStore, ) : VoiceMessagePresenterFactory { override fun createVoiceMessagePresenter( eventId: EventId?, @@ -44,6 +45,7 @@ class DefaultVoiceMessagePresenterFactory( return VoiceMessagePresenter( analyticsService = analyticsService, sessionCoroutineScope = sessionCoroutineScope, + voicePlayerStore = voicePlayerStore, player = player, eventId = eventId, duration = duration, diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt index 37952d34b5..be93ab6526 100644 --- a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenter.kt @@ -9,12 +9,13 @@ package io.element.android.libraries.voiceplayer.impl import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState @@ -34,15 +35,16 @@ import kotlin.time.Duration.Companion.milliseconds class VoiceMessagePresenter( private val analyticsService: AnalyticsService, private val sessionCoroutineScope: CoroutineScope, + private val voicePlayerStore: VoicePlayerStore, private val player: VoiceMessagePlayer, private val eventId: EventId?, private val duration: Duration, ) : Presenter { private val play = mutableStateOf>(AsyncData.Uninitialized) - private val playbackSpeedIndex = mutableIntStateOf(0) @Composable override fun present(): VoiceMessageState { + val localCoroutineScope = rememberCoroutineScope() val playerState by player.state.collectAsState( VoiceMessagePlayer.State( isReady = false, @@ -53,6 +55,12 @@ class VoiceMessagePresenter( ) ) + val playbackSpeedIndex by voicePlayerStore.playBackSpeedIndex().collectAsState(0) + + LaunchedEffect(playbackSpeedIndex) { + player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex]) + } + val buttonType by remember { derivedStateOf { when { @@ -114,9 +122,10 @@ class VoiceMessagePresenter( is VoiceMessageEvent.Seek -> { player.seekTo((event.percentage * duration).toLong()) } - is VoiceMessageEvent.ChangePlaybackSpeed -> { - playbackSpeedIndex.intValue = (playbackSpeedIndex.intValue + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size - player.setPlaybackSpeed(VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue]) + is VoiceMessageEvent.ChangePlaybackSpeed -> localCoroutineScope.launch { + voicePlayerStore.setPlayBackSpeedIndex( + (playbackSpeedIndex + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size + ) } } } @@ -126,7 +135,7 @@ class VoiceMessagePresenter( progress = progress, time = time, showCursor = showCursor, - playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex.intValue], + playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex], eventSink = ::handleEvent, ) } diff --git a/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt new file mode 100644 index 0000000000..3c400b3e92 --- /dev/null +++ b/libraries/voiceplayer/impl/src/main/kotlin/io/element/android/libraries/voiceplayer/impl/VoicePlayerStore.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.voiceplayer.impl + +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface VoicePlayerStore { + suspend fun setPlayBackSpeedIndex(index: Int) + fun playBackSpeedIndex(): Flow +} + +@ContributesBinding(AppScope::class) +class PreferencesVoicePlayerStore( + preferenceDataStoreFactory: PreferenceDataStoreFactory, +) : VoicePlayerStore { + private val store = preferenceDataStoreFactory.create("elementx_voice_player") + private val playbackSpeedIndex = intPreferencesKey("playback_speed_index") + + override fun playBackSpeedIndex(): Flow { + return store.data.map { prefs -> + prefs[playbackSpeedIndex] ?: 0 + } + } + + override suspend fun setPlayBackSpeedIndex(index: Int) { + store.edit { prefs -> + prefs[playbackSpeedIndex] = index + } + } +} diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt new file mode 100644 index 0000000000..e746b5acf5 --- /dev/null +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/InMemoryVoicePlayerStore.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.voiceplayer.impl + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow + +internal class InMemoryVoicePlayerStore( + defaultPlaybackSpeedIndex: Int = 0, +) : VoicePlayerStore { + private val playBackSpeedIndex = MutableStateFlow(defaultPlaybackSpeedIndex) + + override fun playBackSpeedIndex(): Flow { + return playBackSpeedIndex.asStateFlow() + } + + override suspend fun setPlayBackSpeedIndex(index: Int) { + playBackSpeedIndex.emit(index) + } +} diff --git a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt index e6ae760b53..8054677937 100644 --- a/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt +++ b/libraries/voiceplayer/impl/src/test/kotlin/io/element/android/libraries/voiceplayer/impl/VoiceMessagePresenterTest.kt @@ -240,6 +240,7 @@ fun TestScope.createVoiceMessagePresenter( mediaPlayer: FakeMediaPlayer = FakeMediaPlayer(), voiceMessageMediaRepo: VoiceMessageMediaRepo = FakeVoiceMessageMediaRepo(), analyticsService: AnalyticsService = FakeAnalyticsService(), + voicePlayerStore: VoicePlayerStore = InMemoryVoicePlayerStore(), eventId: EventId? = EventId("\$anEventId"), filename: String = "filename doesn't really matter for a voice message", duration: Duration = 61_000.milliseconds, @@ -257,6 +258,7 @@ fun TestScope.createVoiceMessagePresenter( mimeType = mimeType, filename = filename ), + voicePlayerStore = voicePlayerStore, eventId = eventId, duration = duration, ) From c154d55047abf1e228abb27f607c7f626df96f65 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 31 Dec 2025 10:43:57 +0000 Subject: [PATCH 13/13] Update screenshots --- ...components.event_TimelineItemVoiceViewUnified_Day_0_en.png | 4 ++-- ...mponents.event_TimelineItemVoiceViewUnified_Night_0_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_0_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_10_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_11_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_12_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_13_en.png | 4 ++-- ...eline.components.event_TimelineItemVoiceView_Day_14_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_1_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_2_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_3_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_4_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_5_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_6_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_7_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_8_en.png | 4 ++-- ...meline.components.event_TimelineItemVoiceView_Day_9_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_0_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_10_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_11_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_12_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_13_en.png | 4 ++-- ...ine.components.event_TimelineItemVoiceView_Night_14_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_1_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_2_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_3_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_4_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_5_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_6_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_7_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_8_en.png | 4 ++-- ...line.components.event_TimelineItemVoiceView_Night_9_en.png | 4 ++-- .../features.messages.impl.timeline_TimelineView_Day_8_en.png | 4 ++-- ...eatures.messages.impl.timeline_TimelineView_Night_8_en.png | 4 ++-- ...designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png | 3 +++ ...signsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png | 3 +++ ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png | 4 ++-- ...mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png | 4 ++-- ...diaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png | 4 ++-- ...s.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png | 4 ++-- ...ies.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png | 4 ++-- ...s.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png | 4 ++-- 56 files changed, 114 insertions(+), 108 deletions(-) create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png index 71aafa8951..e50176c971 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45f61d7b50a14b483d9459846f002b9ac94c6ccb632c636f891616629ad47248 -size 39899 +oid sha256:21cfef3eb8bb8a0493b1bf22a2b01d7c94a152c7e7e0d1bb558fae1e64e177c5 +size 43941 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png index 5067f5b5d3..f875628537 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceViewUnified_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80ce1738cf56d99afbe781c82e32cdef03564a31fec0450aa66a84c56085ce81 -size 39956 +oid sha256:3caf6bcec609664f2f2e39b1f51b8b08af00d59c7d1f66836e9e0e1751853c2f +size 45675 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png index 0140615ab0..fab08239b1 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a7a5c1978ed1ea48e849e0de8023ac588a29e84152946a9eb0ee6c0680d7a1c -size 4927 +oid sha256:6aa352e97a7f4ffba249fb4da75e508c264aa75335dc27b473b7cc54d56474ab +size 5212 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png index 343e3ddd19..393231091f 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d1cb7c04c321146e7425bc095b9344edf913eeec3588600e500466e326a8107 -size 8165 +oid sha256:0e2aaee1ad3bc909945881c352ad92669f2385d311be551ab0b961011d86e994 +size 8380 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png index a2f4e5c84a..eae2d640d4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:68c8f0a94de98773a3dae69fd44fa87fd3eeee5c6bc44afa710a2ba32eacde7e -size 8620 +oid sha256:2cb0fc5226b16779d984986d8944bead8b4541a1922dcd81892ccc731d0c7b49 +size 8845 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png index 320efac4d0..92eaf6b1df 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b98fde923272c2959c407fb3f62cb150f1b0fac3f54d29d94f30646096d889d2 -size 8261 +oid sha256:4528b5800ad94ad7d6880adbb99430b11e3724fbcf3a1732529a8673d9ad63bf +size 8465 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png index bafbe2ad5f..47f3bd2de0 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:473877bac2a76f565fed0056ee27b8fa91380b5661fd772d17e110caed0fecff -size 8425 +oid sha256:d1e6ae40a1f540c16c5482040c36dc4fe5f03b5b8271a3755129d7cd4a5825ac +size 8779 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png index c1d138f7ad..aa05215cf4 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6e969ae817abeaa153edbc06cbe873439cd3e65be31184f22db1d8becc7953a -size 8487 +oid sha256:706d26007463123c7afbb7b151f07deca03bb1924a27eea4544aac0b932b922c +size 8821 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png index 4b84f30648..3eac64c395 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd514ccd8d00f7f1ea2dc0bce9b786be8fe99c98b44a1b99add18e132d0dc1c1 -size 5171 +oid sha256:33eeb6ecf24ce156fa12dc204f7443bf65682fd1ff8471460b851ae62e6e8a8e +size 5455 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png index 07cf2c5161..6ac15f19b5 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e69b5e773119af8ab4749064e68f6584aac0aa41c11a054db9e9c14e7e9aab0 -size 4908 +oid sha256:cbbe58a0d2c4052af93d199f5501176c79d42aa17765ac623894a9c59beda46a +size 5194 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png index 023fe9f470..983aee397a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07745c25bce426e0736b7546836e67cb5cb6d8da79b4f26448b4fef0486a13c7 -size 5108 +oid sha256:d099ae7db3d850ff78122b5bcc2a7bbe50c7197a30e5aeadfba1174933f85dc2 +size 5408 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png index b49506008e..71cfe52e3d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:df2ac9c5cbee9a350f54ca6892f42c6685d91d9d4fbe46943143b99c915e8ae1 -size 5223 +oid sha256:2d09efdfad91b328c5d480a6e8e9652dea8ccd6f8af617734782ea61a07bb2ba +size 5496 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png index 99bf3c83bc..d94f65f3e7 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5ebd66819a916fa8eeac654281b432b46de3218243d9831666ff962d412e04d -size 5486 +oid sha256:4baec63d3fa378db139ac563a10e414a463500fa3b6240543505a59b598b70ab +size 5742 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png index 771495367c..dc0775522a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93a441c65d9ae6cfba78c4a89a72c037bfe1759325a7bbc0bee05dfbc40e96c7 -size 5732 +oid sha256:35a46a9254a012efdea69e0336e6b9d536ea88265fbc933c23bcbca951f55be9 +size 6006 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png index b379bf3ca9..96737074af 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a82b644e43af13b60c98ccd565873cfbe1c46e3391426bafcd5d71881fabe34c -size 5434 +oid sha256:da9749249afc0c35a171b1a41f1a6189f7e9f7906079be2fd3634f0da1867181 +size 5708 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png index 9d0f1121f8..cc48f3e890 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:257b45fa5de31badce26360dd3c48b502b5ce928bc4d13434f9b42703f29dbb1 -size 5640 +oid sha256:bbb6613af390663a0cbc3a8342cc44baf1b07e0388bafc20281fdeeca9a644b3 +size 5953 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png index fc9b835afa..ccb999411a 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11adeb3f01fa93c159d692cc2323761873bfba37ad6a3a014e2fdbe80cd108b1 -size 5779 +oid sha256:51fca90e22f3dcb48a3d7a958facb523bb20812f009bc384f1ccb70433aec035 +size 6083 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png index 90e1e354da..7cc0515466 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b13c460c659bc743e7aec561ba090ee6174b1acb49821417d13375feee46c6f7 -size 4910 +oid sha256:b282fcfd5e7d4172b0880f2858cabeb6088cd132843ee735230a2739563910fa +size 5304 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png index 7f46d49328..5e578bb7e3 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bebeecb0d945b5b66535c6b1ef63c46a45232f304deb5e48e7fb4e0f92045716 -size 7786 +oid sha256:b3e2391ad08c944c655c9a93b9aabb45bbd4b7c199f97eeb39daf87dd6bf1170 +size 8163 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png index bb12277d62..62b6d1be67 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b13a02e83748f671aa4aec7eb8052bd3637eeb8c898ded100e29aa219ffc1fbb -size 8337 +oid sha256:e4b9d60e3074cfbc779f9d789cbb33feccbafe6ca2fa55dbd81d2436b60eed9e +size 8753 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png index b2ed5f6991..072d54a372 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ef577bfe5233d1194c7bfbaedb38b3690964fe8d3325a9f1c71c3e83fc81d8f -size 8149 +oid sha256:0d30758cd59e52f0b9e5c0d2e23cce3b489db2fc784bbe62df4bd91f38de910f +size 8416 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png index f1740ae350..d15fc5042d 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4788f5817016607483304bcc4557921da51e801d5378d6c410e8c2a5a700b713 -size 8087 +oid sha256:8de312bc408bb1717042d0902469493d262f3df6e6a025b15b28a1129d801197 +size 8511 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png index 92476e7b4b..4d73a4910b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0464770461d9a59015fa3bd2149bdd17c00600ae256fe4d6b2eaec12a029d04d -size 8121 +oid sha256:2c3edf08e3a769fa3603a31d8c21cb2f8a105087bca91967629dbe73f966a904 +size 8522 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png index c9da9a4b6f..ac64fad4ae 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b79152dddd997e11c52b910c19c02d21cf504d2a8ae228e11c9546f2496596da -size 5109 +oid sha256:a442a45bd1b80846060575e10377df39401e7496c306f1b44d6de955cf60b1e2 +size 5543 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png index 89e7d512c1..158fb99afc 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ebee4fdf176801a756018e9c4ea80a7e506e9a58dc789f1fb0b9df8306abacf0 -size 4918 +oid sha256:4dfb8f775a2fbac7f7d7478107e25457b76cd1b9131da8fff50971d06c0a8ab2 +size 5295 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png index 3f8edf9b44..adbd49e48c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a4c30619c89ec5af57edf09b48429171eaeee88c04334b336e45b8478c1ebc0 -size 5106 +oid sha256:fc51049f759f3248a4c376e608c3108e1fff496237de6b3061b2f4f1ff904698 +size 5525 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png index ba74381c3c..fa51877d06 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e1098a584fec0ec74838c2cebf0db3f1c6d75eea8575e2d0e946657cd065395 -size 5184 +oid sha256:3cdadd897dfcf88848e3c8294afa7c5d34d0af8e5cfc6684a1239d4a53171b0a +size 5579 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png index a4654a5547..2c202c1f99 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d3ffddd38f5318e64b9adceecc5f09cf2f6a718327463ecde5b3495ff9bdb0 -size 5455 +oid sha256:a5a6f5c94a4308e4fe3e66c6620b582726aeea0eec3ca7e84216f41fde9d42ac +size 5803 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png index 7c2d0128ff..0d667ac9bb 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8d530adf3152141fafb258bad3cc45349fc2726bd1c5a51440d1608a654dd031 -size 5707 +oid sha256:333cafb2282afb0fdb076f5f8528df9bed46987a6f53993b6689425b60da767b +size 6100 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png index 11bd395271..a060d89e00 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d397a13c3fba112e8bd2f3045c4e9fc9de10869204451b33cc7a88b2938b9797 -size 5451 +oid sha256:b857f3c9a84373b292faae437ede2de4244fd7f5baa3bf7eb14f8978fd575c99 +size 5809 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png index dfedab0787..b5db68c328 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5c87ecb2cbb0bee46b088f1e253e1c969e20cc407bb64827dd98294871f22b92 -size 5635 +oid sha256:6abc6eb10edfbbf0145e291689679eee6c25521564fc4458f402ec98d34af5f7 +size 6024 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png index 7aa2ec7227..98ac3b747b 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:614d88406ef318b65475837e79b10759f3c9ee038dcfea963677d371874a7a1b -size 5774 +oid sha256:98a5873e4696e628f2c79f0c5dbb95d602a6e2facc3a60dee4c24ba4dc4a09c3 +size 6153 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png index 0264fd4296..29819ddfa2 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Day_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a908b65efa9cfa89d121f3e23a0bfad0926d269d9600fe6e58455e2e70a4fac -size 54687 +oid sha256:24dd95b2320c849a5de7d6b23c4c5c429400dbbeb4bd9619eda115e940d8f547 +size 55922 diff --git a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png index 8708028b79..d60e21920c 100644 --- a/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.messages.impl.timeline_TimelineView_Night_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c40bba2d435777c6d990b8cb699c19a2384b64c4c27e65d8baee6ef3dfd8b86f -size 52591 +oid sha256:25d2342f4bbd9adca42ae92f54dc3281e4a9c37f5fb5650c52cdd6a488855ad0 +size 53943 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png new file mode 100644 index 0000000000..675f286746 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7bfa11446dc195a1912857a553f57df926660d32562e9d4af133e7f039cf37d8 +size 8304 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png new file mode 100644 index 0000000000..7ae98066c6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.atomic.atoms_PlaybackSpeedButton_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c8ab3d7799fedc07b9fc39e22af4d61c237426b999e39663444944865954b67 +size 8176 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png index 8ade8b3f8f..29759f506c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c0d4913ae2a0dc42a4c116f731a3b4d822801271423e1248728f86b9cb17eed1 -size 8620 +oid sha256:511c0cb8323fb971989138aa25d0323102de60f43b8635953a12a6301091aac3 +size 9332 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png index 9d5231f601..5fe27b2fe6 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0d9b0271872bb405ec0d6f8afa475404c9612b8d42dc5bb835ce8dcc8b1fa0a -size 9223 +oid sha256:9def0ceeac3ad39fb5c03d7d525c012e3c592ec988a9baa8fd5e424f49438119 +size 9874 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png index 643331cb01..33292b60c5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f969aeedd303cf4c6b90e3ab3b2144c7eddb7860e69af2c1ff395ff2202793f -size 8892 +oid sha256:1ae1bd729e7b91acdc57636a0fc8bd105403af99f4c37c1954917646dc13f54d +size 9644 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png index 2c9c62876a..8450cb430c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:509f29fbd03496acb78f18d4fb51c207981d145a6c675e02a9d0b7b96811c2f8 -size 9014 +oid sha256:266acb20ed53b40bd5fce5698e29e357442823a528db52781641d1e4ee9d7079 +size 9763 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png index 4a13245252..264e629b33 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4d16acd7a9caed097bb7e352c290cb543f70b330800ef2b29b235bd52a0a4dc -size 9213 +oid sha256:d34d9a892baeb6443b390b623f2d355e758f07292d7ca742210032313307b309 +size 9882 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png index 4e05dcce15..21eee169b5 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59784cf1d8c167ecdbe78e3db46b20aa8770a17ffd794193ab9ded221120d301 -size 8054 +oid sha256:451677cf50c127f97fc37a1a1dfadaf62229d8d35d55554c6da0d085f78c4a99 +size 8777 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png index 3512b11bf8..18d5582697 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f36874223538e2d4e5ee1c383ef3c1b83638a6e3c2d1791b46f9393e4bd7afea -size 8675 +oid sha256:193a50065c69de27fed36c7b3151351e6606c4006545b773b89e2c9ca96f68ea +size 9336 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png index b3ef224941..1259b2b518 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:874579b131a2956564603ba279803c4f753736a4545f50f9a1eff93ff2e414a3 -size 8417 +oid sha256:e39948d6cf139439013100ba0559387591656b23b2cff14320f9edfd90c20a65 +size 9105 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png index 431ccbef29..d1cf96241b 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d3da9ef5ffa433a5eaadc964e6d097a474c9b1245e2ebb60c067cc97a0f054b -size 8431 +oid sha256:71c08ef07e6bd0da6cc80de847507bd1f39d161365883eed986f0f600217e765 +size 9211 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png index 8c61303e96..ad202e44bf 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemViewPlay_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf3ab6dc97d3f34b7e25062885a49eeecc563a69f6c337d346ad1d9ad0c45fd1 -size 8583 +oid sha256:0858764ff6bda5d7a693336315023c7a216ffa5f59b2070a2f8d7342aeac6416 +size 9340 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png index 35651f3733..0d2345b4e8 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83593ae45c35e34d5057d45b8a7e66b582b3b52adc7f05fa2d9c3ecdc0bece9c -size 8676 +oid sha256:97818e454a5848c9bf1a1b8d5c4328cf1671b86131b93bb64888b1b28fa28869 +size 9400 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png index c427f30780..50bec8ddb9 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69a4678aba6913f981f344eb730add0f4fdbe0529f7be015019150bac15f4709 -size 11009 +oid sha256:cdc03c9793f1198aa6efdb3a93eb8982cf365055e21bc86553ae83cdcea0b99f +size 11731 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png index d9b62e60e8..9371f2fae7 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dac10693719b9cfe5f3644c25cbb9d1a59ed7c2f89e791eec17bf635c4d59efc -size 36507 +oid sha256:2ce01af104e3ce49a78b6fb9eab021f998938c59e487135a1b4d18f4b4a01b73 +size 37319 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png index 4a7563b96d..f22741654d 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d234492829a729dcb05657af65a3fe97fe025ff42c79d9cf862e4e9925ddd832 -size 6944 +oid sha256:3816f44134580eb501d2a6abb91d713f5209fea3b1c35e500db88bbde1a6003d +size 7691 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png index 1e9225a8b8..d241221cfb 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af28ed6a8b9d3b399531bf82d7be3c5a5b23ecc750654c241b7acc95a036132b -size 8115 +oid sha256:b7ddddb2a610a152474cd01c41b8dd50c7a9befee4f5a206f7ed91633f2d9fbd +size 8841 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png index 423ae8cbd0..5ab196c09c 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:44b0989e9ddb097d3a5ef0f331221a12a90f69ff017e3447e31ef5cccc53af68 -size 10290 +oid sha256:c5686ac15dbfc6cd805662f5e30d17bef529b2fbe84630e158306c1c2ca579f9 +size 11008 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png index f234f447da..8199266700 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98eb5d83d322022956b684699683f25ef6c09be55c60224689685589e0051983 -size 34883 +oid sha256:91f5c2d2fc15eac0c52a6088427bc8ccebe2e2ac966e59d36c17f85023fe3c75 +size 35660 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png index b7ea22436f..7bd5a22139 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery.ui_VoiceItemView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:263371af4d0ac7efcd840a793e663505865d32c425d5b2efe9489a63655e33e1 -size 6563 +oid sha256:ea7e795366ebbd6730f2621b748238f6914c7d83fd76f69f98a6a6f5c785b8a1 +size 7311 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png index d92b8c569d..466a60982a 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4d1d09321fb1220d1be07e6f0ba54495764c935dcf6dc75bb3e7e5879770e46 -size 32646 +oid sha256:1dfe35935e328d87472211f1c6af5ddef99342c4a032dcb6aebab95a2efb0796 +size 33445 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png index 0c9b92ca30..264d00e03e 100644 --- a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46ab31307298aa5ce72f71db8eedefbde78eeebb3ff1426833bcb0a7c6af9ae3 -size 31131 +oid sha256:394bde203edc4e5b91060e0c3ce22291ac550855a8a7d5162ed5a442161e0ae9 +size 31867