Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -72,4 +75,23 @@ public boolean onPreferenceTreeClick(final Preference preference) {

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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static void initSettings(final Context context) {

@Override
protected void onCreate(final Bundle savedInstanceBundle) {
setTheme(ThemeHelper.getSettingsThemeStyle(this));
ThemeHelper.setTheme(this);
assureCorrectAppLanguage(this);
super.onCreate(savedInstanceBundle);

Expand Down
148 changes: 76 additions & 72 deletions app/src/main/java/org/schabi/newpipe/util/ThemeHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@

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;
Expand All @@ -39,7 +40,8 @@
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
Expand Down Expand Up @@ -70,31 +72,12 @@ public static void setTheme(final Context context, final int serviceId) {
* @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));
}


/**
* 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));
}
final String selectedThemeKey = getSelectedThemeKey(context);
final Resources res = context.getResources();

/**
* 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));
}

/**
Expand Down Expand Up @@ -130,71 +113,60 @@ public static int getMinWidthDialogTheme(final Context context) {
*/
@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 String selectedTheme = getSelectedThemeString(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;
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 selectedThemeKey = getSelectedThemeKey(context);

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;
}

/**
Expand Down Expand Up @@ -229,18 +201,27 @@ public static int resolveColorFromAttr(final Context context, @AttrRes final int
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) {
Expand All @@ -251,4 +232,27 @@ public static void setTitleToAppCompatActivity(@Nullable final Activity activity
}
}
}

/**
* Get the device theme
* <p>
* It will return true if the device 's theme is dark, false otherwise.
* <p>
* 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;
}
}
}
2 changes: 1 addition & 1 deletion app/src/main/res/values-eo/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<string name="theme_title">Etoso</string>
<string name="dark_theme_title">Malluma</string>
<string name="light_theme_title">Luma</string>
<string name="black_theme_title">Nigra</string>
<string name="download_dialog_title">Elŝuti</string>
<string name="unsupported_url">Ligilo ne subtenita</string>
<string name="content_language_title">Preferata enhavlingvo</string>
Expand Down Expand Up @@ -90,7 +91,6 @@
<string name="show_higher_resolutions_title">Montri pli altajn rezoluciojn</string>
<string name="show_higher_resolutions_summary">Nur kelkaj aparatoj povas ludi 2K / 4K filmetojn</string>
<string name="default_video_format_title">Defaŭlta fomato de filmeto</string>
<string name="black_theme_title">Nigra</string>
<string name="popup_remember_size_pos_title">Memoru ŝprucfenestran grandecon kaj pozicion</string>
<string name="popup_remember_size_pos_summary">Memoru lastan grandecon kaj pozicion de ŝprucfenestro</string>
<string name="use_inexact_seek_title">Uzi rapide, ne precizan serĉon</string>
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
<string name="use_tor_title">Utiliser Tor</string>
<string name="use_tor_summary">(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).</string>
<string name="theme_title">Thème</string>
<string name="night_theme_title">Thème nuit</string>
<string name="dark_theme_title">Sombre</string>
<string name="light_theme_title">Clair</string>
<string name="black_theme_title">Noir</string>
<string name="settings_category_appearance_title">Apparence</string>
<string name="network_error">Erreur réseau</string>
<string name="download_path_audio_title">Dossier de téléchargement audio</string>
Expand Down Expand Up @@ -103,7 +105,6 @@
<string name="no_available_dir">Veuillez définir ultérieurement un dossier de téléchargement dans les paramètres</string>
<string name="could_not_load_image">Impossible de charger l’image</string>
<string name="app_ui_crash">L’application a planté</string>
<string name="black_theme_title">Noir</string>
<string name="all">Tout</string>
<string name="channel">Chaîne</string>
<string name="title_activity_recaptcha">Défi reCAPTCHA</string>
Expand Down Expand Up @@ -669,4 +670,7 @@
<string name="paid_content">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.</string>
<string name="youtube_music_premium_content">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.</string>
<string name="private_content">Ce contenu est privé, il ne peut donc pas être diffusé en continu ni téléchargé par NewPipe.</string>
<string name="auto_device_theme_title">Automatique (thème de l\'appareil)</string>
<string name="night_theme_summary">Choisissez votre thème nuit favori — %s</string>
<string name="select_night_theme_toast">Vous pouvez chosir votre thème nuit favori</string>
</resources>
13 changes: 13 additions & 0 deletions app/src/main/res/values/settings_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,32 @@

<!-- THEMES -->
<string name="theme_key" translatable="false">theme</string>
<string name="night_theme_key" translatable="false">night_theme</string>
<string name="light_theme_key" translatable="false">light_theme</string>
<string name="dark_theme_key" translatable="false">dark_theme</string>
<string name="black_theme_key" translatable="false">black_theme</string>
<string name="auto_device_theme_key" translatable="false">auto_device_theme</string>
<string name="default_theme_value" translatable="false">@string/dark_theme_key</string>
<string name="default_night_theme_value" translatable="false">@string/dark_theme_key</string>
<string-array name="theme_values_list" translatable="false">
<item>@string/light_theme_key</item>
<item>@string/dark_theme_key</item>
<item>@string/black_theme_key</item>
<item>@string/auto_device_theme_key</item>
</string-array>
<string-array name="theme_description_list" translatable="false">
<item>@string/light_theme_title</item>
<item>@string/dark_theme_title</item>
<item>@string/black_theme_title</item>
<item>@string/auto_device_theme_title</item>
</string-array>
<string-array name="night_theme_values_list" translatable="false">
<item>@string/dark_theme_key</item>
<item>@string/black_theme_key</item>
</string-array>
<string-array name="night_theme_description_list" translatable="false">
<item>@string/dark_theme_title</item>
<item>@string/black_theme_title</item>
</string-array>

<!-- Caption Size -->
Expand Down
Loading