Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ object Key {
const val APP_EXPERT = "isExpert"
const val APP_THEME = "appTheme"
const val NIGHT_THEME = "nightTheme"
// Remembers the user's night-mode setting before the dark-only Dracula theme
// forced it on, so it can be restored when switching to another theme.
const val NIGHT_THEME_BEFORE_DRACULA = "nightThemeBeforeDracula"
const val APP_LANGUAGE = "appLanguage"
const val SERVICE_MODE = "serviceMode"
const val MODE_VPN = "vpn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ object DataStore : OnPreferenceDataStoreChangeListener {
var isExpert by configurationStore.boolean(Key.APP_EXPERT)
var appTheme by configurationStore.int(Key.APP_THEME)
var nightTheme by configurationStore.stringToInt(Key.NIGHT_THEME)
// -1 = not set (no Dracula override active). Otherwise holds the night-mode
// value to restore when leaving the dark-only Dracula theme.
var nightThemeBeforeDracula by configurationStore.int(Key.NIGHT_THEME_BEFORE_DRACULA) { -1 }
var appLanguage by configurationStore.string(Key.APP_LANGUAGE) { "" }
var serviceMode by configurationStore.string(Key.SERVICE_MODE) { Key.MODE_VPN }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,36 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
addPreferencesFromResource(R.xml.global_preferences)

val appTheme = findPreference<ColorPickerPreference>(Key.APP_THEME)!!
val nightTheme = findPreference<SimpleMenuPreference>(Key.NIGHT_THEME)!!
appTheme.setOnPreferenceChangeListener { _, newTheme ->
if (DataStore.serviceState.started) {
SagerNet.reloadService()
}
val theme = Theme.getTheme(newTheme as Int)
val themeId = newTheme as Int
val previousTheme = DataStore.appTheme // still the old value at this point
// Dracula is a dark-only theme: force night mode on so its #282a36
// canvas (values-night) takes effect instead of a washed-out light surface.
// Remember the prior night-mode setting so it can be restored on exit.
if (themeId == Theme.DRACULA) {
if (previousTheme != Theme.DRACULA && DataStore.nightTheme != 1) {
DataStore.nightThemeBeforeDracula = DataStore.nightTheme
DataStore.nightTheme = 1
Theme.currentNightMode = 1
nightTheme.value = "1"
Theme.applyNightTheme()
}
} else if (previousTheme == Theme.DRACULA) {
// Leaving Dracula: restore the night-mode setting we forced on.
val restore = DataStore.nightThemeBeforeDracula
if (restore != -1) {
DataStore.nightThemeBeforeDracula = -1
DataStore.nightTheme = restore
Theme.currentNightMode = restore
nightTheme.value = restore.toString()
Theme.applyNightTheme()
}
}
Comment thread
greptile-apps[bot] marked this conversation as resolved.
val theme = Theme.getTheme(themeId)
app.setTheme(theme)
requireActivity().apply {
setTheme(theme)
Expand All @@ -78,9 +103,11 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
true
}

val nightTheme = findPreference<SimpleMenuPreference>(Key.NIGHT_THEME)!!
nightTheme.setOnPreferenceChangeListener { _, newTheme ->
Theme.currentNightMode = (newTheme as String).toInt()
// A manual night-mode change takes precedence: drop any pending
// Dracula restore so we don't override the user's choice later.
DataStore.nightThemeBeforeDracula = -1
Theme.applyNightTheme()
true
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/io/nekohasekai/sagernet/utils/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object Theme {
const val BLUE_GREY = 20
const val BLACK = 21
const val VERDANT_MINT = 22
const val DRACULA = 23

private fun defaultTheme() = PINK_SSR

Expand Down Expand Up @@ -74,6 +75,7 @@ object Theme {
BLUE_GREY -> R.style.Theme_SagerNet_BlueGrey
BLACK -> R.style.Theme_SagerNet_Black
VERDANT_MINT -> R.style.Theme_SagerNet_VerdantMint
DRACULA -> R.style.Theme_SagerNet_Dracula
else -> getTheme(defaultTheme())
}
}
Expand Down Expand Up @@ -102,6 +104,7 @@ object Theme {
BLUE_GREY -> R.style.Theme_SagerNet_Dialog_BlueGrey
BLACK -> R.style.Theme_SagerNet_Dialog_Black
VERDANT_MINT -> R.style.Theme_SagerNet_Dialog_VerdantMint
DRACULA -> R.style.Theme_SagerNet_Dialog_Dracula
else -> getDialogTheme(defaultTheme())
}
}
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@
<color name="card_elevated_yellow">#2C2A17</color>
<color name="card_elevated_black">#151515</color>
<color name="card_elevated_verdant_mint">#10241C</color>
<!-- Dracula dark surfaces (official palette). -->
<color name="card_elevated_dracula">#343746</color>
<color name="dracula_background">#282A36</color>
<color name="dracula_surface">#343746</color>
<color name="dracula_on_surface">#F8F8F2</color>
</resources>
44 changes: 44 additions & 0 deletions app/src/main/res/values-night/themes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Night-only surface overrides.

Other themes intentionally inherit the Material DayNight defaults, so we do
NOT redeclare them here. Only the Dracula theme paints a full custom canvas:
the official #282a36 background, #343746 surface, and #f8f8f2 foreground.

In day mode the Dracula style (values/themes.xml) keeps the standard light
surfaces, so accents stay readable even if the user is not in dark mode.
Selecting Dracula also forces night mode on (SettingsPreferenceFragment),
which is what brings these overrides into effect.
-->
<style name="Theme.SagerNet.Dracula" parent="Theme.SagerNet">
<item name="colorPrimary">@color/color_dracula</item>
<item name="colorPrimaryDark">@color/color_dracula_dark</item>
<item name="colorAccent">@color/color_dracula_accent</item>
<item name="colorMaterial100">@color/color_dracula_100</item>
<item name="colorMaterial300">@color/color_dracula_300</item>
<item name="cardElevatedSurfaceColor">@color/card_elevated_dracula</item>

<!-- True Dracula dark canvas. -->
<item name="colorSurface">@color/dracula_surface</item>
<item name="colorOnSurface">@color/dracula_on_surface</item>
<item name="android:colorBackground">@color/dracula_background</item>
<item name="colorOnBackground">@color/dracula_on_surface</item>
<item name="android:windowBackground">@color/dracula_background</item>
</style>

<style name="Theme.SagerNet.Dialog.Dracula" parent="Theme.SagerNet.Dialog">
<item name="colorPrimary">@color/color_dracula</item>
<item name="colorPrimaryDark">@color/color_dracula_dark</item>
<item name="colorAccent">@color/color_dracula_accent</item>
<item name="colorMaterial100">@color/color_dracula_100</item>
<item name="colorMaterial300">@color/color_dracula_300</item>
<item name="cardElevatedSurfaceColor">@color/card_elevated_dracula</item>

<item name="colorSurface">@color/dracula_surface</item>
<item name="colorOnSurface">@color/dracula_on_surface</item>
<item name="android:colorBackground">@color/dracula_background</item>
<item name="colorOnBackground">@color/dracula_on_surface</item>
</style>
</resources>
11 changes: 11 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<item>@color/material_blue_grey_500</item>
<item>@color/material_light_black</item>
<item>@color/color_verdant_mint</item>
<item>@color/color_dracula</item>
</integer-array>

<color name="material_amber_100">#FFECB3</color>
Expand Down Expand Up @@ -291,6 +292,15 @@
<color name="color_verdant_mint_100">#B4D7C6</color>
<color name="color_verdant_mint_300">#509177</color>

<!-- Dracula theme accents (https://draculatheme.com). Purple primary,
pink accent. Surfaces are overridden in values-night for the true
#282a36 canvas; see Theme.SagerNet.Dracula. -->
<color name="color_dracula">#BD93F9</color>
<color name="color_dracula_dark">#6272A4</color>
<color name="color_dracula_accent">#FF79C6</color>
<color name="color_dracula_100">#E9DDFB</color>
<color name="color_dracula_300">#9A7BD0</color>

<color name="color_ng_black_accent">#9E9E9E</color>
<color name="color_ng_black_primary">#2B2B2B</color>

Expand Down Expand Up @@ -329,5 +339,6 @@
<color name="card_elevated_yellow">#FFFDEF</color>
<color name="card_elevated_black">#EEEEEE</color>
<color name="card_elevated_verdant_mint">#EBF9F3</color>
<color name="card_elevated_dracula">#F1EAFB</color>

</resources>
22 changes: 22 additions & 0 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,19 @@
<item name="cardElevatedSurfaceColor">@color/card_elevated_verdant_mint</item>
</style>

<!-- Dracula: purple primary, pink accent. Accent colors apply in any mode;
the true #282a36 dark canvas (colorSurface/colorBackground/colorOnSurface)
is layered on in values-night/themes.xml. Selecting this theme forces
night mode on (see SettingsPreferenceFragment). -->
<style name="Theme.SagerNet.Dracula" parent="Theme.SagerNet">
<item name="colorPrimary">@color/color_dracula</item>
<item name="colorPrimaryDark">@color/color_dracula_dark</item>
<item name="colorAccent">@color/color_dracula_accent</item>
<item name="colorMaterial100">@color/color_dracula_100</item>
<item name="colorMaterial300">@color/color_dracula_300</item>
<item name="cardElevatedSurfaceColor">@color/card_elevated_dracula</item>
</style>

<style name="Theme.SagerNet.Dialog.Black" parent="Theme.SagerNet.Dialog">
<item name="colorPrimary">@color/color_ng_black_primary</item>
<item name="colorPrimaryDark">@color/color_ng_black_primary</item>
Expand Down Expand Up @@ -622,6 +635,15 @@
<item name="cardElevatedSurfaceColor">@color/card_elevated_verdant_mint</item>
</style>

<style name="Theme.SagerNet.Dialog.Dracula" parent="Theme.SagerNet.Dialog">
<item name="colorPrimary">@color/color_dracula</item>
<item name="colorPrimaryDark">@color/color_dracula_dark</item>
<item name="colorAccent">@color/color_dracula_accent</item>
<item name="colorMaterial100">@color/color_dracula_100</item>
<item name="colorMaterial300">@color/color_dracula_300</item>
<item name="cardElevatedSurfaceColor">@color/card_elevated_dracula</item>
</style>

<style name="Theme.Start" parent="Theme.MaterialComponents.DayNight">
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="colorPrimary">@android:color/transparent</item>
Expand Down
Loading