From 603c058ec9df375127ab68c764fc5dd19cba2e2b Mon Sep 17 00:00:00 2001 From: Grishka Date: Thu, 31 Oct 2024 10:05:25 +0300 Subject: [PATCH] Allow disabling dynamic colors on Android 12+ (AND-143) --- .../android/GlobalUserPreferences.java | 3 + .../settings/SettingsDisplayFragment.java | 27 ++- .../android/ui/utils/UiUtils.java | 50 +++-- .../src/main/res/drawable/ic_palette_24px.xml | 9 + mastodon/src/main/res/values-night/styles.xml | 3 + mastodon/src/main/res/values/colors.xml | 96 ++++----- mastodon/src/main/res/values/strings.xml | 1 + mastodon/src/main/res/values/styles.xml | 189 ++++++++++++++++++ 8 files changed, 307 insertions(+), 71 deletions(-) create mode 100644 mastodon/src/main/res/drawable/ic_palette_24px.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 7f204b6e..876f5bbe 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -11,6 +11,7 @@ public class GlobalUserPreferences{ public static boolean useCustomTabs; public static boolean altTextReminders, confirmUnfollow, confirmBoost, confirmDeletePost; public static ThemePreference theme=ThemePreference.AUTO; + public static boolean useDynamicColors; private static SharedPreferences getPrefs(){ return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE); @@ -29,6 +30,7 @@ public class GlobalUserPreferences{ confirmBoost=prefs.getBoolean("confirmBoost", false); confirmDeletePost=prefs.getBoolean("confirmDeletePost", true); theme=ThemePreference.values()[prefs.getInt("theme", 0)]; + useDynamicColors=prefs.getBoolean("useDynamicColors", true); } public static void save(){ @@ -40,6 +42,7 @@ public class GlobalUserPreferences{ .putBoolean("confirmUnfollow", confirmUnfollow) .putBoolean("confirmBoost", confirmBoost) .putBoolean("confirmDeletePost", confirmDeletePost) + .putBoolean("useDynamicColors", useDynamicColors) .apply(); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java index 2e85c7ce..5feae1cc 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsDisplayFragment.java @@ -21,6 +21,7 @@ import org.joinmastodon.android.model.viewmodel.CheckableListItem; import org.joinmastodon.android.model.viewmodel.ListItem; import org.joinmastodon.android.ui.M3AlertDialogBuilder; +import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; @@ -29,7 +30,7 @@ import me.grishka.appkit.FragmentStackActivity; public class SettingsDisplayFragment extends BaseSettingsFragment{ private ImageView themeTransitionWindowView; private ListItem themeItem; - private CheckableListItem showCWsItem, hideSensitiveMediaItem, interactionCountsItem, emojiInNamesItem; + private CheckableListItem showCWsItem, hideSensitiveMediaItem, interactionCountsItem, emojiInNamesItem, dynamicColorsItem; @Override public void onCreate(Bundle savedInstanceState){ @@ -37,13 +38,15 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ setTitle(R.string.settings_display); AccountSession s=AccountSessionManager.get(accountID); AccountLocalPreferences lp=s.getLocalPreferences(); - onDataLoaded(List.of( - themeItem=new ListItem<>(R.string.settings_theme, getAppearanceValue(), R.drawable.ic_dark_mode_24px, this::onAppearanceClick), - showCWsItem=new CheckableListItem<>(R.string.settings_show_cws, 0, CheckableListItem.Style.SWITCH, lp.showCWs, R.drawable.ic_warning_24px, this::toggleCheckableItem), - hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_no_adult_content_24px, this::toggleCheckableItem), - interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, 0, CheckableListItem.Style.SWITCH, lp.showInteractionCounts, R.drawable.ic_social_leaderboard_24px, this::toggleCheckableItem), - emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, lp.customEmojiInNames, R.drawable.ic_emoticon_24px, this::toggleCheckableItem) - )); + List> items=new ArrayList<>(); + items.add(themeItem=new ListItem<>(R.string.settings_theme, getAppearanceValue(), R.drawable.ic_dark_mode_24px, this::onAppearanceClick)); + if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.S) + items.add(dynamicColorsItem=new CheckableListItem<>(R.string.settings_use_dynamic_colors, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.useDynamicColors, R.drawable.ic_palette_24px, this::onDynamicColorsClick)); + items.add(showCWsItem=new CheckableListItem<>(R.string.settings_show_cws, 0, CheckableListItem.Style.SWITCH, lp.showCWs, R.drawable.ic_warning_24px, this::toggleCheckableItem)); + items.add(hideSensitiveMediaItem=new CheckableListItem<>(R.string.settings_hide_sensitive_media, 0, CheckableListItem.Style.SWITCH, lp.hideSensitiveMedia, R.drawable.ic_no_adult_content_24px, this::toggleCheckableItem)); + items.add(interactionCountsItem=new CheckableListItem<>(R.string.settings_show_interaction_counts, 0, CheckableListItem.Style.SWITCH, lp.showInteractionCounts, R.drawable.ic_social_leaderboard_24px, this::toggleCheckableItem)); + items.add(emojiInNamesItem=new CheckableListItem<>(R.string.settings_show_emoji_in_names, 0, CheckableListItem.Style.SWITCH, lp.customEmojiInNames, R.drawable.ic_emoticon_24px, this::toggleCheckableItem)); + onDataLoaded(items); } @Override @@ -109,6 +112,14 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ .show(); } + private void onDynamicColorsClick(CheckableListItem item){ + item.toggle(); + rebindItem(item); + GlobalUserPreferences.useDynamicColors=item.checked; + GlobalUserPreferences.save(); + restartActivityToApplyNewTheme(); + } + private void maybeApplyNewThemeRightNow(GlobalUserPreferences.ThemePreference prev){ boolean isCurrentDark=prev==GlobalUserPreferences.ThemePreference.DARK || (prev==GlobalUserPreferences.ThemePreference.AUTO && Build.VERSION.SDK_INT>=30 && getResources().getConfiguration().isNightModeActive()); diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java index ad4b3bcd..d4694302 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java @@ -729,23 +729,43 @@ public class UiUtils{ } public static int getThemeForUserPreference(Context context, GlobalUserPreferences.ThemePreference pref){ - return switch(pref){ - case AUTO -> switch(getColorContrastMode(context)){ - case DEFAULT -> R.style.Theme_Mastodon_AutoLightDark; - case MEDIUM -> R.style.Theme_Mastodon_AutoLightDark_MediumContrast; - case HIGH -> R.style.Theme_Mastodon_AutoLightDark_HighContrast; + if(GlobalUserPreferences.useDynamicColors){ + return switch(pref){ + case AUTO -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_AutoLightDark; + case MEDIUM -> R.style.Theme_Mastodon_AutoLightDark_MediumContrast; + case HIGH -> R.style.Theme_Mastodon_AutoLightDark_HighContrast; + }; + case LIGHT -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_Light; + case MEDIUM -> R.style.Theme_Mastodon_Light_MediumContrast; + case HIGH -> R.style.Theme_Mastodon_Light_HighContrast; + }; + case DARK -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_Dark; + case MEDIUM -> R.style.Theme_Mastodon_Dark_MediumContrast; + case HIGH -> R.style.Theme_Mastodon_Dark_HighContrast; + }; }; - case LIGHT -> switch(getColorContrastMode(context)){ - case DEFAULT -> R.style.Theme_Mastodon_Light; - case MEDIUM -> R.style.Theme_Mastodon_Light_MediumContrast; - case HIGH -> R.style.Theme_Mastodon_Light_HighContrast; + }else{ + return switch(pref){ + case AUTO -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_AutoLightDark_Masterial; + case MEDIUM -> R.style.Theme_Mastodon_AutoLightDark_MediumContrast_Masterial; + case HIGH -> R.style.Theme_Mastodon_AutoLightDark_HighContrast_Masterial; + }; + case LIGHT -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_Light_Masterial; + case MEDIUM -> R.style.Theme_Mastodon_Light_MediumContrast_Masterial; + case HIGH -> R.style.Theme_Mastodon_Light_HighContrast_Masterial; + }; + case DARK -> switch(getColorContrastMode(context)){ + case DEFAULT -> R.style.Theme_Mastodon_Dark_Masterial; + case MEDIUM -> R.style.Theme_Mastodon_Dark_MediumContrast_Masterial; + case HIGH -> R.style.Theme_Mastodon_Dark_HighContrast_Masterial; + }; }; - case DARK -> switch(getColorContrastMode(context)){ - case DEFAULT -> R.style.Theme_Mastodon_Dark; - case MEDIUM -> R.style.Theme_Mastodon_Dark_MediumContrast; - case HIGH -> R.style.Theme_Mastodon_Dark_HighContrast; - }; - }; + } } public static boolean isDarkTheme(){ diff --git a/mastodon/src/main/res/drawable/ic_palette_24px.xml b/mastodon/src/main/res/drawable/ic_palette_24px.xml new file mode 100644 index 00000000..cb4385b3 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_palette_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/res/values-night/styles.xml b/mastodon/src/main/res/values-night/styles.xml index 80b9884f..a6d80791 100644 --- a/mastodon/src/main/res/values-night/styles.xml +++ b/mastodon/src/main/res/values-night/styles.xml @@ -3,4 +3,7 @@ + + + + + + + + + + + +