diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 6cf2a98fb..45610e436 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -1,6 +1,7 @@ package org.joinmastodon.android; import static org.joinmastodon.android.api.MastodonAPIController.gson; +import static org.joinmastodon.android.api.session.AccountLocalPreferences.ColorPreference.MATERIAL3; import android.content.Context; import android.content.SharedPreferences; @@ -10,6 +11,7 @@ import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import org.joinmastodon.android.api.session.AccountLocalPreferences; +import org.joinmastodon.android.api.session.AccountLocalPreferences.ColorPreference; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.ContentType; @@ -59,6 +61,7 @@ public class GlobalUserPreferences{ public static boolean overlayMedia; public static boolean showSuicideHelp; public static boolean underlinedLinks; + public static ColorPreference color; private static SharedPreferences getPrefs(){ return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE); @@ -120,6 +123,7 @@ public class GlobalUserPreferences{ overlayMedia=prefs.getBoolean("overlayMedia", false); showSuicideHelp=prefs.getBoolean("showSuicideHelp", true); underlinedLinks=prefs.getBoolean("underlinedLinks", true); + color=ColorPreference.valueOf(prefs.getString("color", MATERIAL3.name())); if (prefs.contains("prefixRepliesWithRe")) { prefixReplies = prefs.getBoolean("prefixRepliesWithRe", false) @@ -133,8 +137,6 @@ public class GlobalUserPreferences{ int migrationLevel=prefs.getInt("migrationLevel", BuildConfig.VERSION_CODE); if(migrationLevel < 61) migrateToUpstreamVersion61(); - if(migrationLevel < 102) - migrateToVersion102(); if(migrationLevel < BuildConfig.VERSION_CODE) prefs.edit().putInt("migrationLevel", BuildConfig.VERSION_CODE).apply(); } @@ -178,6 +180,7 @@ public class GlobalUserPreferences{ .putBoolean("overlayMedia", overlayMedia) .putBoolean("showSuicideHelp", showSuicideHelp) .putBoolean("underlinedLinks", underlinedLinks) + .putString("color", color.name()) .apply(); } @@ -202,25 +205,6 @@ public class GlobalUserPreferences{ //region preferences migrations - private static void migrateToVersion102(){ - Log.d(TAG, "Migrating preferences to version 102!! (copy current theme to local preferences)"); - - SharedPreferences prefs=getPrefs(); - // only migrate if global prefs even contains a color (but like.. it should) - if(prefs.contains("color")){ - AccountSessionManager asm=AccountSessionManager.getInstance(); - for(AccountSession session : asm.getLoggedInAccounts()){ - if(session.getRawLocalPreferences().contains("color")) continue; - AccountLocalPreferences localPrefs=session.getLocalPreferences(); - localPrefs.color=AccountLocalPreferences.ColorPreference.valueOf(prefs.getString( - "color", AccountLocalPreferences.ColorPreference.MATERIAL3.name() - )); - localPrefs.save(); - } - prefs.edit().remove("color").apply(); - } - } - private static void migrateToUpstreamVersion61(){ Log.d(TAG, "Migrating preferences to upstream version 61!!"); diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java index fa112dd21..19190ab41 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java @@ -10,6 +10,7 @@ import androidx.annotation.StringRes; import com.google.gson.reflect.TypeToken; +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.model.ContentType; import org.joinmastodon.android.model.Emoji; @@ -73,7 +74,7 @@ public class AccountLocalPreferences{ keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false); emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma()); showEmojiReactions=ShowEmojiReactions.valueOf(prefs.getString("showEmojiReactions", ShowEmojiReactions.HIDE_EMPTY.name())); - color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.MATERIAL3.name())); + color=prefs.contains("color") ? ColorPreference.valueOf(prefs.getString("color", null)) : null; likeIcon=prefs.getBoolean("likeIcon", false); recentCustomEmoji=fromJson(prefs.getString("recentCustomEmoji", null), recentCustomEmojiType, new ArrayList<>()); } @@ -86,6 +87,10 @@ public class AccountLocalPreferences{ prefs.edit().putLong("notificationsPauseTime", time).apply(); } + public ColorPreference getCurrentColor(){ + return color!=null ? color : GlobalUserPreferences.color!=null ? GlobalUserPreferences.color : ColorPreference.MATERIAL3; + } + public void save(){ prefs.edit() .putBoolean("interactionCounts", showInteractionCounts) @@ -109,7 +114,7 @@ public class AccountLocalPreferences{ .putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification) .putBoolean("emojiReactionsEnabled", emojiReactionsEnabled) .putString("showEmojiReactions", showEmojiReactions.name()) - .putString("color", color.name()) + .putString("color", color!=null ? color.name() : null) .putBoolean("likeIcon", likeIcon) .putString("recentCustomEmoji", gson.toJson(recentCustomEmoji)) .apply(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java index ef03a45ac..733bc0815 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/ComposeImageDescriptionFragment.java @@ -63,7 +63,8 @@ public class ComposeImageDescriptionFragment extends MastodonToolbarFragment imp accountID=getArguments().getString("account"); attachmentID=getArguments().getString("attachment"); themeWrapper=new ContextThemeWrapper(activity, R.style.Theme_Mastodon_Dark); - ColorPalette.palettes.get(AccountSessionManager.get(accountID).getLocalPreferences().color).apply(themeWrapper, GlobalUserPreferences.ThemePreference.DARK); + ColorPalette.palettes.get(AccountSessionManager.get(accountID).getLocalPreferences().getCurrentColor()) + .apply(themeWrapper, GlobalUserPreferences.ThemePreference.DARK); setTitle(R.string.add_alt_text); } 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 097fbe3d3..b0f421e25 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 @@ -1,6 +1,7 @@ package org.joinmastodon.android.fragments.settings; import android.app.Activity; +import android.app.AlertDialog; import android.graphics.Bitmap; import android.graphics.Canvas; import android.os.Build; @@ -28,6 +29,8 @@ import org.joinmastodon.android.ui.views.TextInputFrameLayout; import java.util.Arrays; import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; import java.util.stream.IntStream; import me.grishka.appkit.FragmentStackActivity; @@ -52,7 +55,7 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ lp=s.getLocalPreferences(); onDataLoaded(List.of( themeItem=new ListItem<>(R.string.settings_theme, getAppearanceValue(), R.drawable.ic_fluent_weather_moon_24_regular, this::onAppearanceClick), - colorItem=new ListItem<>(R.string.sk_settings_color_palette, getColorPaletteValue(), R.drawable.ic_fluent_color_24_regular, this::onColorClick), + colorItem=new ListItem<>(getString(R.string.sk_settings_color_palette), getColorPaletteValue(), R.drawable.ic_fluent_color_24_regular, this::onColorClick), trueBlackModeItem=new CheckableListItem<>(R.string.sk_settings_true_black, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.trueBlackTheme, R.drawable.ic_fluent_dark_theme_24_regular, this::onTrueBlackModeClick, true), publishTextItem=new ListItem<>(getString(R.string.sk_settings_publish_button_text), getPublishButtonText(), R.drawable.ic_fluent_send_24_regular, this::onPublishTextClick), autoRevealCWsItem=new ListItem<>(R.string.sk_settings_auto_reveal_equal_spoilers, getAutoRevealSpoilersText(), R.drawable.ic_fluent_eye_24_regular, this::onAutoRevealSpoilersClick), @@ -136,17 +139,11 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ }; } - private @StringRes int getColorPaletteValue(){ - return switch(AccountSessionManager.get(accountID).getLocalPreferences().color){ - case MATERIAL3 -> R.string.sk_color_palette_material3; - case PINK -> R.string.sk_color_palette_pink; - case PURPLE -> R.string.sk_color_palette_purple; - case GREEN -> R.string.sk_color_palette_green; - case BLUE -> R.string.sk_color_palette_blue; - case BROWN -> R.string.sk_color_palette_brown; - case RED -> R.string.sk_color_palette_red; - case YELLOW -> R.string.sk_color_palette_yellow; - }; + private String getColorPaletteValue(){ + ColorPreference color=AccountSessionManager.get(accountID).getLocalPreferences().color; + return color==null + ? getString(R.string.sk_settings_color_palette_default, getString(GlobalUserPreferences.color.getName())) + : getString(color.getName()); } private String getPublishButtonText() { @@ -202,26 +199,40 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ } private void onColorClick(){ - int selected=lp.color.ordinal(); + boolean multiple=AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1; + int indexOffset=multiple ? 1 : 0; + int selected=lp.color==null ? 0 : lp.color.ordinal() + indexOffset; int[] newSelected={selected}; - String[] names=Arrays.stream(ColorPreference.values()).map(ColorPreference::getName).map(this::getString).toArray(String[]::new); - new M3AlertDialogBuilder(getActivity()) + List items=Arrays.stream(ColorPreference.values()).map(ColorPreference::getName).map(this::getString).collect(Collectors.toList()); + if(multiple) + items.add(0, getString(R.string.sk_settings_color_palette_default, items.get(GlobalUserPreferences.color.ordinal()))); + + Consumer save=(asDefault)->{ + boolean defaultSelected=multiple && newSelected[0]==0; + ColorPreference pref=defaultSelected ? null : ColorPreference.values()[newSelected[0]-indexOffset]; + if(pref!=lp.color){ + ColorPreference prev=lp.color; + lp.color=asDefault ? null : pref; + lp.save(); + if((asDefault || !multiple) && pref!=null){ + GlobalUserPreferences.color=pref; + GlobalUserPreferences.save(); + } + colorItem.subtitle=getColorPaletteValue(); + rebindItem(colorItem); + if(prev==null && pref!=null) restartActivityToApplyNewTheme(); + else maybeApplyNewThemeRightNow(null, prev, null); + } + }; + + AlertDialog.Builder alert=new M3AlertDialogBuilder(getActivity()) .setTitle(R.string.sk_settings_color_palette) - .setSingleChoiceItems(names, + .setSingleChoiceItems(items.toArray(String[]::new), selected, (dlg, item)->newSelected[0]=item) - .setPositiveButton(R.string.ok, (dlg, item)->{ - ColorPreference pref=ColorPreference.values()[newSelected[0]]; - if(pref!=lp.color){ - ColorPreference prev=lp.color; - lp.color=pref; - GlobalUserPreferences.save(); - colorItem.subtitleRes=getColorPaletteValue(); - rebindItem(colorItem); - maybeApplyNewThemeRightNow(null, prev, null); - } - }) - .setNegativeButton(R.string.cancel, null) - .show(); + .setPositiveButton(R.string.ok, (dlg, item)->save.accept(false)) + .setNegativeButton(R.string.cancel, null); + if(multiple) alert.setNeutralButton(R.string.sk_set_as_default, (dlg, item)->save.accept(true)); + alert.show(); } private void onPublishTextClick(){ @@ -266,14 +277,14 @@ public class SettingsDisplayFragment extends BaseSettingsFragment{ private void maybeApplyNewThemeRightNow(GlobalUserPreferences.ThemePreference prevTheme, ColorPreference prevColor, Boolean prevTrueBlack){ if(prevTheme==null) prevTheme=GlobalUserPreferences.theme; if(prevTrueBlack==null) prevTrueBlack=GlobalUserPreferences.trueBlackTheme; - if(prevColor==null) prevColor=lp.color; + if(prevColor==null) prevColor=lp.getCurrentColor(); boolean isCurrentDark=prevTheme==GlobalUserPreferences.ThemePreference.DARK || (prevTheme==GlobalUserPreferences.ThemePreference.AUTO && Build.VERSION.SDK_INT>=30 && getResources().getConfiguration().isNightModeActive()); boolean isNewDark=GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.DARK || (GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.AUTO && Build.VERSION.SDK_INT>=30 && getResources().getConfiguration().isNightModeActive()); boolean isNewBlack=GlobalUserPreferences.trueBlackTheme; - if(isCurrentDark!=isNewDark || prevColor!=lp.color || (isNewDark && prevTrueBlack!=isNewBlack)){ + if(isCurrentDark!=isNewDark || prevColor!=lp.getCurrentColor() || (isNewDark && prevTrueBlack!=isNewBlack)){ restartActivityToApplyNewTheme(); } } 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 80a9cbb5f..89516b6ad 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 @@ -973,8 +973,8 @@ public class UiUtils { default -> R.style.Theme_Mastodon_AutoLightDark; }); - AccountLocalPreferences prefs=session != null ? session.getLocalPreferences() : null; - AccountLocalPreferences.ColorPreference color=prefs != null ? prefs.color : AccountLocalPreferences.ColorPreference.MATERIAL3; + AccountLocalPreferences prefs=session!=null ? session.getLocalPreferences() : null; + AccountLocalPreferences.ColorPreference color=prefs!=null ? prefs.getCurrentColor() : AccountLocalPreferences.ColorPreference.MATERIAL3; ColorPalette palette = ColorPalette.palettes.get(color); if (palette != null) palette.apply(context, theme); diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 6a62111d3..67bb61eb5 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -51,6 +51,7 @@ Posts Post notifications Color palette + Default (%s) System Pink Purple @@ -409,4 +410,5 @@ Use heart as favorite icon Recently used Underlined links + Set as default \ No newline at end of file