mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Extend BlogActivity to also show individual posts
This allows for swiping left/right to read other posts by using a ViewPager. This hasn't been done as a separate activity, but with fragments, so both can share the `BlogPersistentData` without needing to reload it. Closes #428
This commit is contained in:
@@ -2,128 +2,105 @@ package org.briarproject.android.blogs;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.ActivityComponent;
|
||||
import org.briarproject.android.BriarActivity;
|
||||
import org.briarproject.android.util.BriarRecyclerView;
|
||||
import org.briarproject.api.blogs.BlogManager;
|
||||
import org.briarproject.api.blogs.BlogPostHeader;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.NoSuchGroupException;
|
||||
import org.briarproject.android.blogs.BlogController.BlogPostListener;
|
||||
import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
|
||||
import org.briarproject.android.controller.handler.UiResultHandler;
|
||||
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.support.design.widget.Snackbar.LENGTH_LONG;
|
||||
import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
public class BlogActivity extends BriarActivity {
|
||||
public class BlogActivity extends BriarActivity implements BlogPostListener,
|
||||
OnBlogPostClickListener, BaseFragmentListener {
|
||||
|
||||
static final int REQUEST_WRITE_POST = 1;
|
||||
static final String BLOG_NAME = "briar.BLOG_NAME";
|
||||
static final String IS_MY_BLOG = "briar.IS_MY_BLOG";
|
||||
static final String IS_NEW_BLOG = "briar.IS_NEW_BLOG";
|
||||
private static final int WRITE_POST = 1;
|
||||
|
||||
private static final String BLOG_PAGER_ADAPTER = "briar.BLOG_PAGER_ADAPTER";
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(BlogActivity.class.getName());
|
||||
|
||||
private BlogPostAdapter adapter;
|
||||
private BriarRecyclerView list;
|
||||
private ProgressBar progressBar;
|
||||
private ViewPager pager;
|
||||
private BlogPagerAdapter blogPagerAdapter;
|
||||
private BlogPostPagerAdapter postPagerAdapter;
|
||||
private String blogName;
|
||||
private boolean myBlog;
|
||||
private boolean myBlog, isNew;
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
private volatile GroupId groupId = null;
|
||||
private volatile boolean scrollToTop = false;
|
||||
@Inject
|
||||
volatile BlogManager blogManager;
|
||||
BlogController blogController;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle state) {
|
||||
super.onCreate(state);
|
||||
|
||||
setContentView(R.layout.activity_blog);
|
||||
|
||||
// GroupId from Intent
|
||||
Intent i = getIntent();
|
||||
byte[] b = i.getByteArrayExtra(GROUP_ID);
|
||||
if (b == null) throw new IllegalStateException("No Group in intent.");
|
||||
groupId = new GroupId(b);
|
||||
|
||||
// Name of the Blog from Intent
|
||||
blogName = i.getStringExtra(BLOG_NAME);
|
||||
if (blogName != null) setTitle(blogName);
|
||||
|
||||
// Is this our blog and was it just created?
|
||||
myBlog = i.getBooleanExtra(IS_MY_BLOG, false);
|
||||
isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
|
||||
|
||||
adapter = new BlogPostAdapter(this, groupId, blogName);
|
||||
list = (BriarRecyclerView) this.findViewById(R.id.postList);
|
||||
list.setLayoutManager(new LinearLayoutManager(this));
|
||||
list.setAdapter(adapter);
|
||||
if (myBlog) {
|
||||
list.setEmptyText(
|
||||
getString(R.string.blogs_my_blogs_blog_empty_state));
|
||||
setContentView(R.layout.activity_blog);
|
||||
|
||||
pager = (ViewPager) findViewById(R.id.pager);
|
||||
progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
hideLoadingScreen();
|
||||
|
||||
blogPagerAdapter = new BlogPagerAdapter(getSupportFragmentManager());
|
||||
if (state == null || state.getBoolean(BLOG_PAGER_ADAPTER, true)) {
|
||||
pager.setAdapter(blogPagerAdapter);
|
||||
} else {
|
||||
list.setEmptyText(getString(R.string.blogs_other_blog_empty_state));
|
||||
}
|
||||
|
||||
// show snackbar if this blog was just created
|
||||
boolean isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
|
||||
if (isNew) {
|
||||
Snackbar s = Snackbar.make(list, R.string.blogs_my_blogs_created,
|
||||
LENGTH_LONG);
|
||||
s.getView().setBackgroundResource(R.color.briar_primary);
|
||||
s.show();
|
||||
// this initializes and restores the postPagerAdapter
|
||||
loadBlogPosts();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
loadBlogPosts();
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
// remember which adapter we had active
|
||||
outState.putBoolean(BLOG_PAGER_ADAPTER,
|
||||
pager.getAdapter() == blogPagerAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (myBlog) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.blogs_my_blog_actions, menu);
|
||||
}
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_write_blog_post:
|
||||
Intent i = new Intent(this, WriteBlogPostActivity.class);
|
||||
i.putExtra(GROUP_ID, groupId.getBytes());
|
||||
i.putExtra(BLOG_NAME, blogName);
|
||||
ActivityOptionsCompat options =
|
||||
makeCustomAnimation(this, android.R.anim.slide_in_left,
|
||||
android.R.anim.slide_out_right);
|
||||
ActivityCompat.startActivityForResult(this, i, WRITE_POST,
|
||||
options.toBundle());
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == WRITE_POST && resultCode == RESULT_OK) {
|
||||
scrollToTop = true;
|
||||
public void onBackPressed() {
|
||||
if (pager.getAdapter() == postPagerAdapter) {
|
||||
pager.setAdapter(blogPagerAdapter);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,50 +109,153 @@ public class BlogActivity extends BriarActivity {
|
||||
component.inject(this);
|
||||
}
|
||||
|
||||
private void loadBlogPosts() {
|
||||
runOnDbThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// load blog posts
|
||||
long now = System.currentTimeMillis();
|
||||
Collection<BlogPostItem> posts = new ArrayList<>();
|
||||
try {
|
||||
Collection<BlogPostHeader> header =
|
||||
blogManager.getPostHeaders(groupId);
|
||||
for (BlogPostHeader h : header) {
|
||||
posts.add(new BlogPostItem(h));
|
||||
}
|
||||
} catch (NoSuchGroupException e) {
|
||||
// Continue
|
||||
}
|
||||
displayBlogPosts(posts);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Post header load took " + duration + " ms");
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void showLoadingScreen(boolean isBlocking, int stringId) {
|
||||
progressBar.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
private void displayBlogPosts(final Collection<BlogPostItem> items) {
|
||||
private void showLoadingScreen() {
|
||||
showLoadingScreen(false, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideLoadingScreen() {
|
||||
progressBar.setVisibility(GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFragmentCreated(String tag) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlogPostClick(final int position) {
|
||||
loadBlogPosts(position, true);
|
||||
}
|
||||
|
||||
private void loadBlogPosts() {
|
||||
loadBlogPosts(0, false);
|
||||
}
|
||||
|
||||
private void loadBlogPosts(final int position, final boolean setItem) {
|
||||
showLoadingScreen();
|
||||
blogController
|
||||
.loadBlog(groupId, false, new UiResultHandler<Boolean>(this) {
|
||||
@Override
|
||||
public void onResultUi(Boolean result) {
|
||||
if (result) {
|
||||
Collection<BlogPostItem> posts =
|
||||
blogController.getBlogPosts();
|
||||
|
||||
if (postPagerAdapter == null) {
|
||||
postPagerAdapter = new BlogPostPagerAdapter(
|
||||
getSupportFragmentManager(),
|
||||
posts.size());
|
||||
} else {
|
||||
postPagerAdapter.setSize(posts.size());
|
||||
}
|
||||
pager.setAdapter(postPagerAdapter);
|
||||
if (setItem) pager.setCurrentItem(position);
|
||||
} else {
|
||||
Toast.makeText(BlogActivity.this,
|
||||
R.string.blogs_blog_post_failed_to_load,
|
||||
LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlogPostAdded(final BlogPostItem post, final boolean local) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (items.size() == 0) {
|
||||
list.showData();
|
||||
} else {
|
||||
adapter.addAll(items);
|
||||
if (scrollToTop) list.scrollToPosition(0);
|
||||
if (blogPagerAdapter != null) {
|
||||
BlogFragment f = blogPagerAdapter.getFragment();
|
||||
if (f != null && f.isVisible()) {
|
||||
f.onBlogPostAdded(post, local);
|
||||
}
|
||||
}
|
||||
|
||||
if (postPagerAdapter != null) {
|
||||
postPagerAdapter.onBlogPostAdded();
|
||||
postPagerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
scrollToTop = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO listen to events and add new blog posts as they come in
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
Intent data) {
|
||||
|
||||
// The BlogPostAddedEvent arrives when the controller is not listening,
|
||||
// so we need to manually reload the blog posts :(
|
||||
if (requestCode == REQUEST_WRITE_POST && resultCode == RESULT_OK) {
|
||||
BlogFragment f = blogPagerAdapter.getFragment();
|
||||
if (f != null && f.isVisible()) {
|
||||
f.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class BlogPagerAdapter extends FragmentStatePagerAdapter {
|
||||
private BlogFragment fragment = null;
|
||||
|
||||
BlogPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
return BlogFragment.newInstance(groupId, blogName, myBlog, isNew);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
// save a reference to the single fragment here for later
|
||||
fragment =
|
||||
(BlogFragment) super.instantiateItem(container, position);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
BlogFragment getFragment() {
|
||||
return fragment;
|
||||
}
|
||||
}
|
||||
|
||||
private class BlogPostPagerAdapter extends FragmentStatePagerAdapter {
|
||||
private int size;
|
||||
|
||||
BlogPostPagerAdapter(FragmentManager fm, int size) {
|
||||
super(fm);
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int position) {
|
||||
MessageId postIdOfPos = blogController.getBlogPostId(position);
|
||||
return BlogPostFragment.newInstance(groupId, postIdOfPos);
|
||||
}
|
||||
|
||||
void onBlogPostAdded() {
|
||||
size++;
|
||||
}
|
||||
|
||||
void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user