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) {