From a713ce21263c29347e633efa871576f31c0d4249 Mon Sep 17 00:00:00 2001 From: bopol Date: Fri, 22 May 2020 15:37:14 +0200 Subject: [PATCH 1/4] Add settings for device theme (dark & black) fix bugs related to isLightThemeSelected not handling device themes such as license having dark background when it should be white --- .../org/schabi/newpipe/util/ThemeHelper.java | 91 +++++++++++++++---- app/src/main/res/values-eo/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values/settings_keys.xml | 6 ++ app/src/main/res/values/strings.xml | 2 + 5 files changed, 89 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index 5ac4de84c..b8246f0b2 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -21,6 +21,8 @@ package org.schabi.newpipe.util; import android.app.Activity; import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; import android.content.res.TypedArray; import android.util.TypedValue; import android.view.ContextThemeWrapper; @@ -39,7 +41,8 @@ import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.exceptions.ExtractionException; public final class ThemeHelper { - private ThemeHelper() { } + private ThemeHelper() { + } /** * Apply the selected theme (on NewPipe settings) in the context @@ -70,8 +73,13 @@ public final class ThemeHelper { * @return whether the light theme is selected */ public static boolean isLightThemeSelected(final Context context) { - return getSelectedThemeString(context).equals(context.getResources() - .getString(R.string.light_theme_key)); + final String selectedThemeString = getSelectedThemeString(context); + final Resources res = context.getResources(); + + return selectedThemeString.equals(res.getString(R.string.light_theme_key)) + || (selectedThemeString.equals(res.getString(R.string.device_dark_theme_key)) + || selectedThemeString.equals(res.getString(R.string.device_black_theme_key)) + && !isDeviceDarkThemeEnabled(context)); } @@ -130,9 +138,12 @@ public final class ThemeHelper { */ @StyleRes public static int getThemeForService(final Context context, final int serviceId) { - final String lightTheme = context.getResources().getString(R.string.light_theme_key); - final String darkTheme = context.getResources().getString(R.string.dark_theme_key); - final String blackTheme = context.getResources().getString(R.string.black_theme_key); + final Resources res = context.getResources(); + final String lightTheme = res.getString(R.string.light_theme_key); + final String darkTheme = res.getString(R.string.dark_theme_key); + final String blackTheme = res.getString(R.string.black_theme_key); + final String deviceDarkTheme = res.getString(R.string.device_dark_theme_key); + final String deviceBlackTheme = res.getString(R.string.device_black_theme_key); final String selectedTheme = getSelectedThemeString(context); @@ -141,8 +152,18 @@ public final class ThemeHelper { defaultTheme = R.style.LightTheme; } else if (selectedTheme.equals(blackTheme)) { defaultTheme = R.style.BlackTheme; - } else if (selectedTheme.equals(darkTheme)) { - defaultTheme = R.style.DarkTheme; + } else if (selectedTheme.equals(deviceDarkTheme)) { + if (isDeviceDarkThemeEnabled(context)) { + defaultTheme = R.style.DarkTheme; + } else { + defaultTheme = R.style.LightTheme; + } + } else if (selectedTheme.equals(deviceBlackTheme)) { + if (isDeviceDarkThemeEnabled(context)) { + defaultTheme = R.style.BlackTheme; + } else { + defaultTheme = R.style.LightTheme; + } } if (serviceId <= -1) { @@ -157,12 +178,10 @@ public final class ThemeHelper { } String themeName = "DarkTheme"; - if (selectedTheme.equals(lightTheme)) { + if (defaultTheme == R.style.LightTheme) { themeName = "LightTheme"; - } else if (selectedTheme.equals(blackTheme)) { + } else if (defaultTheme == R.style.BlackTheme) { themeName = "BlackTheme"; - } else if (selectedTheme.equals(darkTheme)) { - themeName = "DarkTheme"; } themeName += "." + service.getServiceInfo().getName(); @@ -179,9 +198,12 @@ public final class ThemeHelper { @StyleRes public static int getSettingsThemeStyle(final Context context) { - final String lightTheme = context.getResources().getString(R.string.light_theme_key); - final String darkTheme = context.getResources().getString(R.string.dark_theme_key); - final String blackTheme = context.getResources().getString(R.string.black_theme_key); + final Resources res = context.getResources(); + final String lightTheme = res.getString(R.string.light_theme_key); + final String darkTheme = res.getString(R.string.dark_theme_key); + final String blackTheme = res.getString(R.string.black_theme_key); + final String deviceDarkTheme = res.getString(R.string.device_dark_theme_key); + final String deviceBlackTheme = res.getString(R.string.device_black_theme_key); final String selectedTheme = getSelectedThemeString(context); @@ -191,6 +213,18 @@ public final class ThemeHelper { return R.style.BlackSettingsTheme; } else if (selectedTheme.equals(darkTheme)) { return R.style.DarkSettingsTheme; + } else if (selectedTheme.equals(deviceDarkTheme)) { + if (isDeviceDarkThemeEnabled(context)) { + return R.style.DarkSettingsTheme; + } else { + return R.style.LightSettingsTheme; + } + } else if (selectedTheme.equals(deviceBlackTheme)) { + if (isDeviceDarkThemeEnabled(context)) { + return R.style.BlackSettingsTheme; + } else { + return R.style.LightSettingsTheme; + } } else { // Fallback return R.style.DarkSettingsTheme; @@ -239,8 +273,9 @@ public final class ThemeHelper { /** * Sets the title to the activity, if the activity is an {@link AppCompatActivity} and has an * action bar. + * * @param activity the activity to set the title of - * @param title the title to set to the activity + * @param title the title to set to the activity */ public static void setTitleToAppCompatActivity(@Nullable final Activity activity, final CharSequence title) { @@ -251,4 +286,28 @@ public final class ThemeHelper { } } } + + /** + * Get the device theme + *

+ * It will return true if the device 's theme is dark, false otherwise. + *

+ * From https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#java + * + * @param context the context to use + * @return true:dark theme, false:light or unknown + */ + private static boolean isDeviceDarkThemeEnabled(final Context context) { + int deviceTheme = context.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK; + switch (deviceTheme) { + case Configuration.UI_MODE_NIGHT_YES: + return true; + + case Configuration.UI_MODE_NIGHT_UNDEFINED: + case Configuration.UI_MODE_NIGHT_NO: + default: + return false; + } + } } diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 38e83b662..cb190ea91 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -23,6 +23,9 @@ Etoso Malluma Luma + Nigra + Etoson (Malluma) + Etoson de la aparato (Nigra) Elŝuti Ligilo ne subtenita Preferata enhavlingvo @@ -90,7 +93,6 @@ Montri pli altajn rezoluciojn Nur kelkaj aparatoj povas ludi 2K / 4K filmetojn Defaŭlta fomato de filmeto - Nigra Memoru ŝprucfenestran grandecon kaj pozicion Memoru lastan grandecon kaj pozicion de ŝprucfenestro Uzi rapide, ne precizan serĉon diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 86f4fe09c..a538c2721 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -43,6 +43,9 @@ Thème Sombre Clair + Noir + Thème de l\'appareil (Sombre) + Thème de l\'appareil (Noir) Apparence Erreur réseau Dossier de téléchargement audio @@ -103,7 +106,6 @@ Veuillez définir ultérieurement un dossier de téléchargement dans les paramètres Impossible de charger l’image L’application a planté - Noir Tout Chaîne Défi reCAPTCHA diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 0958fce26..195e43e61 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -179,16 +179,22 @@ light_theme dark_theme black_theme + device_dark_theme + device_black_theme @string/dark_theme_key @string/light_theme_key @string/dark_theme_key @string/black_theme_key + @string/device_dark_theme_key + @string/device_black_theme_key @string/light_theme_title @string/dark_theme_title @string/black_theme_title + @string/device_dark_theme_title + @string/device_black_theme_title diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9fb15e463..4bb21c0cf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,6 +82,8 @@ Light Dark Black + Device theme (Dark) + Device theme (Black) Remember popup properties Remember last size and position of popup Use fast inexact seek From 22b2f52f8c83df746153f197cf6fef40a75e3976 Mon Sep 17 00:00:00 2001 From: bopol Date: Fri, 3 Jul 2020 18:44:34 +0200 Subject: [PATCH 2/4] Use a switch preference to follow device theme --- .../settings/AppearanceSettingsFragment.java | 18 ++++++ .../org/schabi/newpipe/util/ThemeHelper.java | 59 ++++++++----------- app/src/main/res/values-eo/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values/settings_keys.xml | 7 +-- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/appearance_settings.xml | 7 +++ 7 files changed, 55 insertions(+), 46 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 8126bd2c5..6d1cd3687 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -1,5 +1,6 @@ package org.schabi.newpipe.settings; +import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Build; @@ -38,6 +39,20 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { return false; } }; + private final Preference.OnPreferenceChangeListener deviceThemePreferenceChange + = new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(final Preference preference, final Object newValue) { + defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); + + final Activity activity = getActivity(); + if (activity != null) { + activity.recreate(); + } + + return true; + } + }; private String captionSettingsKey; @Override @@ -48,6 +63,9 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { .getString(themeKey, getString(R.string.default_theme_value)); findPreference(themeKey).setOnPreferenceChangeListener(themePreferenceChange); + findPreference(getString(R.string.use_device_theme_key)) + .setOnPreferenceChangeListener(deviceThemePreferenceChange); + captionSettingsKey = getString(R.string.caption_settings_key); if (!CAPTIONING_SETTINGS_ACCESSIBLE) { final Preference captionSettings = findPreference(captionSettingsKey); diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index b8246f0b2..8129b3295 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -77,9 +77,7 @@ public final class ThemeHelper { final Resources res = context.getResources(); return selectedThemeString.equals(res.getString(R.string.light_theme_key)) - || (selectedThemeString.equals(res.getString(R.string.device_dark_theme_key)) - || selectedThemeString.equals(res.getString(R.string.device_black_theme_key)) - && !isDeviceDarkThemeEnabled(context)); + || (shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context)); } @@ -142,8 +140,6 @@ public final class ThemeHelper { final String lightTheme = res.getString(R.string.light_theme_key); final String darkTheme = res.getString(R.string.dark_theme_key); final String blackTheme = res.getString(R.string.black_theme_key); - final String deviceDarkTheme = res.getString(R.string.device_dark_theme_key); - final String deviceBlackTheme = res.getString(R.string.device_black_theme_key); final String selectedTheme = getSelectedThemeString(context); @@ -151,19 +147,11 @@ public final class ThemeHelper { if (selectedTheme.equals(lightTheme)) { defaultTheme = R.style.LightTheme; } else if (selectedTheme.equals(blackTheme)) { - defaultTheme = R.style.BlackTheme; - } else if (selectedTheme.equals(deviceDarkTheme)) { - if (isDeviceDarkThemeEnabled(context)) { - defaultTheme = R.style.DarkTheme; - } else { - defaultTheme = R.style.LightTheme; - } - } else if (selectedTheme.equals(deviceBlackTheme)) { - if (isDeviceDarkThemeEnabled(context)) { - defaultTheme = R.style.BlackTheme; - } else { - defaultTheme = R.style.LightTheme; - } + defaultTheme = shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) + ? R.style.LightTheme : R.style.BlackTheme; + } else if (selectedTheme.equals(darkTheme)) { + defaultTheme = shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) + ? R.style.LightTheme : R.style.DarkTheme; } if (serviceId <= -1) { @@ -202,29 +190,17 @@ public final class ThemeHelper { final String lightTheme = res.getString(R.string.light_theme_key); final String darkTheme = res.getString(R.string.dark_theme_key); final String blackTheme = res.getString(R.string.black_theme_key); - final String deviceDarkTheme = res.getString(R.string.device_dark_theme_key); - final String deviceBlackTheme = res.getString(R.string.device_black_theme_key); final String selectedTheme = getSelectedThemeString(context); if (selectedTheme.equals(lightTheme)) { return R.style.LightSettingsTheme; } else if (selectedTheme.equals(blackTheme)) { - return R.style.BlackSettingsTheme; + return shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) + ? R.style.LightSettingsTheme : R.style.BlackSettingsTheme; } else if (selectedTheme.equals(darkTheme)) { - return R.style.DarkSettingsTheme; - } else if (selectedTheme.equals(deviceDarkTheme)) { - if (isDeviceDarkThemeEnabled(context)) { - return R.style.DarkSettingsTheme; - } else { - return R.style.LightSettingsTheme; - } - } else if (selectedTheme.equals(deviceBlackTheme)) { - if (isDeviceDarkThemeEnabled(context)) { - return R.style.BlackSettingsTheme; - } else { - return R.style.LightSettingsTheme; - } + return shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) + ? R.style.LightSettingsTheme : R.style.DarkSettingsTheme; } else { // Fallback return R.style.DarkSettingsTheme; @@ -297,8 +273,8 @@ public final class ThemeHelper { * @param context the context to use * @return true:dark theme, false:light or unknown */ - private static boolean isDeviceDarkThemeEnabled(final Context context) { - int deviceTheme = context.getResources().getConfiguration().uiMode + public static boolean isDeviceDarkThemeEnabled(final Context context) { + final int deviceTheme = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; switch (deviceTheme) { case Configuration.UI_MODE_NIGHT_YES: @@ -310,4 +286,15 @@ public final class ThemeHelper { return false; } } + + /** + * Tells if the user wants the theme to follow the device theme. + * + * @param context the context to use + * @return whether the user wants the theme to follow the device's theme + */ + public static boolean shouldFollowDeviceTheme(final Context context) { + return PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(context.getString(R.string.use_device_theme_key), false); + } } diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index cb190ea91..4245700cd 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -24,8 +24,6 @@ Malluma Luma Nigra - Etoson (Malluma) - Etoson de la aparato (Nigra) Elŝuti Ligilo ne subtenita Preferata enhavlingvo @@ -581,4 +579,6 @@ Artistoj Albumoj Kantoj + Sekvi la etoson de la aparato + La apo sekvos la etoson de la aparato. Ĝi povus malfunkcii se via Android versiono malsupras Android 10. \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a538c2721..8525538ab 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -44,8 +44,6 @@ Sombre Clair Noir - Thème de l\'appareil (Sombre) - Thème de l\'appareil (Noir) Apparence Erreur réseau Dossier de téléchargement audio @@ -671,4 +669,6 @@ Ce contenu n\'est disponible que pour les abonnés, il ne peut donc pas être diffusé en continu ni téléchargé par NewPipe. Cette vidéo n\'est disponible que pour les membres de YouTube Music Premium, elle ne peut donc pas être diffusée en continu ni téléchargée par NewPipe. Ce contenu est privé, il ne peut donc pas être diffusé en continu ni téléchargé par NewPipe. + Suivre le thème de l\'appareil + L\'application suivera le thème de votre appareil. Il se peut que ça ne marche pas si vous utiliser une version d\'Android inférieure à 10. \ No newline at end of file diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 195e43e61..42cf4cd60 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -179,23 +179,18 @@ light_theme dark_theme black_theme - device_dark_theme - device_black_theme @string/dark_theme_key @string/light_theme_key @string/dark_theme_key @string/black_theme_key - @string/device_dark_theme_key - @string/device_black_theme_key @string/light_theme_title @string/dark_theme_title @string/black_theme_title - @string/device_dark_theme_title - @string/device_black_theme_title + use_device_theme_key caption_settings_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4bb21c0cf..4e45b57f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -711,4 +711,6 @@ This content is only available to users who have paid, so it cannot be streamed or downloaded by NewPipe. Featured Radio + Follow device theme + The app theme will follow your device theme. It may not work for devices below Android 10. diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index 7f30d2091..c3363b865 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -12,6 +12,13 @@ android:title="@string/theme_title" app:iconSpaceReserved="false" /> + + Date: Sun, 11 Oct 2020 13:16:22 +0200 Subject: [PATCH 3/4] Use a list for night themes Also remove unused strings --- .../settings/AppearanceSettingsFragment.java | 90 ++++++++++--------- .../org/schabi/newpipe/util/ThemeHelper.java | 62 ++++++++----- app/src/main/res/values-eo/strings.xml | 2 - app/src/main/res/values-fr/strings.xml | 6 +- app/src/main/res/values/settings_keys.xml | 14 ++- app/src/main/res/values/strings.xml | 8 +- app/src/main/res/xml/appearance_settings.xml | 12 +-- 7 files changed, 116 insertions(+), 78 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java index 6d1cd3687..e2ac2c20d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -1,6 +1,5 @@ package org.schabi.newpipe.settings; -import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Build; @@ -19,57 +18,43 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { private static final boolean CAPTIONING_SETTINGS_ACCESSIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - /** - * Theme that was applied when the settings was opened (or recreated after a theme change). - */ - private String startThemeKey; - private final Preference.OnPreferenceChangeListener themePreferenceChange - = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(final Preference preference, final Object newValue) { - defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); - defaultPreferences.edit() - .putString(getString(R.string.theme_key), newValue.toString()).apply(); - - if (!newValue.equals(startThemeKey) && getActivity() != null) { - // If it's not the current theme - ActivityCompat.recreate(requireActivity()); - } - - return false; - } - }; - private final Preference.OnPreferenceChangeListener deviceThemePreferenceChange - = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(final Preference preference, final Object newValue) { - defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); - - final Activity activity = getActivity(); - if (activity != null) { - activity.recreate(); - } - - return true; - } - }; private String captionSettingsKey; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); - final String themeKey = getString(R.string.theme_key); - startThemeKey = defaultPreferences - .getString(themeKey, getString(R.string.default_theme_value)); - findPreference(themeKey).setOnPreferenceChangeListener(themePreferenceChange); - findPreference(getString(R.string.use_device_theme_key)) - .setOnPreferenceChangeListener(deviceThemePreferenceChange); + final String themeKey = getString(R.string.theme_key); + // the key of the active theme when settings were opened (or recreated after theme change) + final String startThemeKey = defaultPreferences + .getString(themeKey, getString(R.string.default_theme_value)); + final String autoDeviceThemeKey = getString(R.string.auto_device_theme_key); + findPreference(themeKey).setOnPreferenceChangeListener((preference, newValue) -> { + if (newValue.toString().equals(autoDeviceThemeKey)) { + Toast.makeText(getContext(), getString(R.string.select_night_theme_toast), + Toast.LENGTH_LONG).show(); + } + + applyThemeChange(startThemeKey, themeKey, newValue); + return false; + }); + + final String nightThemeKey = getString(R.string.night_theme_key); + if (startThemeKey.equals(autoDeviceThemeKey)) { + final String startNightThemeKey = defaultPreferences + .getString(nightThemeKey, getString(R.string.default_night_theme_value)); + + findPreference(nightThemeKey).setOnPreferenceChangeListener((preference, newValue) -> { + applyThemeChange(startNightThemeKey, nightThemeKey, newValue); + return false; + }); + } else { + removePreference(nightThemeKey); + } captionSettingsKey = getString(R.string.caption_settings_key); if (!CAPTIONING_SETTINGS_ACCESSIBLE) { - final Preference captionSettings = findPreference(captionSettingsKey); - getPreferenceScreen().removePreference(captionSettings); + removePreference(captionSettingsKey); } } @@ -90,4 +75,23 @@ public class AppearanceSettingsFragment extends BasePreferenceFragment { return super.onPreferenceTreeClick(preference); } + + private void removePreference(final String preferenceKey) { + final Preference preference = findPreference(preferenceKey); + if (preference != null) { + getPreferenceScreen().removePreference(preference); + } + } + + private void applyThemeChange(final String beginningThemeKey, + final String themeKey, + final Object newValue) { + defaultPreferences.edit().putBoolean(Constants.KEY_THEME_CHANGE, true).apply(); + defaultPreferences.edit().putString(themeKey, newValue.toString()).apply(); + + if (!newValue.equals(beginningThemeKey) && getActivity() != null) { + // if it's not the current theme + ActivityCompat.recreate(getActivity()); + } + } } diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index 8129b3295..aaa196c60 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -77,7 +77,8 @@ public final class ThemeHelper { final Resources res = context.getResources(); return selectedThemeString.equals(res.getString(R.string.light_theme_key)) - || (shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context)); + || (selectedThemeString.equals(res.getString(R.string.auto_device_theme_key)) + && !isDeviceDarkThemeEnabled(context)); } @@ -140,6 +141,7 @@ public final class ThemeHelper { final String lightTheme = res.getString(R.string.light_theme_key); final String darkTheme = res.getString(R.string.dark_theme_key); final String blackTheme = res.getString(R.string.black_theme_key); + final String automaticDeviceTheme = res.getString(R.string.auto_device_theme_key); final String selectedTheme = getSelectedThemeString(context); @@ -147,11 +149,20 @@ public final class ThemeHelper { if (selectedTheme.equals(lightTheme)) { defaultTheme = R.style.LightTheme; } else if (selectedTheme.equals(blackTheme)) { - defaultTheme = shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) - ? R.style.LightTheme : R.style.BlackTheme; - } else if (selectedTheme.equals(darkTheme)) { - defaultTheme = shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) - ? R.style.LightTheme : R.style.DarkTheme; + defaultTheme = R.style.BlackTheme; + } else if (selectedTheme.equals(automaticDeviceTheme)) { + + if (isDeviceDarkThemeEnabled(context)) { + final String selectedNightTheme = getSelectedNightThemeString(context); + if (selectedNightTheme.equals(blackTheme)) { + defaultTheme = R.style.BlackTheme; + } else { + defaultTheme = R.style.DarkTheme; + } + } else { + // there is only one day theme + defaultTheme = R.style.LightTheme; + } } if (serviceId <= -1) { @@ -190,17 +201,29 @@ public final class ThemeHelper { final String lightTheme = res.getString(R.string.light_theme_key); final String darkTheme = res.getString(R.string.dark_theme_key); final String blackTheme = res.getString(R.string.black_theme_key); + final String automaticDeviceTheme = res.getString(R.string.auto_device_theme_key); + final String selectedTheme = getSelectedThemeString(context); if (selectedTheme.equals(lightTheme)) { return R.style.LightSettingsTheme; } else if (selectedTheme.equals(blackTheme)) { - return shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) - ? R.style.LightSettingsTheme : R.style.BlackSettingsTheme; + return R.style.BlackSettingsTheme; } else if (selectedTheme.equals(darkTheme)) { - return shouldFollowDeviceTheme(context) && !isDeviceDarkThemeEnabled(context) - ? R.style.LightSettingsTheme : R.style.DarkSettingsTheme; + return R.style.DarkSettingsTheme; + } else if (selectedTheme.equals(automaticDeviceTheme)) { + if (isDeviceDarkThemeEnabled(context)) { + final String selectedNightTheme = getSelectedNightThemeString(context); + if (selectedNightTheme.equals(blackTheme)) { + return R.style.BlackSettingsTheme; + } else { + return R.style.DarkSettingsTheme; + } + } else { + // there is only one day theme + return R.style.LightSettingsTheme; + } } else { // Fallback return R.style.DarkSettingsTheme; @@ -246,6 +269,14 @@ public final class ThemeHelper { .getString(themeKey, defaultTheme); } + private static String getSelectedNightThemeString(final Context context) { + final String nightThemeKey = context.getString(R.string.night_theme_key); + final String defaultNightTheme = context.getResources() + .getString(R.string.default_night_theme_value); + return PreferenceManager.getDefaultSharedPreferences(context) + .getString(nightThemeKey, defaultNightTheme); + } + /** * Sets the title to the activity, if the activity is an {@link AppCompatActivity} and has an * action bar. @@ -286,15 +317,4 @@ public final class ThemeHelper { return false; } } - - /** - * Tells if the user wants the theme to follow the device theme. - * - * @param context the context to use - * @return whether the user wants the theme to follow the device's theme - */ - public static boolean shouldFollowDeviceTheme(final Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getBoolean(context.getString(R.string.use_device_theme_key), false); - } } diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 4245700cd..2f2a9622c 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -579,6 +579,4 @@ Artistoj Albumoj Kantoj - Sekvi la etoson de la aparato - La apo sekvos la etoson de la aparato. Ĝi povus malfunkcii se via Android versiono malsupras Android 10. \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 8525538ab..6020f8cb1 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -41,6 +41,7 @@ Utiliser Tor (Expérimental) Forcer la redirection du trafic de téléchargement via Tor pour plus de confidentialité (les flux vidéos ne sont pas encore pris en charge). Thème + Thème nuit Sombre Clair Noir @@ -669,6 +670,7 @@ Ce contenu n\'est disponible que pour les abonnés, il ne peut donc pas être diffusé en continu ni téléchargé par NewPipe. Cette vidéo n\'est disponible que pour les membres de YouTube Music Premium, elle ne peut donc pas être diffusée en continu ni téléchargée par NewPipe. Ce contenu est privé, il ne peut donc pas être diffusé en continu ni téléchargé par NewPipe. - Suivre le thème de l\'appareil - L\'application suivera le thème de votre appareil. Il se peut que ça ne marche pas si vous utiliser une version d\'Android inférieure à 10. + Automatique (thème de l\'appareil) + Choisissez votre thème nuit favori — %s + Vous pouvez chosir votre thème nuit favori \ No newline at end of file diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml index 42cf4cd60..9044c65aa 100644 --- a/app/src/main/res/values/settings_keys.xml +++ b/app/src/main/res/values/settings_keys.xml @@ -176,21 +176,33 @@ theme + night_theme light_theme dark_theme black_theme + auto_device_theme @string/dark_theme_key + @string/dark_theme_key @string/light_theme_key @string/dark_theme_key @string/black_theme_key + @string/auto_device_theme_key @string/light_theme_title @string/dark_theme_title @string/black_theme_title + @string/auto_device_theme_title + + + @string/dark_theme_key + @string/black_theme_key + + + @string/dark_theme_title + @string/black_theme_title - use_device_theme_key caption_settings_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4e45b57f2..99702dab0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -79,11 +79,10 @@ Default audio format Default video format Theme + Night Theme Light Dark Black - Device theme (Dark) - Device theme (Black) Remember popup properties Remember last size and position of popup Use fast inexact seek @@ -711,6 +710,7 @@ This content is only available to users who have paid, so it cannot be streamed or downloaded by NewPipe. Featured Radio - Follow device theme - The app theme will follow your device theme. It may not work for devices below Android 10. + Automatic (device theme) + Select your favorite night theme — %s + You can select your favorite night theme below diff --git a/app/src/main/res/xml/appearance_settings.xml b/app/src/main/res/xml/appearance_settings.xml index c3363b865..e5afef805 100644 --- a/app/src/main/res/xml/appearance_settings.xml +++ b/app/src/main/res/xml/appearance_settings.xml @@ -12,11 +12,13 @@ android:title="@string/theme_title" app:iconSpaceReserved="false" /> - Date: Thu, 18 Mar 2021 12:35:53 +0100 Subject: [PATCH 4/4] Refactor ThemeHelper --- .../newpipe/settings/SettingsActivity.java | 2 +- .../org/schabi/newpipe/util/ThemeHelper.java | 118 +++++------------- 2 files changed, 29 insertions(+), 91 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java index 4de166a55..c445928c4 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java +++ b/app/src/main/java/org/schabi/newpipe/settings/SettingsActivity.java @@ -48,7 +48,7 @@ public class SettingsActivity extends AppCompatActivity @Override protected void onCreate(final Bundle savedInstanceBundle) { - setTheme(ThemeHelper.getSettingsThemeStyle(this)); + ThemeHelper.setTheme(this); assureCorrectAppLanguage(this); super.onCreate(savedInstanceBundle); diff --git a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java index aaa196c60..0c890dddc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -25,7 +25,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; import android.util.TypedValue; -import android.view.ContextThemeWrapper; import androidx.annotation.AttrRes; import androidx.annotation.Nullable; @@ -73,37 +72,14 @@ public final class ThemeHelper { * @return whether the light theme is selected */ public static boolean isLightThemeSelected(final Context context) { - final String selectedThemeString = getSelectedThemeString(context); + final String selectedThemeKey = getSelectedThemeKey(context); final Resources res = context.getResources(); - return selectedThemeString.equals(res.getString(R.string.light_theme_key)) - || (selectedThemeString.equals(res.getString(R.string.auto_device_theme_key)) + return selectedThemeKey.equals(res.getString(R.string.light_theme_key)) + || (selectedThemeKey.equals(res.getString(R.string.auto_device_theme_key)) && !isDeviceDarkThemeEnabled(context)); } - - /** - * Create and return a wrapped context with the default selected theme set. - * - * @param baseContext the base context for the wrapper - * @return a wrapped-styled context - */ - public static Context getThemedContext(final Context baseContext) { - return new ContextThemeWrapper(baseContext, getThemeForService(baseContext, -1)); - } - - /** - * Return the selected theme without being styled to any service. - * See {@link #getThemeForService(Context, int)}. - * - * @param context context to get the selected theme - * @return the selected style (the default one) - */ - @StyleRes - public static int getDefaultTheme(final Context context) { - return getThemeForService(context, -1); - } - /** * Return a dialog theme styled according to the (default) selected theme. * @@ -138,96 +114,59 @@ public final class ThemeHelper { @StyleRes public static int getThemeForService(final Context context, final int serviceId) { final Resources res = context.getResources(); - final String lightTheme = res.getString(R.string.light_theme_key); - final String darkTheme = res.getString(R.string.dark_theme_key); - final String blackTheme = res.getString(R.string.black_theme_key); - final String automaticDeviceTheme = res.getString(R.string.auto_device_theme_key); + final String lightThemeKey = res.getString(R.string.light_theme_key); + final String blackThemeKey = res.getString(R.string.black_theme_key); + final String automaticDeviceThemeKey = res.getString(R.string.auto_device_theme_key); - final String selectedTheme = getSelectedThemeString(context); + final String selectedThemeKey = getSelectedThemeKey(context); - int defaultTheme = R.style.DarkTheme; - if (selectedTheme.equals(lightTheme)) { - defaultTheme = R.style.LightTheme; - } else if (selectedTheme.equals(blackTheme)) { - defaultTheme = R.style.BlackTheme; - } else if (selectedTheme.equals(automaticDeviceTheme)) { + int baseTheme = R.style.DarkTheme; // default to dark theme + if (selectedThemeKey.equals(lightThemeKey)) { + baseTheme = R.style.LightTheme; + } else if (selectedThemeKey.equals(blackThemeKey)) { + baseTheme = R.style.BlackTheme; + } else if (selectedThemeKey.equals(automaticDeviceThemeKey)) { if (isDeviceDarkThemeEnabled(context)) { - final String selectedNightTheme = getSelectedNightThemeString(context); - if (selectedNightTheme.equals(blackTheme)) { - defaultTheme = R.style.BlackTheme; + // use the dark theme variant preferred by the user + final String selectedNightThemeKey = getSelectedNightThemeKey(context); + if (selectedNightThemeKey.equals(blackThemeKey)) { + baseTheme = R.style.BlackTheme; } else { - defaultTheme = R.style.DarkTheme; + baseTheme = R.style.DarkTheme; } } else { // there is only one day theme - defaultTheme = R.style.LightTheme; + baseTheme = R.style.LightTheme; } } if (serviceId <= -1) { - return defaultTheme; + return baseTheme; } final StreamingService service; try { service = NewPipe.getService(serviceId); } catch (final ExtractionException ignored) { - return defaultTheme; + return baseTheme; } - String themeName = "DarkTheme"; - if (defaultTheme == R.style.LightTheme) { + String themeName = "DarkTheme"; // default + if (baseTheme == R.style.LightTheme) { themeName = "LightTheme"; - } else if (defaultTheme == R.style.BlackTheme) { + } else if (baseTheme == R.style.BlackTheme) { themeName = "BlackTheme"; } themeName += "." + service.getServiceInfo().getName(); - final int resourceId = context - .getResources() + final int resourceId = context.getResources() .getIdentifier(themeName, "style", context.getPackageName()); if (resourceId > 0) { return resourceId; } - - return defaultTheme; - } - - @StyleRes - public static int getSettingsThemeStyle(final Context context) { - final Resources res = context.getResources(); - final String lightTheme = res.getString(R.string.light_theme_key); - final String darkTheme = res.getString(R.string.dark_theme_key); - final String blackTheme = res.getString(R.string.black_theme_key); - final String automaticDeviceTheme = res.getString(R.string.auto_device_theme_key); - - - final String selectedTheme = getSelectedThemeString(context); - - if (selectedTheme.equals(lightTheme)) { - return R.style.LightSettingsTheme; - } else if (selectedTheme.equals(blackTheme)) { - return R.style.BlackSettingsTheme; - } else if (selectedTheme.equals(darkTheme)) { - return R.style.DarkSettingsTheme; - } else if (selectedTheme.equals(automaticDeviceTheme)) { - if (isDeviceDarkThemeEnabled(context)) { - final String selectedNightTheme = getSelectedNightThemeString(context); - if (selectedNightTheme.equals(blackTheme)) { - return R.style.BlackSettingsTheme; - } else { - return R.style.DarkSettingsTheme; - } - } else { - // there is only one day theme - return R.style.LightSettingsTheme; - } - } else { - // Fallback - return R.style.DarkSettingsTheme; - } + return baseTheme; } /** @@ -262,14 +201,14 @@ public final class ThemeHelper { return value.data; } - private static String getSelectedThemeString(final Context context) { + private static String getSelectedThemeKey(final Context context) { final String themeKey = context.getString(R.string.theme_key); final String defaultTheme = context.getResources().getString(R.string.default_theme_value); return PreferenceManager.getDefaultSharedPreferences(context) .getString(themeKey, defaultTheme); } - private static String getSelectedNightThemeString(final Context context) { + private static String getSelectedNightThemeKey(final Context context) { final String nightThemeKey = context.getString(R.string.night_theme_key); final String defaultNightTheme = context.getResources() .getString(R.string.default_night_theme_value); @@ -310,7 +249,6 @@ public final class ThemeHelper { switch (deviceTheme) { case Configuration.UI_MODE_NIGHT_YES: return true; - case Configuration.UI_MODE_NIGHT_UNDEFINED: case Configuration.UI_MODE_NIGHT_NO: default: