From 7df234ceaaf663ba152463088b39404c95d9816e Mon Sep 17 00:00:00 2001 From: Ivan Kupalov Date: Sun, 7 Jun 2020 19:37:34 +0200 Subject: [PATCH] Fix loading more than one page of favs/bookmarks, fix #1824 (#1825) --- .../tusky/fragment/TimelineFragment.java | 52 ++++++++++++++++--- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java b/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java index d1c29801..ac5ebea4 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java @@ -18,6 +18,7 @@ package com.keylesspalace.tusky.fragment; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -62,6 +63,7 @@ import com.keylesspalace.tusky.repository.TimelineRepository; import com.keylesspalace.tusky.repository.TimelineRequestMode; import com.keylesspalace.tusky.util.CardViewMode; import com.keylesspalace.tusky.util.Either; +import com.keylesspalace.tusky.util.HttpHeaderLink; import com.keylesspalace.tusky.util.LinkHelper; import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate; import com.keylesspalace.tusky.util.ListUtils; @@ -151,6 +153,10 @@ public class TimelineFragment extends SFragment implements private Kind kind; private String id; private List tags; + /** + * For some timeline kinds we must use LINK headers and not just status ids. + */ + private String nextId; private LinearLayoutManager layoutManager; private EndlessOnScrollListener scrollListener; private boolean filterRemoveReplies; @@ -220,7 +226,7 @@ public class TimelineFragment extends SFragment implements || kind == Kind.LIST) { id = arguments.getString(ID_ARG); } - if(kind == Kind.TAG) { + if (kind == Kind.TAG) { tags = arguments.getStringArrayList(HASHTAGS_ARG); } @@ -974,13 +980,17 @@ public class TimelineFragment extends SFragment implements updateAdapter(); String bottomId = null; - final ListIterator> iterator = - this.statuses.listIterator(this.statuses.size()); - while (iterator.hasPrevious()) { - Either previous = iterator.previous(); - if (previous.isRight()) { - bottomId = previous.asRight().getId(); - break; + if (kind == Kind.FAVOURITES || kind == Kind.BOOKMARKS) { + bottomId = this.nextId; + } else { + final ListIterator> iterator = + this.statuses.listIterator(this.statuses.size()); + while (iterator.hasPrevious()) { + Either previous = iterator.previous(); + if (previous.isRight()) { + bottomId = previous.asRight().getId(); + break; + } } } sendFetchTimelineRequest(bottomId, null, null, FetchEnd.BOTTOM, -1); @@ -1063,6 +1073,14 @@ public class TimelineFragment extends SFragment implements @Override public void onResponse(@NonNull Call> call, @NonNull Response> response) { if (response.isSuccessful()) { + @Nullable + String newNextId = extractNextId(response); + if (newNextId != null) { + // when we reach the bottom of the list, we won't have a new link. If + // we blindly write `null` here we will start loading from the top + // again. + nextId = newNextId; + } onFetchTimelineSuccess(liftStatusList(response.body()), fetchEnd, pos); } else { onFetchTimelineFailure(new Exception(response.message()), fetchEnd, pos); @@ -1081,6 +1099,24 @@ public class TimelineFragment extends SFragment implements } } + @Nullable + private String extractNextId(Response response) { + String linkHeader = response.headers().get("Link"); + if (linkHeader == null) { + return null; + } + List links = HttpHeaderLink.parse(linkHeader); + HttpHeaderLink nextHeader = HttpHeaderLink.findByRelationType(links, "next"); + if (nextHeader == null) { + return null; + } + Uri nextLink = nextHeader.uri; + if (nextLink == null) { + return null; + } + return nextLink.getQueryParameter("max_id"); + } + private void onFetchTimelineSuccess(List> statuses, FetchEnd fetchEnd, int pos) {