diff --git a/app/src/main/java/app/fedilab/android/BaseMainActivity.java b/app/src/main/java/app/fedilab/android/BaseMainActivity.java index 019e7c94..4aa32056 100644 --- a/app/src/main/java/app/fedilab/android/BaseMainActivity.java +++ b/app/src/main/java/app/fedilab/android/BaseMainActivity.java @@ -164,6 +164,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt public static String regex_home, regex_local, regex_public; public static BaseAccount currentAccount; Fragment currentFragment; + public static String slugOfFirstFragment; private AppBarConfiguration mAppBarConfiguration; private ActivityMainBinding binding; private final BroadcastReceiver broadcast_error_message = new BroadcastReceiver() { @@ -894,6 +895,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt new ViewModelProvider(BaseMainActivity.this).get(TopBarVM.class).getDBPinned() .observe(this, pinned -> { this.pinned = pinned; + //Initialize the slug of the first fragment + slugOfFirstFragment = PinnedTimelineHelper.firstTimelineSlug(BaseMainActivity.this, pinned, bottomMenu); //First it's taken from db (last stored values) PinnedTimelineHelper.redrawTopBarPinned(BaseMainActivity.this, binding, pinned, bottomMenu, null); //Fetch remote lists for the authenticated account and update them 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 9c62ca9c..ba4fb6ea 100644 --- a/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +++ b/app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java @@ -22,6 +22,7 @@ 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; @@ -91,6 +92,59 @@ public class PinnedTimelineHelper { Collections.sort(menuItemList, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position)); } + + /** + * 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 = null; + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean singleBar = sharedpreferences.getBoolean(context.getString(R.string.SET_USE_SINGLE_TOPBAR), false); + PinnedTimeline pinnedTimelineMin = null; + if (singleBar) { + 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 if (pinned == null) { diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java index c8c3bf33..1f3e9742 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java @@ -16,6 +16,7 @@ package app.fedilab.android.ui.fragment.timeline; import static app.fedilab.android.BaseMainActivity.networkAvailable; +import static app.fedilab.android.BaseMainActivity.slugOfFirstFragment; import android.content.BroadcastReceiver; import android.content.Context; @@ -78,14 +79,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. private Timeline.TimeLineEnum timelineType; private List timelineStatuses; public UpdateCounters update; - - @Override - public void onResume() { - super.onResume(); - if (timelineStatuses != null && timelineStatuses.size() > 0) { - route(DIRECTION.FETCH_NEW, true); - } - } + private boolean isViewInitialized; + private Statuses initialStatuses; //Handle actions that can be done in other fragments private final BroadcastReceiver receive_action = new BroadcastReceiver() { @@ -147,6 +142,18 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. private TimelinesVM.TimelineParams timelineParams; private boolean canBeFederated; + @Override + public void onResume() { + super.onResume(); + if (slug.compareTo(slugOfFirstFragment) != 0 && !isViewInitialized) { + isViewInitialized = true; + initializeStatusesCommonView(initialStatuses); + } + if (timelineStatuses != null && timelineStatuses.size() > 0) { + route(DIRECTION.FETCH_NEW, true); + } + } + /** * Return the position of the status in the ArrayList * @@ -196,6 +203,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. ViewGroup container, Bundle savedInstanceState) { timelineType = Timeline.TimeLineEnum.HOME; + canBeFederated = true; if (getArguments() != null) { timelineType = (Timeline.TimeLineEnum) getArguments().get(Helper.ARG_TIMELINE_TYPE); @@ -244,6 +252,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (timelineType != null) { slug = timelineType.getValue() + (ident != null ? "|" + ident : ""); } + //Only the first fragment will initialize its view + isViewInitialized = slug.compareTo(slugOfFirstFragment) == 0; SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()); //Retrieve the max_id to keep position @@ -357,6 +367,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. */ private void initializeStatusesCommonView(final Statuses statuses) { flagLoading = false; + if (!isViewInitialized) { + return; + } if (binding == null || !isAdded() || getActivity() == null) { if (binding != null) { binding.loader.setVisibility(View.GONE); @@ -528,6 +541,9 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. * @param direction - DIRECTION null if first call, then is set to TOP or BOTTOM depending of scroll */ private void routeCommon(DIRECTION direction, boolean fetchingMissing, Status status) { + if (direction == null) { + isViewInitialized = slug.compareTo(slugOfFirstFragment) == 0; + } if (binding == null || getActivity() == null || !isAdded()) { return; } @@ -584,13 +600,17 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. Handler handler = new Handler(); //The action for fetching new messages is delayed for other timelines than HOME + if (slugOfFirstFragment == null) { + slugOfFirstFragment = slug; + } + handler.postDelayed(() -> { if (useCache && direction != DIRECTION.SCROLL_TOP && direction != DIRECTION.FETCH_NEW) { getCachedStatus(direction, fetchingMissing, timelineParams); } else { getLiveStatus(direction, fetchingMissing, timelineParams, status); } - }, timelineType == Timeline.TimeLineEnum.HOME ? 0 : 1000); + }, slug.compareTo(slugOfFirstFragment) == 0 ? 0 : 1000); } @@ -652,6 +672,7 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (direction == null) { timelinesVM.getTimelineCache(timelineStatuses, timelineParams) .observe(getViewLifecycleOwner(), statusesCached -> { + initialStatuses = statusesCached; if (statusesCached == null || statusesCached.statuses == null || statusesCached.statuses.size() == 0) { getLiveStatus(null, fetchingMissing, timelineParams, null); } else { @@ -694,9 +715,15 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. } private void getLiveStatus(DIRECTION direction, boolean fetchingMissing, TimelinesVM.TimelineParams timelineParams, Status status) { + if (getView() == null) { + return; + } if (direction == null) { timelinesVM.getTimeline(timelineStatuses, timelineParams) - .observe(getViewLifecycleOwner(), this::initializeStatusesCommonView); + .observe(getViewLifecycleOwner(), statuses -> { + initialStatuses = statuses; + initializeStatusesCommonView(statuses); + }); } else if (direction == DIRECTION.BOTTOM) { timelinesVM.getTimeline(timelineStatuses, timelineParams) .observe(getViewLifecycleOwner(), statusesBottom -> dealWithPagination(statusesBottom, DIRECTION.BOTTOM, fetchingMissing, status));