Skip to content
Snippets Groups Projects
BlogActivity.java 8.19 KiB
Newer Older
package org.briarproject.android.blogs;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
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 org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.BriarActivity;
import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.api.blogs.BlogPostHeader;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.inject.Inject;

import static android.view.View.GONE;
import static android.view.View.VISIBLE;
public class BlogActivity extends BriarActivity implements
		OnBlogPostAddedListener,
		OnBlogPostClickListener, BaseFragmentListener {
	static final int REQUEST_WRITE_POST = 1;
Torsten Grote's avatar
Torsten Grote committed
	static final int REQUEST_SHARE = 2;
	public static final String BLOG_NAME = "briar.BLOG_NAME";
	static final String IS_NEW_BLOG = "briar.IS_NEW_BLOG";

	public static final String POST_ID = "briar.POST_ID";
	private GroupId groupId;
	private ProgressBar progressBar;
	private ViewPager pager;
	private BlogPagerAdapter blogPagerAdapter;
	private BlogPostPagerAdapter postPagerAdapter;
	private String blogName;
	private boolean isNew;
	private MessageId savedPostId;
	BlogController blogController;

	@Override
	public void onCreate(Bundle state) {
		super.onCreate(state);

		// GroupId from Intent
		Intent i = getIntent();
		byte[] b = i.getByteArrayExtra(GROUP_ID);
		if (b == null) throw new IllegalStateException("No group ID in intent");
		groupId = new GroupId(b);
		blogController.setGroupId(groupId);
		// Name of the blog
		blogName = i.getStringExtra(BLOG_NAME);
		if (blogName != null) setTitle(blogName);
		// Was this blog just created?
		isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
		setContentView(R.layout.activity_blog);

		pager = (ViewPager) findViewById(R.id.pager);
		progressBar = (ProgressBar) findViewById(R.id.progressBar);

		blogPagerAdapter = new BlogPagerAdapter(getSupportFragmentManager());
		postPagerAdapter = new BlogPostPagerAdapter(
				getSupportFragmentManager());

		if (state == null || state.getByteArray(POST_ID) == null) {
akwizgran's avatar
akwizgran committed
			// The blog fragment has its own progress bar
			hideLoadingScreen();
			pager.setAdapter(blogPagerAdapter);
			savedPostId = null;
			// Adapter will be set in selectPostInPostPager()
			savedPostId = new MessageId(state.getByteArray(POST_ID));
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		if (savedPostId == null) {
			MessageId selected = getSelectedPostInPostPager();
			if (selected != null) loadBlogPosts(selected);
		} else {
			loadBlogPosts(savedPostId);
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		MessageId selected = getSelectedPostInPostPager();
		if (selected != null)
			outState.putByteArray(POST_ID, selected.getBytes());
	}

	@Override
	public void onBackPressed() {
		if (pager.getAdapter() == postPagerAdapter) {
			pager.setAdapter(blogPagerAdapter);
			savedPostId = null;
		} else {
			super.onBackPressed();
	public void injectActivity(ActivityComponent component) {
		component.inject(this);
	public void showLoadingScreen(boolean isBlocking, int stringId) {
		progressBar.setVisibility(VISIBLE);
	}

	public void hideLoadingScreen() {
		progressBar.setVisibility(GONE);
	public void onFragmentCreated(String tag) {

	public void onBlogPostClick(BlogPostItem post) {
		loadBlogPosts(post.getId());
	private void loadBlogPosts(final MessageId select) {
		blogController.loadBlogPosts(
				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
						this) {
					public void onResultUi(Collection<BlogPostItem> posts) {
						hideLoadingScreen();
						savedPostId = null;
						postPagerAdapter.setPosts(posts);
						selectPostInPostPager(select);
					}

					@Override
					public void onExceptionUi(DbException exception) {
						// TODO: Decide how to handle errors in the UI
						finish();
	public void onBlogPostAdded(BlogPostHeader header, boolean local) {
		if (pager.getAdapter() == postPagerAdapter) {
			loadBlogPost(header);
		} else {
			BlogFragment f = blogPagerAdapter.getFragment();
			if (f != null && f.isVisible()) f.onBlogPostAdded(header, local);
		}
	}

	private void loadBlogPost(BlogPostHeader header) {
		blogController.loadBlogPost(header,
				new UiResultExceptionHandler<BlogPostItem, DbException>(this) {
					@Override
					public void onResultUi(BlogPostItem post) {
						addPostToPostPager(post);
					@Override
					public void onExceptionUi(DbException exception) {
						// TODO: Decide how to handle errors in the UI
						finish();
					}
				});
	}

	@Nullable
	private MessageId getSelectedPostInPostPager() {
		if (pager.getAdapter() != postPagerAdapter) return null;
		if (postPagerAdapter.getCount() == 0) return null;
		int position = pager.getCurrentItem();
		return postPagerAdapter.getPost(position).getId();
	}

	private void selectPostInPostPager(MessageId m) {
		int count = postPagerAdapter.getCount();
		for (int i = 0; i < count; i++) {
			if (postPagerAdapter.getPost(i).getId().equals(m)) {
				pager.setAdapter(postPagerAdapter);
				pager.setCurrentItem(i);
				return;
		}
	}

	private void addPostToPostPager(BlogPostItem post) {
		MessageId selected = getSelectedPostInPostPager();
		postPagerAdapter.addPost(post);
		if (selected != null) selectPostInPostPager(selected);
	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent data) {
Torsten Grote's avatar
Torsten Grote committed
		super.onActivityResult(requestCode, resultCode, 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) {
			if (pager.getAdapter() == postPagerAdapter) {
				MessageId selected = getSelectedPostInPostPager();
				if (selected != null) loadBlogPosts(selected);
			} else {
				BlogFragment f = blogPagerAdapter.getFragment();
				if (f != null && f.isVisible()) f.loadBlogPosts(true);
	private class BlogPagerAdapter extends FragmentStatePagerAdapter {
		private BlogFragment fragment = null;

		private BlogPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public int getCount() {
			return 1;
		}

		@Override
		public Fragment getItem(int position) {
			return BlogFragment.newInstance(groupId, blogName, 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;
		}

		private BlogFragment getFragment() {
	@UiThread
	private static class BlogPostPagerAdapter
			extends FragmentStatePagerAdapter {

		private final List<BlogPostItem> posts = new ArrayList<>();
		private BlogPostPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public int getCount() {
			return posts.size();
		}

		@Override
		public Fragment getItem(int position) {
			return BlogPostFragment.newInstance(posts.get(position).getId());
		}

		private BlogPostItem getPost(int position) {
			return posts.get(position);
		private void setPosts(Collection<BlogPostItem> posts) {
			this.posts.clear();
			this.posts.addAll(posts);
			Collections.sort(this.posts);
			notifyDataSetChanged();
		private void addPost(BlogPostItem post) {
			posts.add(post);
			Collections.sort(posts);
			notifyDataSetChanged();