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 a3f214f979..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 @@ -9,6 +9,7 @@ package io.element.android.features.messages.impl.timeline.components.event import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -42,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 @@ -51,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 @@ -64,26 +66,26 @@ fun TimelineItemVoiceView( modifier: Modifier = Modifier, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } 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 @@ -101,30 +103,41 @@ 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)) - 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(VoiceMessageEvent.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)) }, + onSeek = { state.eventSink(VoiceMessageEvent.Seek(it)) }, ) } } 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..dfd98dd5da --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/atoms/PlaybackSpeedButton.kt @@ -0,0 +1,75 @@ +/* + * 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.Arrangement +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.draw.clip +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 +import io.element.android.libraries.designsystem.theme.messageFromMeBackground + +@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 + .clip(RoundedCornerShape(12.dp)) + .background( + color = ElementTheme.colors.bgCanvasDefault, + ) + .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( + 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 = {}, + ) + } + } +} 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 bfbd2bb35e..7087235fec 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 @@ -47,6 +47,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 098e7e4d3a..12b36207a6 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 @@ -159,6 +159,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 f0b8746042..17bfe682e3 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 @@ -34,6 +34,7 @@ interface SimplePlayer { fun isPlaying(): Boolean fun pause() fun seekTo(positionMs: Long) + fun setPlaybackSpeed(speed: Float) fun release() interface Listener { fun onIsPlayingChanged(isPlaying: Boolean) @@ -88,5 +89,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 609862c3cf..c1e2dc9763 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 @@ -20,6 +20,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() @@ -45,6 +46,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 54fed2be11..1d1fd07ebd 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 @@ -96,6 +96,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 9e62451dba..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 @@ -11,6 +11,7 @@ package io.element.android.libraries.mediaviewer.impl.gallery.ui import androidx.compose.foundation.background import androidx.compose.foundation.border 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 @@ -38,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 @@ -50,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 @@ -92,7 +94,7 @@ private fun VoiceInfoRow( onLongClick: () -> Unit, ) { fun playPause() { - state.eventSink(VoiceMessageEvents.PlayPause) + state.eventSink(VoiceMessageEvent.PlayPause) } Row( @@ -112,21 +114,30 @@ 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)) - 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(VoiceMessageEvent.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 @@ -136,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 59% 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 4adc1cfab6..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,7 +8,8 @@ package io.element.android.libraries.voiceplayer.api -sealed interface VoiceMessageEvents { - data object PlayPause : VoiceMessageEvents - data class Seek(val percentage: Float) : 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 e13d97b18f..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,13 +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 eventSink: (event: VoiceMessageEvents) -> Unit, + 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 7a98c52833..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,14 +44,16 @@ 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 } } } @@ -85,9 +95,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) { @@ -109,17 +119,23 @@ class VoiceMessagePresenter( } } } - is VoiceMessageEvents.Seek -> { + is VoiceMessageEvent.Seek -> { player.seekTo((event.percentage * duration).toLong()) } + is VoiceMessageEvent.ChangePlaybackSpeed -> localCoroutineScope.launch { + voicePlayerStore.setPlayBackSpeedIndex( + (playbackSpeedIndex + 1) % VoicePlayerConfig.availablePlaybackSpeeds.size + ) + } } } return VoiceMessageState( - button = button, + buttonType = buttonType, progress = progress, time = time, showCursor = showCursor, + playbackSpeed = VoicePlayerConfig.availablePlaybackSpeeds[playbackSpeedIndex], 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) +} 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 642a55dead..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 @@ -8,19 +8,17 @@ 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 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 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,11 +29,9 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -48,29 +44,27 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + 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") } @@ -86,24 +80,22 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + 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") } @@ -122,27 +114,25 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:02") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) 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(VoiceMessageEvents.PlayPause) + 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") } @@ -154,11 +144,9 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Disabled) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("1:01") } @@ -171,19 +159,17 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) 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) + assertThat(it.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0.5f) assertThat(it.time).isEqualTo("0:05") } @@ -195,40 +181,66 @@ 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.buttonType).isEqualTo(VoiceMessageState.ButtonType.Play) assertThat(it.progress).isEqualTo(0f) assertThat(it.time).isEqualTo("0:10") } - initialState.eventSink(VoiceMessageEvents.PlayPause) + initialState.eventSink(VoiceMessageEvent.PlayPause) 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)) } - initialState.eventSink(VoiceMessageEvents.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") } } } + + @Test + fun `changing playback speed cycles through available speeds`() = runTest { + val presenter = createVoiceMessagePresenter( + duration = 10_000.milliseconds, + ) + presenter.test { + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) + } + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.5f) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) + } + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(2.0f) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) + } + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(0.5f) + it.eventSink(VoiceMessageEvent.ChangePlaybackSpeed) + } + awaitItem().also { + assertThat(it.playbackSpeed).isEqualTo(1.0f) + } + } + } } 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, @@ -246,6 +258,7 @@ fun TestScope.createVoiceMessagePresenter( mimeType = mimeType, filename = filename ), + voicePlayerStore = voicePlayerStore, eventId = eventId, duration = duration, ) 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