diff --git a/res/anim/fade_scale_out.xml b/res/anim/fade_scale_out.xml
index 2ee729071b..c87edc7ee6 100644
--- a/res/anim/fade_scale_out.xml
+++ b/res/anim/fade_scale_out.xml
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:anim/decelerate_interpolator">
+
     <scale
         android:duration="150"
         android:fromXScale="1.0"
@@ -10,8 +12,10 @@
         android:toYScale="0.85"
         android:pivotX="50%"
         android:pivotY="50%" />
+
     <alpha
         android:duration="150"
         android:fromAlpha="1.0"
         android:toAlpha="0.6" />
+
 </set>
\ No newline at end of file
diff --git a/res/anim/slide_from_left.xml b/res/anim/slide_from_left.xml
index 7e00a0272f..5369636d1e 100644
--- a/res/anim/slide_from_left.xml
+++ b/res/anim/slide_from_left.xml
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:interpolator="@android:anim/decelerate_interpolator">
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/decelerate_interpolator">
+
     <translate
-        android:duration="250"
+        android:duration="150"
         android:fromXDelta="-100%"
         android:toXDelta="0%" />
+
 </set>
\ No newline at end of file
diff --git a/res/anim/slide_from_right.xml b/res/anim/slide_from_right.xml
index feeaaf7513..f94fbcc957 100644
--- a/res/anim/slide_from_right.xml
+++ b/res/anim/slide_from_right.xml
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-     android:interpolator="@android:anim/decelerate_interpolator">
+<set
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@android:anim/decelerate_interpolator">
+
     <translate
-        android:duration="250"
+        android:duration="150"
         android:fromXDelta="100%"
         android:toXDelta="0%" />
+
 </set>
\ No newline at end of file
diff --git a/res/drawable/conversation_view_background.xml b/res/drawable/conversation_view_background.xml
new file mode 100644
index 0000000000..ee5f321c99
--- /dev/null
+++ b/res/drawable/conversation_view_background.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ripple
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/cell_selected">
+
+    <item>
+        <color android:color="@color/cell_background" />
+    </item>
+</ripple>
\ No newline at end of file
diff --git a/res/layout/activity_home.xml b/res/layout/activity_home.xml
index 6a47433f51..4dc06c5cc3 100644
--- a/res/layout/activity_home.xml
+++ b/res/layout/activity_home.xml
@@ -25,6 +25,7 @@
             android:background="@drawable/new_conversation_button_background" />
 
         <Button
+            android:id="@+id/newConversationButton"
             android:layout_width="@dimen/new_conversation_button_size"
             android:layout_height="@dimen/new_conversation_button_size"
             android:layout_centerInParent="true"
diff --git a/res/layout/conversation_view.xml b/res/layout/conversation_view.xml
index f2977dd4bb..d91fbee0d4 100644
--- a/res/layout/conversation_view.xml
+++ b/res/layout/conversation_view.xml
@@ -3,7 +3,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="@color/cell_background"
+    android:background="@drawable/conversation_view_background"
     android:orientation="horizontal"
     android:gravity="center_vertical">
 
@@ -31,12 +31,15 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal">
+            android:orientation="horizontal"
+            android:gravity="center_vertical">
 
             <TextView
                 android:id="@+id/displayNameTextView"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:maxLines="1"
+                android:ellipsize="end"
                 android:textSize="@dimen/medium_font_size"
                 android:textStyle="bold"
                 android:textColor="@color/text"
@@ -52,6 +55,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="@dimen/medium_spacing"
+                android:maxLines="1"
+                android:ellipsize="end"
                 android:textSize="@dimen/small_font_size"
                 android:textColor="@color/text"
                 android:alpha="0.4"
@@ -62,12 +67,15 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal">
+            android:orientation="horizontal"
+            android:gravity="center_vertical">
 
             <TextView
                 android:id="@+id/snippetTextView"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:maxLines="1"
+                android:ellipsize="end"
                 android:textSize="@dimen/medium_font_size"
                 android:textColor="@color/text"
                 android:text="Sorry, gotta go fight crime again" />
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
index 95ee82b41d..5bb483e7c5 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/DisplayNameActivity.kt
@@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.ApplicationContext
 import org.thoughtcrime.securesms.BaseActionBarActivity
 import org.thoughtcrime.securesms.ConversationListActivity
 import org.thoughtcrime.securesms.database.DatabaseFactory
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
 import org.thoughtcrime.securesms.util.TextSecurePreferences
 import org.whispersystems.signalservice.api.crypto.ProfileCipher
@@ -54,6 +55,6 @@ class DisplayNameActivity : BaseActionBarActivity() {
             servers.forEach { publicChatAPI.setDisplayName(displayName, it) }
         }
         startActivity(Intent(this, ConversationListActivity::class.java))
-        finish()
+        push(intent)
     }
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
index 099199fb86..e1f50616a8 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt
@@ -1,15 +1,21 @@
 package org.thoughtcrime.securesms.loki.redesign.activities
 
+import android.content.Intent
 import android.os.Bundle
 import android.support.v7.widget.LinearLayoutManager
 import kotlinx.android.synthetic.main.activity_home.*
 import network.loki.messenger.R
 import org.thoughtcrime.securesms.ApplicationContext
 import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
+import org.thoughtcrime.securesms.conversation.ConversationActivity
 import org.thoughtcrime.securesms.database.DatabaseFactory
+import org.thoughtcrime.securesms.database.model.ThreadRecord
+import org.thoughtcrime.securesms.loki.NewConversationActivity
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
+import org.thoughtcrime.securesms.loki.redesign.views.ConversationView
 import org.thoughtcrime.securesms.util.TextSecurePreferences
 
-class HomeActivity : PassphraseRequiredActionBarActivity {
+class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener {
 
     constructor() : super()
 
@@ -21,8 +27,12 @@ class HomeActivity : PassphraseRequiredActionBarActivity {
         supportActionBar!!.title = "Messages"
         // Set up recycler view
         val cursor = DatabaseFactory.getThreadDatabase(this).conversationList
-        recyclerView.adapter = ConversationAdapter(this, cursor)
+        val conversationAdapter = ConversationAdapter(this, cursor)
+        conversationAdapter.conversationClickListener = this
+        recyclerView.adapter = conversationAdapter
         recyclerView.layoutManager = LinearLayoutManager(this)
+        // Set up new conversation button
+        newConversationButton.setOnClickListener { createPrivateChat() }
         // Set up public chats and RSS feeds if needed
         if (TextSecurePreferences.getLocalNumber(this) != null) {
             val application = ApplicationContext.getInstance(this)
@@ -32,4 +42,29 @@ class HomeActivity : PassphraseRequiredActionBarActivity {
             application.startRSSFeedPollersIfNeeded()
         }
     }
+
+    override fun onConversationClick(view: ConversationView) {
+        val thread = view.thread ?: return
+        openConversation(thread)
+    }
+
+    override fun onLongConversationClick(view: ConversationView) {
+        // TODO: Implement
+    }
+
+    private fun openConversation(thread: ThreadRecord) {
+        val intent = Intent(this, ConversationActivity::class.java)
+        intent.putExtra(ConversationActivity.ADDRESS_EXTRA, thread.recipient.getAddress())
+        intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, thread.threadId)
+        intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, thread.distributionType)
+        intent.putExtra(ConversationActivity.TIMING_EXTRA, System.currentTimeMillis())
+        intent.putExtra(ConversationActivity.LAST_SEEN_EXTRA, thread.lastSeen)
+        intent.putExtra(ConversationActivity.STARTING_POSITION_EXTRA, -1)
+        push(intent)
+    }
+
+    private fun createPrivateChat() {
+        val intent = Intent(this, NewConversationActivity::class.java)
+        startActivity(intent)
+    }
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt
index d1204e6dd4..b7231db086 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt
@@ -5,6 +5,7 @@ import android.os.Bundle
 import kotlinx.android.synthetic.main.activity_landing.*
 import network.loki.messenger.R
 import org.thoughtcrime.securesms.BaseActionBarActivity
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
 
 class LandingActivity : BaseActionBarActivity() {
@@ -20,11 +21,11 @@ class LandingActivity : BaseActionBarActivity() {
 
     private fun register() {
         val intent = Intent(this, RegisterActivity::class.java)
-        startActivity(intent)
+        push(intent)
     }
 
     private fun restore() {
         val intent = Intent(this, RestoreActivity::class.java)
-        startActivity(intent)
+        push(intent)
     }
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/RegisterActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/RegisterActivity.kt
index ff73be7db8..6e7aa93f94 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/RegisterActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/RegisterActivity.kt
@@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
 import org.thoughtcrime.securesms.database.Address
 import org.thoughtcrime.securesms.database.DatabaseFactory
 import org.thoughtcrime.securesms.database.IdentityDatabase
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
 import org.thoughtcrime.securesms.util.Base64
 import org.thoughtcrime.securesms.util.Hex
@@ -103,7 +104,7 @@ class RegisterActivity : BaseActionBarActivity() {
             true, System.currentTimeMillis(), true)
         TextSecurePreferences.setLocalNumber(this, userHexEncodedPublicKey)
         val intent = Intent(this, DisplayNameActivity::class.java)
-        startActivity(intent)
+        push(intent)
     }
 
     private fun copyPublicKey() {
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/RestoreActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/RestoreActivity.kt
index ffc4105758..6cf18b0670 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/activities/RestoreActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/RestoreActivity.kt
@@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
 import org.thoughtcrime.securesms.database.Address
 import org.thoughtcrime.securesms.database.DatabaseFactory
 import org.thoughtcrime.securesms.database.IdentityDatabase
+import org.thoughtcrime.securesms.loki.redesign.utilities.push
 import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
 import org.thoughtcrime.securesms.util.Base64
 import org.thoughtcrime.securesms.util.Hex
@@ -92,7 +93,7 @@ class RestoreActivity : BaseActionBarActivity() {
                     true, System.currentTimeMillis(), true)
             TextSecurePreferences.setLocalNumber(this, userHexEncodedPublicKey)
             val intent = Intent(this, DisplayNameActivity::class.java)
-            startActivity(intent)
+            push(intent)
         } catch (e: Exception) {
             val message = if (e is MnemonicCodec.DecodingError) e.description else MnemonicCodec.DecodingError.Generic.description
             return Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/utilities/ActivityUtilities.kt b/src/org/thoughtcrime/securesms/loki/redesign/utilities/ActivityUtilities.kt
index d112684e0f..316ec8a503 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/utilities/ActivityUtilities.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/utilities/ActivityUtilities.kt
@@ -1,5 +1,6 @@
 package org.thoughtcrime.securesms.loki.redesign.utilities
 
+import android.content.Intent
 import android.support.v7.app.ActionBar
 import android.support.v7.app.AppCompatActivity
 import android.view.Gravity
@@ -18,4 +19,9 @@ fun AppCompatActivity.setUpActionBarSessionLogo() {
     val logoImageViewContainerLayoutParams = ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT)
     supportActionBar!!.setCustomView(logoImageViewContainer, logoImageViewContainerLayoutParams)
     supportActionBar!!.setDisplayShowCustomEnabled(true)
+}
+
+fun AppCompatActivity.push(intent: Intent) {
+    startActivity(intent)
+    overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out)
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/views/ConversationView.kt b/src/org/thoughtcrime/securesms/loki/redesign/views/ConversationView.kt
index 647699a844..c2d292ee1e 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/views/ConversationView.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/views/ConversationView.kt
@@ -1,14 +1,22 @@
 package org.thoughtcrime.securesms.loki.redesign.views
 
 import android.content.Context
+import android.graphics.Typeface
 import android.util.AttributeSet
 import android.view.LayoutInflater
+import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
+import kotlinx.android.synthetic.main.conversation_view.view.*
 import network.loki.messenger.R
 import org.thoughtcrime.securesms.database.model.ThreadRecord
+import org.thoughtcrime.securesms.loki.LokiAPIUtilities.populateUserHexEncodedPublicKeyCacheIfNeeded
+import org.thoughtcrime.securesms.loki.MentionUtilities.highlightMentions
+import org.thoughtcrime.securesms.util.DateUtils
+import java.util.*
 
 class ConversationView : LinearLayout {
+    var thread: ThreadRecord? = null
 
     // region Lifecycle
     companion object {
@@ -29,7 +37,16 @@ class ConversationView : LinearLayout {
 
     // region Updating
     fun bind(thread: ThreadRecord) {
-
+        this.thread = thread
+        populateUserHexEncodedPublicKeyCacheIfNeeded(thread.threadId, context) // FIXME: This is a terrible place to do this
+        unreadMessagesIndicatorView.visibility = if (thread.unreadCount > 0) View.VISIBLE else View.INVISIBLE
+        val senderDisplayName = if (thread.recipient.isLocalNumber) context.getString(R.string.note_to_self) else thread.recipient.name
+        displayNameTextView.text = senderDisplayName
+        timestampTextView.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), thread.date)
+        val rawSnippet = thread.getDisplayBody(context)
+        val snippet = highlightMentions(rawSnippet, thread.threadId, context)
+        snippetTextView.text = snippet
+        snippetTextView.typeface = if (thread.unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
     }
     // endregion
 }
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/redesign/views/FakeChatView.kt b/src/org/thoughtcrime/securesms/loki/redesign/views/FakeChatView.kt
index 74a14ed4eb..88a739beb5 100644
--- a/src/org/thoughtcrime/securesms/loki/redesign/views/FakeChatView.kt
+++ b/src/org/thoughtcrime/securesms/loki/redesign/views/FakeChatView.kt
@@ -10,7 +10,6 @@ import android.widget.ScrollView
 import kotlinx.android.synthetic.main.fake_chat_content_view.view.*
 import network.loki.messenger.R
 
-
 class FakeChatView : ScrollView {
 
     // region Settings