Setup multiplatform settings with KMP and theme

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta 2026-03-20 19:18:51 +08:00
parent 677c99c34a
commit c0469371a3
7 changed files with 48 additions and 6 deletions

View file

@ -55,6 +55,7 @@ runner = "1.7.0"
rxandroid = "3.0.2" rxandroid = "3.0.2"
rxbinding = "4.0.0" rxbinding = "4.0.0"
rxjava = "3.1.12" rxjava = "3.1.12"
settings = "1.3.0"
sonarqube = "7.3.0.8198" sonarqube = "7.3.0.8198"
statesaver = "1.4.1" # TODO: Drop because it is deprecated and incompatible with KSP2 statesaver = "1.4.1" # TODO: Drop because it is deprecated and incompatible with KSP2
stetho = "1.6.0" stetho = "1.6.0"
@ -156,6 +157,7 @@ pinterest-ktlint = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "
puppycrawl-checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" } puppycrawl-checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" }
reactivex-rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" } reactivex-rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
reactivex-rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" } reactivex-rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
russhwolf-settings = { module = "com.russhwolf:multiplatform-settings", version.ref = "settings" }
squareup-leakcanary-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" } squareup-leakcanary-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" }
squareup-leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref = "leakcanary" } squareup-leakcanary-plumber = { module = "com.squareup.leakcanary:plumber-android", version.ref = "leakcanary" }
squareup-leakcanary-watcher = { module = "com.squareup.leakcanary:leakcanary-object-watcher-android", version.ref = "leakcanary" } squareup-leakcanary-watcher = { module = "com.squareup.leakcanary:leakcanary-object-watcher-android", version.ref = "leakcanary" }

View file

@ -15,6 +15,9 @@ kotlin {
jvmToolchain(21) jvmToolchain(21)
compilerOptions { compilerOptions {
freeCompilerArgs.addAll(
"-Xexpect-actual-classes"
)
optIn.addAll( optIn.addAll(
"androidx.compose.material3.ExperimentalMaterial3Api", "androidx.compose.material3.ExperimentalMaterial3Api",
"androidx.compose.material3.ExperimentalMaterial3ExpressiveApi", "androidx.compose.material3.ExperimentalMaterial3ExpressiveApi",
@ -80,6 +83,8 @@ kotlin {
implementation(libs.koin.compose.viewmodel) implementation(libs.koin.compose.viewmodel)
implementation(libs.koin.annotations) implementation(libs.koin.annotations)
implementation(libs.russhwolf.settings)
} }
} }
commonTest.dependencies { commonTest.dependencies {
@ -89,6 +94,7 @@ kotlin {
androidMain.dependencies { androidMain.dependencies {
implementation(libs.jetbrains.compose.preview) implementation(libs.jetbrains.compose.preview)
implementation(libs.androidx.activity) implementation(libs.androidx.activity)
implementation(libs.androidx.preference)
} }
val androidDeviceTest by getting { val androidDeviceTest by getting {
dependencies { dependencies {

View file

@ -7,11 +7,15 @@
package net.newpipe.app.theme package net.newpipe.app.theme
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialExpressiveTheme import androidx.compose.material3.MaterialExpressiveTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
import com.russhwolf.settings.Settings
import org.koin.compose.koinInject
private val lightScheme = lightColorScheme( private val lightScheme = lightColorScheme(
primary = primaryLight, primary = primaryLight,
@ -89,13 +93,43 @@ private val darkScheme = darkColorScheme(
surfaceContainerHighest = surfaceContainerHighestDark surfaceContainerHighest = surfaceContainerHighestDark
) )
private val blackScheme = darkScheme.copy(surface = Color.Black)
/**
* Gets current color scheme chosen by the user
*/
@Composable @Composable
fun AppTheme(useDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { fun currentColorScheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
settings: Settings = koinInject()
): ColorScheme {
val nightScheme = when (settings.getString("night_theme", "dark_theme")) {
"black_theme" -> blackScheme
else -> darkScheme
}
return when (settings.getString("theme", "auto_device_theme")) {
"light_theme" -> lightScheme
"dark_theme" -> darkScheme
"black_theme" -> blackScheme
else -> if (!useDarkTheme) lightScheme else nightScheme
}
}
/**
* Default app theme for the NewPipe composables
* @param isPreview Whether the theme is being used in preview mode
* @param colorScheme Color scheme to use for theme, defaults to light in preview mode
* @param content Composable content to show to the user
*/
@Composable
fun AppTheme(
isPreview: Boolean = LocalInspectionMode.current,
colorScheme: ColorScheme = if (isPreview) lightScheme else currentColorScheme(),
content: @Composable () -> Unit
) {
MaterialExpressiveTheme( MaterialExpressiveTheme(
colorScheme = when { colorScheme = colorScheme,
!useDarkTheme -> lightScheme
else -> darkScheme
},
content = content content = content
) )
} }