Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: feat: Dark theme for AMOLED screens #1178

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 1 addition & 21 deletions app/src/main/java/com/chesire/nekome/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.chesire.nekome.ui
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.collectAsState
import com.chesire.lifecyklelog.LogLifecykle
import com.chesire.nekome.core.compose.theme.NekomeTheme
Expand All @@ -24,29 +23,10 @@ class MainActivity : ComponentActivity() {

setContent {
val themeState = appSettings.theme.collectAsState(initial = Theme.System)
val (isDarkMode, isDynamicColor) = generateTheme(
theme = themeState.value,
isSystemDarkMode = isSystemInDarkTheme()
)
NekomeTheme(
isDarkTheme = isDarkMode,
isDynamicColor = isDynamicColor
) {
NekomeTheme(theme = themeState.value) {
MainActivityScreen()
}
}
}

/**
* Returns a [Pair] of (dark mode enabled) to (dynamic color enabled).
*/
private fun generateTheme(theme: Theme, isSystemDarkMode: Boolean): Pair<Boolean, Boolean> {
return when (theme) {
Theme.System -> isSystemDarkMode to true
Theme.Dark -> true to false
Theme.Light -> false to false
Theme.DynamicDark -> true to true
Theme.DynamicLight -> false to true
}
}
}
1 change: 1 addition & 0 deletions core/compose/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ dependencies {
implementation(libs.androidx.compose.ui.test.manifest)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.google.accompanist.systemuicontroller)
implementation(project(":core:preferences"))
debugImplementation(libs.androidx.compose.ui.tooling)
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,12 @@ val LightColorPalette = lightColorScheme(
onSurface = Color(0xFF191c1e),
outline = Color(0xFF70787d),
surfaceVariant = Color(0xFFdce4e9),
onSurfaceVariant = Color(0xFF40484c)
onSurfaceVariant = Color(0xFF40484c),

)

val BlackColorPalette = DarkColorPalette.copy(
background = Color(0xFF000000),
surface = Color(0xFF000000),
surfaceVariant = Color(0xFF000000),
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,54 @@ import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import com.chesire.nekome.core.preferences.flags.Theme
import com.google.accompanist.systemuicontroller.rememberSystemUiController

/**
* Used to set the theme for your app.
*
* If the device is incompatible with a given dynamic theme
* due to the api level being below [Build.VERSION_CODES.S], they will default to their
* non-dynamic versions
* @param theme a [Theme] enum, this defaults to [Theme.System].
* @param content a composable you want to set the given theme to.
*/
@Composable
fun NekomeTheme(
isDarkTheme: Boolean = isSystemInDarkTheme(),
isDynamicColor: Boolean = true,
content: @Composable () -> Unit
theme: Theme = Theme.System,
content: @Composable () -> Unit,
) {
val dynamicCompatible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val isSystemDarkTheme = isSystemInDarkTheme()
val systemUiController = rememberSystemUiController()

val dynamicColor = isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colorScheme = when {
dynamicColor && isDarkTheme -> dynamicDarkColorScheme(LocalContext.current)
dynamicColor && !isDarkTheme -> dynamicLightColorScheme(LocalContext.current)
isDarkTheme -> DarkColorPalette
else -> LightColorPalette
val dynamicDarkColorPalette =
if (dynamicCompatible) dynamicDarkColorScheme(LocalContext.current) else DarkColorPalette

val dynamicLightColorPalette =
if (dynamicCompatible) dynamicLightColorScheme(LocalContext.current) else LightColorPalette

val systemTheme = if(isSystemDarkTheme) dynamicDarkColorPalette else dynamicLightColorPalette
val colorScheme = when (theme) {
Theme.System -> systemTheme
Theme.Dark -> DarkColorPalette
Theme.Light -> LightColorPalette
Theme.Black -> BlackColorPalette
Theme.DynamicDark -> dynamicDarkColorPalette
Theme.DynamicLight -> dynamicLightColorPalette
else -> systemTheme
}

systemUiController.apply {
setNavigationBarColor(color = colorScheme.surface)
setStatusBarColor(color = colorScheme.background)
}

Log.d(
"Nekome",
"Is system in dark theme? [$isDarkTheme], is using dynamic color? [$isDynamicColor]"
"Is system in dark theme? [$isSystemDarkTheme]\n\t " +
"Dynamic compatible device? [$dynamicCompatible]\n\t" +
"selected theme : [${theme.name}] "
)

MaterialTheme(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ enum class Theme(val value: Int, @StringRes val stringId: Int) {
Dark(2, StringResource.settings_theme_dark),
Light(1, StringResource.settings_theme_light),
DynamicDark(3, StringResource.settings_theme_dynamic_dark),
DynamicLight(4, StringResource.settings_theme_dynamic_light);
DynamicLight(4, StringResource.settings_theme_dynamic_light),
Black(5, StringResource.settings_theme_black);

companion object {
/**
* Gets a map of [value] to the string acquired from the [stringId].
*/
fun getValueMap(context: Context) = values()
fun getValueMap(context: Context) = entries
.associate { it.value to context.getString(it.stringId) }

/**
Expand All @@ -28,8 +29,9 @@ enum class Theme(val value: Int, @StringRes val stringId: Int) {
*/
fun fromValue(value: String): Theme {
return value.toIntOrNull()?.let { intValue ->
values().find { it.value == intValue } ?: System
entries.find { it.value == intValue } ?: System
} ?: System
}

}
}
1 change: 1 addition & 0 deletions core/resources/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
<string name="settings_theme_dynamic_dark">ダイナミックダークテーマ</string>
<string name="settings_theme_dynamic_light">ダイナミックライトテーマ</string>

<string name="settings_theme_black">アモールド ブラックテーマ</string>
<string name="discover_trending_anime">流行中のアニメ</string>
<string name="discover_trending_manga">流行中の漫画</string>
<string name="discover_trending_track">トラック</string>
Expand Down
1 change: 1 addition & 0 deletions core/resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
<string name="settings_theme_light">Light</string>
<string name="settings_theme_dynamic_dark">Dynamic Dark</string>
<string name="settings_theme_dynamic_light">Dynamic Light</string>
<string name="settings_theme_black">AMOLED Black</string>

<string name="discover_trending_anime">Trending Anime</string>
<string name="discover_trending_manga">Trending Manga</string>
Expand Down
1 change: 1 addition & 0 deletions features/login/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation(project(":libraries:datasource:auth"))
implementation(project(":libraries:datasource:series"))
implementation(project(":libraries:datasource:user"))
implementation(project(":core:preferences"))

implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.appcompat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ private fun Preview() {
errorSnackbarMessage = null,
navigateScreenEvent = null
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(initialValue = initialState, producer = { value = initialState }),
{ /**/ },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private fun Preview() {
avatar = "https://media.kitsu.io/users/avatars/294558/large.jpeg",
finishedSyncing = null
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(initialValue = initialState, producer = { value = initialState })
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ private fun Preview() {
resultModels = emptyList(),
errorSnackbar = null
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(initialValue = initialState, producer = { value = initialState }),
onInputTextChanged = { /**/ },
Expand Down Expand Up @@ -387,7 +387,7 @@ private fun PopulatedPreview() {
),
errorSnackbar = null
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(initialValue = initialState, producer = { value = initialState }),
onInputTextChanged = { /**/ },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ private fun Preview() {
)
)
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(
initialValue = initialState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ data class FilterOption(
@Composable
@Preview
private fun Preview() {
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
filters = listOf(
FilterOption(UserSeriesStatus.Current, true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private fun Render(
@Composable
@Preview
private fun Preview() {
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
series = Series(
userId = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ private fun Preview() {
),
errorSnackbar = null
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(
initialValue = initialState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ private fun Preview() {
showTitleLanguageDialog = false,
rateSeriesValue = false
)
NekomeTheme(isDarkTheme = true) {
NekomeTheme() {
Render(
state = produceState(
initialValue = initialState,
Expand Down