From 1e825c979c92b4a7f6c5efd1a23dc1eadf637198 Mon Sep 17 00:00:00 2001 From: sk Date: Sun, 22 Jan 2023 00:43:17 +0100 Subject: [PATCH] rearrange home menus --- .../fragments/AnnouncementsFragment.java | 10 +- .../android/fragments/HomeTabFragment.java | 259 ++++++++++-------- .../android/ui/utils/UiUtils.java | 2 +- mastodon/src/main/res/layout/home_toolbar.xml | 2 + mastodon/src/main/res/menu/home.xml | 53 +++- mastodon/src/main/res/values/ids.xml | 1 + mastodon/src/main/res/values/strings_sk.xml | 2 +- 7 files changed, 191 insertions(+), 138 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java index 385d3464c..a945bf453 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/AnnouncementsFragment.java @@ -77,12 +77,7 @@ public class AnnouncementsFragment extends BaseStatusListFragment public void onMarkAsRead(String id) { if (unreadIDs == null) return; unreadIDs.remove(id); - if (unreadIDs.size() == 0) setResult(true, null); - } - - @Override - public void onDestroy() { - super.onDestroy(); + if (unreadIDs.isEmpty()) setResult(true, null); } @Override @@ -101,7 +96,8 @@ public class AnnouncementsFragment extends BaseStatusListFragment List read = result.stream().filter(a -> a.read).collect(toList()); onDataLoaded(unread, true); onDataLoaded(read, false); - unreadIDs = unread.stream().map(a -> a.id).collect(toList()); + if (unread.isEmpty()) setResult(true, null); + else unreadIDs = unread.stream().map(a -> a.id).collect(toList()); } }) .exec(accountID); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java index fa7506246..bed7c797a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HomeTabFragment.java @@ -9,6 +9,7 @@ import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.Context; +import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; @@ -49,7 +50,6 @@ import org.joinmastodon.android.ui.SimpleViewHolder; import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.updater.GithubSelfUpdater; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -66,7 +66,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab private static final int ANNOUNCEMENTS_RESULT = 654; private String accountID; - private MenuItem announcements; + private MenuItem announcements, announcementsAction, settings, settingsAction; // private ImageView toolbarLogo; private Button toolbarShowNewPostsBtn; private boolean newPostsBtnShown; @@ -86,6 +86,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab private FrameLayout[] tabViews; private TimelineDefinition[] timelines; private final Map timelinesByMenuItem = new HashMap<>(); + private SubMenu hashtagsMenu, listsMenu; + private Menu optionsMenu; + private MenuInflater optionsMenuInflater; + private boolean announcementsBadged, settingsBadged; @Override public void onCreate(Bundle savedInstanceState) { @@ -155,15 +159,9 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab switcherPopup = new PopupMenu(getContext(), switcher); switcherPopup.setOnMenuItemClickListener(this::onSwitcherItemSelected); UiUtils.enablePopupMenuIcons(getContext(), switcherPopup); - switcher.setOnClickListener(v->{ - updateSwitcherMenu(); - switcherPopup.show(); - }); - View.OnTouchListener listener = switcherPopup.getDragToOpenListener(); - switcher.setOnTouchListener((v, m)-> { - updateSwitcherMenu(); - return listener.onTouch(v, m); - }); + switcher.setOnClickListener(v->switcherPopup.show()); + switcher.setOnTouchListener(switcherPopup.getDragToOpenListener()); + updateSwitcherMenu(); UiUtils.reduceSwipeSensitivity(pager); pager.setUserInputEnabled(!GlobalUserPreferences.disableSwipe); @@ -191,34 +189,60 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab updateToolbarLogo(); + ViewTreeObserver vto = getToolbar().getViewTreeObserver(); + if (vto.isAlive()) { + vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + Toolbar t = getToolbar(); + if (t == null) return; + int toolbarWidth = t.getWidth(); + if (toolbarWidth == 0) return; + + int toolbarFrameWidth = toolbarFrame.getWidth(); + int padding = toolbarWidth - toolbarFrameWidth; + FrameLayout parent = ((FrameLayout) toolbarShowNewPostsBtn.getParent()); + if (padding == parent.getPaddingStart()) return; + + // toolbar frame goes from screen edge to beginning of right-aligned option buttons. + // centering button by applying the same space on the left + parent.setPaddingRelative(padding, 0, 0, 0); + toolbarShowNewPostsBtn.setMaxWidth(toolbarWidth - padding * 2); + + switcher.setPivotX(V.dp(28)); // padding + half of icon + switcher.setPivotY(switcher.getHeight() / 2f); + } + }); + } + if(GithubSelfUpdater.needSelfUpdating()){ E.register(this); updateUpdateState(GithubSelfUpdater.getInstance().getState()); } + } - new GetLists().setCallback(new Callback<>() { - @Override - public void onSuccess(List lists) { - addItemsToMap(lists, listItems); - } + private void addListsToOptionsMenu() { + Context ctx = getContext(); + listsMenu.clear(); + listsMenu.getItem().setVisible(listItems.size() > 0); + UiUtils.insetPopupMenuIcon(ctx, UiUtils.makeBackItem(listsMenu)); + listItems.forEach((id, list) -> { + MenuItem item = listsMenu.add(Menu.NONE, id, Menu.NONE, list.title); + item.setIcon(R.drawable.ic_fluent_people_list_24_regular); + UiUtils.insetPopupMenuIcon(ctx, item); + }); + } - @Override - public void onError(ErrorResponse error) { - error.showToast(getContext()); - } - }).exec(accountID); - - new GetFollowedHashtags().setCallback(new Callback<>() { - @Override - public void onSuccess(HeaderPaginationList hashtags) { - addItemsToMap(hashtags, hashtagsItems); - } - - @Override - public void onError(ErrorResponse error) { - error.showToast(getContext()); - } - }).exec(accountID); + private void addHashtagsToOptionsMenu() { + Context ctx = getContext(); + hashtagsMenu.clear(); + hashtagsMenu.getItem().setVisible(hashtagsItems.size() > 0); + UiUtils.insetPopupMenuIcon(ctx, UiUtils.makeBackItem(hashtagsMenu)); + hashtagsItems.forEach((id, hashtag) -> { + MenuItem item = hashtagsMenu.add(Menu.NONE, id, Menu.NONE, hashtag.name); + item.setIcon(R.drawable.ic_fluent_number_symbol_24_regular); + UiUtils.insetPopupMenuIcon(ctx, item); + }); } public void updateToolbarLogo(){ @@ -258,43 +282,70 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab toolbarShowNewPostsBtn.setScaleY(.8f); timelineTitle.setVisibility(View.VISIBLE); } + } - ViewTreeObserver vto = toolbar.getViewTreeObserver(); - if (vto.isAlive()) { - vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - Toolbar t = getToolbar(); - if (t == null) return; - int toolbarWidth = t.getWidth(); - if (toolbarWidth == 0) return; - t.getViewTreeObserver().removeOnGlobalLayoutListener(this); + private void createOptionsMenu() { + optionsMenu.clear(); + optionsMenuInflater.inflate(R.menu.home, optionsMenu); + announcements = optionsMenu.findItem(R.id.announcements); + announcementsAction = optionsMenu.findItem(R.id.announcements_action); + settings = optionsMenu.findItem(R.id.settings); + settingsAction = optionsMenu.findItem(R.id.settings_action); + hashtagsMenu = optionsMenu.findItem(R.id.hashtags).getSubMenu(); + listsMenu = optionsMenu.findItem(R.id.lists).getSubMenu(); - int toolbarFrameWidth = toolbarFrame.getWidth(); - int padding = toolbarWidth - toolbarFrameWidth; - // toolbar frame goes from screen edge to beginning of right-aligned option buttons. - // centering button by applying the same space on the left - ((FrameLayout) toolbarShowNewPostsBtn.getParent()).setPaddingRelative(padding, 0, 0, 0); - toolbarShowNewPostsBtn.setMaxWidth(toolbarWidth - padding * 2); + announcements.setVisible(!announcementsBadged); + announcementsAction.setVisible(announcementsBadged); + settings.setVisible(!settingsBadged); + settingsAction.setVisible(settingsBadged); - switcher.setPivotX(V.dp(28)); // padding + half of icon - switcher.setPivotY(switcher.getHeight() / 2f); - } - }); - } + UiUtils.enableOptionsMenuIcons(getContext(), optionsMenu, + R.id.overflow, R.id.announcements_action, R.id.settings_action); + + addListsToOptionsMenu(); + addHashtagsToOptionsMenu(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ - inflater.inflate(R.menu.home, menu); - announcements = menu.findItem(R.id.announcements); + this.optionsMenu = menu; + this.optionsMenuInflater = inflater; + createOptionsMenu(); + + new GetLists().setCallback(new Callback<>() { + @Override + public void onSuccess(List lists) { + updateList(lists, listItems); + addListsToOptionsMenu(); + } + + @Override + public void onError(ErrorResponse error) { + error.showToast(getContext()); + } + }).exec(accountID); + + new GetFollowedHashtags().setCallback(new Callback<>() { + @Override + public void onSuccess(HeaderPaginationList hashtags) { + updateList(hashtags, hashtagsItems); + addHashtagsToOptionsMenu(); + } + + @Override + public void onError(ErrorResponse error) { + error.showToast(getContext()); + } + }).exec(accountID); new GetAnnouncements(false).setCallback(new Callback<>() { @Override public void onSuccess(List result) { - boolean hasUnread = result.stream().anyMatch(a -> !a.read); - announcements.setIcon(hasUnread ? R.drawable.ic_announcements_24_badged : R.drawable.ic_fluent_megaphone_24_regular); - updateBadgedOptionsItem(announcements, hasUnread); + if (result.stream().anyMatch(a -> !a.read)) { + announcementsBadged = true; + announcements.setVisible(false); + announcementsAction.setVisible(true); + } } @Override @@ -302,27 +353,14 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab error.showToast(getActivity()); } }).exec(accountID); - - UiUtils.enableOptionsMenuIcons(getContext(), menu); } - private void updateBadgedOptionsItem(MenuItem item, boolean asAction) { - item.setShowAsAction(asAction ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER); - if (asAction) { - UiUtils.resetPopupItemTint(item); - } else { - UiUtils.insetPopupMenuIcon(getContext(), item); - } - } - - private void addItemsToMap(List addItems, Map items) { + private void updateList(List addItems, Map items) { if (addItems.size() == 0) return; for (int i = 0; i < addItems.size(); i++) items.put(View.generateViewId(), addItems.get(i)); - updateSwitcherMenu(); } private void updateSwitcherMenu() { - Context context = getContext(); Menu switcherMenu = switcherPopup.getMenu(); switcherMenu.clear(); timelinesByMenuItem.clear(); @@ -332,40 +370,16 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab timelinesByMenuItem.put(menuItemId, tl); MenuItem item = switcherMenu.add(0, menuItemId, 0, tl.getTitle(getContext())); item.setIcon(tl.getIcon().iconRes); - UiUtils.insetPopupMenuIcon(getContext(), item); } - if (!listItems.isEmpty()) { - SubMenu listsMenu = switcherMenu.addSubMenu(R.string.sk_list_timelines); - UiUtils.insetPopupMenuIcon(context, listsMenu.getItem().setVisible(true) - .setIcon(R.drawable.ic_fluent_people_list_24_regular)); - listsMenu.clear(); - UiUtils.insetPopupMenuIcon(context, UiUtils.makeBackItem(listsMenu)); - listItems.forEach((id, list) -> { - MenuItem item = listsMenu.add(Menu.NONE, id, Menu.NONE, list.title); - item.setIcon(R.drawable.ic_fluent_people_list_24_regular); - UiUtils.insetPopupMenuIcon(context, item); - }); - } + switcherMenu.add(0, R.id.menu_edit, Menu.NONE, R.string.sk_edit_timelines) + .setIcon(R.drawable.ic_fluent_edit_24_regular); - if (!hashtagsItems.isEmpty()) { - SubMenu hashtagsMenu = switcherMenu.addSubMenu(R.string.sk_hashtags_you_follow); - UiUtils.insetPopupMenuIcon(context, hashtagsMenu.getItem().setVisible(true) - .setIcon(R.drawable.ic_fluent_number_symbol_24_regular)); - hashtagsMenu.clear(); - UiUtils.insetPopupMenuIcon(context, UiUtils.makeBackItem(hashtagsMenu)); - hashtagsItems.forEach((id, hashtag) -> { - MenuItem item = hashtagsMenu.add(Menu.NONE, id, Menu.NONE, hashtag.name); - item.setIcon(R.drawable.ic_fluent_number_symbol_24_regular); - UiUtils.insetPopupMenuIcon(context, item); - }); - } + UiUtils.enablePopupMenuIcons(getContext(), switcherPopup); } private boolean onSwitcherItemSelected(MenuItem item) { int id = item.getItemId(); - ListTimeline list; - Hashtag hashtag; Bundle args = new Bundle(); args.putString("account", accountID); @@ -373,15 +387,8 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab if (id == R.id.menu_back) { switcher.post(() -> switcherPopup.show()); return true; - } else if ((list = listItems.get(id)) != null) { - args.putString("listID", list.id); - args.putString("listTitle", list.title); - args.putInt("repliesPolicy", list.repliesPolicy.ordinal()); - Nav.go(getActivity(), ListTimelineFragment.class, args); - } else if ((hashtag = hashtagsItems.get(id)) != null) { - args.putString("hashtag", hashtag.name); - args.putBoolean("following", hashtag.following); - Nav.go(getActivity(), HashtagTimelineFragment.class, args); + } else if (id == R.id.menu_edit) { + Nav.go(getActivity(), EditTimelinesFragment.class, args); } else { TimelineDefinition tl = timelinesByMenuItem.get(id); if (tl != null) { @@ -414,12 +421,26 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab Bundle args=new Bundle(); args.putString("account", accountID); int id = item.getItemId(); - if (id == R.id.settings) { + ListTimeline list; + Hashtag hashtag; + + if (item.getItemId() == R.id.menu_back) { + createOptionsMenu(); + optionsMenu.performIdentifierAction(R.id.overflow, 0); + return true; + } else if (id == R.id.settings || id == R.id.settings_action) { Nav.go(getActivity(), SettingsFragment.class, args); - } else if (id == R.id.announcements) { + } else if (id == R.id.announcements || id == R.id.announcements_action) { Nav.goForResult(getActivity(), AnnouncementsFragment.class, args, ANNOUNCEMENTS_RESULT, this); - } else if (id == R.id.edit_timelines) { - Nav.go(getActivity(), EditTimelinesFragment.class, args); + } else if ((list = listItems.get(id)) != null) { + args.putString("listID", list.id); + args.putString("listTitle", list.title); + args.putInt("repliesPolicy", list.repliesPolicy.ordinal()); + Nav.go(getActivity(), ListTimelineFragment.class, args); + } else if ((hashtag = hashtagsItems.get(id)) != null) { + args.putString("hashtag", hashtag.name); + args.putBoolean("following", hashtag.following); + Nav.go(getActivity(), HashtagTimelineFragment.class, args); } return true; } @@ -507,17 +528,17 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab @Override public void onFragmentResult(int reqCode, boolean success, Bundle result){ if (reqCode == ANNOUNCEMENTS_RESULT && success) { - announcements.setIcon(R.drawable.ic_fluent_megaphone_24_regular); - announcements.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - UiUtils.insetPopupMenuIcon(getContext(), announcements); + announcementsBadged = false; + announcements.setVisible(true); + announcementsAction.setVisible(false); } } private void updateUpdateState(GithubSelfUpdater.UpdateState state){ if(state!=GithubSelfUpdater.UpdateState.NO_UPDATE && state!=GithubSelfUpdater.UpdateState.CHECKING) { - MenuItem settings = getToolbar().getMenu().findItem(R.id.settings); - settings.setIcon(R.drawable.ic_settings_24_badged); - updateBadgedOptionsItem(settings, true); + settingsBadged = true; + settingsAction.setVisible(true); + settings.setVisible(false); } } 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 e43b2aeeb..ee216a4d5 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 @@ -908,7 +908,7 @@ public class UiUtils{ public static MenuItem makeBackItem(Menu m) { MenuItem back = m.add(0, R.id.menu_back, NONE, R.string.back); - back.setIcon(R.drawable.ic_arrow_back); + back.setIcon(R.drawable.ic_fluent_arrow_left_24_regular); return back; } diff --git a/mastodon/src/main/res/layout/home_toolbar.xml b/mastodon/src/main/res/layout/home_toolbar.xml index 8b5af9473..a9d5b2b91 100644 --- a/mastodon/src/main/res/layout/home_toolbar.xml +++ b/mastodon/src/main/res/layout/home_toolbar.xml @@ -47,6 +47,8 @@ android:layout_height="wrap_content" android:paddingVertical="2dp" android:minHeight="32sp" + android:maxLines="2" + android:ellipsize="end" android:lineSpacingMultiplier="0.8" android:textAppearance="@style/m3_title_medium" android:text="@string/see_new_posts" diff --git a/mastodon/src/main/res/menu/home.xml b/mastodon/src/main/res/menu/home.xml index f55f48e12..3ebc28150 100644 --- a/mastodon/src/main/res/menu/home.xml +++ b/mastodon/src/main/res/menu/home.xml @@ -1,15 +1,48 @@ - + + android:id="@+id/announcements_action" + android:icon="@drawable/ic_announcements_24_badged" + android:title="@string/sk_announcements" + android:visible="false" + android:showAsAction="always" /> + android:id="@+id/settings_action" + android:icon="@drawable/ic_settings_24_badged" + android:title="@string/settings" + android:visible="false" + android:showAsAction="always" /> + android:id="@+id/overflow" + android:title="@string/more_options" + android:icon="@drawable/ic_fluent_more_vertical_24_regular" + android:showAsAction="always"> + + + + + + + + + + + \ No newline at end of file diff --git a/mastodon/src/main/res/values/ids.xml b/mastodon/src/main/res/values/ids.xml index 6994f851b..8947f97b8 100644 --- a/mastodon/src/main/res/values/ids.xml +++ b/mastodon/src/main/res/values/ids.xml @@ -21,4 +21,5 @@ + \ No newline at end of file diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index ef445cee2..db16b5cfe 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -169,7 +169,7 @@ Heart Star Edit timeline - Edit timelines + Edit timelines… ALT edited Edited posts