Loading app/src/main/java/app/fedilab/android/BaseMainActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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 Loading app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +54 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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<MastodonList> mastodonLists) { //Values must be initialized if there is no records in db if (pinned == null) { Loading app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +37 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -78,14 +79,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. private Timeline.TimeLineEnum timelineType; private List<Status> 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() { Loading Loading @@ -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 * Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); } Loading Loading @@ -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 { Loading Loading @@ -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)); Loading Loading
app/src/main/java/app/fedilab/android/BaseMainActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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 Loading
app/src/main/java/app/fedilab/android/helper/PinnedTimelineHelper.java +54 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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<MastodonList> mastodonLists) { //Values must be initialized if there is no records in db if (pinned == null) { Loading
app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +37 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -78,14 +79,8 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. private Timeline.TimeLineEnum timelineType; private List<Status> 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() { Loading Loading @@ -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 * Loading Loading @@ -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); Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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); } Loading Loading @@ -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 { Loading Loading @@ -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)); Loading