Fix loading more than one page of favs/bookmarks, fix #1824 (#1825)

This commit is contained in:
Ivan Kupalov 2020-06-07 19:37:34 +02:00 committed by GitHub
parent 8f2514dbe0
commit 4188b6ea09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 44 additions and 8 deletions

View File

@ -18,6 +18,7 @@ package com.keylesspalace.tusky.fragment;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -75,6 +76,7 @@ import com.keylesspalace.tusky.repository.TimelineRepository;
import com.keylesspalace.tusky.repository.TimelineRequestMode; import com.keylesspalace.tusky.repository.TimelineRequestMode;
import com.keylesspalace.tusky.util.CardViewMode; import com.keylesspalace.tusky.util.CardViewMode;
import com.keylesspalace.tusky.util.Either; import com.keylesspalace.tusky.util.Either;
import com.keylesspalace.tusky.util.HttpHeaderLink;
import com.keylesspalace.tusky.util.LinkHelper; import com.keylesspalace.tusky.util.LinkHelper;
import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate; import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate;
import com.keylesspalace.tusky.util.ListUtils; import com.keylesspalace.tusky.util.ListUtils;
@ -163,6 +165,10 @@ public class TimelineFragment extends SFragment implements
private Kind kind; private Kind kind;
private String id; private String id;
private List<String> tags; private List<String> tags;
/**
* For some timeline kinds we must use LINK headers and not just status ids.
*/
private String nextId;
private LinearLayoutManager layoutManager; private LinearLayoutManager layoutManager;
private EndlessOnScrollListener scrollListener; private EndlessOnScrollListener scrollListener;
private boolean filterRemoveReplies; private boolean filterRemoveReplies;
@ -232,7 +238,7 @@ public class TimelineFragment extends SFragment implements
|| kind == Kind.LIST) { || kind == Kind.LIST) {
id = arguments.getString(ID_ARG); id = arguments.getString(ID_ARG);
} }
if(kind == Kind.TAG) { if (kind == Kind.TAG) {
tags = arguments.getStringArrayList(HASHTAGS_ARG); tags = arguments.getStringArrayList(HASHTAGS_ARG);
} }
@ -963,13 +969,17 @@ public class TimelineFragment extends SFragment implements
updateAdapter(); updateAdapter();
String bottomId = null; String bottomId = null;
final ListIterator<Either<Placeholder, Status>> iterator = if (kind == Kind.FAVOURITES || kind == Kind.BOOKMARKS) {
this.statuses.listIterator(this.statuses.size()); bottomId = this.nextId;
while (iterator.hasPrevious()) { } else {
Either<Placeholder, Status> previous = iterator.previous(); final ListIterator<Either<Placeholder, Status>> iterator =
if (previous.isRight()) { this.statuses.listIterator(this.statuses.size());
bottomId = previous.asRight().getId(); while (iterator.hasPrevious()) {
break; Either<Placeholder, Status> previous = iterator.previous();
if (previous.isRight()) {
bottomId = previous.asRight().getId();
break;
}
} }
} }
sendFetchTimelineRequest(bottomId, null, null, FetchEnd.BOTTOM, -1); sendFetchTimelineRequest(bottomId, null, null, FetchEnd.BOTTOM, -1);
@ -1050,6 +1060,14 @@ public class TimelineFragment extends SFragment implements
@Override @Override
public void onResponse(@NonNull Call<List<Status>> call, @NonNull Response<List<Status>> response) { public void onResponse(@NonNull Call<List<Status>> call, @NonNull Response<List<Status>> response) {
if (response.isSuccessful()) { 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); onFetchTimelineSuccess(liftStatusList(response.body()), fetchEnd, pos);
} else { } else {
onFetchTimelineFailure(new Exception(response.message()), fetchEnd, pos); onFetchTimelineFailure(new Exception(response.message()), fetchEnd, pos);
@ -1068,6 +1086,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<HttpHeaderLink> 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<Either<Placeholder, Status>> statuses, private void onFetchTimelineSuccess(List<Either<Placeholder, Status>> statuses,
FetchEnd fetchEnd, int pos) { FetchEnd fetchEnd, int pos) {