diff --git a/briar-android/res/layout/activity_fragment_container.xml b/briar-android/res/layout/activity_fragment_container.xml
index e6c20760f..8bf59ee5a 100644
--- a/briar-android/res/layout/activity_fragment_container.xml
+++ b/briar-android/res/layout/activity_fragment_container.xml
@@ -3,4 +3,14 @@
android:id="@+id/fragmentContainer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
\ No newline at end of file
+ android:layout_height="match_parent">
+
+
+
+
\ No newline at end of file
diff --git a/briar-android/res/layout/fragment_blog_post.xml b/briar-android/res/layout/fragment_blog_post.xml
index 7a0df0d0b..bc1b87c2a 100644
--- a/briar-android/res/layout/fragment_blog_post.xml
+++ b/briar-android/res/layout/fragment_blog_post.xml
@@ -6,7 +6,12 @@
+ android:layout_height="wrap_content"
+ android:descendantFocusability="beforeDescendants"
+ android:focusable="true"
+ android:focusableInTouchMode="true">
+
+
\ No newline at end of file
diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java
index 2a0d82c4b..baee29d41 100644
--- a/briar-android/src/org/briarproject/android/ActivityComponent.java
+++ b/briar-android/src/org/briarproject/android/ActivityComponent.java
@@ -6,8 +6,11 @@ import org.briarproject.android.blogs.BlogActivity;
import org.briarproject.android.blogs.BlogFragment;
import org.briarproject.android.blogs.BlogListFragment;
import org.briarproject.android.blogs.BlogPostFragment;
+import org.briarproject.android.blogs.BlogPostPagerFragment;
import org.briarproject.android.blogs.CreateBlogActivity;
+import org.briarproject.android.blogs.FeedPostFragment;
import org.briarproject.android.blogs.FeedFragment;
+import org.briarproject.android.blogs.FeedPostPagerFragment;
import org.briarproject.android.blogs.ReblogActivity;
import org.briarproject.android.blogs.ReblogFragment;
import org.briarproject.android.blogs.RssFeedImportActivity;
@@ -92,6 +95,10 @@ public interface ActivityComponent {
void inject(BlogFragment fragment);
void inject(BlogPostFragment fragment);
+ void inject(FeedPostFragment fragment);
+
+ void inject(BlogPostPagerFragment fragment);
+ void inject(FeedPostPagerFragment fragment);
void inject(ReblogFragment fragment);
diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java
index 6381bc9cd..d4bacf55a 100644
--- a/briar-android/src/org/briarproject/android/NavDrawerActivity.java
+++ b/briar-android/src/org/briarproject/android/NavDrawerActivity.java
@@ -74,7 +74,9 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
super.onNewIntent(intent);
exitIfStartupFailed(intent);
checkAuthorHandle(intent);
- clearBackStack();
+ // FIXME why was the stack cleared here?
+ // This prevents state from being restored properly
+// clearBackStack();
if (intent.getBooleanExtra(INTENT_FORUMS, false)) {
startFragment(ForumListFragment.newInstance());
}
@@ -248,7 +250,6 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
@Override
public void hideLoadingScreen() {
drawerLayout.setDrawerLockMode(LOCK_MODE_UNLOCKED);
- CustomAnimations.animateHeight(toolbar, true, 250);
progressViewGroup.setVisibility(INVISIBLE);
}
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
new file mode 100644
index 000000000..e340a3fcb
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
@@ -0,0 +1,99 @@
+package org.briarproject.android.blogs;
+
+import android.os.Bundle;
+import android.support.annotation.CallSuper;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.briarproject.R;
+import org.briarproject.android.fragment.BaseFragment;
+import org.briarproject.api.db.DbException;
+
+import java.util.logging.Logger;
+
+import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION;
+
+public abstract class BasePostFragment extends BaseFragment {
+
+ private final Logger LOG =
+ Logger.getLogger(BasePostFragment.class.getName());
+
+ private View view;
+ private BlogPostViewHolder ui;
+ private BlogPostItem post;
+ private Runnable refresher;
+
+ @CallSuper
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ setHasOptionsMenu(true);
+
+ view = inflater.inflate(R.layout.fragment_blog_post, container,
+ false);
+ ui = new BlogPostViewHolder(view);
+ return view;
+ }
+
+ @CallSuper
+ @Override
+ public void onStart() {
+ super.onStart();
+ startPeriodicUpdate();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ stopPeriodicUpdate();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ getActivity().onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ protected void onBlogPostLoaded(BlogPostItem post) {
+ listener.hideLoadingScreen();
+ this.post = post;
+ ui.bindItem(post);
+ }
+
+ protected void onBlogPostLoadException(DbException exception) {
+ // TODO: Decide how to handle errors in the UI
+ finish();
+ }
+
+ private void startPeriodicUpdate() {
+ refresher = new Runnable() {
+ @Override
+ public void run() {
+ if (ui == null) return;
+ LOG.info("Updating Content...");
+
+ ui.updateDate(post.getTimestamp());
+ view.postDelayed(refresher, MIN_RESOLUTION);
+ }
+ };
+ LOG.info("Adding Handler Callback");
+ view.postDelayed(refresher, MIN_RESOLUTION);
+ }
+
+ private void stopPeriodicUpdate() {
+ if (refresher != null && ui != null) {
+ LOG.info("Removing Handler Callback");
+ view.removeCallbacks(refresher);
+ }
+ }
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
new file mode 100644
index 000000000..b24f6be3a
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
@@ -0,0 +1,187 @@
+package org.briarproject.android.blogs;
+
+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.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.briarproject.R;
+import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
+import org.briarproject.android.controller.handler.UiResultExceptionHandler;
+import org.briarproject.android.fragment.BaseFragment;
+import org.briarproject.api.blogs.BlogPostHeader;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.briarproject.android.blogs.BasePostPagerFragment.BlogPostPagerAdapter.INVALID_POSITION;
+import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+
+abstract class BasePostPagerFragment extends BaseFragment
+ implements OnBlogPostAddedListener {
+
+ private ViewPager pager;
+ private BlogPostPagerAdapter postPagerAdapter;
+ private MessageId postId;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle state) {
+
+ Bundle args;
+ if (state == null) args = getArguments();
+ else args = state;
+ byte[] p = args.getByteArray(POST_ID);
+ if (p == null)
+ throw new IllegalStateException("No post ID in args");
+ postId = new MessageId(p);
+
+ View v = inflater.inflate(R.layout.fragment_blog_post_pager, container,
+ false);
+ pager = (ViewPager) v.findViewById(R.id.pager);
+ postPagerAdapter = new BlogPostPagerAdapter(getChildFragmentManager());
+ listener.showLoadingScreen(false, R.string.progress_title_please_wait);
+
+ return v;
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (postId == null) {
+ MessageId selected = getSelectedPost();
+ if (selected != null) loadBlogPosts(selected);
+ } else {
+ loadBlogPosts(postId);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ MessageId selected = getSelectedPost();
+ if (selected != null)
+ outState.putByteArray(POST_ID, selected.getBytes());
+ }
+
+ @Override
+ public void onBlogPostAdded(BlogPostHeader header, boolean local) {
+ loadBlogPost(header);
+ }
+
+ abstract void loadBlogPosts(final MessageId select);
+
+ abstract BaseController getController();
+
+ protected void onBlogPostsLoaded(MessageId select,
+ Collection posts) {
+
+ postId = null;
+ postPagerAdapter.setPosts(posts);
+ selectPost(select);
+ }
+
+ protected void onBlogPostsLoadedException(DbException exception) {
+ // TODO: Decide how to handle errors in the UI
+ finish();
+ }
+
+ private void loadBlogPost(BlogPostHeader header) {
+ getController().loadBlogPost(header,
+ new UiResultExceptionHandler(
+ getActivity()) {
+ @Override
+ public void onResultUi(BlogPostItem post) {
+ addPost(post);
+ }
+
+ @Override
+ public void onExceptionUi(DbException exception) {
+ // TODO: Decide how to handle errors in the UI
+ finish();
+ }
+ });
+ }
+
+ @Nullable
+ private MessageId getSelectedPost() {
+ if (postPagerAdapter.getCount() == 0) return null;
+ int position = pager.getCurrentItem();
+ return postPagerAdapter.getPost(position).getId();
+ }
+
+ private void selectPost(MessageId m) {
+ int pos = postPagerAdapter.getPostPosition(m);
+ if (pos != INVALID_POSITION) {
+ pager.setAdapter(postPagerAdapter);
+ pager.setCurrentItem(pos);
+ }
+ }
+
+ protected void addPost(BlogPostItem post) {
+ MessageId selected = getSelectedPost();
+ postPagerAdapter.addPost(post);
+ if (selected != null) selectPost(selected);
+ }
+
+ @UiThread
+ static class BlogPostPagerAdapter extends FragmentStatePagerAdapter {
+
+ static final int INVALID_POSITION = -1;
+ private final List posts = new ArrayList<>();
+
+ private BlogPostPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ @Override
+ public int getCount() {
+ return posts.size();
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ BlogPostItem post = posts.get(position);
+ return FeedPostFragment.newInstance(post.getGroupId(), post.getId());
+ }
+
+ private BlogPostItem getPost(int position) {
+ return posts.get(position);
+ }
+
+ private void setPosts(Collection 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();
+ }
+
+ private int getPostPosition(MessageId m) {
+ int count = getCount();
+ for (int i = 0; i < count; i++) {
+ if (getPost(i).getId().equals(m)) {
+ return i;
+ }
+ }
+ return INVALID_POSITION;
+ }
+ }
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
index 249d0ff7c..34ba66f98 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
@@ -2,13 +2,6 @@ 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;
@@ -16,42 +9,25 @@ 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.INVISIBLE;
import static android.view.View.VISIBLE;
public class BlogActivity extends BriarActivity implements
- OnBlogPostAddedListener,
- OnBlogPostClickListener, BaseFragmentListener {
+ OnBlogPostAddedListener, OnBlogPostClickListener, BaseFragmentListener {
static final int REQUEST_WRITE_POST = 1;
static final int REQUEST_SHARE = 2;
- public static final String BLOG_NAME = "briar.BLOG_NAME";
+ static final String BLOG_NAME = "briar.BLOG_NAME";
static final String IS_NEW_BLOG = "briar.IS_NEW_BLOG";
+ static final String POST_ID = "briar.POST_ID";
- 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;
@Inject
BlogController blogController;
@@ -64,63 +40,30 @@ public class BlogActivity extends BriarActivity implements
Intent i = getIntent();
byte[] b = i.getByteArrayExtra(GROUP_ID);
if (b == null) throw new IllegalStateException("No group ID in intent");
- groupId = new GroupId(b);
+ GroupId groupId = new GroupId(b);
blogController.setGroupId(groupId);
// Name of the blog
- blogName = i.getStringExtra(BLOG_NAME);
+ String blogName = i.getStringExtra(BLOG_NAME);
if (blogName != null) setTitle(blogName);
// Was this blog just created?
- isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
+ boolean isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
- setContentView(R.layout.activity_blog);
-
- pager = (ViewPager) findViewById(R.id.pager);
+ setContentView(R.layout.activity_fragment_container);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
- blogPagerAdapter = new BlogPagerAdapter(getSupportFragmentManager());
- postPagerAdapter = new BlogPostPagerAdapter(
- getSupportFragmentManager());
-
- if (state == null || state.getByteArray(POST_ID) == null) {
- // The blog fragment has its own progress bar
- hideLoadingScreen();
- pager.setAdapter(blogPagerAdapter);
- savedPostId = null;
- } else {
- // Adapter will be set in selectPostInPostPager()
- savedPostId = new MessageId(state.getByteArray(POST_ID));
+ if (state == null) {
+ BlogFragment f = BlogFragment.newInstance(groupId, blogName, isNew);
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.fragmentContainer, f, f.getUniqueTag())
+ .commit();
}
}
@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();
- }
}
@Override
@@ -128,6 +71,21 @@ public class BlogActivity extends BriarActivity implements
component.inject(this);
}
+ @Override
+ public void onBlogPostAdded(BlogPostHeader header, boolean local) {
+ // all our fragments are implementing and registering that hook,
+ // so we don't need to do that ourselves
+ }
+
+ @Override
+ public void onBlogPostClick(BlogPostItem post) {
+ BlogPostPagerFragment f = BlogPostPagerFragment.newInstance(post.getId());
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.fragmentContainer, f, f.getUniqueTag())
+ .addToBackStack(f.getUniqueTag())
+ .commit();
+ }
+
@Override
public void showLoadingScreen(boolean isBlocking, int stringId) {
progressBar.setVisibility(VISIBLE);
@@ -135,176 +93,10 @@ public class BlogActivity extends BriarActivity implements
@Override
public void hideLoadingScreen() {
- progressBar.setVisibility(GONE);
+ progressBar.setVisibility(INVISIBLE);
}
@Override
public void onFragmentCreated(String tag) {
-
}
-
- @Override
- public void onBlogPostClick(BlogPostItem post) {
- loadBlogPosts(post.getId());
- }
-
- private void loadBlogPosts(final MessageId select) {
- blogController.loadBlogPosts(
- new UiResultExceptionHandler, DbException>(
- this) {
- @Override
- public void onResultUi(Collection 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();
- }
- });
- }
-
- @Override
- 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(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) {
- 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);
- }
- }
- }
-
- @UiThread
- 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() {
- return fragment;
- }
- }
-
- @UiThread
- private static class BlogPostPagerAdapter
- extends FragmentStatePagerAdapter {
-
- private final List 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 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();
- }
- }
-
}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
index b3b87a113..0d9a0fe98 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
@@ -5,8 +5,8 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
-import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
+import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
@@ -59,6 +59,7 @@ public class BlogFragment extends BaseFragment implements
private BlogPostAdapter adapter;
private BriarRecyclerView list;
private MenuItem writeButton, deleteButton;
+ private boolean isMyBlog = false, canDeleteBlog = false;
static BlogFragment newInstance(GroupId groupId, String name,
boolean isNew) {
@@ -114,7 +115,7 @@ public class BlogFragment extends BaseFragment implements
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
- blogController.setGroupId(groupId);
+ blogController.setOnBlogPostAddedListener(this);
}
@Override
@@ -141,7 +142,9 @@ public class BlogFragment extends BaseFragment implements
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.blogs_blog_actions, menu);
writeButton = menu.findItem(R.id.action_write_blog_post);
+ if (isMyBlog) writeButton.setVisible(true);
deleteButton = menu.findItem(R.id.action_blog_delete);
+ if (canDeleteBlog) deleteButton.setVisible(true);
super.onCreateOptionsMenu(menu, inflater);
}
@@ -161,8 +164,8 @@ public class BlogFragment extends BaseFragment implements
new Intent(getActivity(), WriteBlogPostActivity.class);
i.putExtra(GROUP_ID, groupId.getBytes());
i.putExtra(BLOG_NAME, blogName);
- ActivityCompat.startActivityForResult(getActivity(), i,
- REQUEST_WRITE_POST, options.toBundle());
+ startActivityForResult(i, REQUEST_WRITE_POST,
+ options.toBundle());
return true;
case R.id.action_blog_share:
Intent i2 = new Intent(getActivity(), ShareBlogActivity.class);
@@ -190,9 +193,10 @@ public class BlogFragment extends BaseFragment implements
super.onActivityResult(request, result, data);
if (request == REQUEST_WRITE_POST && result == RESULT_OK) {
- displaySnackbar(R.string.blogs_blog_post_created);
+ displaySnackbar(R.string.blogs_blog_post_created, true);
+ loadBlogPosts(true);
} else if (request == REQUEST_SHARE && result == RESULT_OK) {
- displaySnackbar(R.string.blogs_sharing_snackbar);
+ displaySnackbar(R.string.blogs_sharing_snackbar, true);
}
}
@@ -211,9 +215,9 @@ public class BlogFragment extends BaseFragment implements
adapter.add(post);
if (local) {
list.scrollToPosition(0);
- displaySnackbar(R.string.blogs_blog_post_created);
+ displaySnackbar(R.string.blogs_blog_post_created, false);
} else {
- displaySnackbar(R.string.blogs_blog_post_received);
+ displaySnackbar(R.string.blogs_blog_post_received, true);
}
}
@@ -243,13 +247,13 @@ public class BlogFragment extends BaseFragment implements
@Override
public void onExceptionUi(DbException exception) {
// TODO: Decide how to handle errors in the UI
- getActivity().finish();
+ finish();
}
});
}
private void checkIfThisIsMyBlog() {
- blogController.canDeleteBlog(
+ blogController.isMyBlog(
new UiResultExceptionHandler(
getActivity()) {
@Override
@@ -262,7 +266,7 @@ public class BlogFragment extends BaseFragment implements
@Override
public void onExceptionUi(DbException exception) {
// TODO: Decide how to handle errors in the UI
- getActivity().finish();
+ finish();
}
});
}
@@ -281,25 +285,39 @@ public class BlogFragment extends BaseFragment implements
@Override
public void onExceptionUi(DbException exception) {
// TODO: Decide how to handle errors in the UI
- getActivity().finish();
+ finish();
}
});
}
private void showWriteButton() {
+ isMyBlog = true;
if (writeButton != null)
writeButton.setVisible(true);
}
private void showDeleteButton() {
+ canDeleteBlog = true;
if (deleteButton != null)
deleteButton.setVisible(true);
}
- private void displaySnackbar(int stringId) {
+ private void displaySnackbar(int stringId, boolean scroll) {
Snackbar snackbar =
- Snackbar.make(list, stringId, Snackbar.LENGTH_SHORT);
+ Snackbar.make(list, stringId, Snackbar.LENGTH_LONG);
snackbar.getView().setBackgroundResource(R.color.briar_primary);
+ if (scroll) {
+ View.OnClickListener onClick = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ list.smoothScrollToPosition(0);
+ }
+ };
+ snackbar.setActionTextColor(ContextCompat
+ .getColor(getContext(),
+ R.color.briar_button_positive));
+ snackbar.setAction(R.string.blogs_blog_post_scroll_to, onClick);
+ }
snackbar.show();
}
@@ -335,7 +353,7 @@ public class BlogFragment extends BaseFragment implements
@Override
public void onExceptionUi(DbException exception) {
// TODO: Decide how to handle errors in the UI
- getActivity().finish();
+ finish();
}
});
}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
index 926ce7f37..b70a36062 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
@@ -3,35 +3,23 @@ package org.briarproject.android.blogs;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import org.briarproject.R;
import org.briarproject.android.ActivityComponent;
import org.briarproject.android.controller.handler.UiResultExceptionHandler;
-import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.MessageId;
-import java.util.logging.Logger;
-
import javax.inject.Inject;
-import static org.briarproject.android.util.AndroidUtils.MIN_RESOLUTION;
+import static org.briarproject.android.blogs.BlogActivity.POST_ID;
-public class BlogPostFragment extends BaseFragment {
+public class BlogPostFragment extends BasePostFragment {
public final static String TAG = BlogPostFragment.class.getName();
- private static final Logger LOG = Logger.getLogger(TAG);
- private static final String BLOG_POST_ID = "briar.BLOG_POST_ID";
-
- private View view;
private MessageId postId;
- private BlogPostViewHolder ui;
- private BlogPostItem post;
- private Runnable refresher;
@Inject
BlogController blogController;
@@ -40,7 +28,7 @@ public class BlogPostFragment extends BaseFragment {
BlogPostFragment f = new BlogPostFragment();
Bundle bundle = new Bundle();
- bundle.putByteArray(BLOG_POST_ID, postId.getBytes());
+ bundle.putByteArray(POST_ID, postId.getBytes());
f.setArguments(bundle);
return f;
@@ -50,16 +38,18 @@ public class BlogPostFragment extends BaseFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- setHasOptionsMenu(true);
- byte[] b = getArguments().getByteArray(BLOG_POST_ID);
- if (b == null) throw new IllegalStateException("No post ID in args");
- postId = new MessageId(b);
+ Bundle args = getArguments();
+ byte[] p = args.getByteArray(POST_ID);
+ if (p == null) throw new IllegalStateException("No post ID in args");
+ postId = new MessageId(p);
- view = inflater.inflate(R.layout.fragment_blog_post, container,
- false);
- ui = new BlogPostViewHolder(view);
- return view;
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @Override
+ public String getUniqueTag() {
+ return TAG;
}
@Override
@@ -75,62 +65,12 @@ public class BlogPostFragment extends BaseFragment {
getActivity()) {
@Override
public void onResultUi(BlogPostItem post) {
- listener.hideLoadingScreen();
- BlogPostFragment.this.post = post;
- ui.bindItem(post);
- startPeriodicUpdate();
+ onBlogPostLoaded(post);
}
-
@Override
public void onExceptionUi(DbException exception) {
- // TODO: Decide how to handle errors in the UI
- finish();
+ onBlogPostLoadException(exception);
}
});
}
-
- @Override
- public void onStop() {
- super.onStop();
- stopPeriodicUpdate();
- }
-
- @Override
- public boolean onOptionsItemSelected(final MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- getActivity().onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- @Override
- public String getUniqueTag() {
- return TAG;
- }
-
- private void startPeriodicUpdate() {
- refresher = new Runnable() {
- @Override
- public void run() {
- if (ui == null) return;
- LOG.info("Updating Content...");
-
- ui.updateDate(post.getTimestamp());
- view.postDelayed(refresher, MIN_RESOLUTION);
- }
- };
- LOG.info("Adding Handler Callback");
- view.postDelayed(refresher, MIN_RESOLUTION);
- }
-
- private void stopPeriodicUpdate() {
- if (refresher != null && ui != null) {
- LOG.info("Removing Handler Callback");
- view.removeCallbacks(refresher);
- }
- }
-
}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
new file mode 100644
index 000000000..54e646f9c
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
@@ -0,0 +1,66 @@
+package org.briarproject.android.blogs;
+
+import android.os.Bundle;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.controller.handler.UiResultExceptionHandler;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+import javax.inject.Inject;
+
+import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+
+
+public class BlogPostPagerFragment extends BasePostPagerFragment {
+
+ public final static String TAG = BlogPostPagerFragment.class.getName();
+
+ @Inject
+ BlogController blogController;
+
+ static BlogPostPagerFragment newInstance(MessageId postId) {
+ BlogPostPagerFragment f = new BlogPostPagerFragment();
+
+ Bundle args = new Bundle();
+ args.putByteArray(POST_ID, postId.getBytes());
+ f.setArguments(args);
+
+ return f;
+ }
+
+ @Override
+ public void injectFragment(ActivityComponent component) {
+ component.inject(this);
+ blogController.setOnBlogPostAddedListener(this);
+ }
+
+ @Override
+ public String getUniqueTag() {
+ return TAG;
+ }
+
+ @Override
+ BaseController getController() {
+ return blogController;
+ }
+
+ void loadBlogPosts(final MessageId select) {
+ blogController.loadBlogPosts(
+ new UiResultExceptionHandler, DbException>(
+ getActivity()) {
+ @Override
+ public void onResultUi(Collection posts) {
+ onBlogPostsLoaded(select, posts);
+ }
+
+ @Override
+ public void onExceptionUi(DbException exception) {
+ onBlogPostsLoadedException(exception);
+ }
+ });
+ }
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
index 9e6f57748..dbdd11127 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
@@ -195,7 +195,12 @@ public class FeedFragment extends BaseFragment implements
@Override
public void onBlogPostClick(BlogPostItem post) {
- // TODO Open detail view of post
+ FeedPostPagerFragment f = FeedPostPagerFragment
+ .newInstance(post.getId());
+ getActivity().getSupportFragmentManager().beginTransaction()
+ .replace(R.id.content_fragment, f, f.getUniqueTag())
+ .addToBackStack(f.getUniqueTag())
+ .commit();
}
@Override
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java
new file mode 100644
index 000000000..5b4841cd4
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/FeedPostFragment.java
@@ -0,0 +1,85 @@
+package org.briarproject.android.blogs;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.controller.handler.UiResultExceptionHandler;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.MessageId;
+
+import javax.inject.Inject;
+
+import static org.briarproject.android.BriarActivity.GROUP_ID;
+import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+
+public class FeedPostFragment extends BasePostFragment {
+
+ public final static String TAG = FeedPostFragment.class.getName();
+
+ private MessageId postId;
+ private GroupId blogId;
+
+ @Inject
+ FeedController feedController;
+
+ static FeedPostFragment newInstance(GroupId blogId, MessageId postId) {
+ FeedPostFragment f = new FeedPostFragment();
+
+ Bundle bundle = new Bundle();
+ bundle.putByteArray(GROUP_ID, blogId.getBytes());
+ bundle.putByteArray(POST_ID, postId.getBytes());
+
+ f.setArguments(bundle);
+ return f;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ Bundle args = getArguments();
+ byte[] b = args.getByteArray(GROUP_ID);
+ if (b == null) throw new IllegalStateException("No group ID in args");
+ blogId = new GroupId(b);
+
+ byte[] p = args.getByteArray(POST_ID);
+ if (p == null) throw new IllegalStateException("No post ID in args");
+ postId = new MessageId(p);
+
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+ @Override
+ public void injectFragment(ActivityComponent component) {
+ component.inject(this);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ feedController.loadBlogPost(blogId, postId,
+ new UiResultExceptionHandler(
+ getActivity()) {
+ @Override
+ public void onResultUi(BlogPostItem post) {
+ onBlogPostLoaded(post);
+ }
+ @Override
+ public void onExceptionUi(DbException exception) {
+ onBlogPostLoadException(exception);
+ }
+ });
+ }
+
+ @Override
+ public String getUniqueTag() {
+ return TAG;
+ }
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
new file mode 100644
index 000000000..db30ac1f3
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
@@ -0,0 +1,65 @@
+package org.briarproject.android.blogs;
+
+import android.os.Bundle;
+
+import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.controller.handler.UiResultExceptionHandler;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+import javax.inject.Inject;
+
+import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+
+public class FeedPostPagerFragment extends BasePostPagerFragment {
+
+ public final static String TAG = FeedPostPagerFragment.class.getName();
+
+ @Inject
+ FeedController feedController;
+
+ static FeedPostPagerFragment newInstance(MessageId postId) {
+ FeedPostPagerFragment f = new FeedPostPagerFragment();
+
+ Bundle args = new Bundle();
+ args.putByteArray(POST_ID, postId.getBytes());
+ f.setArguments(args);
+
+ return f;
+ }
+
+ @Override
+ public void injectFragment(ActivityComponent component) {
+ component.inject(this);
+ feedController.setOnBlogPostAddedListener(this);
+ }
+
+ @Override
+ public String getUniqueTag() {
+ return TAG;
+ }
+
+ @Override
+ BaseController getController() {
+ return feedController;
+ }
+
+ void loadBlogPosts(final MessageId select) {
+ feedController.loadBlogPosts(
+ new UiResultExceptionHandler, DbException>(
+ getActivity()) {
+ @Override
+ public void onResultUi(Collection posts) {
+ onBlogPostsLoaded(select, posts);
+ }
+
+ @Override
+ public void onExceptionUi(DbException exception) {
+ onBlogPostsLoadedException(exception);
+ }
+ });
+ }
+
+}