From f976b6dd72f6ad812fac341438a0bf24401bec1b Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 31 Dec 2022 18:12:31 +0100 Subject: [PATCH] Add Bubble timeline support --- .../endpoints/MastodonTimelinesService.java | 13 +++ .../android/client/entities/app/Timeline.java | 2 + .../android/helper/PinnedTimelineHelper.java | 92 +++++++------------ .../android/ui/drawer/ReorderTabAdapter.java | 4 + .../timeline/FragmentMastodonTimeline.java | 10 +- .../viewmodel/mastodon/TimelinesVM.java | 6 ++ .../drawable/ic_baseline_bubble_chart_24.xml | 16 ++++ app/src/main/res/values/strings.xml | 1 + 8 files changed, 84 insertions(+), 60 deletions(-) create mode 100644 app/src/main/res/drawable/ic_baseline_bubble_chart_24.xml diff --git a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonTimelinesService.java b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonTimelinesService.java index 619bc92a7..a2c953dbb 100644 --- a/app/src/main/java/app/fedilab/android/client/endpoints/MastodonTimelinesService.java +++ b/app/src/main/java/app/fedilab/android/client/endpoints/MastodonTimelinesService.java @@ -53,6 +53,19 @@ public interface MastodonTimelinesService { @Query("limit") Integer limit ); + @GET("timelines/bubble") + Call> getBubble( + @Header("Authorization") String token, + @Query("only_media") Boolean only_media, + @Query("remote") Boolean remote, + @Query("with_muted") Boolean with_muted, + @Query("exclude_visibilities") List exclude_visibilities, + @Query("reply_visibility") String reply_visibility, + @Query("max_id") String max_id, + @Query("since_id") String since_id, + @Query("min_id") String min_id, + @Query("limit") Integer limit + ); @GET("trends/statuses") Call> getStatusTrends( diff --git a/app/src/main/java/app/fedilab/android/client/entities/app/Timeline.java b/app/src/main/java/app/fedilab/android/client/entities/app/Timeline.java index 109a8790f..e3c5fa665 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/app/Timeline.java +++ b/app/src/main/java/app/fedilab/android/client/entities/app/Timeline.java @@ -364,6 +364,8 @@ public class Timeline { LOCAL("LOCAL"), @SerializedName("PUBLIC") PUBLIC("PUBLIC"), + @SerializedName("BUBBLE") + BUBBLE("BUBBLE"), @SerializedName("CONTEXT") CONTEXT("CONTEXT"), @SerializedName("TAG") diff --git a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java index e39da3142..2deefd41c 100644 --- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java @@ -22,7 +22,6 @@ import static app.fedilab.android.BaseMainActivity.show_replies; import static app.fedilab.android.ui.pageadapter.FedilabPageAdapter.BOTTOM_TIMELINE_COUNT; import android.annotation.SuppressLint; -import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; import android.text.Editable; @@ -57,6 +56,7 @@ import java.util.regex.Pattern; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; +import app.fedilab.android.activities.MainActivity; import app.fedilab.android.client.entities.api.MastodonList; import app.fedilab.android.client.entities.app.BottomMenu; import app.fedilab.android.client.entities.app.Pinned; @@ -94,59 +94,6 @@ public class PinnedTimelineHelper { } - /** - * Returns the slug of the first loaded fragment - * - * @param context - Context - * @param pinned - {@link Pinned} - * @param bottomMenu - {@link BottomMenu} - * @return String - slug - */ - public static String firstTimelineSlug(Context context, Pinned pinned, BottomMenu bottomMenu) { - String slug = Timeline.TimeLineEnum.HOME.getValue(); - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - boolean singleBar = sharedpreferences.getBoolean(context.getString(R.string.SET_USE_SINGLE_TOPBAR), false); - PinnedTimeline pinnedTimelineMin = null; - if (singleBar) { - if (pinned != null && pinned.pinnedTimelines != null) { - for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { - if (pinnedTimeline.displayed) { - if (pinnedTimelineMin == null) { - pinnedTimelineMin = pinnedTimeline; - } else if (pinnedTimelineMin.position > pinnedTimeline.position) { - pinnedTimelineMin = pinnedTimeline; - } - } - } - } - } else { - if (bottomMenu != null && bottomMenu.bottom_menu != null && bottomMenu.bottom_menu.size() > 0) { - BottomMenu.MenuItem menuItem = bottomMenu.bottom_menu.get(0); - return menuItem.item_menu_type.getValue(); - } - - } - String ident = null; - if (pinnedTimelineMin != null) { - if (pinnedTimelineMin.tagTimeline != null) { - ident = "@T@" + pinnedTimelineMin.tagTimeline.name; - if (pinnedTimelineMin.tagTimeline.isART) { - pinnedTimelineMin.type = Timeline.TimeLineEnum.ART; - } - } else if (pinnedTimelineMin.mastodonList != null) { - ident = "@l@" + pinnedTimelineMin.mastodonList.id; - } else if (pinnedTimelineMin.remoteInstance != null) { - if (pinnedTimelineMin.remoteInstance.type == RemoteInstance.InstanceType.NITTER) { - String remoteInstance = sharedpreferences.getString(context.getString(R.string.SET_NITTER_HOST), context.getString(R.string.DEFAULT_NITTER_HOST)).toLowerCase(); - ident = "@R@" + remoteInstance; - } else { - ident = "@R@" + pinnedTimelineMin.remoteInstance.host; - } - } - slug = pinnedTimelineMin.type.getValue() + (ident != null ? "|" + ident : ""); - } - return slug; - } public synchronized static void redrawTopBarPinned(BaseMainActivity activity, ActivityMainBinding activityMainBinding, Pinned pinned, BottomMenu bottomMenu, List mastodonLists) { //Values must be initialized if there is no records in db @@ -159,8 +106,8 @@ public class PinnedTimelineHelper { pinned.pinnedTimelines = new ArrayList<>(); } //Set the slug of first visible fragment - String slugOfFirstFragment = PinnedTimelineHelper.firstTimelineSlug(activity, pinned, bottomMenu); - Helper.setSlugOfFirstFragment(activity, slugOfFirstFragment, currentUserID, currentInstance); + /*String slugOfFirstFragment = PinnedTimelineHelper.firstTimelineSlug(activity, pinned, bottomMenu); + Helper.setSlugOfFirstFragment(activity, slugOfFirstFragment, currentUserID, currentInstance);*/ SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity); boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false); @@ -187,6 +134,7 @@ public class PinnedTimelineHelper { activityMainBinding.viewPager.setLayoutParams(params); List pinnedTimelines = pinned.pinnedTimelines; + boolean extraFeatures = sharedpreferences.getBoolean(activity.getString(R.string.SET_EXTAND_EXTRA_FEATURES) + MainActivity.currentUserID + MainActivity.currentInstance, false); if (singleBar) { boolean createDefaultAtTop = true; @@ -222,15 +170,40 @@ public class PinnedTimelineHelper { pinnedTimelineConversations.type = Timeline.TimeLineEnum.DIRECT; pinnedTimelineConversations.position = 4; pinned.pinnedTimelines.add(pinnedTimelineConversations); - try { new Pinned(activity).updatePinned(pinned); } catch (DBException e) { e.printStackTrace(); } } - } + if (extraFeatures) { + try { + Pinned pinnedAll = new Pinned(activity).getAllPinned(currentAccount); + boolean createDefaultBubbleAtTop = true; + for (PinnedTimeline pinnedTimeline : pinnedAll.pinnedTimelines) { + if (pinnedTimeline.type == Timeline.TimeLineEnum.BUBBLE) { + createDefaultBubbleAtTop = false; + break; + } + } + if (createDefaultBubbleAtTop) { + PinnedTimeline pinnedTimelineBubble = new PinnedTimeline(); + pinnedTimelineBubble.type = Timeline.TimeLineEnum.BUBBLE; + pinnedTimelineBubble.position = pinnedAll.pinnedTimelines != null ? pinnedAll.pinnedTimelines.size() : 0; + pinned.pinnedTimelines.add(pinnedTimelineBubble); + boolean exist = new Pinned(activity).pinnedExist(pinned); + if (exist) { + new Pinned(activity).updatePinned(pinned); + } else { + new Pinned(activity).insertPinned(pinned); + } + } + } catch (DBException e) { + e.printStackTrace(); + } + } + sortPositionAsc(pinnedTimelines); //Check if changes occurred, if mastodonLists is null it does need, because it is the first call to draw pinned boolean needRedraw = mastodonLists == null; @@ -421,6 +394,9 @@ public class PinnedTimelineHelper { case DIRECT: tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_mail_24); break; + case BUBBLE: + tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_bubble_chart_24); + break; } tab.setCustomView(tabCustomDefaultViewBinding.getRoot()); } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java index 7665ca4e5..d23cb7a23 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ReorderTabAdapter.java @@ -141,6 +141,10 @@ public class ReorderTabAdapter extends RecyclerView.Adapter all; public List any; @@ -961,6 +965,8 @@ public class TimelinesVM extends AndroidViewModel { public int limit = 40; public Boolean local; public List excludeType; + public List excludeVisibilities; + public String replyVisibility; public TimelineParams(@NonNull Timeline.TimeLineEnum timeLineEnum, @Nullable FragmentMastodonTimeline.DIRECTION timelineDirection, @Nullable String ident) { if (type != Timeline.TimeLineEnum.REMOTE) { diff --git a/app/src/main/res/drawable/ic_baseline_bubble_chart_24.xml b/app/src/main/res/drawable/ic_baseline_bubble_chart_24.xml new file mode 100644 index 000000000..86b72699d --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_bubble_chart_24.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9e929584c..e3256ec44 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2174,4 +2174,5 @@ If your instance does not accept some extra features, you can hide these icons Display the \"Quote\" button Display \"Reactions\" buttons + Bubble \ No newline at end of file