parent
8f2514dbe0
commit
4188b6ea09
1 changed files with 44 additions and 8 deletions
|
@ -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) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue