1package eu.siacs.conversations;
2
3import android.annotation.SuppressLint;
4import android.app.Application;
5import android.content.Context;
6import android.content.SharedPreferences;
7import android.preference.PreferenceManager;
8
9import androidx.appcompat.app.AppCompatDelegate;
10
11import com.google.android.material.color.DynamicColors;
12import com.google.android.material.color.DynamicColorsOptions;
13
14import eu.siacs.conversations.utils.ExceptionHelper;
15import eu.siacs.conversations.utils.ThemeHelper;
16
17public class Conversations extends Application {
18
19 @SuppressLint("StaticFieldLeak")
20 private static Context CONTEXT;
21
22 public static Context getContext() {
23 return Conversations.CONTEXT;
24 }
25
26 @Override
27 public void onCreate() {
28 super.onCreate();
29 CONTEXT = this.getApplicationContext();
30 ExceptionHelper.init(getApplicationContext());
31 applyThemeSettings();
32 }
33
34 public void applyThemeSettings() {
35 final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
36 if (sharedPreferences == null) {
37 return;
38 }
39 applyThemeSettings(sharedPreferences);
40 }
41
42 private void applyThemeSettings(final SharedPreferences sharedPreferences) {
43 AppCompatDelegate.setDefaultNightMode(getDesiredNightMode(this, sharedPreferences));
44 var dynamicColorsOptions =
45 new DynamicColorsOptions.Builder()
46 .setPrecondition((activity, t) -> isDynamicColorsDesired(activity))
47 .build();
48 DynamicColors.applyToActivitiesIfAvailable(this, dynamicColorsOptions);
49 }
50
51 public static int getDesiredNightMode(final Context context) {
52 final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
53 if (sharedPreferences == null) {
54 return AppCompatDelegate.getDefaultNightMode();
55 }
56 return getDesiredNightMode(context, sharedPreferences);
57 }
58
59 public static boolean isDynamicColorsDesired(final Context context) {
60 final var preferences = PreferenceManager.getDefaultSharedPreferences(context);
61 if (isCustomColorsDesired(context)) return false;
62 return preferences.getBoolean(AppSettings.DYNAMIC_COLORS, false);
63 }
64
65 public static boolean isCustomColorsDesired(final Context context) {
66 final var sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
67 final String theme =
68 sharedPreferences.getString(AppSettings.THEME, context.getString(R.string.theme));
69 return "custom".equals(theme);
70 }
71
72 private static int getDesiredNightMode(
73 final Context context, final SharedPreferences sharedPreferences) {
74 var theme =
75 sharedPreferences.getString(AppSettings.THEME, context.getString(R.string.theme));
76
77 // Migrate old themes to equivalent custom
78 if ("oledblack".equals(theme)) {
79 theme = "custom";
80 final var p = PreferenceManager.getDefaultSharedPreferences(context);
81 p
82 .edit()
83 .putString(AppSettings.THEME, "custom")
84 .putBoolean("custom_theme_automatic", false)
85 .putBoolean("custom_theme_dark", true)
86 .putBoolean("custom_theme_color_match", true)
87 .putInt("custom_dark_theme_primary", context.getColor(R.color.white))
88 .putInt("custom_dark_theme_primary_dark", context.getColor(android.R.color.black))
89 .putInt("custom_dark_theme_accent", context.getColor(R.color.yeller))
90 .putInt("custom_dark_theme_background_primary", context.getColor(android.R.color.black))
91 .commit();
92 }
93
94 // Migrate old themes to equivalent custom
95 if ("obsidian".equals(theme)) {
96 theme = "custom";
97 final var p = PreferenceManager.getDefaultSharedPreferences(context);
98 p
99 .edit()
100 .putString(AppSettings.THEME, "custom")
101 .putBoolean("custom_theme_automatic", false)
102 .putBoolean("custom_theme_dark", true)
103 .putInt("custom_dark_theme_primary", context.getColor(R.color.black_perpy))
104 .putInt("custom_dark_theme_primary_dark", context.getColor(R.color.black_perpy))
105 .putInt("custom_dark_theme_accent", context.getColor(R.color.yeller))
106 .putInt("custom_dark_theme_background_primary", context.getColor(R.color.blacker_perpy))
107 .commit();
108 }
109
110 if ("custom".equals(theme)) {
111 if (sharedPreferences.getBoolean("custom_theme_automatic", false)) return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
112 return sharedPreferences.getBoolean("custom_theme_dark", false) ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO;
113 }
114
115 return getDesiredNightMode(theme);
116 }
117
118 public static int getDesiredNightMode(final String theme) {
119 if ("automatic".equals(theme)) {
120 return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
121 } else if ("light".equals(theme)) {
122 return AppCompatDelegate.MODE_NIGHT_NO;
123 } else {
124 return AppCompatDelegate.MODE_NIGHT_YES;
125 }
126 }
127}