diff --git a/res/values-v29/arrays.xml b/res/values-v29/arrays.xml new file mode 100644 index 000000000..fbade03c3 --- /dev/null +++ b/res/values-v29/arrays.xml @@ -0,0 +1,16 @@ + + + + + @string/pref_system_default + @string/pref_light_theme + @string/pref_dark_theme + + + + system + light + dark + + + diff --git a/res/values/arrays.xml b/res/values/arrays.xml index a6b1587f8..87171cdfe 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1,5 +1,5 @@ - + @@ -84,12 +84,12 @@ te - + @string/pref_light_theme @string/pref_dark_theme - + light dark diff --git a/res/values/strings.xml b/res/values/strings.xml index 034d898b0..ff32898b6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -457,6 +457,7 @@ Silent Privacy Chats and media + System default Light Dark diff --git a/res/xml-v29/preferences_appearance.xml b/res/xml-v29/preferences_appearance.xml new file mode 100644 index 000000000..30838b118 --- /dev/null +++ b/res/xml-v29/preferences_appearance.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + diff --git a/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java b/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java index bc7132e27..81047531b 100644 --- a/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java +++ b/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java @@ -1,16 +1,15 @@ package org.thoughtcrime.securesms.util; -import android.app.Activity; +import androidx.annotation.StyleRes; import org.thoughtcrime.securesms.R; public class DynamicNoActionBarTheme extends DynamicTheme { - @Override - protected int getSelectedTheme(Activity activity) { - String theme = Prefs.getTheme(activity); - - if (theme.equals("dark")) return R.style.TextSecure_DarkNoActionBar; - + protected @StyleRes int getLightThemeStyle() { return R.style.TextSecure_LightNoActionBar; } + + protected @StyleRes int getDarkThemeStyle() { + return R.style.TextSecure_DarkNoActionBar; + } } diff --git a/src/org/thoughtcrime/securesms/util/DynamicTheme.java b/src/org/thoughtcrime/securesms/util/DynamicTheme.java index 0ff7c780e..12836761d 100644 --- a/src/org/thoughtcrime/securesms/util/DynamicTheme.java +++ b/src/org/thoughtcrime/securesms/util/DynamicTheme.java @@ -3,19 +3,37 @@ package org.thoughtcrime.securesms.util; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.annotation.StyleRes; import org.thoughtcrime.securesms.R; public class DynamicTheme { - public static final String DARK = "dark"; - public static final String LIGHT = "light"; + public static final String DARK = "dark"; + public static final String LIGHT = "light"; + public static final String SYSTEM = "system"; + + //private static boolean isDarkTheme; private int currentTheme; public void onCreate(Activity activity) { + //boolean wasDarkTheme = isDarkTheme; + currentTheme = getSelectedTheme(activity); + //isDarkTheme = isDarkTheme(activity); + activity.setTheme(currentTheme); + + // In case you introduce a CachedInflater and there are problems with the dark mode, uncomment + // this line and the line in onResume(): + //if (isDarkTheme != wasDarkTheme) { + //CachedInflater.from(activity).clear(); + //} } public void onResume(Activity activity) { @@ -25,19 +43,45 @@ public class DynamicTheme { OverridePendingTransition.invoke(activity); activity.startActivity(intent); OverridePendingTransition.invoke(activity); + //CachedInflater.from(activity).clear(); } } - protected int getSelectedTheme(Activity activity) { - String theme = Prefs.getTheme(activity); - - if (theme.equals(DARK)) return R.style.TextSecure_DarkTheme; + private @StyleRes int getSelectedTheme(Activity activity) { + if (isDarkTheme(activity)) { + return getDarkThemeStyle(); + } else { + return getLightThemeStyle(); + } + } + protected @StyleRes int getLightThemeStyle() { return R.style.TextSecure_LightTheme; } - public static boolean isDarkTheme(Context context) { - return Prefs.getTheme(context).equals(DARK); + protected @StyleRes int getDarkThemeStyle() { + return R.style.TextSecure_DarkTheme; + } + + static boolean systemThemeAvailable() { + return Build.VERSION.SDK_INT >= 29; + } + + /** + * Takes the system theme into account. + */ + public static boolean isDarkTheme(@NonNull Context context) { + String theme = Prefs.getTheme(context); + + if (theme.equals(SYSTEM) && systemThemeAvailable()) { + return isSystemInDarkTheme(context); + } else { + return theme.equals(DARK); + } + } + + private static boolean isSystemInDarkTheme(@NonNull Context context) { + return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; } private static final class OverridePendingTransition { diff --git a/src/org/thoughtcrime/securesms/util/Prefs.java b/src/org/thoughtcrime/securesms/util/Prefs.java index b679976f0..00a7dadfd 100644 --- a/src/org/thoughtcrime/securesms/util/Prefs.java +++ b/src/org/thoughtcrime/securesms/util/Prefs.java @@ -138,7 +138,7 @@ public class Prefs { } public static String getTheme(Context context) { - return getStringPreference(context, THEME_PREF, "light"); + return getStringPreference(context, THEME_PREF, DynamicTheme.systemThemeAvailable() ? DynamicTheme.SYSTEM : DynamicTheme.LIGHT); } public static boolean isScreenLockTimeoutEnabled(Context context) {