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..e2ac2c20d 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/AppearanceSettingsFragment.java @@ -18,40 +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 String captionSettingsKey; @Override public void onCreate(@Nullable final Bundle savedInstanceState) { super.onCreate(savedInstanceState); + final String themeKey = getString(R.string.theme_key); - startThemeKey = defaultPreferences + // 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)); - findPreference(themeKey).setOnPreferenceChangeListener(themePreferenceChange); + 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); } } @@ -72,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/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 5ac4de84c..0c890dddc 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java @@ -21,9 +21,10 @@ 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; import androidx.annotation.AttrRes; import androidx.annotation.Nullable; @@ -39,7 +40,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,31 +72,12 @@ 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 selectedThemeKey = getSelectedThemeKey(context); + final Resources res = context.getResources(); - - /** - * 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 selectedThemeKey.equals(res.getString(R.string.light_theme_key)) + || (selectedThemeKey.equals(res.getString(R.string.auto_device_theme_key)) + && !isDeviceDarkThemeEnabled(context)); } /** @@ -130,71 +113,60 @@ 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 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(darkTheme)) { - defaultTheme = R.style.DarkTheme; + 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)) { + // use the dark theme variant preferred by the user + final String selectedNightThemeKey = getSelectedNightThemeKey(context); + if (selectedNightThemeKey.equals(blackThemeKey)) { + baseTheme = R.style.BlackTheme; + } else { + baseTheme = R.style.DarkTheme; + } + } else { + // there is only one day theme + 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 (selectedTheme.equals(lightTheme)) { + String themeName = "DarkTheme"; // default + if (baseTheme == R.style.LightTheme) { themeName = "LightTheme"; - } else if (selectedTheme.equals(blackTheme)) { + } else if (baseTheme == R.style.BlackTheme) { themeName = "BlackTheme"; - } else if (selectedTheme.equals(darkTheme)) { - themeName = "DarkTheme"; } 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 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 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 { - // Fallback - return R.style.DarkSettingsTheme; - } + return baseTheme; } /** @@ -229,18 +201,27 @@ 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 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); + 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. + * * @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 +232,27 @@ 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
+ */
+ 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:
+ 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..2f2a9622c 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -23,6 +23,7 @@