diff --git a/briar-android/res/drawable/ic_chat.xml b/briar-android/res/drawable/ic_chat.xml
deleted file mode 100644
index 04f9fdcdfd7427decad183a5e0a8ae3434f2b4f8..0000000000000000000000000000000000000000
--- a/briar-android/res/drawable/ic_chat.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:alpha="0.54"
-        android:viewportHeight="24.0"
-        android:viewportWidth="24.0">
-	<path
-		android:fillColor="#FF000000"
-		android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z"/>
-</vector>
diff --git a/briar-android/res/drawable/ic_expand_more_black_24dp.xml b/briar-android/res/drawable/ic_expand_more_black_24dp.xml
deleted file mode 100644
index 8d57dbc10f814f6014d3965c9a8a268d080bc775..0000000000000000000000000000000000000000
--- a/briar-android/res/drawable/ic_expand_more_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
-</vector>
diff --git a/briar-android/res/layout/activity_fragment_container.xml b/briar-android/res/layout/activity_fragment_container.xml
index e6c20760fb5078de5def86eec38402fc2db9042a..8bf59ee5acc2ae1186ebae445268a3028fbb7bae 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">
+
+	<ProgressBar
+		android:id="@+id/progressBar"
+		style="?android:attr/progressBarStyleLarge"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_gravity="center"
+		android:visibility="invisible"/>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/briar-android/res/layout/dropdown_author.xml b/briar-android/res/layout/dropdown_author.xml
deleted file mode 100644
index 1af9c5965ab51dd1452d8c38e80ed89d66b90578..0000000000000000000000000000000000000000
--- a/briar-android/res/layout/dropdown_author.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	xmlns:tools="http://schemas.android.com/tools"
-	android:layout_width="match_parent"
-	android:layout_height="match_parent"
-	android:gravity="center_vertical">
-
-	<de.hdodenhof.circleimageview.CircleImageView
-		android:id="@+id/avatarView"
-		style="@style/BriarAvatar"
-		android:layout_width="@dimen/dropdown_picture_size"
-		android:layout_height="@dimen/dropdown_picture_size"
-		android:layout_margin="@dimen/margin_small"
-		tools:src="@drawable/ic_launcher"/>
-
-	<TextView
-		android:id="@+id/nameView"
-		android:layout_width="0dp"
-		android:layout_height="wrap_content"
-		android:layout_margin="@dimen/margin_small"
-		android:layout_weight="1"
-		android:ellipsize="end"
-		android:singleLine="true"
-		android:textSize="@dimen/text_size_medium"
-		tools:text="This is a name of an author. It can be quite long."/>
-
-</LinearLayout>
\ 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 7a0df0d0b5d964b25bd2ef3a6b5c3cd1630f7b3d..18ec1f417cd1f72ba54f917eabb8913ea2c04631 100644
--- a/briar-android/res/layout/fragment_blog_post.xml
+++ b/briar-android/res/layout/fragment_blog_post.xml
@@ -6,7 +6,12 @@
 
 	<FrameLayout
 		android:layout_width="wrap_content"
-		android:layout_height="wrap_content">
+		android:layout_height="wrap_content"
+		android:descendantFocusability="beforeDescendants"
+		android:focusable="true"
+		android:focusableInTouchMode="true">
+		<!-- Above Focusability attributes prevent automatic scroll-down,
+		     because body text is selectable -->
 
 		<include
 			android:id="@+id/postLayout"
@@ -15,6 +20,13 @@
 			android:layout_width="wrap_content"
 			android:layout_height="wrap_content"/>
 
+		<ProgressBar
+			android:id="@+id/progressBar"
+			style="?android:attr/progressBarStyleLarge"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_gravity="center"/>
+
 	</FrameLayout>
 
 </ScrollView>
diff --git a/briar-android/res/layout/activity_blog.xml b/briar-android/res/layout/fragment_blog_post_pager.xml
similarity index 79%
rename from briar-android/res/layout/activity_blog.xml
rename to briar-android/res/layout/fragment_blog_post_pager.xml
index 3ff8d409e0e60ee2b749b2e51726b8af8e5cab7c..626dcaf26e21df50e8349d692406ef4f0c4c3a4c 100644
--- a/briar-android/res/layout/activity_blog.xml
+++ b/briar-android/res/layout/fragment_blog_post_pager.xml
@@ -1,15 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
-	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
 	android:layout_height="match_parent">
 
 	<android.support.v4.view.ViewPager
 		android:id="@+id/pager"
+		xmlns:android="http://schemas.android.com/apk/res/android"
 		android:layout_width="match_parent"
-		android:layout_height="match_parent"
-		tools:context=".android.blogs.BlogActivity"/>
+		android:layout_height="match_parent"/>
 
 	<ProgressBar
 		android:id="@+id/progressBar"
diff --git a/briar-android/res/layout/fragment_blogs.xml b/briar-android/res/layout/fragment_blogs.xml
deleted file mode 100644
index 2e618a9b1e78a86cde64fc731ffa5d318852a0da..0000000000000000000000000000000000000000
--- a/briar-android/res/layout/fragment_blogs.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	android:layout_width="match_parent"
-	android:layout_height="match_parent"
-	android:orientation="vertical">
-
-	<android.support.design.widget.TabLayout
-		android:id="@+id/tabLayout"
-		style="@style/BriarTabLayout"
-		android:layout_width="match_parent"
-		android:layout_height="wrap_content">
-
-		<android.support.design.widget.TabItem
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:text="@string/blogs_feed"/>
-
-		<android.support.design.widget.TabItem
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:text="@string/blogs_my_blogs"/>
-
-		<android.support.design.widget.TabItem
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:text="@string/blogs_blog_list"/>
-
-		<android.support.design.widget.TabItem
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:text="@string/blogs_available_blogs"/>
-
-		<android.support.design.widget.TabItem
-			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:text="@string/blogs_drafts"/>
-
-	</android.support.design.widget.TabLayout>
-
-	<android.support.v4.view.ViewPager
-		android:id="@+id/pager"
-		android:layout_width="match_parent"
-		android:layout_height="match_parent"/>
-
-</LinearLayout>
\ No newline at end of file
diff --git a/briar-android/res/layout/fragment_blogs_my.xml b/briar-android/res/layout/fragment_blogs_my.xml
deleted file mode 100644
index 288adfaa3937ea3d0b242b6c7177007b3e994d67..0000000000000000000000000000000000000000
--- a/briar-android/res/layout/fragment_blogs_my.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<org.briarproject.android.util.BriarRecyclerView
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	xmlns:tools="http://schemas.android.com/tools"
-	android:layout_width="match_parent"
-	android:layout_height="match_parent"
-	tools:listitem="@layout/list_item_blog"/>
diff --git a/briar-android/res/layout/list_item_blog_comment.xml b/briar-android/res/layout/list_item_blog_comment.xml
index bdbe42842d003db9c92fc6e1a8515366da1957ff..1be478ab2fd9f60b3e7235034c1ee8f9e52544d3 100644
--- a/briar-android/res/layout/list_item_blog_comment.xml
+++ b/briar-android/res/layout/list_item_blog_comment.xml
@@ -29,7 +29,6 @@
 		android:paddingLeft="@dimen/listitem_vertical_margin"
 		android:paddingRight="@dimen/listitem_vertical_margin"
 		android:textColor="@color/briar_text_secondary"
-		android:textIsSelectable="true"
 		android:textSize="@dimen/text_size_small"
 		tools:text="This is a comment that appears below a blog post. Usually, it is expected to be rather short. Not much longer than this one."/>
 
diff --git a/briar-android/res/layout/list_item_blog_post.xml b/briar-android/res/layout/list_item_blog_post.xml
index 8b136f2b7d5682623d1adb7a777895fb5a457b8c..d3cd14d489ab70c9b6dced4a313af848eb68807a 100644
--- a/briar-android/res/layout/list_item_blog_post.xml
+++ b/briar-android/res/layout/list_item_blog_post.xml
@@ -6,7 +6,8 @@
 	xmlns:app="http://schemas.android.com/apk/res-auto"
 	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
-	android:layout_height="wrap_content">
+	android:layout_height="wrap_content"
+	android:foreground="?android:attr/selectableItemBackground">
 
 	<LinearLayout
 		android:layout_width="match_parent"
@@ -55,7 +56,6 @@
 				android:layout_height="wrap_content"
 				android:layout_below="@+id/authorView"
 				android:textColor="@color/briar_text_secondary"
-				android:textIsSelectable="true"
 				android:textSize="@dimen/text_size_medium"
 				tools:text="This is a body text that shows the content of a blog post.\n\nThis one is not short, but it is also not too long."/>
 
diff --git a/briar-android/res/menu/blogs_my_actions.xml b/briar-android/res/menu/blogs_my_actions.xml
deleted file mode 100644
index 9a3ce5b49a27da3c2484e66fe542ca375b669b2b..0000000000000000000000000000000000000000
--- a/briar-android/res/menu/blogs_my_actions.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	xmlns:app="http://schemas.android.com/apk/res-auto">
-
-	<item
-		android:id="@+id/action_create_blog"
-		android:icon="@drawable/ic_add_white"
-		android:title="@string/blogs_my_blogs_create"
-		app:showAsAction="ifRoom"/>
-
-</menu>
\ No newline at end of file
diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml
index e7cb49b1526b08ad1bae60378005f885793d46a0..0ac3140eeef7b00dadaa8cddaf3302d4d34c22eb 100644
--- a/briar-android/res/values/color.xml
+++ b/briar-android/res/values/color.xml
@@ -35,7 +35,6 @@
 	<color name="menu_background">#FFFFFF</color>
 
 	<color name="spinner_border">#61000000</color> <!-- 38% Black -->
-	<color name="spinner_arrow">@color/briar_blue_dark</color>
 	<color name="forum_discussion_nested_line">#cfd2d4</color>
 	<color name="forum_cell_highlight">#ffffff</color>
 </resources>
\ No newline at end of file
diff --git a/briar-android/res/values/dimens.xml b/briar-android/res/values/dimens.xml
index 9f62ff0944d8491f42245eeecb7b4a858524a423..c8e7eca7d0dfa6c3a8b2a51123547edf60fb748c 100644
--- a/briar-android/res/values/dimens.xml
+++ b/briar-android/res/values/dimens.xml
@@ -27,7 +27,6 @@
 	<dimen name="listitem_picture_frame_size">53dp</dimen>
 	<dimen name="listitem_picture_frame_offset">2dp</dimen>
 	<dimen name="listitem_selectable_picture_size">40dp</dimen>
-	<dimen name="dropdown_picture_size">32dp</dimen>
 	<dimen name="avatar_forum_size">48dp</dimen>
 	<dimen name="avatar_border_width">2dp</dimen>
 	<dimen name="avatar_text_size">30sp</dimen>
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index ba764c356d3880c5a16081cb1d98e02dd48466dd..e866545097665ba4ad001540e73f0e50ce157360 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -73,6 +73,7 @@
 	<string name="offline">Offline</string>
 	<string name="send">Send</string>
 	<string name="no_data">No data</string>
+	<string name="ellipsis">…</string>
 
 	<!-- Contacts and Private Conversations-->
 	<string name="no_contacts">It seems that you are new here and have no contacts yet.\n\nTap the + icon at the top and follow the instructions to add some friends to your list.\n\nPlease remember: You can only add new contacts face-to-face to prevent anyone from impersonating you or reading your messages in the future.</string>
@@ -199,18 +200,16 @@
 	<string name="nobody">Nobody</string>
 
 	<!-- Blogs -->
-	<string name="blogs_feed">Feed</string>
-	<string name="blogs_my_blogs">My Blogs</string>
 	<string name="blogs_my_blogs_create">Create Blog</string>
 	<string name="blogs_my_blogs_label">Add new Blog</string>
 	<string name="blogs_my_blogs_create_hint_title">Blog title (cannot be changed later)</string>
 	<string name="blogs_my_blogs_create_hint_desc">A short description of your new blog</string>
 	<string name="blogs_my_blogs_create_hint_desc_explanation">Potential readers may or may not subscribe to your blog based on the content of the description.</string>
-	<string name="blogs_my_blogs_empty_state">You don\'t have any blogs.\n\nWhy don\'t you create one now by clicking the plus in the top right screen corner?</string>
 	<string name="blogs_my_blogs_created">Blog created</string>
 	<string name="blogs_blog_is_empty">This blog is empty</string>
 	<string name="blogs_other_blog_empty_state">This blog is currently empty.\n\nEither the author hasn\'t written anything yet, or the person who shared this blog with you needs to come online, so posts can be synchronized.</string>
 	<string name="tag_new">NEW</string>
+	<string name="read_more">read more</string>
 	<string name="blogs_write_blog_post">Write Blog Post</string>
 	<string name="blogs_write_blog_post_title_hint">Add a title (optional)</string>
 	<string name="blogs_write_blog_post_body_hint">Type your blog post here</string>
@@ -231,7 +230,6 @@
 
 	<string name="blogs_blog_list">Blog List</string>
 	<string name="blogs_available_blogs">Available Blogs</string>
-	<string name="blogs_drafts">Drafts</string>
 
 	<!-- Blog Sharing -->
 	<string name="blogs_sharing_share">Share Blog</string>
@@ -312,7 +310,6 @@
 
 	<!-- Multiple Identities -->
 	<string name="anonymous">Anonymous</string>
-	<string name="new_identity_item">New identity\u2026</string>
 	<string name="new_identity_title">New Identity</string>
 	<string name="create_identity_button">Create Identity</string>
 	<string name="identity_created_toast">Identity created</string>
diff --git a/briar-android/src/org/briarproject/android/ActivityComponent.java b/briar-android/src/org/briarproject/android/ActivityComponent.java
index 2a0d82c4b26811aec01e7b8656e1aa0e169e6dd3..baee29d41e90080be85f317de5c3130415935ff9 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/Destroyable.java b/briar-android/src/org/briarproject/android/Destroyable.java
index a9a9ef8ce5063d305c5db2a40287f6c57d3291ba..17c7dc8503367e81337d47f0e984e8c5d0ef0077 100644
--- a/briar-android/src/org/briarproject/android/Destroyable.java
+++ b/briar-android/src/org/briarproject/android/Destroyable.java
@@ -2,7 +2,7 @@ package org.briarproject.android;
 
 import android.support.annotation.UiThread;
 
-interface Destroyable {
+public interface Destroyable {
 
 	@UiThread
 	boolean hasBeenDestroyed();
diff --git a/briar-android/src/org/briarproject/android/NavDrawerActivity.java b/briar-android/src/org/briarproject/android/NavDrawerActivity.java
index 6381bc9cd1491eefb9b94cde41b0bfca989e12b4..d4bacf55a9517b9b93d33ba542b7fd516ed6e2d1 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/BaseControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
index ab513217afa2a58a0dea5220a7b8275e247a3921..3c4f1bc21bbee32c2be22b73ae56f772acb96c5a 100644
--- a/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/BaseControllerImpl.java
@@ -59,6 +59,9 @@ abstract class BaseControllerImpl extends DbControllerImpl
 	@Override
 	@CallSuper
 	public void onStart() {
+		if (listener == null)
+			throw new IllegalStateException(
+					"OnBlogPostAddedListener needs to be attached");
 		eventBus.addListener(this);
 	}
 
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 0000000000000000000000000000000000000000..06153e422f286c8278c811af08c4d1b53e32a9d0
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostFragment.java
@@ -0,0 +1,109 @@
+package org.briarproject.android.blogs;
+
+import android.os.Bundle;
+import android.support.annotation.CallSuper;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ProgressBar;
+
+import org.briarproject.R;
+import org.briarproject.android.fragment.BaseFragment;
+import org.briarproject.api.db.DbException;
+
+import java.util.logging.Logger;
+
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+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 ProgressBar progressBar;
+	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);
+		progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
+		progressBar.setVisibility(VISIBLE);
+		ui = new BlogPostViewHolder(view);
+		return view;
+	}
+
+	@CallSuper
+	@Override
+	public void onStart() {
+		super.onStart();
+		startPeriodicUpdate();
+	}
+
+	@CallSuper
+	@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);
+		}
+	}
+
+	@UiThread
+	protected void onBlogPostLoaded(BlogPostItem post) {
+		progressBar.setVisibility(INVISIBLE);
+		this.post = post;
+		ui.bindItem(post);
+	}
+
+	@UiThread
+	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 0000000000000000000000000000000000000000..e27c1470f5fe09d2e401b53189a5a8da3dfea3c9
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BasePostPagerFragment.java
@@ -0,0 +1,177 @@
+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 android.widget.ProgressBar;
+
+import org.briarproject.R;
+import org.briarproject.android.blogs.BaseController.OnBlogPostAddedListener;
+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 android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+import static org.briarproject.android.blogs.BasePostPagerFragment.BlogPostPagerAdapter.INVALID_POSITION;
+
+abstract class BasePostPagerFragment extends BaseFragment
+		implements OnBlogPostAddedListener {
+
+	static final String POST_ID = "briar.POST_ID";
+
+	private ViewPager pager;
+	private ProgressBar progressBar;
+	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);
+		progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
+		progressBar.setVisibility(VISIBLE);
+
+		pager = (ViewPager) v.findViewById(R.id.pager);
+		postPagerAdapter = new BlogPostPagerAdapter(getChildFragmentManager());
+
+		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 void loadBlogPost(BlogPostHeader header);
+
+	protected void onBlogPostsLoaded(MessageId select,
+			Collection<BlogPostItem> posts) {
+
+		postId = null;
+		postPagerAdapter.setPosts(posts);
+		selectPost(select);
+	}
+
+	protected void onBlogPostsLoadedException(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) {
+			progressBar.setVisibility(INVISIBLE);
+			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<BlogPostItem> 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<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();
+		}
+
+		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 249d0ff7cf0fc741b7fad3bff73c02c6d908c7d0..bb7a5cc8d3ec4f6f3f86ba492e8606591aaa0fe0 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogActivity.java
@@ -2,56 +2,29 @@ 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.INVISIBLE;
 import static android.view.View.VISIBLE;
 
 public class BlogActivity extends BriarActivity implements
-		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";
 
-	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,68 +37,39 @@ 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);
-
-		setContentView(R.layout.activity_blog);
+		boolean isNew = i.getBooleanExtra(IS_NEW_BLOG, false);
 
-		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));
-		}
-	}
-
-	@Override
-	public void onResume() {
-		super.onResume();
-		if (savedPostId == null) {
-			MessageId selected = getSelectedPostInPostPager();
-			if (selected != null) loadBlogPosts(selected);
-		} else {
-			loadBlogPosts(savedPostId);
+		if (state == null) {
+			BlogFragment f = BlogFragment.newInstance(groupId, blogName, isNew);
+			getSupportFragmentManager().beginTransaction()
+					.replace(R.id.fragmentContainer, f, f.getUniqueTag())
+					.commit();
 		}
 	}
 
 	@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);
 	}
 
 	@Override
-	public void injectActivity(ActivityComponent component) {
-		component.inject(this);
+	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
@@ -135,176 +79,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<Collection<BlogPostItem>, DbException>(
-						this) {
-					@Override
-					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();
-					}
-				});
-	}
-
-	@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<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) {
-		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<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();
-		}
-	}
-
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogController.java b/briar-android/src/org/briarproject/android/blogs/BlogController.java
index 768d29c14cb059bebe4618c93fa7c1c6156ae03e..4d5c35cbc2d3efc3572cadd6c19983376e671e9b 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogController.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogController.java
@@ -21,9 +21,7 @@ public interface BlogController extends BaseController {
 	void loadBlogPost(MessageId m,
 			ResultExceptionHandler<BlogPostItem, DbException> handler);
 
-	void isMyBlog(ResultExceptionHandler<Boolean, DbException> handler);
-
-	void canDeleteBlog(ResultExceptionHandler<Boolean, DbException> handler);
+	void loadBlog(ResultExceptionHandler<BlogItem, DbException> handler);
 
 	void deleteBlog(ResultExceptionHandler<Void, DbException> handler);
 
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
index d70779e34ea17b04f149c318601f736fe6a3597e..ad7b7597d2e40387fb7acb3f0e1f518d68810fa8 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogControllerImpl.java
@@ -3,6 +3,7 @@ package org.briarproject.android.blogs;
 import org.briarproject.android.controller.ActivityLifecycleController;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
 import org.briarproject.api.blogs.Blog;
+import org.briarproject.api.blogs.BlogPostHeader;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.event.BlogPostAddedEvent;
 import org.briarproject.api.event.Event;
@@ -13,6 +14,7 @@ import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
@@ -33,13 +35,6 @@ public class BlogControllerImpl extends BaseControllerImpl
 
 	@Override
 	public void onActivityCreate() {
-		if (activity instanceof OnBlogPostAddedListener) {
-			listener = (OnBlogPostAddedListener) activity;
-		} else {
-			throw new IllegalStateException(
-					"An activity that injects the BlogController must " +
-							"implement the OnBlogPostAddedListener");
-		}
 	}
 
 	@Override
@@ -102,8 +97,8 @@ public class BlogControllerImpl extends BaseControllerImpl
 	}
 
 	@Override
-	public void isMyBlog(
-			final ResultExceptionHandler<Boolean, DbException> handler) {
+	public void loadBlog(
+			final ResultExceptionHandler<BlogItem, DbException> handler) {
 		if (groupId == null) throw new IllegalStateException();
 		runOnDbThread(new Runnable() {
 			@Override
@@ -111,7 +106,12 @@ public class BlogControllerImpl extends BaseControllerImpl
 				try {
 					LocalAuthor a = identityManager.getLocalAuthor();
 					Blog b = blogManager.getBlog(groupId);
-					handler.onResult(b.getAuthor().getId().equals(a.getId()));
+					boolean ours = a.getId().equals(b.getAuthor().getId());
+					boolean removable = blogManager.canBeRemoved(groupId);
+					BlogItem blog = new BlogItem(b,
+							Collections.<BlogPostHeader>emptyList(),
+							ours, removable);
+					handler.onResult(blog);
 				} catch (DbException e) {
 					if (LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -122,24 +122,6 @@ public class BlogControllerImpl extends BaseControllerImpl
 
 	}
 
-	@Override
-	public void canDeleteBlog(
-			final ResultExceptionHandler<Boolean, DbException> handler) {
-		if (groupId == null) throw new IllegalStateException();
-		runOnDbThread(new Runnable() {
-			@Override
-			public void run() {
-				try {
-					handler.onResult(blogManager.canBeRemoved(groupId));
-				} catch (DbException e) {
-					if (LOG.isLoggable(WARNING))
-						LOG.log(WARNING, e.toString(), e);
-					handler.onException(e);
-				}
-			}
-		});
-	}
-
 	@Override
 	public void deleteBlog(
 			final ResultExceptionHandler<Void, DbException> handler) {
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogFragment.java
index b3b87a113c3481a7e7eae63457ad6d3bf0ed5e17..4ff2695e3d8ddfbefbaba41dc4952c683048865a 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;
@@ -28,6 +28,7 @@ import org.briarproject.android.sharing.SharingStatusBlogActivity;
 import org.briarproject.android.util.BriarRecyclerView;
 import org.briarproject.api.blogs.BlogPostHeader;
 import org.briarproject.api.db.DbException;
+import org.briarproject.api.identity.Author;
 import org.briarproject.api.sync.GroupId;
 
 import java.util.Collection;
@@ -59,6 +60,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,14 +116,13 @@ public class BlogFragment extends BaseFragment implements
 	@Override
 	public void injectFragment(ActivityComponent component) {
 		component.inject(this);
-		blogController.setGroupId(groupId);
+		blogController.setOnBlogPostAddedListener(this);
 	}
 
 	@Override
 	public void onStart() {
 		super.onStart();
-		checkIfThisIsMyBlog();
-		checkIfBlogCanBeDeleted();
+		loadBlog();
 	}
 
 	@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);
 		}
 	}
 
@@ -205,15 +209,15 @@ public class BlogFragment extends BaseFragment implements
 	public void onBlogPostAdded(BlogPostHeader header, final boolean local) {
 		blogController.loadBlogPost(header,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						getActivity()) {
+						listener) {
 					@Override
 					public void onResultUi(BlogPostItem post) {
 						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);
 						}
 					}
 
@@ -229,7 +233,7 @@ public class BlogFragment extends BaseFragment implements
 	void loadBlogPosts(final boolean reload) {
 		blogController.loadBlogPosts(
 				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
-						getActivity()) {
+						listener) {
 					@Override
 					public void onResultUi(Collection<BlogPostItem> posts) {
 						if (posts.size() > 0) {
@@ -243,63 +247,68 @@ 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(
-				new UiResultExceptionHandler<Boolean, DbException>(
-						getActivity()) {
+	private void loadBlog() {
+		blogController.loadBlog(
+				new UiResultExceptionHandler<BlogItem, DbException>(listener) {
 					@Override
-					public void onResultUi(Boolean isMyBlog) {
-						if (isMyBlog) {
+					public void onResultUi(BlogItem blog) {
+						setToolbarTitle(blog.getBlog().getAuthor());
+						if (blog.isOurs())
 							showWriteButton();
-						}
+						if (blog.canBeRemoved())
+							showDeleteButton();
 					}
 
 					@Override
 					public void onExceptionUi(DbException exception) {
 						// TODO: Decide how to handle errors in the UI
-						getActivity().finish();
+						finish();
 					}
 				});
 	}
 
-	private void checkIfBlogCanBeDeleted() {
-		blogController.canDeleteBlog(
-				new UiResultExceptionHandler<Boolean, DbException>(
-						getActivity()) {
-					@Override
-					public void onResultUi(Boolean canBeDeleted) {
-						if (canBeDeleted) {
-							showDeleteButton();
-						}
-					}
+	private void setToolbarTitle(Author a) {
+		String title = getString(R.string.blogs_personal_blog, a.getName());
+		getActivity().setTitle(title);
 
-					@Override
-					public void onExceptionUi(DbException exception) {
-						// TODO: Decide how to handle errors in the UI
-						getActivity().finish();
-					}
-				});
+		// safe title in intent, so it can be restored automatically
+		Intent intent = getActivity().getIntent();
+		intent.putExtra(BLOG_NAME, title);
 	}
 
 	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();
 	}
 
@@ -323,7 +332,7 @@ public class BlogFragment extends BaseFragment implements
 
 	private void deleteBlog() {
 		blogController.deleteBlog(
-				new UiResultExceptionHandler<Void, DbException>(getActivity()) {
+				new UiResultExceptionHandler<Void, DbException>(listener) {
 					@Override
 					public void onResultUi(Void result) {
 						Toast.makeText(getActivity(),
@@ -335,7 +344,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/BlogListItem.java b/briar-android/src/org/briarproject/android/blogs/BlogItem.java
similarity index 82%
rename from briar-android/src/org/briarproject/android/blogs/BlogListItem.java
rename to briar-android/src/org/briarproject/android/blogs/BlogItem.java
index 35c9f532be2a239fecd798a629955afb7d548a95..536d05f241f305b9043441521aed197fd464fce0 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogListItem.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogItem.java
@@ -5,15 +5,16 @@ import org.briarproject.api.blogs.BlogPostHeader;
 
 import java.util.Collection;
 
-class BlogListItem {
+class BlogItem {
 
 	private final Blog blog;
 	private final int postCount;
 	private final long timestamp;
 	private final int unread;
-	private final boolean ours;
+	private final boolean ours, removable;
 
-	BlogListItem(Blog blog, Collection<BlogPostHeader> headers, boolean ours) {
+	BlogItem(Blog blog, Collection<BlogPostHeader> headers, boolean ours,
+			boolean removable) {
 		this.blog = blog;
 		if (headers.isEmpty()) {
 			postCount = 0;
@@ -35,6 +36,7 @@ class BlogListItem {
 			this.unread = unread;
 		}
 		this.ours = ours;
+		this.removable = removable;
 	}
 
 	Blog getBlog() {
@@ -64,4 +66,8 @@ class BlogListItem {
 	boolean isOurs() {
 		return ours;
 	}
+
+	boolean canBeRemoved() {
+		return removable;
+	}
 }
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogListAdapter.java b/briar-android/src/org/briarproject/android/blogs/BlogListAdapter.java
index 37f7dd30167d58160b40b35aa53922ea4543b219..b3e55f8482f2c812d82ea76fd228bd0cb294bbfa 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogListAdapter.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogListAdapter.java
@@ -29,11 +29,11 @@ import static org.briarproject.android.blogs.BlogActivity.BLOG_NAME;
 class BlogListAdapter extends
 		RecyclerView.Adapter<BlogListAdapter.BlogViewHolder> {
 
-	private SortedList<BlogListItem> blogs = new SortedList<>(
-			BlogListItem.class, new SortedList.Callback<BlogListItem>() {
+	private SortedList<BlogItem> blogs = new SortedList<>(
+			BlogItem.class, new SortedList.Callback<BlogItem>() {
 
 		@Override
-		public int compare(BlogListItem a, BlogListItem b) {
+		public int compare(BlogItem a, BlogItem b) {
 			if (a == b) return 0;
 			// The blog with the newest message comes first
 			long aTime = a.getTimestamp(), bTime = b.getTimestamp();
@@ -66,14 +66,14 @@ class BlogListAdapter extends
 		}
 
 		@Override
-		public boolean areContentsTheSame(BlogListItem a, BlogListItem b) {
+		public boolean areContentsTheSame(BlogItem a, BlogItem b) {
 			return a.getBlog().equals(b.getBlog()) &&
 					a.getTimestamp() == b.getTimestamp() &&
 					a.getUnreadCount() == b.getUnreadCount();
 		}
 
 		@Override
-		public boolean areItemsTheSame(BlogListItem a, BlogListItem b) {
+		public boolean areItemsTheSame(BlogItem a, BlogItem b) {
 			return a.getBlog().equals(b.getBlog());
 		}
 	});
@@ -93,7 +93,7 @@ class BlogListAdapter extends
 
 	@Override
 	public void onBindViewHolder(BlogViewHolder ui, int position) {
-		final BlogListItem item = getItem(position);
+		final BlogItem item = getItem(position);
 
 		// Avatar
 		ui.avatar.setText(item.getName().substring(0, 1));
@@ -145,14 +145,14 @@ class BlogListAdapter extends
 		return blogs.size();
 	}
 
-	public BlogListItem getItem(int position) {
+	public BlogItem getItem(int position) {
 		return blogs.get(position);
 	}
 
 	@Nullable
-	public BlogListItem getItem(GroupId g) {
+	public BlogItem getItem(GroupId g) {
 		for (int i = 0; i < blogs.size(); i++) {
-			BlogListItem item = blogs.get(i);
+			BlogItem item = blogs.get(i);
 			if (item.getBlog().getGroup().getId().equals(g)) {
 				return item;
 			}
@@ -160,17 +160,17 @@ class BlogListAdapter extends
 		return null;
 	}
 
-	public void addAll(Collection<BlogListItem> items) {
+	public void addAll(Collection<BlogItem> items) {
 		blogs.addAll(items);
 	}
 
-	void updateItem(BlogListItem item) {
-		BlogListItem oldItem = getItem(item.getBlog().getGroup().getId());
+	void updateItem(BlogItem item) {
+		BlogItem oldItem = getItem(item.getBlog().getGroup().getId());
 		int position = blogs.indexOf(oldItem);
 		blogs.updateItemAt(position, item);
 	}
 
-	public void remove(BlogListItem item) {
+	public void remove(BlogItem item) {
 		blogs.remove(item);
 	}
 
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java b/briar-android/src/org/briarproject/android/blogs/BlogPostFragment.java
index 926ce7f37d951713625081a9b9eecc4ddd4a2bd3..ac7b4d504e440bafdf8254703239bd079bfca530 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.BasePostPagerFragment.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);
+
+		return super.onCreateView(inflater, container, savedInstanceState);
+	}
 
-		view = inflater.inflate(R.layout.fragment_blog_post, container,
-				false);
-		ui = new BlogPostViewHolder(view);
-		return view;
+	@Override
+	public String getUniqueTag() {
+		return TAG;
 	}
 
 	@Override
@@ -72,65 +62,15 @@ public class BlogPostFragment extends BaseFragment {
 		super.onStart();
 		blogController.loadBlogPost(postId,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						getActivity()) {
+						listener) {
 					@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 0000000000000000000000000000000000000000..f0a534b84714e8616dc77b07d671167ce76ebb12
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostPagerFragment.java
@@ -0,0 +1,78 @@
+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.blogs.BlogPostHeader;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+import javax.inject.Inject;
+
+
+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;
+	}
+
+
+	void loadBlogPosts(final MessageId select) {
+		blogController.loadBlogPosts(
+				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
+						listener) {
+					@Override
+					public void onResultUi(Collection<BlogPostItem> posts) {
+						onBlogPostsLoaded(select, posts);
+					}
+
+					@Override
+					public void onExceptionUi(DbException exception) {
+						onBlogPostsLoadedException(exception);
+					}
+				});
+	}
+
+	void loadBlogPost(BlogPostHeader header) {
+		blogController.loadBlogPost(header,
+				new UiResultExceptionHandler<BlogPostItem, DbException>(
+						listener) {
+					@Override
+					public void onResultUi(BlogPostItem post) {
+						addPost(post);
+					}
+
+					@Override
+					public void onExceptionUi(DbException exception) {
+						// TODO: Decide how to handle errors in the UI
+						finish();
+					}
+				});
+	}
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
index 9cc23d0797e69049f7c36d80808d9cf15c902d5c..13a1b3f177215d6b94b9bf23f689bf3891cd4316 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostViewHolder.java
@@ -10,6 +10,7 @@ import android.support.v4.view.ViewCompat;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -26,7 +27,9 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 import static org.briarproject.android.BriarActivity.GROUP_ID;
-import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
+import static org.briarproject.android.util.AndroidUtils.TEASER_LENGTH;
+import static org.briarproject.android.util.AndroidUtils.getTeaser;
 import static org.briarproject.api.blogs.MessageType.POST;
 
 @UiThread
@@ -81,14 +84,15 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 
 	void bindItem(final BlogPostItem item) {
 		setTransitionName(item.getId());
-		layout.setOnClickListener(new View.OnClickListener() {
-			@Override
-			public void onClick(View v) {
-				if (listener != null) {
+		if (listener != null) {
+			layout.setClickable(true);
+			layout.setOnClickListener(new OnClickListener() {
+				@Override
+				public void onClick(View v) {
 					listener.onBlogPostClick(item);
 				}
-			}
-		});
+			});
+		}
 
 		// author and date
 		BlogPostHeader post = item.getPostHeader();
@@ -104,10 +108,18 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 		}
 
 		// post body
-		body.setText(item.getBody());
+		CharSequence bodyText = item.getBody();
+		if (listener == null) {
+			body.setTextIsSelectable(true);
+		} else {
+			body.setTextIsSelectable(false);
+			if (item.getBody().length() > TEASER_LENGTH)
+				bodyText = getTeaser(ctx, item.getBody());
+		}
+		body.setText(bodyText);
 
 		// reblog button
-		reblogButton.setOnClickListener(new View.OnClickListener() {
+		reblogButton.setOnClickListener(new OnClickListener() {
 			@Override
 			public void onClick(View v) {
 				Intent i = new Intent(ctx, ReblogActivity.class);
@@ -154,6 +166,7 @@ class BlogPostViewHolder extends RecyclerView.ViewHolder {
 			// TODO make author clickable #624
 
 			body.setText(c.getComment());
+			if (listener == null) body.setTextIsSelectable(true);
 
 			commentContainer.addView(v);
 		}
diff --git a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
index 9e6f5774877c5a43f99aef2f21780f02dba2d446..41791e962cd69bbca1106f91f53a2f99c51cdf97 100644
--- a/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/FeedFragment.java
@@ -108,7 +108,7 @@ public class FeedFragment extends BaseFragment implements
 				});
 		feedController.loadBlogPosts(
 				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
-						getActivity()) {
+						listener) {
 					@Override
 					public void onResultUi(Collection<BlogPostItem> posts) {
 						if (posts.isEmpty()) {
@@ -175,7 +175,7 @@ public class FeedFragment extends BaseFragment implements
 	public void onBlogPostAdded(BlogPostHeader header, final boolean local) {
 		feedController.loadBlogPost(header,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						getActivity()) {
+						listener) {
 					@Override
 					public void onResultUi(BlogPostItem post) {
 						adapter.add(post);
@@ -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 0000000000000000000000000000000000000000..442a85ef9877a91c9ee3f94e557b1e76f182e289
--- /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.BasePostPagerFragment.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<BlogPostItem, DbException>(
+						listener) {
+					@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 0000000000000000000000000000000000000000..ab9444104c6b3a84496be03d97cbe9d81a26f941
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/blogs/FeedPostPagerFragment.java
@@ -0,0 +1,77 @@
+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.blogs.BlogPostHeader;
+import org.briarproject.api.db.DbException;
+import org.briarproject.api.sync.MessageId;
+
+import java.util.Collection;
+
+import javax.inject.Inject;
+
+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;
+	}
+
+
+	void loadBlogPosts(final MessageId select) {
+		feedController.loadBlogPosts(
+				new UiResultExceptionHandler<Collection<BlogPostItem>, DbException>(
+						listener) {
+					@Override
+					public void onResultUi(Collection<BlogPostItem> posts) {
+						onBlogPostsLoaded(select, posts);
+					}
+
+					@Override
+					public void onExceptionUi(DbException exception) {
+						onBlogPostsLoadedException(exception);
+					}
+				});
+	}
+
+	void loadBlogPost(BlogPostHeader header) {
+		feedController.loadBlogPost(header,
+				new UiResultExceptionHandler<BlogPostItem, DbException>(
+						listener) {
+					@Override
+					public void onResultUi(BlogPostItem post) {
+						addPost(post);
+					}
+
+					@Override
+					public void onExceptionUi(DbException exception) {
+						// TODO: Decide how to handle errors in the UI
+						finish();
+					}
+				});
+	}
+
+}
diff --git a/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java b/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
index 923d520a65053f6d7adfc3c2e7ab03c977acf2f8..6b4afb89bac8121f8dfac031bc6c60b783cf2512 100644
--- a/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
+++ b/briar-android/src/org/briarproject/android/blogs/ReblogActivity.java
@@ -15,7 +15,7 @@ import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
-import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
 
 public class ReblogActivity extends BriarActivity implements
 		BaseFragmentListener {
diff --git a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
index 1fee6c6473124c6d2893cbcb5bd01d3e33fe6274..305273ba8d78e77c34a2b93398a2436fcf07a0d1 100644
--- a/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
+++ b/briar-android/src/org/briarproject/android/blogs/ReblogFragment.java
@@ -27,7 +27,7 @@ import static android.view.View.GONE;
 import static android.view.View.INVISIBLE;
 import static android.view.View.VISIBLE;
 import static org.briarproject.android.BriarActivity.GROUP_ID;
-import static org.briarproject.android.blogs.BlogActivity.POST_ID;
+import static org.briarproject.android.blogs.BasePostPagerFragment.POST_ID;
 
 public class ReblogFragment extends BaseFragment {
 
@@ -106,7 +106,7 @@ public class ReblogFragment extends BaseFragment {
 		// TODO: Load blog post when fragment is created. #631
 		feedController.loadBlogPost(blogId, postId,
 				new UiResultExceptionHandler<BlogPostItem, DbException>(
-						getActivity()) {
+						listener) {
 					@Override
 					public void onResultUi(BlogPostItem result) {
 						item = result;
@@ -148,7 +148,7 @@ public class ReblogFragment extends BaseFragment {
 	private void send() {
 		String comment = getComment();
 		feedController.repeatPost(item, comment,
-				new UiResultExceptionHandler<Void, DbException>(getActivity()) {
+				new UiResultExceptionHandler<Void, DbException>(listener) {
 					@Override
 					public void onResultUi(Void result) {
 						// do nothing, this fragment is gone already
diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
index ba2eab195ade5bd7c2ded6a9445041b025d70aec..1f9cab0937b755488ff56313f564d2aa1553df91 100644
--- a/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
+++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultExceptionHandler.java
@@ -1,33 +1,36 @@
 package org.briarproject.android.controller.handler;
 
-import android.app.Activity;
 import android.support.annotation.UiThread;
 
+import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
+
 public abstract class UiResultExceptionHandler<R, E extends Exception>
 		implements ResultExceptionHandler<R, E> {
 
-	private final Activity activity;
+	private final BaseFragmentListener listener;
 
-	public UiResultExceptionHandler(Activity activity) {
-		this.activity = activity;
+	protected UiResultExceptionHandler(BaseFragmentListener listener) {
+		this.listener = listener;
 	}
 
 	@Override
 	public void onResult(final R result) {
-		activity.runOnUiThread(new Runnable() {
+		listener.runOnUiThread(new Runnable() {
 			@Override
 			public void run() {
-				onResultUi(result);
+				if (!listener.hasBeenDestroyed())
+					onResultUi(result);
 			}
 		});
 	}
 
 	@Override
 	public void onException(final E exception) {
-		activity.runOnUiThread(new Runnable() {
+		listener.runOnUiThread(new Runnable() {
 			@Override
 			public void run() {
-				onExceptionUi(exception);
+				if (!listener.hasBeenDestroyed())
+					onExceptionUi(exception);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
index 0616b82a2bf2ad263575803c79f1d765a4826315..03c68d7ac6c694882f37e923f764c4ff93f0bba2 100644
--- a/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
+++ b/briar-android/src/org/briarproject/android/controller/handler/UiResultHandler.java
@@ -1,22 +1,24 @@
 package org.briarproject.android.controller.handler;
 
-import android.app.Activity;
 import android.support.annotation.UiThread;
 
+import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
+
 public abstract class UiResultHandler<R> implements ResultHandler<R> {
 
-	private final Activity activity;
+	private final BaseFragmentListener listener;
 
-	public UiResultHandler(Activity activity) {
-		this.activity = activity;
+	protected UiResultHandler(BaseFragmentListener listener) {
+		this.listener = listener;
 	}
 
 	@Override
 	public void onResult(final R result) {
-		activity.runOnUiThread(new Runnable() {
+		listener.runOnUiThread(new Runnable() {
 			@Override
 			public void run() {
-				onResultUi(result);
+				if (!listener.hasBeenDestroyed())
+					onResultUi(result);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
index c19bcf1eed31cafa16714666da3283ab0a1901cb..d6f4ed363a1a125c5e88fe74de44e4f6fc779f2a 100644
--- a/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
+++ b/briar-android/src/org/briarproject/android/fragment/BaseFragment.java
@@ -7,6 +7,7 @@ import android.support.annotation.UiThread;
 import android.support.v4.app.Fragment;
 
 import org.briarproject.android.ActivityComponent;
+import org.briarproject.android.Destroyable;
 
 public abstract class BaseFragment extends Fragment {
 
@@ -45,7 +46,7 @@ public abstract class BaseFragment extends Fragment {
 		getActivity().supportFinishAfterTransition();
 	}
 
-	public interface BaseFragmentListener {
+	public interface BaseFragmentListener extends Destroyable {
 
 		@UiThread
 		void showLoadingScreen(boolean isBlocking, int stringId);
diff --git a/briar-android/src/org/briarproject/android/util/AndroidUtils.java b/briar-android/src/org/briarproject/android/util/AndroidUtils.java
index 610e480e51bb684d2a03cef9f590dc92bb484436..66593d0f8281c64d45d9ea9517bf9655840756c1 100644
--- a/briar-android/src/org/briarproject/android/util/AndroidUtils.java
+++ b/briar-android/src/org/briarproject/android/util/AndroidUtils.java
@@ -6,7 +6,12 @@ import android.content.Context;
 import android.os.Build;
 import android.provider.Settings;
 import android.support.design.widget.TextInputLayout;
+import android.support.v4.content.ContextCompat;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
 import android.text.format.DateUtils;
+import android.text.style.ForegroundColorSpan;
 
 import org.briarproject.R;
 import org.briarproject.util.IoUtils;
@@ -31,6 +36,7 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS;
 public class AndroidUtils {
 
 	public static final long MIN_RESOLUTION = MINUTE_IN_MILLIS;
+	public static final int TEASER_LENGTH = 240;
 
 	// Fake Bluetooth address returned by BluetoothAdapter on API 23 and later
 	private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00";
@@ -115,4 +121,25 @@ public class AndroidUtils {
 						MIN_RESOLUTION, flags).toString();
 	}
 
+	public static SpannableStringBuilder getTeaser(Context ctx, String body) {
+		if (body.length() < TEASER_LENGTH)
+			throw new IllegalArgumentException(
+					"String is shorter than TEASER_LENGTH");
+
+		SpannableStringBuilder builder =
+				new SpannableStringBuilder(body.substring(0, TEASER_LENGTH));
+		String ellipsis = ctx.getString(R.string.ellipsis);
+		builder.append(ellipsis).append(" ");
+
+		Spannable readMore = new SpannableString(
+				ctx.getString(R.string.read_more) + ellipsis);
+		ForegroundColorSpan fg = new ForegroundColorSpan(
+				ContextCompat.getColor(ctx, R.color.briar_text_link));
+		readMore.setSpan(fg, 0, readMore.length(),
+				Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+		builder.append(readMore);
+
+		return builder;
+	}
+
 }
diff --git a/briar-android/src/org/briarproject/android/util/AuthorView.java b/briar-android/src/org/briarproject/android/util/AuthorView.java
index 6920ebbf15dd2388c18367e4d3e89b487da32524..45ab5d34741fc519a45c92f2c371b99851b1b004 100644
--- a/briar-android/src/org/briarproject/android/util/AuthorView.java
+++ b/briar-android/src/org/briarproject/android/util/AuthorView.java
@@ -26,6 +26,7 @@ import de.hdodenhof.circleimageview.CircleImageView;
 import im.delight.android.identicons.IdenticonDrawable;
 
 import static android.content.Context.LAYOUT_INFLATER_SERVICE;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.graphics.Typeface.BOLD;
 import static android.graphics.Typeface.NORMAL;
 import static android.support.v4.app.ActivityOptionsCompat.makeCustomAnimation;
@@ -106,6 +107,7 @@ public class AuthorView extends RelativeLayout {
 			public void onClick(View v) {
 				Intent i = new Intent(getContext(), BlogActivity.class);
 				i.putExtra(GROUP_ID, groupId.getBytes());
+				i.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
 				ActivityOptionsCompat options =
 						makeCustomAnimation(getContext(),
 								android.R.anim.slide_in_left,