From afca57501f41d6bdf4d4baa706fd6b9eb32f6769 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 12:10:43 +0200 Subject: [PATCH 01/10] fix: move method to fix compiler error --- .../settings/SettingsAppearanceFragment.java | 48 ++++++++++++------- .../settings/SettingsBaseFragment.java | 44 +++++------------ 2 files changed, 43 insertions(+), 49 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAppearanceFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAppearanceFragment.java index 3fc28515f..62968cece 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAppearanceFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsAppearanceFragment.java @@ -1,32 +1,26 @@ package org.joinmastodon.android.fragments.settings; -import android.graphics.Bitmap; -import android.graphics.Canvas; import android.os.Build; import android.view.Gravity; -import android.view.View; -import android.view.WindowManager; -import android.widget.ImageView; +import android.view.MenuItem; import android.widget.PopupMenu; -import androidx.recyclerview.widget.RecyclerView; - import org.joinmastodon.android.GlobalUserPreferences; -import org.joinmastodon.android.MastodonApp; import org.joinmastodon.android.R; -import org.joinmastodon.android.ui.utils.UiUtils; import java.util.ArrayList; public class SettingsAppearanceFragment extends SettingsBaseFragment { + @Override public void addItems(ArrayList items) { - items.add(themeItem SettingsBaseFragment.ThemeItem()); - items.add(new SettingsFragment.ButtonItem(R.string.sk_settings_color_palette, R.drawable.ic_fluent_color_24_regular, b -> { + themeItem = new ThemeItem(); + items.add(themeItem); + items.add(new ButtonItem(R.string.sk_settings_color_palette, R.drawable.ic_fluent_color_24_regular, b -> { PopupMenu popupMenu = new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL); popupMenu.inflate(R.menu.color_palettes); popupMenu.getMenu().findItem(R.id.m3_color).setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S); - popupMenu.setOnMenuItemClickListener(SettingsBaseFragment.this::onColorPreferenceClick); + popupMenu.setOnMenuItemClickListener(this::onColorPreferenceClick); b.setOnTouchListener(popupMenu.getDragToOpenListener()); b.setOnClickListener(v -> popupMenu.show()); b.setText(switch (GlobalUserPreferences.color) { @@ -41,21 +35,43 @@ public class SettingsAppearanceFragment extends SettingsBaseFragment { case NORD -> R.string.mo_color_palette_nord; }); })); - items.add(new SettingsBaseFragment.SwitchItem(R.string.theme_true_black, R.drawable.ic_fluent_dark_theme_24_regular, GlobalUserPreferences.trueBlackTheme, this::onTrueBlackThemeChanged)); - items.add(new SettingsBaseFragment.SwitchItem(R.string.sk_disable_marquee, R.drawable.ic_fluent_text_more_24_regular, GlobalUserPreferences.disableMarquee, i -> { + items.add(new SwitchItem(R.string.theme_true_black, R.drawable.ic_fluent_dark_theme_24_regular, GlobalUserPreferences.trueBlackTheme, this::onTrueBlackThemeChanged)); + items.add(new SwitchItem(R.string.sk_disable_marquee, R.drawable.ic_fluent_text_more_24_regular, GlobalUserPreferences.disableMarquee, i -> { GlobalUserPreferences.disableMarquee = i.checked; GlobalUserPreferences.save(); needAppRestart = true; })); - items.add(new SettingsBaseFragment.SwitchItem(R.string.sk_settings_uniform_icon_for_notifications, R.drawable.ic_ntf_logo, GlobalUserPreferences.uniformNotificationIcon, i -> { + items.add(new SwitchItem(R.string.sk_settings_uniform_icon_for_notifications, R.drawable.ic_ntf_logo, GlobalUserPreferences.uniformNotificationIcon, i -> { GlobalUserPreferences.uniformNotificationIcon = i.checked; GlobalUserPreferences.save(); })); - items.add(new SettingsBaseFragment.SwitchItem(R.string.sk_settings_reduce_motion, R.drawable.ic_fluent_star_emphasis_24_regular, GlobalUserPreferences.reduceMotion, i -> { + items.add(new SwitchItem(R.string.sk_settings_reduce_motion, R.drawable.ic_fluent_star_emphasis_24_regular, GlobalUserPreferences.reduceMotion, i -> { GlobalUserPreferences.reduceMotion = i.checked; GlobalUserPreferences.save(); needAppRestart = true; })); } + + private boolean onColorPreferenceClick(MenuItem item) { + GlobalUserPreferences.ColorPreference pref = null; + int id = item.getItemId(); + + if (id == R.id.m3_color) pref = GlobalUserPreferences.ColorPreference.MATERIAL3; + else if (id == R.id.pink_color) pref = GlobalUserPreferences.ColorPreference.PINK; + else if (id == R.id.purple_color) pref = GlobalUserPreferences.ColorPreference.PURPLE; + else if (id == R.id.green_color) pref = GlobalUserPreferences.ColorPreference.GREEN; + else if (id == R.id.blue_color) pref = GlobalUserPreferences.ColorPreference.BLUE; + else if (id == R.id.brown_color) pref = GlobalUserPreferences.ColorPreference.BROWN; + else if (id == R.id.red_color) pref = GlobalUserPreferences.ColorPreference.RED; + else if (id == R.id.yellow_color) pref = GlobalUserPreferences.ColorPreference.YELLOW; + else if (id == R.id.nord_color) pref = GlobalUserPreferences.ColorPreference.NORD; + + if (pref == null) return false; + + GlobalUserPreferences.color=pref; + GlobalUserPreferences.save(); + restartActivityToApplyNewTheme(); + return true; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index d11ef067d..d31ca1790 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -64,7 +64,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple protected boolean needAppRestart; - protected SettingsBaseFragment.NotificationPolicyItem notificationPolicyItem; + protected NotificationPolicyItem notificationPolicyItem; protected PushSubscription pushSubscription; protected ArrayList items=new ArrayList<>(); @@ -173,7 +173,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - protected class UpdateItem extends SettingsBaseFragment.Item { + protected class UpdateItem extends Item { @Override public int getViewType(){ @@ -181,7 +181,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - protected static class ThemeItem extends SettingsBaseFragment.Item { + protected static class ThemeItem extends Item { @Override public int getViewType(){ @@ -189,7 +189,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - protected static class NotificationPolicyItem extends SettingsBaseFragment.Item { + protected static class NotificationPolicyItem extends Item { @Override public int getViewType(){ @@ -395,28 +395,6 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - protected boolean onColorPreferenceClick(MenuItem item){ - GlobalUserPreferences.ColorPreference pref = null; - int id = item.getItemId(); - - if (id == R.id.m3_color) pref = GlobalUserPreferences.ColorPreference.MATERIAL3; - else if (id == R.id.pink_color) pref = GlobalUserPreferences.ColorPreference.PINK; - else if (id == R.id.purple_color) pref = GlobalUserPreferences.ColorPreference.PURPLE; - else if (id == R.id.green_color) pref = GlobalUserPreferences.ColorPreference.GREEN; - else if (id == R.id.blue_color) pref = GlobalUserPreferences.ColorPreference.BLUE; - else if (id == R.id.brown_color) pref = GlobalUserPreferences.ColorPreference.BROWN; - else if (id == R.id.red_color) pref = GlobalUserPreferences.ColorPreference.RED; - else if (id == R.id.yellow_color) pref = GlobalUserPreferences.ColorPreference.YELLOW; - else if (id == R.id.nord_color) pref = GlobalUserPreferences.ColorPreference.NORD; - - if (pref == null) return false; - - GlobalUserPreferences.color=pref; - GlobalUserPreferences.save(); - restartActivityToApplyNewTheme(); - return true; - } - protected void onThemePreferenceClick(GlobalUserPreferences.ThemePreference theme){ GlobalUserPreferences.theme=theme; GlobalUserPreferences.save(); @@ -456,13 +434,13 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } - protected void onTrueBlackThemeChanged(SettingsBaseFragment.SwitchItem item){ + protected void onTrueBlackThemeChanged(SwitchItem item){ GlobalUserPreferences.trueBlackTheme=item.checked; GlobalUserPreferences.save(); RecyclerView.ViewHolder themeHolder=list.findViewHolderForAdapterPosition(items.indexOf(themeItem)); if(themeHolder!=null){ - ((SettingsBaseFragment.ThemeViewHolder)themeHolder).bindSubitems(); + ((ThemeViewHolder)themeHolder).bindSubitems(); }else{ list.getAdapter().notifyItemChanged(items.indexOf(themeItem)); } @@ -504,7 +482,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } @Override - public void onBind(SettingsBaseFragment.NotificationPolicyItem item){ + public void onBind(NotificationPolicyItem item){ button.setText(switch(getPushSubscription().policy){ case ALL -> R.string.notify_anyone; case FOLLOWED -> R.string.notify_followed; @@ -523,7 +501,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple int index=items.indexOf(notificationPolicyItem); RecyclerView.ViewHolder policyHolder=list.findViewHolderForAdapterPosition(index); if(policyHolder!=null){ - ((SettingsBaseFragment.NotificationPolicyViewHolder)policyHolder).rebind(); + ((NotificationPolicyViewHolder)policyHolder).rebind(); }else{ list.getAdapter().notifyItemChanged(index); } @@ -533,7 +511,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple onNotificationsChanged(value, newState); } index++; - while(items.get(index) instanceof SettingsBaseFragment.SwitchItem si){ + while(items.get(index) instanceof SwitchItem si){ si.enabled=si.checked=newState; RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(index); if(holder!=null) @@ -622,7 +600,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } @Override - public void onBind(SettingsBaseFragment.ThemeItem item){ + public void onBind(ThemeItem item){ bindSubitems(); } @@ -810,7 +788,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } @Override - public void onBind(SettingsBaseFragment.UpdateItem item){ + public void onBind(UpdateItem item){ GithubSelfUpdater updater=GithubSelfUpdater.getInstance(); GithubSelfUpdater.UpdateState state=updater.getState(); if (state == GithubSelfUpdater.UpdateState.CHECKING) return; From d310673f92f960ae2af69795e9bccd218eb426f2 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 12:24:06 +0200 Subject: [PATCH 02/10] refactor: use SettingsCategory to move between pages --- .../settings/SettingsBaseFragment.java | 51 +++++++------------ .../settings/SettingsMainFragment.java | 4 +- 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index d31ca1790..915d7f787 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -2,6 +2,7 @@ package org.joinmastodon.android.fragments.settings; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; +import android.app.Fragment; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; @@ -50,6 +51,7 @@ import org.joinmastodon.android.updater.GithubSelfUpdater; import java.util.ArrayList; import java.util.function.Consumer; +import me.grishka.appkit.Nav; import me.grishka.appkit.utils.BindableViewHolder; import me.grishka.appkit.utils.V; import me.grishka.appkit.views.UsableRecyclerView; @@ -274,41 +276,20 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple protected class SettingsCategoryItem extends Item{ private String text; - private String secondaryText; - private Runnable onClick; - private boolean loading; private int icon; - public SettingsCategoryItem(@StringRes int text, Runnable onClick) { - this(text, null, onClick, false, 0); - } + private Class fragmentClass; - public SettingsCategoryItem(@StringRes int text, Runnable onClick, @DrawableRes int icon) { - this(text, null, onClick, false, icon); - } + public SettingsCategoryItem(@StringRes int text, Class fragmentClass, @DrawableRes int icon) { + this.text = getString(text); + this.fragmentClass=fragmentClass; + this.icon=icon; + } - public SettingsCategoryItem(@StringRes int text, String secondaryText, Runnable onClick, @DrawableRes int icon) { - this(text, secondaryText, onClick, false, icon); - } + public SettingsCategoryItem(@StringRes int text, Class fragmentClass) { + this(text, fragmentClass, 0); + } - public SettingsCategoryItem(@StringRes int text, String secondaryText, Runnable onClick, boolean loading, @DrawableRes int icon){ - this.text=getString(text); - this.onClick=onClick; - this.loading=loading; - this.icon=icon; - this.secondaryText = secondaryText; - } - - public SettingsCategoryItem(String text, Runnable onClick){ - this.text=text; - this.onClick=onClick; - } - - public SettingsCategoryItem(String text, Runnable onClick, @DrawableRes int icon){ - this.text=text; - this.onClick=onClick; - this.icon=icon; - } @Override public int getViewType(){ @@ -650,7 +631,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - private class SettingsCategoryViewHolder extends BindableViewHolder{ + private class SettingsCategoryViewHolder extends BindableViewHolder implements UsableRecyclerView.Clickable{ private final ImageView icon; private final TextView text; @@ -665,9 +646,13 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple public void onBind(SettingsCategoryItem item){ text.setText(item.text); icon.setImageResource(item.icon); - item.onClick.run(); } - } + + @Override + public void onClick() { + Nav.go(getActivity(), item.fragmentClass, getArguments()); + } + } protected class ButtonViewHolder extends BindableViewHolder{ private final Button button; diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index d2fc74bca..4e2a1f256 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -7,8 +7,6 @@ import java.util.ArrayList; public class SettingsMainFragment extends SettingsBaseFragment{ @Override public void addItems(ArrayList items) { - items.add(new SettingsBaseFragment.SettingsCategoryItem(R.string.settings_theme, () -> { - System.out.println("YAY"); - }, R.drawable.ic_fluent_color_24_regular)); + items.add(new SettingsCategoryItem(R.string.settings_theme, SettingsAppearanceFragment.class, R.drawable.ic_fluent_color_24_regular)); } } From 2751b804fe0fded9c032813eedd9b30617edbce4 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 12:33:03 +0200 Subject: [PATCH 03/10] refactor: move behaviour settings to behaviour page --- .../ic_fluent_chat_settings_24_regular.xml | 9 +++ .../fragments/settings/BehaviourFragment.java | 57 +++++++++++++++++++ .../settings/SettingsMainFragment.java | 1 + 3 files changed, 67 insertions(+) create mode 100644 mastodon/src/github/res/drawable/ic_fluent_chat_settings_24_regular.xml create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java diff --git a/mastodon/src/github/res/drawable/ic_fluent_chat_settings_24_regular.xml b/mastodon/src/github/res/drawable/ic_fluent_chat_settings_24_regular.xml new file mode 100644 index 000000000..703f8f901 --- /dev/null +++ b/mastodon/src/github/res/drawable/ic_fluent_chat_settings_24_regular.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java new file mode 100644 index 000000000..768e9cb34 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java @@ -0,0 +1,57 @@ +package org.joinmastodon.android.fragments.settings; + +import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.R; + +import java.util.ArrayList; + +public class BehaviourFragment extends SettingsBaseFragment{ + @Override + public void addItems(ArrayList items) { + items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{ + GlobalUserPreferences.playGifs=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.settings_custom_tabs, R.drawable.ic_fluent_link_24_regular, GlobalUserPreferences.useCustomTabs, i->{ + GlobalUserPreferences.useCustomTabs=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.mo_hide_compose_button_while_scrolling_setting, R.drawable.ic_fluent_edit_24_regular, GlobalUserPreferences.enableFabAutoHide, i->{ + GlobalUserPreferences.enableFabAutoHide =i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.mo_load_remote_followers, R.drawable.ic_fluent_people_24_regular, GlobalUserPreferences.loadRemoteAccountFollowers, i -> { + GlobalUserPreferences.loadRemoteAccountFollowers=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.sk_settings_show_interaction_counts, R.drawable.ic_fluent_number_row_24_regular, GlobalUserPreferences.showInteractionCounts, i->{ + GlobalUserPreferences.showInteractionCounts=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.sk_settings_always_reveal_content_warnings, R.drawable.ic_fluent_chat_warning_24_regular, GlobalUserPreferences.alwaysExpandContentWarnings, i->{ + GlobalUserPreferences.alwaysExpandContentWarnings=i.checked; + GlobalUserPreferences.save(); + })); + +// items.add(new SwitchItem(R.string.sk_settings_show_differentiated_notification_icons, R.drawable.ic_ntf_logo, GlobalUserPreferences.showUniformPushNoticationIcons, this::onNotificationStyleChanged)); + items.add(new SwitchItem(R.string.sk_tabs_disable_swipe, R.drawable.ic_fluent_swipe_right_24_regular, GlobalUserPreferences.disableSwipe, i->{ + GlobalUserPreferences.disableSwipe=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.mo_disable_double_tap_to_swipe_between_tabs, R.drawable.ic_fluent_double_tap_swipe_right_24_regular, GlobalUserPreferences.disableDoubleTapToSwipe, i->{ + GlobalUserPreferences.disableDoubleTapToSwipe=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_settings_confirm_before_reblog, R.drawable.ic_fluent_checkmark_circle_24_regular, GlobalUserPreferences.confirmBeforeReblog, i->{ + GlobalUserPreferences.confirmBeforeReblog=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.mo_swap_bookmark_with_reblog, R.drawable.ic_boost, GlobalUserPreferences.swapBookmarkWithBoostAction, i -> { + GlobalUserPreferences.swapBookmarkWithBoostAction=i.checked; + GlobalUserPreferences.save(); + })); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index 4e2a1f256..db9398a4f 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -8,5 +8,6 @@ public class SettingsMainFragment extends SettingsBaseFragment{ @Override public void addItems(ArrayList items) { items.add(new SettingsCategoryItem(R.string.settings_theme, SettingsAppearanceFragment.class, R.drawable.ic_fluent_color_24_regular)); + items.add(new SettingsCategoryItem(R.string.settings_behavior, BehaviourFragment.class, R.drawable.ic_fluent_chat_settings_24_regular)); } } From c5e35e550cf17eb596ce90bbeda953c8211212b2 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 12:38:51 +0200 Subject: [PATCH 04/10] refactor: add compose behaviour to behaviour page --- .../fragments/settings/BehaviourFragment.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java index 768e9cb34..8b9633904 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java @@ -1,13 +1,23 @@ package org.joinmastodon.android.fragments.settings; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.Toast; + import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.ui.M3AlertDialogBuilder; import java.util.ArrayList; +import me.grishka.appkit.utils.V; + public class BehaviourFragment extends SettingsBaseFragment{ @Override public void addItems(ArrayList items) { + items.add(new HeaderItem(R.string.settings_behavior)); items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{ GlobalUserPreferences.playGifs=i.checked; GlobalUserPreferences.save(); @@ -53,5 +63,67 @@ public class BehaviourFragment extends SettingsBaseFragment{ GlobalUserPreferences.swapBookmarkWithBoostAction=i.checked; GlobalUserPreferences.save(); })); + + items.add(new HeaderItem(R.string.mo_composer_behavior)); + items.add(new ButtonItem(R.string.sk_settings_publish_button_text, R.drawable.ic_fluent_send_24_regular, b-> { + updatePublishText(b); + b.setOnClickListener(l -> { + if(!GlobalUserPreferences.relocatePublishButton) { + FrameLayout inputWrap = new FrameLayout(getContext()); + EditText input = new EditText(getContext()); + input.setHint(R.string.publish); + input.setText(GlobalUserPreferences.publishButtonText.trim()); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + params.setMargins(V.dp(16), V.dp(4), V.dp(16), V.dp(16)); + input.setLayoutParams(params); + inputWrap.addView(input); + new M3AlertDialogBuilder(getContext()).setTitle(R.string.sk_settings_publish_button_text_title).setView(inputWrap) + .setPositiveButton(R.string.save, (d, which) -> { + GlobalUserPreferences.publishButtonText = input.getText().toString().trim(); + GlobalUserPreferences.save(); + updatePublishText(b); + }) + .setNeutralButton(R.string.clear, (d, which) -> { + GlobalUserPreferences.publishButtonText = ""; + GlobalUserPreferences.save(); + updatePublishText(b); + }) + .setNegativeButton(R.string.cancel, (d, which) -> { + }) + .show(); + + } else { + Toast.makeText(getActivity(), R.string.mo_disable_relocate_publish_button_to_enable_customization, + Toast.LENGTH_LONG).show(); + } + }); + })); + items.add(new SwitchItem(R.string.mo_relocate_publish_button, R.drawable.ic_fluent_arrow_autofit_down_24_regular, GlobalUserPreferences.relocatePublishButton, i->{ + GlobalUserPreferences.relocatePublishButton=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.mo_change_default_reply_visibility_to_unlisted, R.drawable.ic_fluent_lock_open_24_regular, GlobalUserPreferences.defaultToUnlistedReplies, i->{ + GlobalUserPreferences.defaultToUnlistedReplies=i.checked; + GlobalUserPreferences.save(); + })); + // TODO find a good icon for this setting + items.add(new SwitchItem(R.string.mo_mention_reblogger_automatically, R.drawable.ic_fluent_balloon_24_regular, GlobalUserPreferences.mentionRebloggerAutomatically, i -> { + GlobalUserPreferences.mentionRebloggerAutomatically=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.mo_disable_reminder_to_add_alt_text, R.drawable.ic_fluent_image_alt_text_24_regular, GlobalUserPreferences.disableAltTextReminder, i->{ + GlobalUserPreferences.disableAltTextReminder=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_settings_prefix_reply_cw_with_re, R.drawable.ic_fluent_arrow_reply_24_regular, GlobalUserPreferences.prefixRepliesWithRe, i->{ + GlobalUserPreferences.prefixRepliesWithRe=i.checked; + GlobalUserPreferences.save(); + })); + } + + private void updatePublishText(Button btn) { + if (GlobalUserPreferences.publishButtonText.isBlank()) btn.setText(R.string.publish); + else btn.setText(GlobalUserPreferences.publishButtonText); } } From 57f513048a8a975d8dad37b9f3f4d60958cfc800 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 12:44:40 +0200 Subject: [PATCH 05/10] refactor: move timelines to TimelineFragment --- .../settings/SettingsBaseFragment.java | 17 ++- .../settings/SettingsMainFragment.java | 1 + .../fragments/settings/TimeLineFragment.java | 123 ++++++++++++++++++ 3 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index 915d7f787..4e4d4f6b0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -42,6 +42,7 @@ import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.DomainDisplay; import org.joinmastodon.android.fragments.MastodonToolbarFragment; +import org.joinmastodon.android.model.Instance; import org.joinmastodon.android.model.PushNotification; import org.joinmastodon.android.model.PushSubscription; import org.joinmastodon.android.ui.OutlineProviders; @@ -65,6 +66,8 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple protected ThemeItem themeItem; protected boolean needAppRestart; + private Instance instance; + private String instanceName; protected NotificationPolicyItem notificationPolicyItem; @@ -85,6 +88,8 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple accountID=getArguments().getString("account"); AccountSession session = AccountSessionManager.getInstance().getAccount(accountID); + instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain); + instanceName = UiUtils.getInstanceName(accountID); DomainManager.getInstance().setCurrentDomain(session.domain + "/settings"); addItems(items); @@ -125,6 +130,14 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple this.view = view; } + protected Instance getInstance() { + return instance; + } + + protected String getInstanceName() { + return instanceName; + } + static abstract class Item{ public abstract int getViewType(); @@ -152,7 +165,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple private int icon; boolean checked; private Consumer onChanged; - private boolean enabled=true; + protected boolean enabled=true; public SwitchItem(@StringRes int text, @DrawableRes int icon, boolean checked, Consumer onChanged){ this.text=getString(text); @@ -532,7 +545,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple return pushSubscription; } - private class SwitchViewHolder extends BindableViewHolder implements UsableRecyclerView.DisableableClickable{ + protected class SwitchViewHolder extends BindableViewHolder implements UsableRecyclerView.DisableableClickable{ private final TextView text; private final ImageView icon; private final Switch checkbox; diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index db9398a4f..64141cca3 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -9,5 +9,6 @@ public class SettingsMainFragment extends SettingsBaseFragment{ public void addItems(ArrayList items) { items.add(new SettingsCategoryItem(R.string.settings_theme, SettingsAppearanceFragment.class, R.drawable.ic_fluent_color_24_regular)); items.add(new SettingsCategoryItem(R.string.settings_behavior, BehaviourFragment.class, R.drawable.ic_fluent_chat_settings_24_regular)); + items.add(new SettingsCategoryItem(R.string.sk_timelines, TimeLineFragment.class, R.drawable.ic_fluent_timeline_24_regular)); } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java new file mode 100644 index 000000000..528a06fd3 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java @@ -0,0 +1,123 @@ +package org.joinmastodon.android.fragments.settings; + +import android.view.Gravity; +import android.view.MenuItem; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.PopupMenu; +import android.widget.Toast; + +import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.R; +import org.joinmastodon.android.ui.M3AlertDialogBuilder; + +import java.util.ArrayList; + +import me.grishka.appkit.utils.V; + +public class TimeLineFragment extends SettingsBaseFragment{ + + private SwitchItem showNewPostsButtonItem, compactReblogReplyLineItem; + @Override + public void addItems(ArrayList items) { + items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{ + GlobalUserPreferences.showReplies=i.checked; + GlobalUserPreferences.save(); + })); + if (getInstance().pleroma != null) { + items.add(new ButtonItem(R.string.sk_settings_reply_visibility, R.drawable.ic_fluent_chat_24_regular, b->{ + PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL); + popupMenu.inflate(R.menu.reply_visibility); + popupMenu.setOnMenuItemClickListener(item -> this.onReplyVisibilityChanged(item, b)); + b.setOnTouchListener(popupMenu.getDragToOpenListener()); + b.setOnClickListener(v->popupMenu.show()); + b.setText(GlobalUserPreferences.replyVisibility == null ? + R.string.sk_settings_reply_visibility_all : + switch(GlobalUserPreferences.replyVisibility){ + case "following" -> R.string.sk_settings_reply_visibility_following; + case "self" -> R.string.sk_settings_reply_visibility_self; + default -> R.string.sk_settings_reply_visibility_all; + }); + })); + } + items.add(new SwitchItem(R.string.sk_settings_show_boosts, R.drawable.ic_fluent_arrow_repeat_all_24_regular, GlobalUserPreferences.showBoosts, i->{ + GlobalUserPreferences.showBoosts=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.sk_settings_load_new_posts, R.drawable.ic_fluent_arrow_sync_24_regular, GlobalUserPreferences.loadNewPosts, i->{ + GlobalUserPreferences.loadNewPosts=i.checked; + showNewPostsButtonItem.enabled = i.checked; + if (!i.checked) { + GlobalUserPreferences.showNewPostsButton = false; + showNewPostsButtonItem.checked = false; + } + if (list.findViewHolderForAdapterPosition(items.indexOf(showNewPostsButtonItem)) instanceof SwitchViewHolder svh) svh.rebind(); + GlobalUserPreferences.save(); + })); + items.add(showNewPostsButtonItem = new SwitchItem(R.string.sk_settings_show_new_posts_button, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.showNewPostsButton, i->{ + GlobalUserPreferences.showNewPostsButton=i.checked; + GlobalUserPreferences.save(); + })); + + items.add(new SwitchItem(R.string.sk_settings_show_alt_indicator, R.drawable.ic_fluent_scan_text_24_regular, GlobalUserPreferences.showAltIndicator, i->{ + GlobalUserPreferences.showAltIndicator=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_settings_show_no_alt_indicator, R.drawable.ic_fluent_important_24_regular, GlobalUserPreferences.showNoAltIndicator, i->{ + GlobalUserPreferences.showNoAltIndicator=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_settings_collapse_long_posts, R.drawable.ic_fluent_chevron_down_24_regular, GlobalUserPreferences.collapseLongPosts, i->{ + GlobalUserPreferences.collapseLongPosts=i.checked; + GlobalUserPreferences.save(); + })); + items.add(new SwitchItem(R.string.sk_settings_hide_fab, R.drawable.ic_fluent_edit_24_regular, GlobalUserPreferences.autoHideFab, i->{ + GlobalUserPreferences.autoHideFab=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_reply_line_above_avatar, R.drawable.ic_fluent_arrow_reply_24_regular, GlobalUserPreferences.replyLineAboveHeader, i->{ + GlobalUserPreferences.replyLineAboveHeader=i.checked; + GlobalUserPreferences.compactReblogReplyLine=i.checked; + compactReblogReplyLineItem.enabled=i.checked; + compactReblogReplyLineItem.checked= GlobalUserPreferences.replyLineAboveHeader; + if (list.findViewHolderForAdapterPosition(items.indexOf(compactReblogReplyLineItem)) instanceof SwitchViewHolder svh) svh.rebind(); + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(compactReblogReplyLineItem=new SwitchItem(R.string.sk_compact_reblog_reply_line, R.drawable.ic_fluent_re_order_24_regular, GlobalUserPreferences.compactReblogReplyLine, i->{ + GlobalUserPreferences.compactReblogReplyLine=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + compactReblogReplyLineItem.enabled=GlobalUserPreferences.replyLineAboveHeader; + items.add(new SwitchItem(R.string.sk_settings_hide_interaction, R.drawable.ic_fluent_eye_24_regular, GlobalUserPreferences.spectatorMode, i->{ + GlobalUserPreferences.spectatorMode=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + } + + private boolean onReplyVisibilityChanged(MenuItem item, Button btn){ + String pref = null; + int id = item.getItemId(); + + if (id == R.id.reply_visibility_following) pref = "following"; + else if (id == R.id.reply_visibility_self) pref = "self"; + + GlobalUserPreferences.replyVisibility=pref; + GlobalUserPreferences.save(); + btn.setText(GlobalUserPreferences.replyVisibility == null ? + R.string.sk_settings_reply_visibility_all : + switch(GlobalUserPreferences.replyVisibility){ + case "following" -> R.string.sk_settings_reply_visibility_following; + case "self" -> R.string.sk_settings_reply_visibility_self; + default -> R.string.sk_settings_reply_visibility_all; + }); + return true; + } +} From 9b11fbbbfe3d7c7b0a8b36a29c6e784cfbeebd33 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 14:45:57 +0200 Subject: [PATCH 06/10] refactor: move notifications to NotificationsFragment --- .../settings/NotificationsFragment.java | 25 +++++++++++++++++++ .../settings/SettingsBaseFragment.java | 2 +- .../settings/SettingsMainFragment.java | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java new file mode 100644 index 000000000..75d9d9326 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java @@ -0,0 +1,25 @@ +package org.joinmastodon.android.fragments.settings; + +import org.joinmastodon.android.R; +import org.joinmastodon.android.model.PushNotification; +import org.joinmastodon.android.model.PushSubscription; + +import java.util.ArrayList; + +public class NotificationsFragment extends SettingsBaseFragment { + @Override + public void addItems(ArrayList items) { + items.add(notificationPolicyItem = new NotificationPolicyItem()); + PushSubscription pushSubscription = getPushSubscription(); + boolean switchEnabled = pushSubscription.policy != PushSubscription.Policy.NONE; + + items.add(new SwitchItem(R.string.notify_favorites, R.drawable.ic_fluent_star_24_regular, pushSubscription.alerts.favourite, i -> onNotificationsChanged(PushNotification.Type.FAVORITE, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.notify_follow, R.drawable.ic_fluent_person_add_24_regular, pushSubscription.alerts.follow, i -> onNotificationsChanged(PushNotification.Type.FOLLOW, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.notify_reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, pushSubscription.alerts.reblog, i -> onNotificationsChanged(PushNotification.Type.REBLOG, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_fluent_mention_24_regular, pushSubscription.alerts.mention, i -> onNotificationsChanged(PushNotification.Type.MENTION, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.sk_notify_posts, R.drawable.ic_fluent_chat_24_regular, pushSubscription.alerts.status, i -> onNotificationsChanged(PushNotification.Type.STATUS, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.sk_notify_update, R.drawable.ic_fluent_history_24_regular, pushSubscription.alerts.update, i -> onNotificationsChanged(PushNotification.Type.UPDATE, i.checked), switchEnabled)); + items.add(new SwitchItem(R.string.sk_notify_poll_results, R.drawable.ic_fluent_poll_24_regular, pushSubscription.alerts.poll, i -> onNotificationsChanged(PushNotification.Type.POLL, i.checked), switchEnabled)); + + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index 4e4d4f6b0..0810cdcf0 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -505,7 +505,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple onNotificationsChanged(value, newState); } index++; - while(items.get(index) instanceof SwitchItem si){ + while(items.size() > index && items.get(index) instanceof SwitchItem si){ si.enabled=si.checked=newState; RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(index); if(holder!=null) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index 64141cca3..d9dad5c5c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -10,5 +10,6 @@ public class SettingsMainFragment extends SettingsBaseFragment{ items.add(new SettingsCategoryItem(R.string.settings_theme, SettingsAppearanceFragment.class, R.drawable.ic_fluent_color_24_regular)); items.add(new SettingsCategoryItem(R.string.settings_behavior, BehaviourFragment.class, R.drawable.ic_fluent_chat_settings_24_regular)); items.add(new SettingsCategoryItem(R.string.sk_timelines, TimeLineFragment.class, R.drawable.ic_fluent_timeline_24_regular)); + items.add(new SettingsCategoryItem(R.string.settings_notifications, NotificationsFragment.class, R.drawable.ic_fluent_alert_28_regular_badged)); } } From aaa80f80f1991a59c879fea3730d8bda7db6defa Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 14:50:00 +0200 Subject: [PATCH 07/10] refactor: move miscellanious settings --- .../fragments/settings/NotificationsFragment.java | 13 +++++++++++++ .../fragments/settings/TimeLineFragment.java | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java index 75d9d9326..6904ac153 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/NotificationsFragment.java @@ -1,5 +1,6 @@ package org.joinmastodon.android.fragments.settings; +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.model.PushNotification; import org.joinmastodon.android.model.PushSubscription; @@ -21,5 +22,17 @@ public class NotificationsFragment extends SettingsBaseFragment { items.add(new SwitchItem(R.string.sk_notify_update, R.drawable.ic_fluent_history_24_regular, pushSubscription.alerts.update, i -> onNotificationsChanged(PushNotification.Type.UPDATE, i.checked), switchEnabled)); items.add(new SwitchItem(R.string.sk_notify_poll_results, R.drawable.ic_fluent_poll_24_regular, pushSubscription.alerts.poll, i -> onNotificationsChanged(PushNotification.Type.POLL, i.checked), switchEnabled)); + items.add(new HeaderItem(R.string.mo_miscellaneous_settings)); + items.add(new SwitchItem(R.string.sk_enable_delete_notifications, R.drawable.ic_fluent_mail_inbox_dismiss_24_regular, GlobalUserPreferences.enableDeleteNotifications, i->{ + GlobalUserPreferences.enableDeleteNotifications=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); + items.add(new SwitchItem(R.string.sk_settings_single_notification, R.drawable.ic_fluent_convert_range_24_regular, GlobalUserPreferences.keepOnlyLatestNotification, i->{ + GlobalUserPreferences.keepOnlyLatestNotification=i.checked; + GlobalUserPreferences.save(); + })); + + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java index 528a06fd3..3ff44655b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/TimeLineFragment.java @@ -100,6 +100,11 @@ public class TimeLineFragment extends SettingsBaseFragment{ GlobalUserPreferences.save(); needAppRestart=true; })); + items.add(new SwitchItem(R.string.mo_disable_dividers, R.drawable.ic_fluent_timeline_24_regular, GlobalUserPreferences.disableDividers, i->{ + GlobalUserPreferences.disableDividers=i.checked; + GlobalUserPreferences.save(); + needAppRestart=true; + })); } private boolean onReplyVisibilityChanged(MenuItem item, Button btn){ From 69420b23993fe45011c13e9eb537d952574375c3 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 15:02:26 +0200 Subject: [PATCH 08/10] refactor: move account and instance setttings to account page --- .../fragments/settings/AccountFragment.java | 122 ++++++++++++++++++ .../settings/SettingsBaseFragment.java | 3 +- .../settings/SettingsMainFragment.java | 1 + 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AccountFragment.java diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AccountFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AccountFragment.java new file mode 100644 index 000000000..fdbe31369 --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AccountFragment.java @@ -0,0 +1,122 @@ +package org.joinmastodon.android.fragments.settings; + +import android.content.Intent; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.Toast; + +import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.MainActivity; +import org.joinmastodon.android.R; +import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken; +import org.joinmastodon.android.api.session.AccountSession; +import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment; +import org.joinmastodon.android.ui.M3AlertDialogBuilder; +import org.joinmastodon.android.ui.utils.UiUtils; +import org.parceler.Parcels; + +import java.util.ArrayList; + +import me.grishka.appkit.Nav; +import me.grishka.appkit.api.Callback; +import me.grishka.appkit.api.ErrorResponse; +import me.grishka.appkit.utils.V; + +public class AccountFragment extends SettingsBaseFragment{ + + + private SwitchItem glitchModeItem; + @Override + public void addItems(ArrayList items) { + items.add(new HeaderItem(R.string.settings_account)); + items.add(new TextItem(R.string.sk_settings_profile, ()-> UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/profile"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.sk_settings_posting, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/preferences/other"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.sk_settings_filters, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/filters"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.sk_settings_auth, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/auth/edit"), R.drawable.ic_fluent_open_24_regular)); + + items.add(new HeaderItem(getInstanceName())); + items.add(new TextItem(R.string.sk_settings_rules, ()->{ + Bundle args=new Bundle(); + args.putParcelable("instance", Parcels.wrap(getInstance())); + Nav.go(getActivity(), InstanceRulesFragment.class, args); + }, R.drawable.ic_fluent_task_list_ltr_24_regular)); + items.add(new TextItem(R.string.sk_settings_about_instance , ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/about"), R.drawable.ic_fluent_info_24_regular)); + items.add(new TextItem(R.string.settings_tos, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.settings_privacy_policy, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.log_out, this::confirmLogOut, R.drawable.ic_fluent_sign_out_24_regular)); + if (!TextUtils.isEmpty(getInstance().version)) items.add(new SmallTextItem(getString(R.string.sk_settings_server_version, getInstance().version))); + + items.add(new HeaderItem(R.string.sk_instance_features)); + items.add(new SwitchItem(R.string.sk_settings_support_local_only, 0, GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID), i->{ + glitchModeItem.enabled = i.checked; + if (i.checked) { + GlobalUserPreferences.accountsWithLocalOnlySupport.add(accountID); + if (getInstance().pleroma == null) GlobalUserPreferences.accountsInGlitchMode.add(accountID); + } else { + GlobalUserPreferences.accountsWithLocalOnlySupport.remove(accountID); + GlobalUserPreferences.accountsInGlitchMode.remove(accountID); + } + glitchModeItem.checked = GlobalUserPreferences.accountsInGlitchMode.contains(accountID); + if (list.findViewHolderForAdapterPosition(items.indexOf(glitchModeItem)) instanceof SwitchViewHolder svh) svh.rebind(); + GlobalUserPreferences.save(); + })); + items.add(new SmallTextItem(getString(R.string.sk_settings_local_only_explanation))); + items.add(glitchModeItem = new SwitchItem(R.string.sk_settings_glitch_instance, 0, GlobalUserPreferences.accountsInGlitchMode.contains(accountID), i->{ + if (i.checked) { + GlobalUserPreferences.accountsInGlitchMode.add(accountID); + } else { + GlobalUserPreferences.accountsInGlitchMode.remove(accountID); + } + GlobalUserPreferences.save(); + })); + glitchModeItem.enabled = GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID); + items.add(new SmallTextItem(getString(R.string.sk_settings_glitch_mode_explanation))); + + + boolean translationAvailable = getInstance().v2 != null && getInstance().v2.configuration.translation != null && getInstance().v2.configuration.translation.enabled; + items.add(new SmallTextItem(getString(translationAvailable ? + R.string.sk_settings_translation_availability_note_available : + R.string.sk_settings_translation_availability_note_unavailable, getInstance().title))); + + } + + private void confirmLogOut(){ + new M3AlertDialogBuilder(getActivity()) + .setTitle(R.string.log_out) + .setMessage(R.string.confirm_log_out) + .setPositiveButton(R.string.log_out, (dialog, which) -> logOut()) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + private void logOut(){ + AccountSession session= AccountSessionManager.getInstance().getAccount(accountID); + new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken) + .setCallback(new Callback<>(){ + @Override + public void onSuccess(Object result){ + onLoggedOut(); + } + + @Override + public void onError(ErrorResponse error){ + onLoggedOut(); + } + }) + .wrapProgress(getActivity(), R.string.loading, false) + .exec(accountID); + } + + private void onLoggedOut(){ + if (getActivity() == null) return; + AccountSessionManager.getInstance().removeAccount(accountID); + getActivity().finish(); + Intent intent=new Intent(getActivity(), MainActivity.class); + startActivity(intent); + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index 0810cdcf0..4260bbf11 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -74,6 +74,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple protected PushSubscription pushSubscription; protected ArrayList items=new ArrayList<>(); protected String accountID; + protected AccountSession session; protected boolean needUpdateNotificationSettings; @@ -87,7 +88,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple setTitle(R.string.settings); accountID=getArguments().getString("account"); - AccountSession session = AccountSessionManager.getInstance().getAccount(accountID); + session = AccountSessionManager.getInstance().getAccount(accountID); instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain); instanceName = UiUtils.getInstanceName(accountID); DomainManager.getInstance().setCurrentDomain(session.domain + "/settings"); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index d9dad5c5c..7a82368f4 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -11,5 +11,6 @@ public class SettingsMainFragment extends SettingsBaseFragment{ items.add(new SettingsCategoryItem(R.string.settings_behavior, BehaviourFragment.class, R.drawable.ic_fluent_chat_settings_24_regular)); items.add(new SettingsCategoryItem(R.string.sk_timelines, TimeLineFragment.class, R.drawable.ic_fluent_timeline_24_regular)); items.add(new SettingsCategoryItem(R.string.settings_notifications, NotificationsFragment.class, R.drawable.ic_fluent_alert_28_regular_badged)); + items.add(new SettingsCategoryItem(R.string.settings_account, AccountFragment.class, R.drawable.ic_fluent_person_28_regular)); } } From 5a5181fde8b79ae17e61180d00351d0cc028e0fb Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 15:10:47 +0200 Subject: [PATCH 09/10] refactor(settings): move about to about page --- .../fragments/settings/AboutFragment.java | 126 ++++++++++++++++++ .../settings/SettingsBaseFragment.java | 4 +- .../settings/SettingsMainFragment.java | 1 + 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java new file mode 100644 index 000000000..c8cdb82bf --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java @@ -0,0 +1,126 @@ +package org.joinmastodon.android.fragments.settings; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.LruCache; +import android.widget.Toast; + +import org.joinmastodon.android.BuildConfig; +import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.MainActivity; +import org.joinmastodon.android.R; +import org.joinmastodon.android.api.MastodonAPIController; +import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken; +import org.joinmastodon.android.api.session.AccountActivationInfo; +import org.joinmastodon.android.api.session.AccountSession; +import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.fragments.onboarding.AccountActivationFragment; +import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment; +import org.joinmastodon.android.ui.M3AlertDialogBuilder; +import org.joinmastodon.android.ui.utils.UiUtils; +import org.joinmastodon.android.updater.GithubSelfUpdater; +import org.parceler.Parcels; + +import java.util.ArrayList; + +import me.grishka.appkit.Nav; +import me.grishka.appkit.api.Callback; +import me.grishka.appkit.api.ErrorResponse; +import me.grishka.appkit.imageloader.ImageCache; + +public class AboutFragment extends SettingsBaseFragment{ + + private TextItem checkForUpdateItem, clearImageCacheItem; + private ImageCache imageCache; + @Override + public void addItems(ArrayList items) { + items.add(new HeaderItem(R.string.sk_settings_about)); + +// if(BuildConfig.BUILD_TYPE.equals("nightly")){ +// items.add(new TextItem(R.string.mo_download_latest_nightly_release, ()->UiUtils.launchWebBrowser(getActivity(), "https://nightly.link/LucasGGamerM/moshidon/workflows/nightly-builds/master/moshidon-nightly.apk.zip"), R.drawable.ic_fluent_open_24_regular)); +// } + + items.add(new TextItem(R.string.mo_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/LucasGGamerM/moshidon"), R.drawable.ic_fluent_open_24_regular)); + items.add(new TextItem(R.string.sk_settings_donate, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sponsors/LucasGGamerM"), R.drawable.ic_fluent_heart_24_regular)); + + if (GithubSelfUpdater.needSelfUpdating()) { + checkForUpdateItem = new TextItem(R.string.sk_check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates); + items.add(checkForUpdateItem); + items.add(new SwitchItem(R.string.sk_updater_enable_pre_releases, 0, GlobalUserPreferences.enablePreReleases, i->{ + GlobalUserPreferences.enablePreReleases=i.checked; + GlobalUserPreferences.save(); + })); + } + + LruCache cache = imageCache == null ? null : imageCache.getLruCache(); + clearImageCacheItem = new TextItem(R.string.settings_clear_cache, UiUtils.formatFileSize(getContext(), cache != null ? cache.size() : 0, true), this::clearImageCache, 0); + items.add(clearImageCacheItem); + items.add(new TextItem(R.string.sk_clear_recent_languages, ()->UiUtils.showConfirmationAlert(getActivity(), R.string.sk_clear_recent_languages, R.string.sk_confirm_clear_recent_languages, R.string.clear, ()->{ + GlobalUserPreferences.recentLanguages.remove(accountID); + GlobalUserPreferences.save(); + }))); + + items.add(new TextItem(R.string.mo_clear_recent_emoji, ()-> { + GlobalUserPreferences.recentEmojis.clear(); + GlobalUserPreferences.save(); + })); + + if(BuildConfig.DEBUG){ + items.add(new HeaderItem("Debug options")); + + items.add(new TextItem("Test E-Mail confirmation flow", ()->{ + AccountSession sess=AccountSessionManager.getInstance().getAccount(accountID); + sess.activated=false; + sess.activationInfo=new AccountActivationInfo("test@email", System.currentTimeMillis()); + Bundle args=new Bundle(); + args.putString("account", accountID); + args.putBoolean("debug", true); + Nav.goClearingStack(getActivity(), AccountActivationFragment.class, args); + })); + + items.add(new TextItem("Copy preferences", ()->{ + StringBuilder prefBuilder = new StringBuilder(); + GlobalUserPreferences.load(); + GlobalUserPreferences.getPrefs().getAll().forEach((key, value) -> prefBuilder.append(key).append(": ").append(value).append('\n')); + UiUtils.copyText(view, prefBuilder.toString()); + })); + + items.add(new TextItem("Reset preferences", ()->{ + GlobalUserPreferences.load(); + GlobalUserPreferences.getPrefs().edit().clear().commit(); + UiUtils.restartApp(); + }, R.drawable.ic_fluent_warning_24_regular)); + + items.add(new TextItem("Open App Info", () -> + getContext().startActivity(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + .setData(Uri.fromParts("package", getContext().getPackageName(), null))), + R.drawable.ic_fluent_open_24_regular + ) + ); + + items.add(new TextItem("Open developer settings", + ()-> getContext().startActivity(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)), + R.drawable.ic_fluent_open_24_regular) + ); + } + + String version = getContext().getString(R.string.mo_settings_app_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE); + items.add(new FooterItem(version, () -> UiUtils.copyText(view, version))); + } + + private void clearImageCache(){ + MastodonAPIController.runInBackground(()->{ + Activity activity=getActivity(); + imageCache.clear(); + Toast.makeText(activity, R.string.media_cache_cleared, Toast.LENGTH_SHORT).show(); + }); + if (list.findViewHolderForAdapterPosition(items.indexOf(clearImageCacheItem)) instanceof TextViewHolder tvh) { + clearImageCacheItem.secondaryText = UiUtils.formatFileSize(getContext(), 0, true); + tvh.rebind(); + } + } +} diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index 4260bbf11..a31cac8b1 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -246,7 +246,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple protected class TextItem extends Item{ private String text; - private String secondaryText; + protected String secondaryText; private Runnable onClick; private boolean loading; private int icon; @@ -689,7 +689,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } - private class TextViewHolder extends BindableViewHolder implements UsableRecyclerView.Clickable{ + protected class TextViewHolder extends BindableViewHolder implements UsableRecyclerView.Clickable{ private final TextView text, secondaryText; private final ProgressBar progress; private final ImageView icon; diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java index 7a82368f4..eb3ef9f67 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsMainFragment.java @@ -12,5 +12,6 @@ public class SettingsMainFragment extends SettingsBaseFragment{ items.add(new SettingsCategoryItem(R.string.sk_timelines, TimeLineFragment.class, R.drawable.ic_fluent_timeline_24_regular)); items.add(new SettingsCategoryItem(R.string.settings_notifications, NotificationsFragment.class, R.drawable.ic_fluent_alert_28_regular_badged)); items.add(new SettingsCategoryItem(R.string.settings_account, AccountFragment.class, R.drawable.ic_fluent_person_28_regular)); + items.add(new SettingsCategoryItem(R.string.sk_settings_about, AboutFragment.class, R.drawable.ic_fluent_info_24_regular)); } } From cdeeb24eac998c28370b2af101398d4398eee6b4 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Sun, 23 Apr 2023 15:20:57 +0200 Subject: [PATCH 10/10] refactor(settings): add red header item --- .../fragments/settings/AboutFragment.java | 6 +--- .../settings/SettingsBaseFragment.java | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java index c8cdb82bf..e902d8d7c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/AboutFragment.java @@ -40,10 +40,6 @@ public class AboutFragment extends SettingsBaseFragment{ public void addItems(ArrayList items) { items.add(new HeaderItem(R.string.sk_settings_about)); -// if(BuildConfig.BUILD_TYPE.equals("nightly")){ -// items.add(new TextItem(R.string.mo_download_latest_nightly_release, ()->UiUtils.launchWebBrowser(getActivity(), "https://nightly.link/LucasGGamerM/moshidon/workflows/nightly-builds/master/moshidon-nightly.apk.zip"), R.drawable.ic_fluent_open_24_regular)); -// } - items.add(new TextItem(R.string.mo_settings_contribute, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/LucasGGamerM/moshidon"), R.drawable.ic_fluent_open_24_regular)); items.add(new TextItem(R.string.sk_settings_donate, ()->UiUtils.launchWebBrowser(getActivity(), "https://github.com/sponsors/LucasGGamerM"), R.drawable.ic_fluent_heart_24_regular)); @@ -70,7 +66,7 @@ public class AboutFragment extends SettingsBaseFragment{ })); if(BuildConfig.DEBUG){ - items.add(new HeaderItem("Debug options")); + items.add(new RedHeaderItem("Debug options")); items.add(new TextItem("Test E-Mail confirmation flow", ()->{ AccountSession sess=AccountSessionManager.getInstance().getAccount(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index a31cac8b1..efb29350a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -161,6 +161,23 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple } } + protected class RedHeaderItem extends HeaderItem { + + public RedHeaderItem(int text){ + super(text); + } + + public RedHeaderItem(String text){ + super(text); + } + + @Override + public int getViewType(){ + return Type.RED_HEADER.ordinal(); + } + } + + protected class SwitchItem extends Item{ private String text; private int icon; @@ -329,6 +346,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple public enum Type{ HEADER, + RED_HEADER, SWITCH, THEME, TEXT, @@ -337,7 +355,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple BUTTON, SMALL_TEXT, UPDATER, - SETTINGS_CATEGORY + SETTINGS_CATEGORY; } @@ -349,6 +367,7 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple //noinspection unchecked return (BindableViewHolder) switch(Type.values()[viewType]){ case HEADER -> new HeaderViewHolder(); + case RED_HEADER -> new HeaderViewHolder(true); case SWITCH -> new SwitchViewHolder(); case THEME -> new ThemeViewHolder(); case TEXT -> new TextViewHolder(); @@ -384,6 +403,13 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple text=(TextView) itemView; } + public HeaderViewHolder(boolean red){ + super(getActivity(), R.layout.item_settings_header, list); + text=(TextView) itemView; + if(red) + text.setTextColor(getResources().getColor(UiUtils.isDarkTheme() ? R.color.error_400 : R.color.error_700)); + } + @Override public void onBind(HeaderItem item){ text.setText(item.text);