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()