diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index c088fa1a062739a8f10173ed1f4b1653c2148e20..510f9dbb169de226891156b5ea0277d04aca07ff 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,4 +1,4 @@
-import { 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 } from 'lodash'
 import moment from 'moment'
 import apiService from '../services/api/api.service.js'
 // import parse from '../services/status_parser/status_parser.js'
@@ -73,6 +73,10 @@ const statusType = (status) => {
     return 'favorite'
   }
 
+  if (status.text.match(/deleted notice {{tag/)) {
+    return 'deletion'
+  }
+
   return 'unknown'
 }
 
@@ -145,18 +149,37 @@ export const mutations = {
       'retweet': (status) => {
         // RetweetedStatuses are never shown immediately
         const retweetedStatus = addStatus(status.retweeted_status, false, false)
-        const retweet = addStatus(status, showImmediately)
+
+        let retweet
+        // If the retweeted status is already there, don't add the retweet
+        // to the timeline.
+        if (find(timelineObject.visibleStatuses, {id: retweetedStatus.id})) {
+          // Already have it visible, don't add to timeline, don't show.
+          retweet = addStatus(status, false, false)
+        } else {
+          retweet = addStatus(status, showImmediately)
+        }
+
         retweet.retweeted_status = retweetedStatus
       },
-      'favorite': (status) => {
-        updateMaxId(status)
-        favoriteStatus(status)
+      'favorite': (favorite) => {
+        updateMaxId(favorite)
+        favoriteStatus(favorite)
+      },
+      'deletion': ({uri}) => {
+        remove(allStatuses, { tag: uri })
+        remove(timelineObject.statuses, { tag: uri })
+        remove(timelineObject.visibleStatuses, { tag: uri })
+      },
+      'default': (unknown) => {
+        console.log(unknown)
       }
     }
 
     each(statuses, (status) => {
       const type = statusType(status)
-      processors[type](status)
+      const processor = processors[type] || processors['default']
+      processor(status)
     })
 
     // Keep the visible statuses sorted
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index 80bb5fc681ea2a9262d3e2ee2774d73a2aa9f9ee..d6e1dc20270929c0fd78f27df291ac985c732add 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -78,6 +78,22 @@ describe('The Statuses module', () => {
     expect(state.timelines.public.newStatusCount).to.equal(0)
   })
 
+  it('removes statuses by tag on deletion', () => {
+    const state = cloneDeep(defaultState)
+    const status = makeMockStatus({id: 1})
+    status.tag = 'xxx'
+    const deletion = makeMockStatus({id: 2, is_post_verb: false})
+    deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
+    deletion.uri = 'xxx'
+
+    mutations.addNewStatuses(state, { statuses: [status], showImmediately: true, timeline: 'public' })
+    mutations.addNewStatuses(state, { statuses: [deletion], showImmediately: true, timeline: 'public' })
+
+    expect(state.allStatuses).to.eql([])
+    expect(state.timelines.public.statuses).to.eql([])
+    expect(state.timelines.public.visibleStatuses).to.eql([])
+  })
+
   it('keeps a descending by id order in timeline.visibleStatuses and timeline.statuses', () => {
     const state = cloneDeep(defaultState)
     const status = makeMockStatus({id: 2})
@@ -152,6 +168,8 @@ describe('The Statuses module', () => {
     // Add new version of status
     mutations.addNewStatuses(state, { statuses: [retweet], showImmediately: false, timeline: 'public' })
     expect(state.timelines.public.visibleStatuses).to.have.length(1)
+    // Don't add the retweet itself if the tweet is visible
+    expect(state.timelines.public.statuses).to.have.length(1)
     expect(state.allStatuses).to.have.length(2)
     expect(state.allStatuses[0].text).to.eql(modStatus.text)
   })