From 5ff899b455e07e41eb1b89985177655279f8263f Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 17 Sep 2019 15:59:17 -0400
Subject: [PATCH 1/7] add mention button

---
 src/components/user_card/user_card.js  | 3 +++
 src/components/user_card/user_card.vue | 9 +++++++++
 src/i18n/en.json                       | 1 +
 3 files changed, 13 insertions(+)

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index e3bd7697..d42be9fc 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -168,6 +168,9 @@ export default {
       }
       this.$store.dispatch('setMedia', [attachment])
       this.$store.dispatch('setCurrent', attachment)
+    },
+    mentionUser () {
+
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 0b83cf16..f25d16d3 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -188,6 +188,15 @@
             </ProgressButton>
           </div>
 
+          <div>
+            <button
+              class="btn btn-default btn-block"
+              @click="mentionUser"
+            >
+              {{ $t('user_card.mention') }}
+            </button>
+          </div>
+
           <div>
             <button
               v-if="user.muted"
diff --git a/src/i18n/en.json b/src/i18n/en.json
index ddde471a..e4af507e 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -529,6 +529,7 @@
     "follows_you": "Follows you!",
     "its_you": "It's you!",
     "media": "Media",
+    "mention": "Mention",
     "mute": "Mute",
     "muted": "Muted",
     "per_day": "per day",

From 90981dcce6bbed1ba7700a7f1f4d74838e217b55 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 17 Sep 2019 22:32:17 -0400
Subject: [PATCH 2/7] remove needless condition

---
 src/components/user_panel/user_panel.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index c92630e3..e859d612 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -11,7 +11,7 @@
         rounded="top"
       />
       <div class="panel-footer">
-        <post-status-form v-if="user" />
+        <post-status-form />
       </div>
     </div>
     <auth-form

From f4bbf1d4e205e3c3438226d0cf71e77d4bc0be11 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 19 Sep 2019 13:27:37 -0400
Subject: [PATCH 3/7] add new module and modal to post new status

---
 src/App.js                                    |  4 +-
 src/App.vue                                   |  1 +
 .../post_status_modal/post_status_modal.js    | 25 +++++++++++
 .../post_status_modal/post_status_modal.vue   | 42 +++++++++++++++++++
 src/components/user_card/user_card.js         |  2 +-
 src/main.js                                   |  4 +-
 src/modules/postStatus.js                     | 25 +++++++++++
 7 files changed, 100 insertions(+), 3 deletions(-)
 create mode 100644 src/components/post_status_modal/post_status_modal.js
 create mode 100644 src/components/post_status_modal/post_status_modal.vue
 create mode 100644 src/modules/postStatus.js

diff --git a/src/App.js b/src/App.js
index e9cd5917..40f362d2 100644
--- a/src/App.js
+++ b/src/App.js
@@ -11,6 +11,7 @@ import SideDrawer from './components/side_drawer/side_drawer.vue'
 import MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue'
 import MobileNav from './components/mobile_nav/mobile_nav.vue'
 import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
+import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
 import { windowWidth } from './services/window_utils/window_utils'
 
 export default {
@@ -28,7 +29,8 @@ export default {
     SideDrawer,
     MobilePostStatusModal,
     MobileNav,
-    UserReportingModal
+    UserReportingModal,
+    PostStatusModal
   },
   data: () => ({
     mobileActivePanel: 'timeline',
diff --git a/src/App.vue b/src/App.vue
index 719e00a4..46d3ac42 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -109,6 +109,7 @@
     />
     <MobilePostStatusModal />
     <UserReportingModal />
+    <PostStatusModal />
     <portal-target name="modal" />
   </div>
 </template>
diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js
new file mode 100644
index 00000000..86a4e1d8
--- /dev/null
+++ b/src/components/post_status_modal/post_status_modal.js
@@ -0,0 +1,25 @@
+import PostStatusForm from '../post_status_form/post_status_form.vue'
+
+const PostStatusModal = {
+  components: {
+    PostStatusForm
+  },
+  computed: {
+    isLoggedIn () {
+      return !!this.$store.state.users.currentUser
+    },
+    isOpen () {
+      return this.isLoggedIn && this.$store.state.postStatus.modalActivated
+    },
+    params () {
+      return this.$store.state.postStatus.params
+    }
+  },
+  methods: {
+    closeModal () {
+      this.$store.dispatch('closePostStatusModal')
+    }
+  }
+}
+
+export default PostStatusModal
diff --git a/src/components/post_status_modal/post_status_modal.vue b/src/components/post_status_modal/post_status_modal.vue
new file mode 100644
index 00000000..85a5401c
--- /dev/null
+++ b/src/components/post_status_modal/post_status_modal.vue
@@ -0,0 +1,42 @@
+<template>
+  <div
+    v-if="isOpen"
+    class="post-form-modal-view modal-view"
+    @click="closeModal"
+  >
+    <div
+      class="post-form-modal-panel panel"
+      @click.stop=""
+    >
+      <div class="panel-heading">
+        {{ $t('post_status.new_status') }}
+      </div>
+      <PostStatusForm
+        class="panel-body"
+        @posted="closeModal"
+      />
+    </div>
+  </div>
+</template>
+
+<script src="./post_status_modal.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+
+.post-form-modal-view {
+  align-items: flex-start;
+}
+
+.post-form-modal-panel {
+  flex-shrink: 0;
+  margin-top: 25%;
+  margin-bottom: 2em;
+  width: 100%;
+  max-width: 700px;
+
+  @media (orientation: landscape) {
+    margin-top: 8%;
+  }
+}
+</style>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index d42be9fc..0c200ad1 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -170,7 +170,7 @@ export default {
       this.$store.dispatch('setCurrent', attachment)
     },
     mentionUser () {
-
+      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/main.js b/src/main.js
index b3256e8e..a43d31e2 100644
--- a/src/main.js
+++ b/src/main.js
@@ -15,6 +15,7 @@ import mediaViewerModule from './modules/media_viewer.js'
 import oauthTokensModule from './modules/oauth_tokens.js'
 import reportsModule from './modules/reports.js'
 import pollsModule from './modules/polls.js'
+import postStatusModule from './modules/postStatus.js'
 
 import VueI18n from 'vue-i18n'
 
@@ -76,7 +77,8 @@ const persistedStateOptions = {
       mediaViewer: mediaViewerModule,
       oauthTokens: oauthTokensModule,
       reports: reportsModule,
-      polls: pollsModule
+      polls: pollsModule,
+      postStatus: postStatusModule
     },
     plugins: [persistedState, pushNotifications],
     strict: false // Socket modifies itself, let's ignore this for now.
diff --git a/src/modules/postStatus.js b/src/modules/postStatus.js
new file mode 100644
index 00000000..638c1fb2
--- /dev/null
+++ b/src/modules/postStatus.js
@@ -0,0 +1,25 @@
+const postStatus = {
+  state: {
+    params: null,
+    modalActivated: false
+  },
+  mutations: {
+    openPostStatusModal (state, params) {
+      state.params = params
+      state.modalActivated = true
+    },
+    closePostStatusModal (state) {
+      state.modalActivated = false
+    }
+  },
+  actions: {
+    openPostStatusModal ({ commit }, params) {
+      commit('openPostStatusModal', params)
+    },
+    closePostStatusModal ({ commit }) {
+      commit('closePostStatusModal')
+    }
+  }
+}
+
+export default postStatus

From a9f33272a860fd95def54c7dafa863056324122d Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 19 Sep 2019 13:52:20 -0400
Subject: [PATCH 4/7] refactor MobilePostStatusModal using new PostStatusModal

---
 .../mobile_post_status_modal.js               | 21 ++---------
 .../mobile_post_status_modal.vue              | 36 +------------------
 2 files changed, 4 insertions(+), 53 deletions(-)

diff --git a/src/components/mobile_post_status_modal/mobile_post_status_modal.js b/src/components/mobile_post_status_modal/mobile_post_status_modal.js
index 3cec23c6..3be4a1d8 100644
--- a/src/components/mobile_post_status_modal/mobile_post_status_modal.js
+++ b/src/components/mobile_post_status_modal/mobile_post_status_modal.js
@@ -1,14 +1,9 @@
-import PostStatusForm from '../post_status_form/post_status_form.vue'
 import { debounce } from 'lodash'
 
 const MobilePostStatusModal = {
-  components: {
-    PostStatusForm
-  },
   data () {
     return {
       hidden: false,
-      postFormOpen: false,
       scrollingDown: false,
       inputActive: false,
       oldScrollPos: 0,
@@ -28,8 +23,8 @@ const MobilePostStatusModal = {
     window.removeEventListener('resize', this.handleOSK)
   },
   computed: {
-    currentUser () {
-      return this.$store.state.users.currentUser
+    isLoggedIn () {
+      return !!this.$store.state.users.currentUser
     },
     isHidden () {
       return this.autohideFloatingPostButton && (this.hidden || this.inputActive)
@@ -57,17 +52,7 @@ const MobilePostStatusModal = {
       window.removeEventListener('scroll', this.handleScrollEnd)
     },
     openPostForm () {
-      this.postFormOpen = true
-      this.hidden = true
-
-      const el = this.$el.querySelector('textarea')
-      this.$nextTick(function () {
-        el.focus()
-      })
-    },
-    closePostForm () {
-      this.postFormOpen = false
-      this.hidden = false
+      this.$store.dispatch('openPostStatusModal')
     },
     handleOSK () {
       // This is a big hack: we're guessing from changed window sizes if the
diff --git a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue b/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
index b6d7d3ba..38c5fce0 100644
--- a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
+++ b/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
@@ -1,23 +1,5 @@
 <template>
-  <div v-if="currentUser">
-    <div
-      v-show="postFormOpen"
-      class="post-form-modal-view modal-view"
-      @click="closePostForm"
-    >
-      <div
-        class="post-form-modal-panel panel"
-        @click.stop=""
-      >
-        <div class="panel-heading">
-          {{ $t('post_status.new_status') }}
-        </div>
-        <PostStatusForm
-          class="panel-body"
-          @posted="closePostForm"
-        />
-      </div>
-    </div>
+  <div v-if="isLoggedIn">
     <button
       class="new-status-button"
       :class="{ 'hidden': isHidden }"
@@ -33,22 +15,6 @@
 <style lang="scss">
 @import '../../_variables.scss';
 
-.post-form-modal-view {
-  align-items: flex-start;
-}
-
-.post-form-modal-panel {
-  flex-shrink: 0;
-  margin-top: 25%;
-  margin-bottom: 2em;
-  width: 100%;
-  max-width: 700px;
-
-  @media (orientation: landscape) {
-    margin-top: 8%;
-  }
-}
-
 .new-status-button {
   width: 5em;
   height: 5em;

From 0c8038d4f610bd7260b920e6fb55a8ea0341d291 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 19 Sep 2019 13:52:54 -0400
Subject: [PATCH 5/7] recover autofocusing behavior

---
 src/components/post_status_modal/post_status_modal.js | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js
index 86a4e1d8..15783642 100644
--- a/src/components/post_status_modal/post_status_modal.js
+++ b/src/components/post_status_modal/post_status_modal.js
@@ -15,6 +15,13 @@ const PostStatusModal = {
       return this.$store.state.postStatus.params
     }
   },
+  watch: {
+    isOpen (val) {
+      if (val) {
+        this.$nextTick(() => this.$el.querySelector('textarea').focus())
+      }
+    }
+  },
   methods: {
     closeModal () {
       this.$store.dispatch('closePostStatusModal')

From d6a941a128f37a2d04f5e60ad21037c2c5efcfa3 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 19 Sep 2019 13:59:34 -0400
Subject: [PATCH 6/7] rename component

---
 src/App.js                                                    | 4 ++--
 src/App.vue                                                   | 2 +-
 .../mobile_post_status_button.js}                             | 4 ++--
 .../mobile_post_status_button.vue}                            | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)
 rename src/components/{mobile_post_status_modal/mobile_post_status_modal.js => mobile_post_status_button/mobile_post_status_button.js} (97%)
 rename src/components/{mobile_post_status_modal/mobile_post_status_modal.vue => mobile_post_status_button/mobile_post_status_button.vue} (95%)

diff --git a/src/App.js b/src/App.js
index 40f362d2..fe63b54c 100644
--- a/src/App.js
+++ b/src/App.js
@@ -8,7 +8,7 @@ import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_pan
 import ChatPanel from './components/chat_panel/chat_panel.vue'
 import MediaModal from './components/media_modal/media_modal.vue'
 import SideDrawer from './components/side_drawer/side_drawer.vue'
-import MobilePostStatusModal from './components/mobile_post_status_modal/mobile_post_status_modal.vue'
+import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
 import MobileNav from './components/mobile_nav/mobile_nav.vue'
 import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
 import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
@@ -27,7 +27,7 @@ export default {
     ChatPanel,
     MediaModal,
     SideDrawer,
-    MobilePostStatusModal,
+    MobilePostStatusButton,
     MobileNav,
     UserReportingModal,
     PostStatusModal
diff --git a/src/App.vue b/src/App.vue
index 46d3ac42..f1086e60 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -107,7 +107,7 @@
       :floating="true"
       class="floating-chat mobile-hidden"
     />
-    <MobilePostStatusModal />
+    <MobilePostStatusButton />
     <UserReportingModal />
     <PostStatusModal />
     <portal-target name="modal" />
diff --git a/src/components/mobile_post_status_modal/mobile_post_status_modal.js b/src/components/mobile_post_status_button/mobile_post_status_button.js
similarity index 97%
rename from src/components/mobile_post_status_modal/mobile_post_status_modal.js
rename to src/components/mobile_post_status_button/mobile_post_status_button.js
index 3be4a1d8..3e77148a 100644
--- a/src/components/mobile_post_status_modal/mobile_post_status_modal.js
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.js
@@ -1,6 +1,6 @@
 import { debounce } from 'lodash'
 
-const MobilePostStatusModal = {
+const MobilePostStatusButton = {
   data () {
     return {
       hidden: false,
@@ -90,4 +90,4 @@ const MobilePostStatusModal = {
   }
 }
 
-export default MobilePostStatusModal
+export default MobilePostStatusButton
diff --git a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue b/src/components/mobile_post_status_button/mobile_post_status_button.vue
similarity index 95%
rename from src/components/mobile_post_status_modal/mobile_post_status_modal.vue
rename to src/components/mobile_post_status_button/mobile_post_status_button.vue
index 38c5fce0..9cf45de3 100644
--- a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.vue
@@ -10,7 +10,7 @@
   </div>
 </template>
 
-<script src="./mobile_post_status_modal.js"></script>
+<script src="./mobile_post_status_button.js"></script>
 
 <style lang="scss">
 @import '../../_variables.scss';

From c8a18f387c28d5f895c1e727b0d040da96dcebc1 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 19 Sep 2019 14:38:55 -0400
Subject: [PATCH 7/7] wire up props with PostStatusModal

---
 src/components/post_status_form/post_status_form.js    | 2 +-
 src/components/post_status_modal/post_status_modal.js  | 2 +-
 src/components/post_status_modal/post_status_modal.vue | 1 +
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 40bbf6d4..dc4b419c 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -8,7 +8,7 @@ import fileTypeService from '../../services/file_type/file_type.service.js'
 import { reject, map, uniqBy } from 'lodash'
 import suggestor from '../emoji-input/suggestor.js'
 
-const buildMentionsString = ({ user, attentions }, currentUser) => {
+const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
   let allAttentions = [...attentions]
 
   allAttentions.unshift(user)
diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js
index 15783642..1033ba11 100644
--- a/src/components/post_status_modal/post_status_modal.js
+++ b/src/components/post_status_modal/post_status_modal.js
@@ -12,7 +12,7 @@ const PostStatusModal = {
       return this.isLoggedIn && this.$store.state.postStatus.modalActivated
     },
     params () {
-      return this.$store.state.postStatus.params
+      return this.$store.state.postStatus.params || {}
     }
   },
   watch: {
diff --git a/src/components/post_status_modal/post_status_modal.vue b/src/components/post_status_modal/post_status_modal.vue
index 85a5401c..3f8eec69 100644
--- a/src/components/post_status_modal/post_status_modal.vue
+++ b/src/components/post_status_modal/post_status_modal.vue
@@ -13,6 +13,7 @@
       </div>
       <PostStatusForm
         class="panel-body"
+        v-bind="params"
         @posted="closeModal"
       />
     </div>