diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt index 228ca4d754..68aba21188 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt @@ -47,6 +47,7 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.api.ShowAllActivityInRoomListFeature import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId @@ -119,7 +120,7 @@ class RoomListPresenter( val declineInviteMenu = remember { mutableStateOf(RoomListState.DeclineInviteMenu.Hidden) } val showAllActivity by produceState(initialValue = false) { - featureFlagService.isFeatureEnabledFlow(FeatureFlags.ShowAllActivityInRoomList).collect { value = it } + featureFlagService.isFeatureEnabledFlow(ShowAllActivityInRoomListFeature).collect { value = it } } fun handleEvent(event: RoomListEvent) { diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index dc96df2739..f73e39b8d7 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -40,6 +40,7 @@ import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.api.ShowAllActivityInRoomListFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.MatrixClient @@ -655,7 +656,7 @@ class RoomListPresenterTest { ) val featureFlagService = FakeFeatureFlagService( initialState = mapOf( - FeatureFlags.ShowAllActivityInRoomList.key to true, + ShowAllActivityInRoomListFeature.key to true, FeatureFlags.UnreadIndicatorCount.key to true, ) ) @@ -672,7 +673,7 @@ class RoomListPresenterTest { assertThat(enabledState.contentAsRooms().showAllActivity).isTrue() assertThat(enabledState.contentAsRooms().showUnreadCount).isTrue() - featureFlagService.setFeatureEnabled(FeatureFlags.ShowAllActivityInRoomList, false) + featureFlagService.setFeatureEnabled(ShowAllActivityInRoomListFeature, false) val allActivityDisabledState = consumeItemsUntilPredicate { state -> state.contentState is RoomListContentState.Rooms && !state.contentAsRooms().showAllActivity }.last() diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsEvent.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsEvent.kt index 18365fdbb4..b356d154a7 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsEvent.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsEvent.kt @@ -34,5 +34,5 @@ sealed interface NotificationSettingsEvent { data object DismissCallRingtoneDialog : NotificationSettingsEvent data class SelectCallRingtonePreset(val sound: NotificationSound) : NotificationSettingsEvent data object LaunchCallRingtonePicker : NotificationSettingsEvent - data object ToggleShowAllActivityInRoomList : NotificationSettingsEvent + data class ToggleShowAllActivityInRoomList(val newValue: Boolean) : NotificationSettingsEvent } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt index 24a366b52d..d2e5fc5b50 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt @@ -29,7 +29,7 @@ import io.element.android.libraries.architecture.runUpdatingStateNoSuccess import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService -import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.api.ShowAllActivityInRoomListFeature import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService @@ -200,7 +200,7 @@ class NotificationSettingsPresenter( } val showAllActivityInRoomList by produceState(false) { - featureFlagService.isFeatureEnabledFlow(FeatureFlags.ShowAllActivityInRoomList) + featureFlagService.isFeatureEnabledFlow(ShowAllActivityInRoomListFeature) .collect { value = it } } @@ -284,8 +284,8 @@ class NotificationSettingsPresenter( NotificationSettingsEvent.DismissCallRingtoneCopyError -> { callRingtoneCopyError = false } - NotificationSettingsEvent.ToggleShowAllActivityInRoomList -> localCoroutineScope.launch { - featureFlagService.setFeatureEnabled(FeatureFlags.ShowAllActivityInRoomList, !showAllActivityInRoomList) + is NotificationSettingsEvent.ToggleShowAllActivityInRoomList -> localCoroutineScope.launch { + featureFlagService.setFeatureEnabled(ShowAllActivityInRoomListFeature, event.newValue) } } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt index aa085f3ac6..e6784b5ce7 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt @@ -205,7 +205,7 @@ private fun NotificationSettingsContentView( title = stringResource(R.string.screen_notification_settings_show_all_activity_title), subtitle = stringResource(R.string.screen_notification_settings_show_all_activity_subtitle), isChecked = state.showAllActivityInRoomList, - onCheckedChange = { state.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList) } + onCheckedChange = { newValue -> state.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList(newValue)) } ) } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenterTest.kt index c8dad6659e..f189949cdc 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenterTest.kt @@ -11,7 +11,7 @@ package io.element.android.features.preferences.impl.notifications import com.google.common.truth.Truth.assertThat import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService -import io.element.android.libraries.featureflag.api.FeatureFlags +import io.element.android.libraries.featureflag.api.ShowAllActivityInRoomListFeature import io.element.android.libraries.featureflag.test.FakeFeatureFlagService import io.element.android.libraries.fullscreenintent.api.FullScreenIntentPermissionsState import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState @@ -1110,13 +1110,13 @@ class NotificationSettingsPresenterTest { @Test fun `present - showAllActivityInRoomList reflects the feature flag value`() = runTest { val featureFlagService = FakeFeatureFlagService( - initialState = mapOf(FeatureFlags.ShowAllActivityInRoomList.key to true) + initialState = mapOf(ShowAllActivityInRoomListFeature.key to true) ) val presenter = createNotificationSettingsPresenter(featureFlagService = featureFlagService) presenter.test { val state = consumeItemsUntilPredicate { it.showAllActivityInRoomList }.last() assertThat(state.showAllActivityInRoomList).isTrue() - featureFlagService.setFeatureEnabled(FeatureFlags.ShowAllActivityInRoomList, false) + featureFlagService.setFeatureEnabled(ShowAllActivityInRoomListFeature, false) val updatedState = consumeItemsUntilPredicate { !it.showAllActivityInRoomList }.last() assertThat(updatedState.showAllActivityInRoomList).isFalse() @@ -1127,22 +1127,22 @@ class NotificationSettingsPresenterTest { @Test fun `present - ToggleShowAllActivityInRoomList toggles the feature flag`() = runTest { val featureFlagService = FakeFeatureFlagService( - initialState = mapOf(FeatureFlags.ShowAllActivityInRoomList.key to false) + initialState = mapOf(ShowAllActivityInRoomListFeature.key to false) ) val presenter = createNotificationSettingsPresenter(featureFlagService = featureFlagService) presenter.test { val initialState = awaitItem() assertThat(initialState.showAllActivityInRoomList).isFalse() - initialState.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList) + initialState.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList(true)) val enabledState = consumeItemsUntilPredicate { it.showAllActivityInRoomList }.last() assertThat(enabledState.showAllActivityInRoomList).isTrue() - assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.ShowAllActivityInRoomList)).isTrue() - enabledState.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList) + assertThat(featureFlagService.isFeatureEnabled(ShowAllActivityInRoomListFeature)).isTrue() + enabledState.eventSink(NotificationSettingsEvent.ToggleShowAllActivityInRoomList(false)) val disabledState = consumeItemsUntilPredicate { !it.showAllActivityInRoomList }.last() assertThat(disabledState.showAllActivityInRoomList).isFalse() - assertThat(featureFlagService.isFeatureEnabled(FeatureFlags.ShowAllActivityInRoomList)).isFalse() + assertThat(featureFlagService.isFeatureEnabled(ShowAllActivityInRoomListFeature)).isFalse() cancelAndIgnoreRemainingEvents() } } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsViewTest.kt index fe7238beea..10510d1172 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsViewTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsViewTest.kt @@ -207,7 +207,7 @@ class NotificationSettingsViewTest : RobolectricTest() { eventsRecorder.assertList( listOf( NotificationSettingsEvent.RefreshSystemNotificationsEnabled, - NotificationSettingsEvent.ToggleShowAllActivityInRoomList, + NotificationSettingsEvent.ToggleShowAllActivityInRoomList(!initialState), ) ) } diff --git a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt index 4b40236c5f..d241d72c68 100644 --- a/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt +++ b/libraries/featureflag/api/src/main/kotlin/io/element/android/libraries/featureflag/api/FeatureFlags.kt @@ -169,13 +169,19 @@ enum class FeatureFlags( defaultValue = { false }, isFinished = false, ), - ShowAllActivityInRoomList( - key = "feature.show_all_activity_in_room_list", - title = "Show all activity in room list", - description = "Show all activity indicators in the room list, using unread messages instead of notifications.", - defaultValue = { true }, - // To hide it from the developer options, since it's displayed in the notification settings instead - isFinished = true, - isInLabs = false, - ) +} + +/** + * Feature flag to show all activity indicators in the room list, using unread messages instead of notifications. + * + * This is separate from the [FeatureFlags] enum because it is not a feature flag that can be toggled in developer options, + * but rather a setting that can be toggled in the app settings. + */ +object ShowAllActivityInRoomListFeature : Feature { + override val key: String = "feature.show_all_activity_in_room_list" + override val title: String = "Show all activity in room list" + override val description: String = "Show all activity indicators in the room list, using unread messages instead of notifications." + override val defaultValue: (BuildMeta) -> Boolean = { true } + override val isFinished: Boolean = false + override val isInLabs: Boolean = false }