diff --git a/src/App.scss b/src/App.scss
index a97ad56d..47886e31 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -145,10 +145,6 @@ status.ng-enter.ng-enter-active {
 }
 
 
-.media-body {
-    flex: 1
-}
-
 #content {
     margin: auto;
     max-width: 920px;
@@ -163,34 +159,14 @@ status.ng-enter.ng-enter-active {
     padding-left: 0.3em;
 }
 
-.status .avatar {
-    width: 48px;
-}
-
-.status.compact .avatar {
-    width: 32px;
-}
-
-.status {
-    padding: 0.5em;
-    padding-right: 1em;
-    border-bottom: 1px solid silver;
-}
-
-.status-el:last-child .status {
-    border: none
+.container > * {
+    min-width: 0px;
 }
 
 [ng-click] {
     cursor: pointer;
 }
 
-.status-el p {
-    margin: 0;
-    margin-top: 0.2em;
-    margin-bottom: 0.5em;
-}
-
 .user-info {
     padding: 1em;
     img {
diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index fa43c12f..9f751863 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -20,4 +20,4 @@ const Attachment = {
   }
 }
 
-export default Attachment
+export default Attachment
\ No newline at end of file
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 1cb53c32..1e49cbeb 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -11,6 +11,8 @@
 
     <video v-if="type === 'video' && !nsfw" :src="attachment.url" controls></video>
 
+    <audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
+
     <span v-if="type === 'unknown'">Don't know how to display this...</span>
 
     <div v-if="type === 'html' && attachment.oembed" class="oembed">
@@ -45,6 +47,10 @@
               width: 100%;
           }
 
+          audio {
+              width: 100%;
+          }
+
           img.media-upload {
               width: 100%;
               height: 100%;
@@ -94,7 +100,6 @@
 
               img {
                   width: 100%;
-                  flex: 1;
                   border: 1px solid;
                   border-radius: 0.5em;
                   width: 100%;
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
new file mode 100644
index 00000000..ea26d958
--- /dev/null
+++ b/src/components/conversation/conversation.js
@@ -0,0 +1,48 @@
+import { find, filter, sortBy, toInteger } from 'lodash'
+import Status from '../status/status.vue'
+import apiService from '../../services/api/api.service.js'
+
+const conversation = {
+  computed: {
+    status () {
+      const id = toInteger(this.$route.params.id)
+      const statuses = this.$store.state.statuses.allStatuses
+      const status = find(statuses, {id})
+
+      return status
+    },
+    conversation () {
+      if (!this.status) {
+        return false
+      }
+
+      const conversationId = this.status.statusnet_conversation_id
+      const statuses = this.$store.state.statuses.allStatuses
+      const conversation = filter(statuses, { statusnet_conversation_id: conversationId })
+      return sortBy(conversation, 'id')
+    }
+  },
+  components: {
+    Status
+  },
+  created () {
+    this.fetchConversation()
+  },
+  methods: {
+    fetchConversation () {
+      if (this.status) {
+        const conversationId = this.status.statusnet_conversation_id
+        apiService.fetchConversation({id: conversationId})
+          .then((statuses) => this.$store.dispatch('addNewStatuses', { statuses }))
+          .then(() => this.$store.commit('updateTimestamps'))
+      } else {
+        const id = this.$route.params.id
+        apiService.fetchStatus({id})
+          .then((status) => this.$store.dispatch('addNewStatuses', { statuses: [status] }))
+          .then(() => this.fetchConversation())
+      }
+    }
+  }
+}
+
+export default conversation
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
new file mode 100644
index 00000000..60b3f044
--- /dev/null
+++ b/src/components/conversation/conversation.vue
@@ -0,0 +1,12 @@
+<template>
+  <div class="timeline panel panel-default">
+    <div class="panel-heading">Status</div>
+    <div class="panel-body">
+      <div class="timeline">
+        <status v-for="status in conversation" :key="status.id" v-bind:statusoid="status"></status>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script src="./conversation.js"></script>
diff --git a/src/components/hello/Hello.css b/src/components/hello/Hello.css
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/components/hello/Hello.html b/src/components/hello/Hello.html
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/components/hello/Hello.js b/src/components/hello/Hello.js
deleted file mode 100644
index c701c560..00000000
--- a/src/components/hello/Hello.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
-  name: 'hello',
-  data () {
-    return {
-      msg: 'Welcome to Your Vue.js app'
-    }
-  }
-}
diff --git a/src/components/hello/Hello.vue b/src/components/hello/Hello.vue
deleted file mode 100644
index 828136a8..00000000
--- a/src/components/hello/Hello.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <h2>Essential Links</h2>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
-      <li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
-      <br>
-      <li><a href="http://vuejs-templates.github.io/webpack/" target="_blank">Docs for This template</a></li>
-    </ul>
-    <h2>Ecosystem</h2>
-    <ul>
-      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
-      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
-      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script src='./Hello.js'></script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h1, h2 {
-  font-weight: normal;
-}
-
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-
-a {
-  color: #42b983;
-}
-</style>
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index d4bcc279..9d17b8a7 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -20,7 +20,14 @@
           <small><a :href="status.user.statusnet_profile_url">{{status.user.screen_name}}</a></small>
           <small v-if="status.in_reply_to_screen_name"> &gt; <a :href="status.in_reply_to_profileurl">{{status.in_reply_to_screen_name}}</a></small>
           -
-          <small>{{status.created_at_parsed}}</small>
+          <small>
+            <router-link :to="{ name: 'conversation', params: { id: status.id } }">
+              {{status.created_at_parsed}}
+            </router-link>
+          </small>
+          <small v-if="!status.is_local" class="source_url">
+            <a :href="status.external_url" >Source</a>
+          </small>
         </h4>
 
         <div class="status-content" v-html="status.statusnet_html"></div>
@@ -51,13 +58,21 @@
 <script src="./status.js" ></script>
 
 <style lang="scss">
-  @import '../../_variables.scss';
-  .status-el {
+ @import '../../_variables.scss';
+ .status-el {
      hyphens: auto;
      overflow-wrap: break-word;
      word-wrap: break-word;
      word-break: break-word;
 
+     .source_url {
+       float: right;
+     }
+
+     .greentext {
+         color: green;
+     }
+
      a {
          display: inline-block;
          word-break: break-all;
@@ -67,13 +82,37 @@
          margin-top: 3px;
          margin-bottom: 3px;
      }
-  }
 
-  .status-actions {
+     p {
+         margin: 0;
+         margin-top: 0.2em;
+         margin-bottom: 0.5em;
+     }
+ }
+
+ .status-actions {
      padding-top: 5px;
-  }
+ }
 
-  .icon-reply:hover {
+ .icon-reply:hover {
      color: $blue;
-  }
+ }
+
+ .status .avatar {
+     width: 48px;
+ }
+
+ .status.compact .avatar {
+     width: 32px;
+ }
+
+ .status {
+     padding: 0.5em;
+     padding-right: 1em;
+     border-bottom: 1px solid silver;
+ }
+
+ .status-el:last-child .status {
+     border: none
+ }
 </style>
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 4ebc383f..8799e69c 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -12,12 +12,13 @@ const Timeline = {
   created () {
     const store = this.$store
     const credentials = store.state.users.currentUser.credentials
+    const showImmediately = this.timeline.visibleStatuses.length === 0
 
     timelineFetcher.fetchAndUpdate({
       store,
       credentials,
       timeline: this.timelineName,
-      showImmediately: true
+      showImmediately
     })
   },
   methods: {
diff --git a/src/main.js b/src/main.js
index de3b2af1..3d3ef1b4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -5,6 +5,7 @@ import App from './App.vue'
 import PublicTimeline from './components/public_timeline/public_timeline.vue'
 import PublicAndExternalTimeline from './components/public_and_external_timeline/public_and_external_timeline.vue'
 import FriendsTimeline from './components/friends_timeline/friends_timeline.vue'
+import Conversation from './components/conversation/conversation.vue'
 
 import statusesModule from './modules/statuses.js'
 import usersModule from './modules/users.js'
@@ -23,12 +24,16 @@ const routes = [
   { path: '/', redirect: '/main/all' },
   { path: '/main/all', component: PublicAndExternalTimeline },
   { path: '/main/public', component: PublicTimeline },
-  { path: '/main/friends', component: FriendsTimeline }
+  { path: '/main/friends', component: FriendsTimeline },
+  { name: 'conversation', path: '/notice/:id', component: Conversation }
 ]
 
 const router = new VueRouter({
   mode: 'history',
-  routes
+  routes,
+  scrollBehavior: (to, from, savedPosition) => {
+    return savedPosition || { x: 0, y: 0 }
+  }
 })
 
 /* eslint-disable no-new */
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index a3031b31..37115506 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,4 +1,4 @@
-import { remove, map, slice, sortBy, toInteger, each, find, flatten, maxBy, last, merge, max } from 'lodash'
+import { remove, map, slice, sortBy, toInteger, each, find, flatten, maxBy, last, merge, max, isArray } from 'lodash'
 import moment from 'moment'
 import apiService from '../services/api/api.service.js'
 // import parse from '../services/status_parser/status_parser.js'
@@ -7,6 +7,7 @@ export const defaultState = {
   allStatuses: [],
   maxId: 0,
   notifications: [],
+  favorites: new Set(),
   timelines: {
     public: {
       statuses: [],
@@ -100,11 +101,17 @@ const mergeOrAdd = (arr, item) => {
 }
 
 const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {} }) => {
+  // Sanity check
+  if (!isArray(statuses)) {
+    return false
+  }
+
   const allStatuses = state.allStatuses
   const timelineObject = state.timelines[timeline]
 
   // Set the maxId to the new id if it's larger.
   const updateMaxId = ({id}) => {
+    if (!timeline) { return false }
     timelineObject.maxId = max([id, timelineObject.maxId])
   }
 
@@ -117,15 +124,15 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
     }
 
     // Some statuses should only be added to the global status repository.
-    if (addToTimeline) {
+    if (timeline && addToTimeline) {
       mergeOrAdd(timelineObject.statuses, status)
     }
 
-    if (showImmediately) {
+    if (timeline && showImmediately) {
       // Add it directly to the visibleStatuses, don't change
       // newStatusCount
       mergeOrAdd(timelineObject.visibleStatuses, status)
-    } else if (addToTimeline && result.new) {
+    } else if (timeline && addToTimeline && result.new) {
       // Just change newStatuscount
       timelineObject.newStatusCount += 1
     }
@@ -141,6 +148,13 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
     const status = find(allStatuses, { id: toInteger(favorite.in_reply_to_status_id) })
     if (status) {
       status.fave_num += 1
+
+      // This is our favorite, so the relevant bit.
+      if (favorite.user.id === user.id) {
+        status.favorited = true
+      }
+
+      // Add a notification if the user's status is favorited
       if (status.user.id === user.id) {
         addNotification({type: 'favorite', status, action: favorite})
       }
@@ -159,7 +173,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
       let retweet
       // If the retweeted status is already there, don't add the retweet
       // to the timeline.
-      if (find(timelineObject.visibleStatuses, {id: retweetedStatus.id})) {
+      if (timeline && find(timelineObject.visibleStatuses, {id: retweetedStatus.id})) {
         // Already have it visible, don't add to timeline, don't show.
         retweet = addStatus(status, false, false)
       } else {
@@ -169,16 +183,22 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
       retweet.retweeted_status = retweetedStatus
     },
     'favorite': (favorite) => {
-      updateMaxId(favorite)
-      favoriteStatus(favorite)
+      // Only update if this is a new favorite.
+      if (!state.favorites.has(favorite.id)) {
+        state.favorites.add(favorite.id)
+        updateMaxId(favorite)
+        favoriteStatus(favorite)
+      }
     },
     'deletion': (deletion) => {
       const uri = deletion.uri
       updateMaxId(deletion)
 
       remove(allStatuses, { uri })
-      remove(timelineObject.statuses, { uri })
-      remove(timelineObject.visibleStatuses, { uri })
+      if (timeline) {
+        remove(timelineObject.statuses, { uri })
+        remove(timelineObject.visibleStatuses, { uri })
+      }
     },
     'default': (unknown) => {
       console.log(unknown)
@@ -192,9 +212,11 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
   })
 
   // Keep the visible statuses sorted
-  timelineObject.visibleStatuses = sortBy(timelineObject.visibleStatuses, ({id}) => -id)
-  timelineObject.statuses = sortBy(timelineObject.statuses, ({id}) => -id)
-  timelineObject.minVisibleId = (last(timelineObject.statuses) || {}).id
+  if (timeline) {
+    timelineObject.visibleStatuses = sortBy(timelineObject.visibleStatuses, ({id}) => -id)
+    timelineObject.statuses = sortBy(timelineObject.statuses, ({id}) => -id)
+    timelineObject.minVisibleId = (last(timelineObject.statuses) || {}).id
+  }
 }
 
 export const mutations = {
@@ -228,7 +250,7 @@ export const mutations = {
 const statuses = {
   state: defaultState,
   actions: {
-    addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline }) {
+    addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false }) {
       commit('addNewStatuses', { statuses, showImmediately, timeline, user: rootState.users.currentUser })
     },
     favorite ({ rootState, commit }, status) {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index d828aff0..87102376 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -7,18 +7,16 @@ const FAVORITE_URL = '/api/favorites/create'
 const UNFAVORITE_URL = '/api/favorites/destroy'
 const RETWEET_URL = '/api/statuses/retweet'
 const STATUS_UPDATE_URL = '/api/statuses/update.json'
+const STATUS_URL = '/api/statuses/show'
 const MEDIA_UPLOAD_URL = '/api/statusnet/media/upload'
-// const CONVERSATION_URL = '/api/statusnet/conversation/';
+const CONVERSATION_URL = '/api/statusnet/conversation'
 
-// const FORM_CONTENT_TYPE = {'Content-Type': 'application/x-www-form-urlencoded'};
-
-// import { param, ajax } from 'jquery';
-// import { merge } from 'lodash';
+const oldfetch = window.fetch
 
 let fetch = (url, options) => {
   const baseUrl = ''
   const fullUrl = baseUrl + url
-  return window.fetch(fullUrl, options)
+  return oldfetch(fullUrl, options)
 }
 
 const authHeaders = (user) => {
@@ -29,6 +27,16 @@ const authHeaders = (user) => {
   }
 }
 
+const fetchConversation = ({id}) => {
+  let url = `${CONVERSATION_URL}/${id}.json?count=100`
+  return fetch(url).then((data) => data.json())
+}
+
+const fetchStatus = ({id}) => {
+  let url = `${STATUS_URL}/${id}.json`
+  return fetch(url).then((data) => data.json())
+}
+
 const fetchTimeline = ({timeline, credentials, since = false, until = false}) => {
   const timelineUrls = {
     public: PUBLIC_TIMELINE_URL,
@@ -108,6 +116,8 @@ const uploadMedia = ({formData, credentials}) => {
 const apiService = {
   verifyCredentials,
   fetchTimeline,
+  fetchConversation,
+  fetchStatus,
   favorite,
   unfavorite,
   retweet,
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index 574e4f74..f068bb92 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -67,6 +67,18 @@ describe('The Statuses module', () => {
     expect(state.timelines.public.newStatusCount).to.equal(1)
   })
 
+  it('add the statuses to allStatuses if no timeline is given', () => {
+    const state = cloneDeep(defaultState)
+    const status = makeMockStatus({id: 1})
+
+    mutations.addNewStatuses(state, { statuses: [status] })
+
+    expect(state.allStatuses).to.eql([status])
+    expect(state.timelines.public.statuses).to.eql([])
+    expect(state.timelines.public.visibleStatuses).to.eql([])
+    expect(state.timelines.public.newStatusCount).to.equal(0)
+  })
+
   it('adds the status to allStatuses and to the given timeline, directly visible', () => {
     const state = cloneDeep(defaultState)
     const status = makeMockStatus({id: 1})
@@ -185,7 +197,8 @@ describe('The Statuses module', () => {
       is_post_verb: false,
       in_reply_to_status_id: '1', // The API uses strings here...
       uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
-      text: 'a favorited something by b'
+      text: 'a favorited something by b',
+      user: {}
     }
 
     mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
@@ -194,6 +207,33 @@ describe('The Statuses module', () => {
     expect(state.timelines.public.visibleStatuses.length).to.eql(1)
     expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
     expect(state.timelines.public.maxId).to.eq(favorite.id)
+
+    // Adding it again does nothing
+    mutations.addNewStatuses(state, { statuses: [favorite], showImmediately: true, timeline: 'public' })
+
+    expect(state.timelines.public.visibleStatuses.length).to.eql(1)
+    expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(1)
+    expect(state.timelines.public.maxId).to.eq(favorite.id)
+
+    // If something is favorited by the current user, it also sets the 'favorited' property
+    const user = {
+      id: 1
+    }
+
+    const ownFavorite = {
+      id: 3,
+      is_post_verb: false,
+      in_reply_to_status_id: '1', // The API uses strings here...
+      uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
+      text: 'a favorited something by b',
+      user
+    }
+
+    mutations.addNewStatuses(state, { statuses: [ownFavorite], showImmediately: true, timeline: 'public', user })
+
+    expect(state.timelines.public.visibleStatuses.length).to.eql(1)
+    expect(state.timelines.public.visibleStatuses[0].fave_num).to.eql(2)
+    expect(state.timelines.public.visibleStatuses[0].favorited).to.eql(true)
   })
 
   describe('notifications', () => {
@@ -208,7 +248,8 @@ describe('The Statuses module', () => {
         is_post_verb: false,
         in_reply_to_status_id: '1', // The API uses strings here...
         uri: 'tag:shitposter.club,2016-08-21:fave:3895:note:773501:2016-08-21T16:52:15+00:00',
-        text: 'a favorited something by b'
+        text: 'a favorited something by b',
+        user: {}
       }
 
       mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public', user })