diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java index 20f8896af..379294da0 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/data/Settings.java @@ -448,6 +448,44 @@ public void setTheme(Themes.Theme theme) { setString(R.string.pref_key_ui_theme, theme.toString()); } + public boolean isAutoThemeEnabled() { + return getBoolean(R.string.pref_key_ui_theme_auto, false); + } + + public void setAutoThemeEnabled(boolean value) { + setBoolean(R.string.pref_key_ui_theme_auto, value); + } + + public Themes.Theme getAutoLightTheme() { + String themeName = getString(R.string.pref_key_ui_theme_auto_light); + Themes.Theme theme = null; + if(themeName != null) { + try { + theme = Themes.Theme.valueOf(themeName); + } catch(IllegalArgumentException ignored) {} + } + return theme != null ? theme : Themes.Theme.LIGHT; + } + + public void setAutoLightTheme(Themes.Theme theme) { + setString(R.string.pref_key_ui_theme_auto_light, theme.toString()); + } + + public Themes.Theme getAutoDarkTheme() { + String themeName = getString(R.string.pref_key_ui_theme_auto_dark); + Themes.Theme theme = null; + if(themeName != null) { + try { + theme = Themes.Theme.valueOf(themeName); + } catch(IllegalArgumentException ignored) {} + } + return theme != null ? theme : Themes.Theme.DARK; + } + + public void setAutoDarkTheme(Themes.Theme theme) { + setString(R.string.pref_key_ui_theme_auto_dark, theme.toString()); + } + public boolean isVolumeButtonsScrollingEnabled() { return getBoolean(R.string.pref_key_ui_volumeButtonsScrolling_enabled, false); } diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java index 1bc3ec14b..544a9deaa 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/Themes.java @@ -9,6 +9,8 @@ import fr.gaulupeau.apps.InThePoche.R; import fr.gaulupeau.apps.Poche.App; +import android.content.Context; +import android.content.res.Configuration; public class Themes { @@ -28,23 +30,38 @@ public static Theme getCurrentTheme() { return theme; } + public static Theme getResolvedTheme(Context context) { + if (App.getSettings().isAutoThemeEnabled()) { + int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) { + return App.getSettings().getAutoDarkTheme(); + } else { + return App.getSettings().getAutoLightTheme(); + } + } + return theme; + } + public static void applyTheme(Activity activity) { applyTheme(activity, true); } public static void applyTheme(Activity activity, boolean actionBar) { - activity.setTheme(actionBar ? theme.getResId() : theme.getNoActionBarResId()); - appliedThemes.put(activity, theme); + Theme resolvedTheme = getResolvedTheme(activity); + activity.setTheme(actionBar ? resolvedTheme.getResId() : resolvedTheme.getNoActionBarResId()); + appliedThemes.put(activity, resolvedTheme); } public static void applyDialogTheme(Activity activity) { - activity.setTheme(theme.getDialogResId()); - appliedThemes.put(activity, theme); + Theme resolvedTheme = getResolvedTheme(activity); + activity.setTheme(resolvedTheme.getDialogResId()); + appliedThemes.put(activity, resolvedTheme); } public static void checkTheme(Activity activity) { Theme appliedTheme = appliedThemes.get(activity); - if(appliedTheme != theme) activity.recreate(); + Theme resolvedTheme = getResolvedTheme(activity); + if(appliedTheme != resolvedTheme) activity.recreate(); } public enum Theme { @@ -52,55 +69,67 @@ public enum Theme { R.string.themeName_light, R.style.LightTheme, R.style.LightTheme_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), LIGHT_CONTRAST( R.string.themeName_light_contrast, R.style.LightThemeContrast, R.style.LightThemeContrast_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), E_INK( R.string.themeName_eink, R.style.LightThemeContrast, R.style.LightThemeContrast_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + false ), DARK( R.string.themeName_dark, R.style.DarkTheme, R.style.DarkTheme_NoActionBar, - R.style.DialogThemeDark + R.style.DialogThemeDark, + true ), DARK_CONTRAST( R.string.themeName_dark_contrast, R.style.DarkThemeContrast, R.style.DarkThemeContrast_NoActionBar, - R.style.DialogThemeDark + R.style.DialogThemeDark, + true ), SOLARIZED( R.string.themeName_solarized, R.style.SolarizedTheme, R.style.SolarizedTheme_NoActionBar, - R.style.DialogTheme + R.style.DialogTheme, + true ); private int nameId; private int resId; private int noActionBarResId; private int dialogResId; + private boolean isDark; Theme(@StringRes int nameId, @StyleRes int resId, - @StyleRes int noActionBarResId, @StyleRes int dialogResId) { + @StyleRes int noActionBarResId, @StyleRes int dialogResId, boolean isDark) { this.nameId = nameId; this.resId = resId; this.noActionBarResId = noActionBarResId; this.dialogResId = dialogResId; + this.isDark = isDark; + } + + public boolean isDark() { + return isDark; } public @StringRes int getNameId() { diff --git a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java index afd75ce13..9e28832d9 100644 --- a/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java +++ b/app/src/main/java/fr/gaulupeau/apps/Poche/ui/preferences/SettingsActivity.java @@ -117,6 +117,8 @@ public static class SettingsFragment extends PreferenceFragmentCompat R.string.pref_key_connection_api_clientID, R.string.pref_key_connection_api_clientSecret, R.string.pref_key_ui_theme, + R.string.pref_key_ui_theme_auto_light, + R.string.pref_key_ui_theme_auto_dark, R.string.pref_key_ui_article_fontSize, R.string.pref_key_ui_screenScrolling_percent, R.string.pref_key_autoSync_interval, @@ -444,6 +446,12 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin themeChanged = true; break; + case R.string.pref_key_ui_theme_auto: + case R.string.pref_key_ui_theme_auto_light: + case R.string.pref_key_ui_theme_auto_dark: + themeChanged = true; + break; + case R.string.pref_key_autoSync_enabled: autoSyncChanged = true; break; @@ -760,6 +768,8 @@ private void updateSummary(int keyResID) { break; case R.string.pref_key_ui_theme: + case R.string.pref_key_ui_theme_auto_light: + case R.string.pref_key_ui_theme_auto_dark: case R.string.pref_key_autoSync_interval: case R.string.pref_key_autoSync_type: setListSummaryFromContent(key); diff --git a/app/src/main/res/values/strings-preference-keys.xml b/app/src/main/res/values/strings-preference-keys.xml index ef323c1e4..3aa900f41 100644 --- a/app/src/main/res/values/strings-preference-keys.xml +++ b/app/src/main/res/values/strings-preference-keys.xml @@ -28,6 +28,9 @@ ui.lists.sortOrder ui.tagList.sortOrder ui.theme + ui.theme.auto + ui.theme.auto.light + ui.theme.auto.dark ui.volumeButtonsScrolling.enabled ui.tapToScroll.enabled ui.screenScrolling diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 668194286..7519b106f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -201,6 +201,12 @@ UI App theme + Auto dark mode + Switch between light and dark theme based on system settings + Auto light theme + Theme to use when system is in light mode + Auto dark theme + Theme to use when system is in dark mode Article text size (%) Serif typeface Serif font for articles diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 0039e4f26..6f5600b74 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -80,6 +80,25 @@ android:title="@string/pref_name_ui_theme" android:dialogTitle="@string/pref_name_ui_theme" android:defaultValue="LIGHT"/> + + +