Merge branch '1077-save-threaded-discussion-position' into 'master'

Save list position in threaded conversations and main blog feed

Closes #1077

See merge request briar/briar!1054
This commit is contained in:
akwizgran
2019-03-22 15:42:53 +00:00
3 changed files with 70 additions and 3 deletions

View File

@@ -3,12 +3,14 @@ package org.briarproject.briar.android.blog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
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.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@@ -62,9 +64,12 @@ public class BlogFragment extends BaseFragment
BlogController blogController; BlogController blogController;
@Inject @Inject
SharingController sharingController; SharingController sharingController;
@Nullable
private Parcelable layoutManagerState;
private GroupId groupId; private GroupId groupId;
private BlogPostAdapter adapter; private BlogPostAdapter adapter;
private LayoutManager layoutManager;
private BriarRecyclerView list; private BriarRecyclerView list;
private MenuItem writeButton, deleteButton; private MenuItem writeButton, deleteButton;
private boolean isMyBlog = false, canDeleteBlog = false; private boolean isMyBlog = false, canDeleteBlog = false;
@@ -101,11 +106,17 @@ public class BlogFragment extends BaseFragment
adapter = new BlogPostAdapter(requireNonNull(getActivity()), this, adapter = new BlogPostAdapter(requireNonNull(getActivity()), this,
getFragmentManager()); getFragmentManager());
list = v.findViewById(R.id.postList); list = v.findViewById(R.id.postList);
list.setLayoutManager(new LinearLayoutManager(getActivity())); layoutManager = new LinearLayoutManager(getActivity());
list.setLayoutManager(layoutManager);
list.setAdapter(adapter); list.setAdapter(adapter);
list.showProgressBar(); list.showProgressBar();
list.setEmptyText(getString(R.string.blogs_other_blog_empty_state)); list.setEmptyText(getString(R.string.blogs_other_blog_empty_state));
if (savedInstanceState != null) {
layoutManagerState =
savedInstanceState.getParcelable("layoutManager");
}
return v; return v;
} }
@@ -126,6 +137,15 @@ public class BlogFragment extends BaseFragment
list.stopPeriodicUpdate(); list.stopPeriodicUpdate();
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (layoutManager != null) {
layoutManagerState = layoutManager.onSaveInstanceState();
outState.putParcelable("layoutManager", layoutManagerState);
}
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.blogs_blog_actions, menu); inflater.inflate(R.menu.blogs_blog_actions, menu);
@@ -238,7 +258,12 @@ public class BlogFragment extends BaseFragment
list.showData(); list.showData();
} else { } else {
adapter.addAll(posts); adapter.addAll(posts);
if (reload) list.scrollToPosition(0); if (reload || layoutManagerState == null) {
list.scrollToPosition(0);
} else {
layoutManager.onRestoreInstanceState(
layoutManagerState);
}
} }
} }

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.blog;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
@@ -54,7 +55,10 @@ public class FeedFragment extends BaseFragment implements
private BlogPostAdapter adapter; private BlogPostAdapter adapter;
private LinearLayoutManager layoutManager; private LinearLayoutManager layoutManager;
private BriarRecyclerView list; private BriarRecyclerView list;
private Blog personalBlog = null; @Nullable
private Blog personalBlog;
@Nullable
private Parcelable layoutManagerState;
public static FeedFragment newInstance() { public static FeedFragment newInstance() {
FeedFragment f = new FeedFragment(); FeedFragment f = new FeedFragment();
@@ -91,6 +95,11 @@ public class FeedFragment extends BaseFragment implements
list.setEmptyText(R.string.blogs_feed_empty_state); list.setEmptyText(R.string.blogs_feed_empty_state);
list.setEmptyAction(R.string.blogs_feed_empty_state_action); list.setEmptyAction(R.string.blogs_feed_empty_state_action);
if (savedInstanceState != null) {
layoutManagerState =
savedInstanceState.getParcelable("layoutManager");
}
return v; return v;
} }
@@ -123,6 +132,15 @@ public class FeedFragment extends BaseFragment implements
// TODO save list position in database/preferences? // TODO save list position in database/preferences?
} }
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (layoutManager != null) {
layoutManagerState = layoutManager.onSaveInstanceState();
outState.putParcelable("layoutManager", layoutManagerState);
}
}
private void loadPersonalBlog() { private void loadPersonalBlog() {
feedController.loadPersonalBlog( feedController.loadPersonalBlog(
new UiResultExceptionHandler<Blog, DbException>(this) { new UiResultExceptionHandler<Blog, DbException>(this) {
@@ -150,6 +168,12 @@ public class FeedFragment extends BaseFragment implements
if (clear) adapter.setItems(posts); if (clear) adapter.setItems(posts);
else adapter.addAll(posts); else adapter.addAll(posts);
if (posts.isEmpty()) list.showData(); if (posts.isEmpty()) list.showData();
if (layoutManagerState == null) {
list.scrollToPosition(0); // Scroll to the top
} else {
layoutManager.onRestoreInstanceState(
layoutManagerState);
}
} else { } else {
LOG.info("Concurrent update, reloading"); LOG.info("Concurrent update, reloading");
loadBlogPosts(clear); loadBlogPosts(clear);

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.android.threaded;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.CallSuper; import android.support.annotation.CallSuper;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
@@ -63,6 +64,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
protected TextInputView textInput; protected TextInputView textInput;
protected GroupId groupId; protected GroupId groupId;
@Nullable @Nullable
private Parcelable layoutManagerState;
@Nullable
private MessageId replyId; private MessageId replyId;
protected abstract ThreadListController<G, I> getController(); protected abstract ThreadListController<G, I> getController();
@@ -188,6 +191,11 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
if (messageId != null) if (messageId != null)
adapter.setItemWithIdVisible(messageId); adapter.setItemWithIdVisible(messageId);
list.showData(); list.showData();
if (layoutManagerState == null) {
list.scrollToPosition(0); // Scroll to the top
} else {
layoutManager.onRestoreInstanceState(layoutManagerState);
}
} }
protected void loadSharingContacts() { protected void loadSharingContacts() {
@@ -228,11 +236,21 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
@Override @Override
protected void onSaveInstanceState(Bundle outState) { protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
if (layoutManager != null) {
layoutManagerState = layoutManager.onSaveInstanceState();
outState.putParcelable("layoutManager", layoutManagerState);
}
if (replyId != null) { if (replyId != null) {
outState.putByteArray(KEY_REPLY_ID, replyId.getBytes()); outState.putByteArray(KEY_REPLY_ID, replyId.getBytes());
} }
} }
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
layoutManagerState = savedInstanceState.getParcelable("layoutManager");
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {