Add "Allow black theme" feature flag

This commit is contained in:
Timur Gilfanov 2026-04-05 12:03:50 +04:00
parent 104ae4752a
commit 5e6a6af409
16 changed files with 139 additions and 9 deletions

View file

@ -20,6 +20,10 @@ enum class Theme {
Light,
}
private fun Theme.coerceBlackTheme(allowBlackTheme: Boolean): Theme {
return if (this == Theme.Black && !allowBlackTheme) Theme.Dark else this
}
@Composable
fun Theme.isDark(): Boolean {
return when (this) {
@ -29,9 +33,9 @@ fun Theme.isDark(): Boolean {
}
}
fun Flow<String?>.mapToTheme(): Flow<Theme> = map {
fun Flow<String?>.mapToTheme(allowBlackTheme: Boolean = true): Flow<Theme> = map {
when (it) {
null -> Theme.System
else -> Theme.valueOf(it)
}
}.coerceBlackTheme(allowBlackTheme)
}

View file

@ -15,6 +15,7 @@ import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Test
@ -72,4 +73,14 @@ class ThemeTest {
assertThat(awaitItem()).isTrue()
}
}
@Test
fun `mapToTheme falls back to dark when black theme is disabled`() = runTest {
flowOf(Theme.Black.name)
.mapToTheme(allowBlackTheme = false)
.test {
assertThat(awaitItem()).isEqualTo(Theme.Dark)
awaitComplete()
}
}
}

View file

@ -38,6 +38,7 @@ dependencies {
implementation(projects.libraries.androidutils)
implementation(projects.libraries.architecture)
implementation(projects.libraries.core)
implementation(projects.libraries.featureflag.api)
implementation(projects.libraries.preferences.api)
implementation(projects.libraries.testtags)
implementation(projects.libraries.uiStrings)

View file

@ -22,6 +22,8 @@ import io.element.android.compound.theme.mapToTheme
import io.element.android.compound.tokens.generated.SemanticColors
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
val LocalBuildMeta = staticCompositionLocalOf {
@ -53,15 +55,18 @@ val LocalBuildMeta = staticCompositionLocalOf {
@Composable
fun ElementThemeApp(
appPreferencesStore: AppPreferencesStore,
featureFlagService: FeatureFlagService,
compoundLight: SemanticColors,
compoundDark: SemanticColors,
buildMeta: BuildMeta,
content: @Composable () -> Unit,
) {
val isBlackThemeAllowed by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.AllowBlackTheme)
}.collectAsState(initial = false)
val theme by remember {
appPreferencesStore.getThemeFlow().mapToTheme()
}
.collectAsState(initial = Theme.System)
appPreferencesStore.getThemeFlow().mapToTheme(allowBlackTheme = isBlackThemeAllowed)
}.collectAsState(initial = Theme.System)
LaunchedEffect(theme) {
AppCompatDelegate.setDefaultNightMode(
when (theme) {

View file

@ -147,6 +147,13 @@ enum class FeatureFlags(
defaultValue = { false },
isFinished = false,
),
AllowBlackTheme(
key = "feature.allow_black_theme",
title = "Allow black theme",
description = "Allow selecting the black appearance theme for battery saving on OLED.",
defaultValue = { false },
isFinished = false,
),
LiveLocationSharing(
key = "feature.liveLocationSharing",
title = "Live location sharing",