From a4fcc476d1b6b1c693bbedb63537f063b97a59a3 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 11 Apr 2025 17:09:31 +0200 Subject: [PATCH 1/2] change (preferences) : use PreferenceDropdown for appearance (and add some tests) --- .../impl/advanced/AdvancedSettingsEvents.kt | 5 +- .../advanced/AdvancedSettingsPresenter.kt | 29 ++-- .../impl/advanced/AdvancedSettingsState.kt | 23 ++- .../advanced/AdvancedSettingsStateProvider.kt | 7 +- .../impl/advanced/AdvancedSettingsView.kt | 56 ++------ .../impl/developer/tracing/LogLevelItem.kt | 16 ++- .../advanced/AdvancedSettingsPresenterTest.kt | 135 ++++++++++++------ .../impl/advanced/AdvancedSettingsViewTest.kt | 47 ++++-- .../preferences/PreferenceDropdown.kt | 18 ++- 9 files changed, 198 insertions(+), 138 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt index fabaf7afc5..fc78ae561a 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt @@ -7,16 +7,13 @@ package io.element.android.features.preferences.impl.advanced -import io.element.android.compound.theme.Theme import io.element.android.libraries.matrix.api.media.MediaPreviewValue sealed interface AdvancedSettingsEvents { data class SetDeveloperModeEnabled(val enabled: Boolean) : AdvancedSettingsEvents data class SetSharePresenceEnabled(val enabled: Boolean) : AdvancedSettingsEvents data class SetCompressMedia(val compress: Boolean) : AdvancedSettingsEvents - data object ChangeTheme : AdvancedSettingsEvents - data object CancelChangeTheme : AdvancedSettingsEvents - data class SetTheme(val theme: Theme) : AdvancedSettingsEvents + data class SetTheme(val theme: ThemeOption) : AdvancedSettingsEvents data class SetTimelineMediaPreviewValue(val value: MediaPreviewValue) : AdvancedSettingsEvents data class SetHideInviteAvatars(val value: Boolean) : AdvancedSettingsEvents } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt index 065c6fc553..41ac9bb0f4 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt @@ -9,11 +9,10 @@ package io.element.android.features.preferences.impl.advanced import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue import io.element.android.compound.theme.Theme import io.element.android.compound.theme.mapToTheme import io.element.android.libraries.architecture.Presenter @@ -39,11 +38,9 @@ class AdvancedSettingsPresenter @Inject constructor( val doesCompressMedia by remember { sessionPreferencesStore.doesCompressMedia() }.collectAsState(initial = true) - val theme by remember { + val theme = remember { appPreferencesStore.getThemeFlow().mapToTheme() }.collectAsState(initial = Theme.System) - var showChangeThemeDialog by remember { mutableStateOf(false) } - val hideInviteAvatars by remember { appPreferencesStore.getHideInviteAvatarsFlow() }.collectAsState(false) @@ -52,6 +49,16 @@ class AdvancedSettingsPresenter @Inject constructor( appPreferencesStore.getTimelineMediaPreviewValueFlow() }.collectAsState(initial = MediaPreviewValue.On) + val themeOption by remember { + derivedStateOf { + when (theme.value) { + Theme.System -> ThemeOption.System + Theme.Dark -> ThemeOption.Dark + Theme.Light -> ThemeOption.Light + } + } + } + fun handleEvents(event: AdvancedSettingsEvents) { when (event) { is AdvancedSettingsEvents.SetDeveloperModeEnabled -> localCoroutineScope.launch { @@ -63,11 +70,12 @@ class AdvancedSettingsPresenter @Inject constructor( is AdvancedSettingsEvents.SetCompressMedia -> localCoroutineScope.launch { sessionPreferencesStore.setCompressMedia(event.compress) } - AdvancedSettingsEvents.CancelChangeTheme -> showChangeThemeDialog = false - AdvancedSettingsEvents.ChangeTheme -> showChangeThemeDialog = true is AdvancedSettingsEvents.SetTheme -> localCoroutineScope.launch { - appPreferencesStore.setTheme(event.theme.name) - showChangeThemeDialog = false + when (event.theme) { + ThemeOption.System -> appPreferencesStore.setTheme(Theme.System.name) + ThemeOption.Dark -> appPreferencesStore.setTheme(Theme.Dark.name) + ThemeOption.Light -> appPreferencesStore.setTheme(Theme.Light.name) + } } is AdvancedSettingsEvents.SetHideInviteAvatars -> localCoroutineScope.launch { appPreferencesStore.setHideInviteAvatars(event.value) @@ -82,8 +90,7 @@ class AdvancedSettingsPresenter @Inject constructor( isDeveloperModeEnabled = isDeveloperModeEnabled, isSharePresenceEnabled = isSharePresenceEnabled, doesCompressMedia = doesCompressMedia, - theme = theme, - showChangeThemeDialog = showChangeThemeDialog, + theme = themeOption, hideInviteAvatars = hideInviteAvatars, timelineMediaPreviewValue = timelineMediaPreviewValue, eventSink = { handleEvents(it) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt index 9f55036154..5b91c65f08 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt @@ -7,16 +7,33 @@ package io.element.android.features.preferences.impl.advanced -import io.element.android.compound.theme.Theme +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import io.element.android.libraries.designsystem.components.preferences.DropdownOption import io.element.android.libraries.matrix.api.media.MediaPreviewValue +import io.element.android.libraries.ui.strings.CommonStrings data class AdvancedSettingsState( val isDeveloperModeEnabled: Boolean, val isSharePresenceEnabled: Boolean, val doesCompressMedia: Boolean, - val theme: Theme, - val showChangeThemeDialog: Boolean, + val theme: ThemeOption, val hideInviteAvatars: Boolean, val timelineMediaPreviewValue: MediaPreviewValue, val eventSink: (AdvancedSettingsEvents) -> Unit ) + +enum class ThemeOption : DropdownOption { + System { + @Composable + override fun getText(): String = stringResource(CommonStrings.common_system) + }, + Dark { + @Composable + override fun getText(): String = stringResource(CommonStrings.common_dark) + }, + Light { + @Composable + override fun getText(): String = stringResource(CommonStrings.common_light) + } +} diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt index 19e4b8b26a..b0b9ed34fd 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt @@ -8,7 +8,6 @@ package io.element.android.features.preferences.impl.advanced import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.compound.theme.Theme import io.element.android.libraries.matrix.api.media.MediaPreviewValue open class AdvancedSettingsStateProvider : PreviewParameterProvider { @@ -16,7 +15,6 @@ open class AdvancedSettingsStateProvider : PreviewParameterProvider Unit = {}, ) = AdvancedSettingsState( isDeveloperModeEnabled = isDeveloperModeEnabled, isSharePresenceEnabled = isSharePresenceEnabled, doesCompressMedia = doesCompressMedia, - theme = Theme.System, - showChangeThemeDialog = showChangeThemeDialog, + theme = theme, hideInviteAvatars = hideInviteAvatars, timelineMediaPreviewValue = timelineMediaPreviewValue, eventSink = eventSink diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt index dc26487f91..ab97062e4c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt @@ -12,14 +12,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import im.vector.app.features.analytics.plan.Interaction -import io.element.android.compound.theme.Theme -import io.element.android.compound.theme.themes import io.element.android.features.preferences.impl.R import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage -import io.element.android.libraries.designsystem.components.dialogs.ListOption -import io.element.android.libraries.designsystem.components.dialogs.SingleSelectionDialog import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferenceDropdown import io.element.android.libraries.designsystem.components.preferences.PreferencePage import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch import io.element.android.libraries.designsystem.preview.ElementPreviewDark @@ -34,8 +31,7 @@ import io.element.android.libraries.matrix.api.media.MediaPreviewValue import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.compose.LocalAnalyticsService import io.element.android.services.analyticsproviders.api.trackers.captureInteraction -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.toImmutableList +import kotlinx.collections.immutable.toPersistentList @Composable fun AdvancedSettingsView( @@ -49,15 +45,12 @@ fun AdvancedSettingsView( onBackClick = onBackClick, title = stringResource(id = CommonStrings.common_advanced_settings) ) { - ListItem( - headlineContent = { - Text(text = stringResource(id = CommonStrings.common_appearance)) - }, - trailingContent = ListItemContent.Text( - state.theme.toHumanReadable() - ), - onClick = { - state.eventSink(AdvancedSettingsEvents.ChangeTheme) + PreferenceDropdown( + title = stringResource(id = CommonStrings.common_appearance), + selectedOption = state.theme, + options = ThemeOption.entries.toPersistentList(), + onSelectOption = { logLevel -> + state.eventSink(AdvancedSettingsEvents.SetTheme(logLevel)) } ) ListItem( @@ -108,21 +101,6 @@ fun AdvancedSettingsView( ) ModerationAndSafety(state) } - - if (state.showChangeThemeDialog) { - SingleSelectionDialog( - options = getOptions(), - initialSelection = themes.indexOf(state.theme), - onSelectOption = { - state.eventSink( - AdvancedSettingsEvents.SetTheme( - themes[it] - ) - ) - }, - onDismissRequest = { state.eventSink(AdvancedSettingsEvents.CancelChangeTheme) }, - ) - } } @Composable @@ -176,24 +154,6 @@ private fun ModerationAndSafety( } } -@Composable -private fun getOptions(): ImmutableList { - return themes.map { - ListOption(title = it.toHumanReadable()) - }.toImmutableList() -} - -@Composable -private fun Theme.toHumanReadable(): String { - return stringResource( - id = when (this) { - Theme.System -> CommonStrings.common_system - Theme.Dark -> CommonStrings.common_dark - Theme.Light -> CommonStrings.common_light - } - ) -} - @PreviewWithLargeHeight @Composable internal fun AdvancedSettingsViewLightPreview(@PreviewParameter(AdvancedSettingsStateProvider::class) state: AdvancedSettingsState) = diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt index 9707fc30e7..7148cff57f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/tracing/LogLevelItem.kt @@ -7,22 +7,28 @@ package io.element.android.features.preferences.impl.developer.tracing +import androidx.compose.runtime.Composable import io.element.android.libraries.designsystem.components.preferences.DropdownOption enum class LogLevelItem : DropdownOption { ERROR { - override val text: String = "Error" + @Composable + override fun getText(): String = "Error" }, WARN { - override val text: String = "Warn" + @Composable + override fun getText(): String = "Warn" }, INFO { - override val text: String = "Info" + @Composable + override fun getText(): String = "Info" }, DEBUG { - override val text: String = "Debug" + @Composable + override fun getText(): String = "Debug" }, TRACE { - override val text: String = "Trace" + @Composable + override fun getText(): String = "Trace" } } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenterTest.kt index a5014ac719..317cd5b06c 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenterTest.kt @@ -11,11 +11,10 @@ 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.compound.theme.Theme +import io.element.android.libraries.matrix.api.media.MediaPreviewValue import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore import io.element.android.tests.testutils.WarmUpRule -import io.element.android.tests.testutils.awaitLastSequentialItem import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test @@ -30,12 +29,12 @@ class AdvancedSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitLastSequentialItem() - assertThat(initialState.isDeveloperModeEnabled).isFalse() - assertThat(initialState.showChangeThemeDialog).isFalse() - assertThat(initialState.isSharePresenceEnabled).isTrue() - assertThat(initialState.doesCompressMedia).isTrue() - assertThat(initialState.theme).isEqualTo(Theme.System) + with(awaitItem()) { + assertThat(isDeveloperModeEnabled).isFalse() + assertThat(isSharePresenceEnabled).isTrue() + assertThat(doesCompressMedia).isTrue() + assertThat(theme).isEqualTo(ThemeOption.System) + } } } @@ -45,12 +44,17 @@ class AdvancedSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitLastSequentialItem() - assertThat(initialState.isDeveloperModeEnabled).isFalse() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetDeveloperModeEnabled(true)) - assertThat(awaitItem().isDeveloperModeEnabled).isTrue() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetDeveloperModeEnabled(false)) - assertThat(awaitItem().isDeveloperModeEnabled).isFalse() + with(awaitItem()) { + assertThat(isDeveloperModeEnabled).isFalse() + eventSink(AdvancedSettingsEvents.SetDeveloperModeEnabled(true)) + } + with(awaitItem()) { + assertThat(isDeveloperModeEnabled).isTrue() + eventSink(AdvancedSettingsEvents.SetDeveloperModeEnabled(false)) + } + with(awaitItem()) { + assertThat(isDeveloperModeEnabled).isFalse() + } } } @@ -60,12 +64,17 @@ class AdvancedSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitLastSequentialItem() - assertThat(initialState.isSharePresenceEnabled).isTrue() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetSharePresenceEnabled(false)) - assertThat(awaitItem().isSharePresenceEnabled).isFalse() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetSharePresenceEnabled(true)) - assertThat(awaitItem().isSharePresenceEnabled).isTrue() + with(awaitItem()) { + assertThat(isSharePresenceEnabled).isTrue() + eventSink(AdvancedSettingsEvents.SetSharePresenceEnabled(false)) + } + with(awaitItem()) { + assertThat(isSharePresenceEnabled).isFalse() + eventSink(AdvancedSettingsEvents.SetSharePresenceEnabled(true)) + } + with(awaitItem()) { + assertThat(isSharePresenceEnabled).isTrue() + } } } @@ -75,12 +84,17 @@ class AdvancedSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitLastSequentialItem() - assertThat(initialState.doesCompressMedia).isTrue() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetCompressMedia(false)) - assertThat(awaitItem().doesCompressMedia).isFalse() - initialState.eventSink.invoke(AdvancedSettingsEvents.SetCompressMedia(true)) - assertThat(awaitItem().doesCompressMedia).isTrue() + with(awaitItem()) { + assertThat(doesCompressMedia).isTrue() + eventSink(AdvancedSettingsEvents.SetCompressMedia(false)) + } + with(awaitItem()) { + assertThat(doesCompressMedia).isFalse() + eventSink(AdvancedSettingsEvents.SetCompressMedia(true)) + } + with(awaitItem()) { + assertThat(doesCompressMedia).isTrue() + } } } @@ -90,20 +104,61 @@ class AdvancedSettingsPresenterTest { moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { - val initialState = awaitLastSequentialItem() - initialState.eventSink.invoke(AdvancedSettingsEvents.ChangeTheme) - val withDialog = awaitItem() - assertThat(withDialog.showChangeThemeDialog).isTrue() - // Cancel - withDialog.eventSink(AdvancedSettingsEvents.CancelChangeTheme) - val withoutDialog = awaitItem() - assertThat(withoutDialog.showChangeThemeDialog).isFalse() - withDialog.eventSink.invoke(AdvancedSettingsEvents.ChangeTheme) - assertThat(awaitItem().showChangeThemeDialog).isTrue() - withDialog.eventSink(AdvancedSettingsEvents.SetTheme(Theme.Light)) - val withNewTheme = awaitItem() - assertThat(withNewTheme.showChangeThemeDialog).isFalse() - assertThat(withNewTheme.theme).isEqualTo(Theme.Light) + with(awaitItem()) { + assertThat(theme).isEqualTo(ThemeOption.System) + eventSink(AdvancedSettingsEvents.SetTheme(ThemeOption.Dark)) + } + with(awaitItem()) { + assertThat(theme).isEqualTo(ThemeOption.Dark) + eventSink(AdvancedSettingsEvents.SetTheme(ThemeOption.Light)) + } + with(awaitItem()) { + assertThat(theme).isEqualTo(ThemeOption.Light) + eventSink(AdvancedSettingsEvents.SetTheme(ThemeOption.System)) + } + with(awaitItem()) { + assertThat(theme).isEqualTo(ThemeOption.System) + } + } + } + + @Test + fun `present - hide invite avatars`() = runTest { + val presenter = createAdvancedSettingsPresenter() + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + with(awaitItem()) { + assertThat(hideInviteAvatars).isFalse() + eventSink(AdvancedSettingsEvents.SetHideInviteAvatars(true)) + } + with(awaitItem()) { + assertThat(hideInviteAvatars).isTrue() + eventSink(AdvancedSettingsEvents.SetHideInviteAvatars(false)) + } + with(awaitItem()) { + assertThat(hideInviteAvatars).isFalse() + } + } + } + + @Test + fun `present - timeline media preview value`() = runTest { + val presenter = createAdvancedSettingsPresenter() + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + with(awaitItem()) { + assertThat(timelineMediaPreviewValue).isEqualTo(MediaPreviewValue.On) + eventSink(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.Off)) + } + with(awaitItem()) { + assertThat(timelineMediaPreviewValue).isEqualTo(MediaPreviewValue.Off) + eventSink(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.Private)) + } + with(awaitItem()) { + assertThat(timelineMediaPreviewValue).isEqualTo(MediaPreviewValue.Private) + } } } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsViewTest.kt index a8e105e22a..baf55d2999 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsViewTest.kt @@ -14,8 +14,8 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.test.ext.junit.runners.AndroidJUnit4 import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Interaction -import io.element.android.compound.theme.Theme import io.element.android.features.preferences.impl.R +import io.element.android.libraries.matrix.api.media.MediaPreviewValue import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.compose.LocalAnalyticsService @@ -29,6 +29,7 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule import org.junit.runner.RunWith +import org.robolectric.annotation.Config @RunWith(AndroidJUnit4::class) class AdvancedSettingsViewTest { @@ -49,29 +50,17 @@ class AdvancedSettingsViewTest { } } - @Test - fun `clicking on Appearance emits the expected event`() { - val eventsRecorder = EventsRecorder() - rule.setAdvancedSettingsView( - state = aAdvancedSettingsState( - eventSink = eventsRecorder - ), - ) - rule.clickOn(CommonStrings.common_appearance) - eventsRecorder.assertSingle(AdvancedSettingsEvents.ChangeTheme) - } - @Test fun `clicking on other theme emits the expected event`() { val eventsRecorder = EventsRecorder() rule.setAdvancedSettingsView( state = aAdvancedSettingsState( eventSink = eventsRecorder, - showChangeThemeDialog = true ), ) + rule.clickOn(CommonStrings.common_appearance) rule.clickOn(CommonStrings.common_dark) - eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTheme(Theme.Dark)) + eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTheme(ThemeOption.Dark)) } @Test @@ -140,6 +129,34 @@ class AdvancedSettingsViewTest { ) ) } + + @Test + @Config(qualifiers = "h640dp") + fun `clicking on hide invite avatars emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setAdvancedSettingsView( + state = aAdvancedSettingsState( + eventSink = eventsRecorder, + hideInviteAvatars = false + ), + ) + rule.clickOn(R.string.screen_advanced_settings_hide_invite_avatars_toggle_title) + eventsRecorder.assertSingle(AdvancedSettingsEvents.SetHideInviteAvatars(true)) + } + + @Test + @Config(qualifiers = "h640dp") + fun `clicking on timeline media preview emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setAdvancedSettingsView( + state = aAdvancedSettingsState( + eventSink = eventsRecorder, + timelineMediaPreviewValue = MediaPreviewValue.On + ), + ) + rule.clickOn(R.string.screen_advanced_settings_show_media_timeline_always_hide) + eventsRecorder.assertSingle(AdvancedSettingsEvents.SetTimelineMediaPreviewValue(MediaPreviewValue.Off)) + } } private fun AndroidComposeTestRule.setAdvancedSettingsView( diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt index 44bd714f26..7be47338ca 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceDropdown.kt @@ -99,9 +99,10 @@ fun PreferenceDropdown( */ interface DropdownOption { /** - * The text to display for this option. + * Returns the text to be displayed for this option. */ - val text: String + @Composable + fun getText(): String } @Composable @@ -123,7 +124,7 @@ private fun DropdownTrailingContent( verticalAlignment = Alignment.CenterVertically, ) { Text( - text = selectedOption?.text.orEmpty(), + text = selectedOption?.getText().orEmpty(), maxLines = 1, style = ElementTheme.typography.fontBodyMdRegular, color = ElementTheme.colors.textSecondary, @@ -139,7 +140,7 @@ private fun DropdownTrailingContent( DropdownMenuItem( text = { Text( - text = option.text, + text = option.getText(), style = ElementTheme.typography.fontBodyMdRegular ) }, @@ -158,13 +159,16 @@ private fun DropdownTrailingContent( internal fun PreferenceDropdownPreview() = ElementThemedPreview { val options = listOf( object : DropdownOption { - override val text = "Option 1" + @Composable + override fun getText(): String = "Option 1" }, object : DropdownOption { - override val text = "Option 2" + @Composable + override fun getText(): String = "Option 2" }, object : DropdownOption { - override val text = "Option 3" + @Composable + override fun getText(): String = "Option 3" }, ).toImmutableList() From d5118124bec51030f1db035f8b61621dc534536e Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 11 Apr 2025 15:24:12 +0000 Subject: [PATCH 2/2] Update screenshots --- ...references.impl.advanced_AdvancedSettingsViewDark_0_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_1_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_2_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_3_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_4_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_5_en.png | 4 ++-- ...references.impl.advanced_AdvancedSettingsViewDark_6_en.png | 3 --- ...eferences.impl.advanced_AdvancedSettingsViewLight_0_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_1_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_2_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_3_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_4_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_5_en.png | 4 ++-- ...eferences.impl.advanced_AdvancedSettingsViewLight_6_en.png | 3 --- 14 files changed, 24 insertions(+), 30 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en.png index c6ea7ea86b..6dcb4a0233 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:926ce46cacac7beaac403e1c4e8034398d91dc48ab5f651bc7f0639ac65fe33a -size 46759 +oid sha256:733b71c4199d1a5908b5e76d8e44f5781cee39e97d57a049be99f9e66c3d30e1 +size 46936 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en.png index edccccc989..a7fb1c20db 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84c2474bc4d10e1aa3184c41b12b1bcf51d7e2b7ec801944608613aa46f50eba -size 46636 +oid sha256:ef41e0df758991e44e9abcf3d7d511c7cc932711db58e94ad1b4617fe45c60c3 +size 46826 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en.png index 01cf719299..45ab8e1004 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:611d435a2b3e6e0f8c7721905f635c1c93aa217df3fe4f4b6bb38bf5700e3629 -size 34586 +oid sha256:de45164ae8112206c1cf1a67c284cdea1509f4fa070f963fddf6a87eb9183ee1 +size 46813 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en.png index f844203887..29477d75f1 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d9b0a865db8f87d6c1c95b8fb6d916f261d44cecec52fdebd56288f2df35f0f -size 46627 +oid sha256:7c3c1d2b2fc9e5a16a1bc57551238c5190f25a873575eaf3731c36aaf19d7f00 +size 46802 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en.png index 69f5a502d5..a8639cc5a5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0505bdd3cfccf156249ab27ed0f087bd4d01d11121cb1f5e0c8450c6b7b58059 -size 46615 +oid sha256:1759e7063862ec1de7ce2b894067478599afb7c87b183e904c8d0199c93ed546 +size 46646 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en.png index ef2041611a..9d24cf3869 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a004afcec0cb40f82172c7abdc4404d1a0d879d0e23c63d0dcd1d7325cddff43 -size 46471 +oid sha256:420e10e0eb2c90d38e28262152dd2dee54cfb73f7b031b7a34acea17a8f784fa +size 46943 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en.png deleted file mode 100644 index a3a7ee69cf..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb09af4f9c96afb60b917d9484e28bacb73c494f9dfc2f42abb482896027b7b7 -size 46767 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en.png index a61c1185f1..d526c73fb5 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dfb5f83a129332a84f0184ba6a37ba9a95ded6fd9692a6e5710aaeb6b424c7c -size 48610 +oid sha256:7faf10e196f9275fdafabb53cb354532b2c5aa73869d1fe48ac67b53bbb34531 +size 48681 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en.png index 6c498e613b..b5d33d0961 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:903d0aa3faa5b4feae990139c467a5a6662808ffb768c7a2a5cd314f9ea09ba2 -size 48482 +oid sha256:15b0cf42d99a96ef4b52349301e4e90a5478150396a6890a66df1d33c3b6b89d +size 48558 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en.png index 992a95c8f1..a5808a088f 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4a2538700b5dc993568575e7017fc26c3cba7af7b7567fac069af5aa0c6f6b5f -size 36484 +oid sha256:f7debb36ffa6a60d7d30f9d59e247e6091c455860bdaae67502a52a5cec5e9c9 +size 48572 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en.png index babb6a6546..522326aa21 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9177ba1065f5cfe3137a16c024445332b2fe326969f5f6d65ccf6b1707deabe9 -size 48502 +oid sha256:106251ed2fb0a330fa98d4dabd8aebcb946fdbd098b18372c8a9c3b8df39086f +size 48554 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en.png index 909a027708..85e9963735 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f07064f41aafea6a91e3314d7d3bb099918e348ef9f9154a057d90758b9fb71 -size 48480 +oid sha256:a9b8cb284cc78c03f4bd4f4364d898e656a07ebe228243fdded35c283a1205e0 +size 48492 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en.png index e2d2f592e0..8e06f2bcad 100644 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92c1c93890214c88ed0e4d1d9faee27cc671db94fe928633ccc82471c137b64a -size 48422 +oid sha256:ddb21e08e8047aada11330634ad9c137cdb8a3a349f457c066243394fcc23924 +size 48682 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en.png deleted file mode 100644 index feba53f652..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f21d860514e97b48c3fab7fef4fbf6d710854d21ea2eecc3b44a5ba340c92eb -size 48608