From 58ac8f51a219681e237494b8a730048f2eafbe58 Mon Sep 17 00:00:00 2001
From: Roger Braun <roger@rogerbraun.net>
Date: Sat, 3 Dec 2016 12:43:21 +0100
Subject: [PATCH] Treat mentions more like a timeline.

---
 src/components/mentions/mentions.js      | 21 ++++++++---------
 src/components/mentions/mentions.vue     |  4 +---
 src/modules/statuses.js                  | 29 +++++++++++++++++++++---
 test/unit/specs/modules/statuses.spec.js | 16 +++++++++++++
 4 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/components/mentions/mentions.js b/src/components/mentions/mentions.js
index e84d1912..46a1c63e 100644
--- a/src/components/mentions/mentions.js
+++ b/src/components/mentions/mentions.js
@@ -1,26 +1,25 @@
-import Status from '../status/status.vue'
-// Temporary
-import { prepareStatus } from '../../modules/statuses.js'
-import { map } from 'lodash'
+import Timeline from '../timeline/timeline.vue'
 
 const Mentions = {
-  data () {
-    return {
-      mentions: []
-    }
-  },
   computed: {
     username () {
       return this.$route.params.username
+    },
+    timeline () {
+      return this.$store.state.statuses.timelines.mentions
     }
   },
   components: {
-    Status
+    Timeline
   },
   created () {
     this.$store.state.api.backendInteractor.fetchMentions({username: this.username})
       .then((mentions) => {
-        this.mentions = map(mentions, prepareStatus)
+        this.$store.dispatch('addNewStatuses', {
+          statuses: mentions,
+          timeline: 'mentions',
+          showImmediately: true
+        })
       })
   }
 }
diff --git a/src/components/mentions/mentions.vue b/src/components/mentions/mentions.vue
index a760719c..6287ca11 100644
--- a/src/components/mentions/mentions.vue
+++ b/src/components/mentions/mentions.vue
@@ -2,9 +2,7 @@
   <div class="timeline panel panel-default">
     <div class="panel-heading">Mentions</div>
     <div class="panel-body">
-      <div class="timeline">
-        <status v-for="status in mentions" :key="status.id" v-bind:statusoid="status"></status>
-      </div>
+      <Timeline v-bind:timeline="timeline" v-bind:timeline-name="'mentions'"/>
     </div>
   </div>
 </template>
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 7ce07c96..f58b763a 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -8,6 +8,15 @@ export const defaultState = {
   notifications: [],
   favorites: new Set(),
   timelines: {
+    mentions: {
+      statuses: [],
+      faves: [],
+      visibleStatuses: [],
+      newStatusCount: 0,
+      maxId: 0,
+      minVisibleId: 0,
+      loading: false
+    },
     public: {
       statuses: [],
       faves: [],
@@ -91,6 +100,14 @@ const mergeOrAdd = (arr, item) => {
   }
 }
 
+const sortTimeline = (timeline) => {
+  timeline.visibleStatuses = sortBy(timeline.visibleStatuses, ({id}) => -id)
+  timeline.statuses = sortBy(timeline.statuses, ({id}) => -id)
+  timeline.minVisibleId = (last(timeline.statuses) || {}).id
+
+  return timeline
+}
+
 const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {}, noIdUpdate = false }) => {
   // Sanity check
   if (!isArray(statuses)) {
@@ -117,7 +134,15 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
         addNotification({ type: 'repeat', status: status.retweeted_status, action: status })
       }
 
+      // We are mentioned in a post
       if (statusType(status) === 'status' && find(status.attentions, { id: user.id })) {
+        const mentions = state.timelines.mentions
+
+        mergeOrAdd(mentions.statuses, status)
+        mentions.newStatusCount += 1
+
+        sortTimeline(mentions)
+
         addNotification({ type: 'mention', status, action: status })
       }
     }
@@ -213,9 +238,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
 
   // Keep the visible statuses sorted
   if (timeline) {
-    timelineObject.visibleStatuses = sortBy(timelineObject.visibleStatuses, ({id}) => -id)
-    timelineObject.statuses = sortBy(timelineObject.statuses, ({id}) => -id)
-    timelineObject.minVisibleId = (last(timelineObject.statuses) || {}).id
+    sortTimeline(timelineObject)
   }
 }
 
diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js
index c9c1ad2c..deeeb477 100644
--- a/test/unit/specs/modules/statuses.spec.js
+++ b/test/unit/specs/modules/statuses.spec.js
@@ -292,6 +292,22 @@ describe('The Statuses module', () => {
       expect(state.notifications[0].type).to.eql('mention')
     })
 
+    it('adds the message to mentions when you are mentioned', () => {
+      const user = { id: 1 }
+      const state = cloneDeep(defaultState)
+      const status = makeMockStatus({id: 1})
+      const mentionedStatus = makeMockStatus({id: 2})
+      mentionedStatus.attentions = [user]
+
+      mutations.addNewStatuses(state, { statuses: [status], user })
+
+      expect(state.timelines.mentions.statuses).to.have.length(0)
+
+      mutations.addNewStatuses(state, { statuses: [mentionedStatus], user })
+      expect(state.timelines.mentions.statuses).to.have.length(1)
+      expect(state.timelines.mentions.statuses).to.eql([mentionedStatus])
+    })
+
     it('adds a notfication when one of the user\'s status is favorited', () => {
       const state = cloneDeep(defaultState)
       const status = makeMockStatus({id: 1})