Allow pull-to-refresh in thread view (closes #73)
This commit is contained in:
parent
69c1b88ff4
commit
f4109f38a8
3 changed files with 53 additions and 12 deletions
|
@ -65,20 +65,43 @@ class ThreadAdapter extends RecyclerView.Adapter implements AdapterItemRemover {
|
||||||
notifyItemRemoved(position);
|
notifyItemRemoved(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
int insertStatus(Status status) {
|
int setStatus(Status status) {
|
||||||
|
if (statuses.size() > 0 && statuses.get(statusIndex).equals(status)) {
|
||||||
|
// Do not add this status on refresh, it's already in there.
|
||||||
|
statuses.set(statusIndex, status);
|
||||||
|
return statusIndex;
|
||||||
|
}
|
||||||
int i = statusIndex;
|
int i = statusIndex;
|
||||||
statuses.add(i, status);
|
statuses.add(i, status);
|
||||||
notifyItemInserted(i);
|
notifyItemInserted(i);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addAncestors(List<Status> ancestors) {
|
void setContext(List<Status> ancestors, List<Status> descendants) {
|
||||||
|
Status mainStatus = null;
|
||||||
|
|
||||||
|
// In case of refresh, remove old ancestors and descendants first. We'll remove all blindly,
|
||||||
|
// as we have no guarantee on their order to be the same as before
|
||||||
|
int old_size = statuses.size();
|
||||||
|
if (old_size > 0) {
|
||||||
|
mainStatus = statuses.get(statusIndex);
|
||||||
|
statuses.clear();
|
||||||
|
notifyItemRangeRemoved(0, old_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newly fetched ancestors
|
||||||
statusIndex = ancestors.size();
|
statusIndex = ancestors.size();
|
||||||
statuses.addAll(0, ancestors);
|
statuses.addAll(0, ancestors);
|
||||||
notifyItemRangeInserted(0, statusIndex);
|
notifyItemRangeInserted(0, statusIndex);
|
||||||
}
|
|
||||||
|
|
||||||
void addDescendants(List<Status> descendants) {
|
if (mainStatus != null) {
|
||||||
|
// In case we needed to delete everything (which is way easier than deleting
|
||||||
|
// everything except one), re-insert the remaining status here.
|
||||||
|
statuses.add(statusIndex, mainStatus);
|
||||||
|
notifyItemInserted(statusIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert newly fetched descendants
|
||||||
int end = statuses.size();
|
int end = statuses.size();
|
||||||
statuses.addAll(descendants);
|
statuses.addAll(descendants);
|
||||||
notifyItemRangeInserted(end, descendants.size());
|
notifyItemRangeInserted(end, descendants.size());
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
import android.support.v7.widget.DividerItemDecoration;
|
import android.support.v7.widget.DividerItemDecoration;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
@ -34,9 +35,11 @@ import com.keylesspalace.tusky.entity.StatusContext;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
|
||||||
public class ViewThreadFragment extends SFragment implements StatusActionListener {
|
public class ViewThreadFragment extends SFragment implements
|
||||||
|
SwipeRefreshLayout.OnRefreshListener, StatusActionListener {
|
||||||
private static final String TAG = "ViewThreadFragment";
|
private static final String TAG = "ViewThreadFragment";
|
||||||
|
|
||||||
|
private SwipeRefreshLayout swipeRefreshLayout;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
private ThreadAdapter adapter;
|
private ThreadAdapter adapter;
|
||||||
private String thisThreadsStatusId;
|
private String thisThreadsStatusId;
|
||||||
|
@ -56,6 +59,9 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
|
||||||
View rootView = inflater.inflate(R.layout.fragment_view_thread, container, false);
|
View rootView = inflater.inflate(R.layout.fragment_view_thread, container, false);
|
||||||
|
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
|
swipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
|
||||||
|
swipeRefreshLayout.setOnRefreshListener(this);
|
||||||
|
|
||||||
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
|
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
|
||||||
recyclerView.setHasFixedSize(true);
|
recyclerView.setHasFixedSize(true);
|
||||||
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
|
||||||
|
@ -86,7 +92,7 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
|
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
int position = adapter.insertStatus(response.body());
|
int position = adapter.setStatus(response.body());
|
||||||
recyclerView.scrollToPosition(position);
|
recyclerView.scrollToPosition(position);
|
||||||
} else {
|
} else {
|
||||||
onThreadRequestFailure(id);
|
onThreadRequestFailure(id);
|
||||||
|
@ -109,10 +115,10 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<StatusContext> call, retrofit2.Response<StatusContext> response) {
|
public void onResponse(Call<StatusContext> call, retrofit2.Response<StatusContext> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
StatusContext context = response.body();
|
StatusContext context = response.body();
|
||||||
|
|
||||||
adapter.addAncestors(context.ancestors);
|
adapter.setContext(context.ancestors, context.descendants);
|
||||||
adapter.addDescendants(context.descendants);
|
|
||||||
} else {
|
} else {
|
||||||
onThreadRequestFailure(id);
|
onThreadRequestFailure(id);
|
||||||
}
|
}
|
||||||
|
@ -128,6 +134,7 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
|
||||||
|
|
||||||
private void onThreadRequestFailure(final String id) {
|
private void onThreadRequestFailure(final String id) {
|
||||||
View view = getView();
|
View view = getView();
|
||||||
|
swipeRefreshLayout.setRefreshing(false);
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
Snackbar.make(view, R.string.error_generic, Snackbar.LENGTH_LONG)
|
Snackbar.make(view, R.string.error_generic, Snackbar.LENGTH_LONG)
|
||||||
.setAction(R.string.action_retry, new View.OnClickListener() {
|
.setAction(R.string.action_retry, new View.OnClickListener() {
|
||||||
|
@ -143,6 +150,11 @@ public class ViewThreadFragment extends SFragment implements StatusActionListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onRefresh() {
|
||||||
|
sendStatusRequest(thisThreadsStatusId);
|
||||||
|
sendThreadRequest(thisThreadsStatusId);
|
||||||
|
}
|
||||||
|
|
||||||
public void onReply(int position) {
|
public void onReply(int position) {
|
||||||
super.reply(adapter.getItem(position));
|
super.reply(adapter.getItem(position));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/swipe_refresh_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:scrollbars="vertical" />
|
<android.support.v7.widget.RecyclerView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="vertical" />
|
||||||
|
</android.support.v4.widget.SwipeRefreshLayout>
|
Loading…
Reference in a new issue