setup appearance settings navigation

This commit is contained in:
Ida Delphine
2026-09-17 15:51:13 +02:00
committed by Tobi
parent 62db4d487a
commit c2c3c9f527
4 changed files with 50 additions and 4 deletions
@@ -15,9 +15,13 @@ import net.newpipe.app.model.License
@Serializable
sealed interface Destination : NavKey {
@Serializable
data object AppearanceSettings : Destination
@Serializable
data object Settings : Destination
@Serializable
data object About : Destination
}
@@ -8,6 +8,7 @@ package net.newpipe.app.navigation
import androidx.compose.runtime.mutableStateListOf
import co.touchlab.kermit.Logger
import net.newpipe.app.screen.about.AboutScreen
import net.newpipe.app.screen.settings.AppearanceSettingsScreen
import net.newpipe.app.screen.settings.SettingsHomeScreen
import org.koin.core.annotation.KoinExperimentalAPI
import org.koin.core.annotation.Provided
@@ -32,6 +33,10 @@ fun navModule() = module {
navigation<Destination.Settings> {
SettingsHomeScreen()
}
navigation<Destination.AppearanceSettings> {
AppearanceSettingsScreen()
}
}
/**
@@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.PreviewWrapper
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import net.newpipe.app.composable.PreferenceRow
import net.newpipe.app.composable.TopAppBar
import net.newpipe.app.navigation.Destination
import net.newpipe.app.navigation.Navigator
import net.newpipe.app.preview.ThemePreviewProvider
import net.newpipe.app.screen.settings.model.SettingsCategory
@@ -49,8 +50,14 @@ fun SettingsHomeScreen(
SettingsCategory(
title = type.title,
icon = type.icon,
// TODO: Replace with a Destination once sub-screens are migrated
onClick = {}
onClick = {
when (type) {
SettingsCategoryType.APPEARANCE ->
navigator.navigateTo(Destination.AppearanceSettings)
// TODO: wire remaining sub-screens as they are migrated
else -> Unit
}
}
)
},
onNavigateUp = { navigator.navigateUp() }
@@ -16,6 +16,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
import com.russhwolf.settings.Settings
import org.koin.compose.koinInject
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import com.russhwolf.settings.ObservableSettings
private val lightScheme = lightColorScheme(
primary = primaryLight,
@@ -103,12 +109,15 @@ fun currentColorScheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
settings: Settings = koinInject()
): ColorScheme {
val nightScheme = when (settings.getString("night_theme", "dark_theme")) {
val theme = rememberSettingString(settings, "theme", "auto_device_theme")
val nightTheme = rememberSettingString(settings, "night_theme", "dark_theme")
val nightScheme = when (nightTheme) {
"black_theme" -> blackScheme
else -> darkScheme
}
return when (settings.getString("theme", "auto_device_theme")) {
return when (theme) {
"light_theme" -> lightScheme
"dark_theme" -> darkScheme
"black_theme" -> blackScheme
@@ -116,6 +125,27 @@ fun currentColorScheme(
}
}
/**
* Reads a string setting as Compose state, updating when the stored value changes so theme
* edits made elsewhere (e.g. the Appearance screen) apply live without recreating the host.
*/
@Composable
private fun rememberSettingString(
settings: Settings,
key: String,
defaultValue: String
): String {
var value by remember(key) { mutableStateOf(settings.getString(key, defaultValue)) }
val observable = settings as? ObservableSettings
if (observable != null) {
DisposableEffect(key, observable) {
val listener = observable.addStringListener(key, defaultValue) { value = it }
onDispose { listener.deactivate() }
}
}
return value
}
/**
* Default app theme for the NewPipe composables
* @param isPreview Whether the theme is being used in preview mode