From 07b8115a37a22b2a7d935154e8231c8a90f199d6 Mon Sep 17 00:00:00 2001
From: dave <starpumadev@gmail.com>
Date: Tue, 19 Mar 2019 14:36:27 -0400
Subject: #444 - show `remote follow` button when logged out

---
 src/components/user_card/user_card.vue | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 690e1bde..f4114e6e 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -84,14 +84,8 @@
             </button>
           </span>
         </div>
-        <div class="remote-follow" v-if='!loggedIn && user.is_local'>
-          <form method="POST" :action='subscribeUrl'>
-            <input type="hidden" name="nickname" :value="user.screen_name">
-            <input type="hidden" name="profile" value="">
-            <button click="submit" class="remote-button">
-              {{ $t('user_card.remote_follow') }}
-            </button>
-          </form>
+        <div v-if='!loggedIn && user.is_local'>
+          <RemoteFollow :user="user" />
         </div>
         <div class='block' v-if='isOtherUser && loggedIn'>
           <span v-if='user.statusnet_blocking'>
@@ -375,11 +369,6 @@
       min-height: 28px;
     }
 
-    .remote-follow {
-      max-width: 220px;
-      min-height: 28px;
-    }
-
     .follow {
       max-width: 220px;
       min-height: 28px;
-- 
cgit v1.2.3-70-g09d2


From 3255950b0e9a16f2a477d606b91d90bed8a6cef7 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Sun, 24 Feb 2019 03:02:04 -0500
Subject: Add mute/unmute featrue and mutes management tab

---
 src/components/mute_card/mute_card.js              |  2 +-
 src/components/user_card/user_card.js              | 20 +++++-----
 src/components/user_card/user_card.vue             |  4 +-
 src/components/user_settings/user_settings.vue     |  6 +++
 src/modules/users.js                               | 32 ++++++++++------
 src/services/api/api.service.js                    | 44 ++++++++++++++++++++--
 .../backend_interactor_service.js                  |  6 ++-
 src/utils/url.js                                   |  9 +++++
 8 files changed, 93 insertions(+), 30 deletions(-)
 create mode 100644 src/utils/url.js

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
index 65c9cfb5..5ef17b60 100644
--- a/src/components/mute_card/mute_card.js
+++ b/src/components/mute_card/mute_card.js
@@ -12,7 +12,7 @@ const MuteCard = {
       return this.$store.getters.findUser(this.userId)
     },
     muted () {
-      return this.user.muted
+      return this.user.mastodonMuted
     }
   },
   components: {
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index b07da675..61b784fe 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -121,21 +121,19 @@ export default {
       })
     },
     blockUser () {
-      const store = this.$store
-      store.state.api.backendInteractor.blockUser(this.user.id)
-        .then((blockedUser) => {
-          store.commit('addNewUsers', [blockedUser])
-          store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
-          store.commit('removeStatus', { timeline: 'public', userId: this.user.id })
-          store.commit('removeStatus', { timeline: 'publicAndExternal', userId: this.user.id })
-        })
+      this.$store.dispatch('blockUser', this.user.id)
     },
     unblockUser () {
-      const store = this.$store
-      store.state.api.backendInteractor.unblockUser(this.user.id)
-        .then((unblockedUser) => store.commit('addNewUsers', [unblockedUser]))
+      this.$store.dispatch('unblockUser', this.user.id)
+    },
+    muteUser () {   // Mastodon Mute
+      this.$store.dispatch('muteUser', this.user.id)
+    },
+    unmuteUser () { // Mastodon Unmute
+      this.$store.dispatch('unmuteUser', this.user.id)
     },
     toggleMute () {
+      // TODO: Pleroma mute/unmute, Need to migrate to the Mastodon API
       const store = this.$store
       store.commit('setMuted', {user: this.user, muted: !this.user.muted})
       store.state.api.backendInteractor.setUserMute(this.user)
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f4114e6e..3259d1c5 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -74,12 +74,12 @@
         </div>
         <div class='mute' v-if='isOtherUser && loggedIn'>
           <span v-if='user.muted'>
-            <button @click="toggleMute" class="pressed">
+            <button @click="unmuteUser" class="pressed">
               {{ $t('user_card.muted') }}
             </button>
           </span>
           <span v-if='!user.muted'>
-            <button @click="toggleMute">
+            <button @click="muteUser">
               {{ $t('user_card.mute') }}
             </button>
           </span>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index a1123638..c9e68808 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -192,6 +192,12 @@
             <template slot="empty">{{$t('settings.no_blocks')}}</template>
           </block-list>
         </div>
+
+        <div :label="$t('settings.mutes_tab')">
+          <mute-list :refresh="true">
+            <template slot="empty">{{$t('settings.no_mutes')}}</template>
+          </mute-list>
+        </div>
       </tab-switcher>
     </div>
   </div>
diff --git a/src/modules/users.js b/src/modules/users.js
index 1fe12fc8..9c89f34a 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -177,9 +177,14 @@ const users = {
           return blocks
         })
     },
-    blockUser (store, id) {
-      return store.rootState.api.backendInteractor.blockUser(id)
-        .then((user) => store.commit('addNewUsers', [user]))
+    blockUser (store, userId) {
+      return store.rootState.api.backendInteractor.blockUser(userId)
+        .then((blockedUser) => {
+          store.commit('addNewUsers', [blockedUser])
+          store.commit('removeStatus', { timeline: 'friends', userId })
+          store.commit('removeStatus', { timeline: 'public', userId })
+          store.commit('removeStatus', { timeline: 'publicAndExternal', userId })
+        })
     },
     unblockUser (store, id) {
       return store.rootState.api.backendInteractor.unblockUser(id)
@@ -188,18 +193,26 @@ const users = {
     fetchMutes (store) {
       return store.rootState.api.backendInteractor.fetchMutes()
         .then((mutedUsers) => {
-          each(mutedUsers, (user) => { user.muted = true })
+          each(mutedUsers, (user) => { user.mastodonMuted = true })
           store.commit('addNewUsers', mutedUsers)
           store.commit('saveMutes', map(mutedUsers, 'id'))
         })
     },
     muteUser (store, id) {
-      return store.state.api.backendInteractor.setUserMute({ id, muted: true })
-        .then((user) => store.commit('addNewUsers', [user]))
+      return store.rootState.api.backendInteractor.muteUser(id)
+        .then(() => {
+          const user = store.rootState.users.usersObject[id]
+          set(user, 'mastodonMuted', true)
+          store.commit('addNewUsers', [user])
+        })
     },
     unmuteUser (store, id) {
-      return store.state.api.backendInteractor.setUserMute({ id, muted: false })
-        .then((user) => store.commit('addNewUsers', [user]))
+      return store.rootState.api.backendInteractor.unmuteUser(id)
+        .then(() => {
+          const user = store.rootState.users.usersObject[id]
+          set(user, 'mastodonMuted', false)
+          store.commit('addNewUsers', [user])
+        })
     },
     addFriends ({ rootState, commit }, fetchBy) {
       return new Promise((resolve, reject) => {
@@ -350,9 +363,6 @@ const users = {
               // Start getting fresh posts.
               store.dispatch('startFetching', { timeline: 'friends' })
 
-              // Get user mutes
-              store.dispatch('fetchMutes')
-
               // Fetch our friends
               store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
                 .then((friends) => commit('addNewUsers', friends))
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 176f1c18..92abf94b 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -1,3 +1,5 @@
+import { generateUrl } from '../../utils/url'
+
 /* eslint-env browser */
 const LOGIN_URL = '/api/account/verify_credentials.json'
 const FRIENDS_TIMELINE_URL = '/api/statuses/friends_timeline.json'
@@ -19,6 +21,9 @@ const DM_TIMELINE_URL = '/api/statuses/dm_timeline.json'
 const FOLLOWERS_URL = '/api/statuses/followers.json'
 const FRIENDS_URL = '/api/statuses/friends.json'
 const BLOCKS_URL = '/api/statuses/blocks.json'
+const MUTES_URL = '/api/v1/mutes.json'
+const MUTING_URL = '/api/v1/accounts/:id/mute'
+const UNMUTING_URL = '/api/v1/accounts/:id/unmute'
 const FOLLOWING_URL = '/api/friendships/create.json'
 const UNFOLLOWING_URL = '/api/friendships/destroy.json'
 const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json'
@@ -538,14 +543,43 @@ const changePassword = ({credentials, password, newPassword, newPasswordConfirma
 }
 
 const fetchMutes = ({credentials}) => {
-  const url = '/api/qvitter/mutes.json'
+  return fetch(MUTES_URL, {
+    headers: authHeaders(credentials)
+  }).then((data) => {
+    if (data.ok) {
+      return data.json()
+    }
+    throw new Error('Error fetching mutes', data)
+  })
+}
 
+const muteUser = ({id, credentials}) => {
+  const url = generateUrl(MUTING_URL, { id })
   return fetch(url, {
-    headers: authHeaders(credentials)
-  }).then((data) => data.json())
+    headers: authHeaders(credentials),
+    method: 'POST'
+  }).then((data) => {
+    if (data.ok) {
+      return data.json()
+    }
+    throw new Error('Error muting', data)
+  })
+}
+
+const unmuteUser = ({id, credentials}) => {
+  const url = generateUrl(UNMUTING_URL, { id })
+  return fetch(url, {
+    headers: authHeaders(credentials),
+    method: 'POST'
+  }).then((data) => {
+    if (data.ok) {
+      return data.json()
+    }
+    throw new Error('Error unmuting', data)
+  })
 }
 
-const fetchBlocks = ({page, credentials}) => {
+const fetchBlocks = ({credentials}) => {
   return fetch(BLOCKS_URL, {
     headers: authHeaders(credentials)
   }).then((data) => {
@@ -620,6 +654,8 @@ const apiService = {
   fetchAllFollowing,
   setUserMute,
   fetchMutes,
+  muteUser,
+  unmuteUser,
   fetchBlocks,
   fetchOAuthTokens,
   revokeOAuthToken,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index cbd0b733..674fb4a4 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -67,7 +67,9 @@ const backendInteractorService = (credentials) => {
   }
 
   const fetchMutes = () => apiService.fetchMutes({credentials})
-  const fetchBlocks = (params) => apiService.fetchBlocks({credentials, ...params})
+  const muteUser = (id) => apiService.muteUser({credentials, id})
+  const unmuteUser = (id) => apiService.unmuteUser({credentials, id})
+  const fetchBlocks = () => apiService.fetchBlocks({credentials})
   const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
   const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials})
   const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials})
@@ -102,6 +104,8 @@ const backendInteractorService = (credentials) => {
     startFetching,
     setUserMute,
     fetchMutes,
+    muteUser,
+    unmuteUser,
     fetchBlocks,
     fetchOAuthTokens,
     revokeOAuthToken,
diff --git a/src/utils/url.js b/src/utils/url.js
new file mode 100644
index 00000000..79ea7394
--- /dev/null
+++ b/src/utils/url.js
@@ -0,0 +1,9 @@
+// Generate url based on template
+// Example: /api/v1/accounts/:id/mute -> /api/v1/accounts/123/mute
+export const generateUrl = (template, params = {}) => {
+  let url = template
+  Object.entries(params).forEach(([key, value]) => {
+    url = url.replace(':' + key, value)
+  })
+  return url
+}
-- 
cgit v1.2.3-70-g09d2


From 6b6878bde06b375b1e715a3557f153acc73a8af0 Mon Sep 17 00:00:00 2001
From: eugenijm <eugenijm@protonmail.com>
Date: Mon, 18 Feb 2019 17:49:32 +0300
Subject: Added moderation menu

---
 package.json                                       |   2 +
 src/App.scss                                       |   8 ++
 src/boot/after_store.js                            |   1 +
 src/components/delete_button/delete_button.js      |   6 +-
 src/components/dialog_modal/dialog_modal.js        |  14 ++
 src/components/dialog_modal/dialog_modal.vue       |  92 ++++++++++++
 .../moderation_tools/moderation_tools.js           | 106 ++++++++++++++
 .../moderation_tools/moderation_tools.vue          | 158 +++++++++++++++++++++
 src/components/notification/notification.js        |   3 +
 src/components/notification/notification.vue       |   2 +-
 src/components/popper/popper.scss                  |  70 +++++++++
 src/components/user_card/user_card.js              |  13 +-
 src/components/user_card/user_card.vue             |   2 +
 src/components/user_profile/user_profile.js        |   4 +-
 src/i18n/en.json                                   |  24 +++-
 src/i18n/ru.json                                   |  24 +++-
 src/modules/statuses.js                            |  10 ++
 src/modules/users.js                               |  22 +++
 src/services/api/api.service.js                    |  90 ++++++++++++
 .../backend_interactor_service.js                  |  30 ++++
 .../entity_normalizer/entity_normalizer.service.js |  19 ++-
 yarn.lock                                          |  10 ++
 22 files changed, 697 insertions(+), 13 deletions(-)
 create mode 100644 src/components/dialog_modal/dialog_modal.js
 create mode 100644 src/components/dialog_modal/dialog_modal.vue
 create mode 100644 src/components/moderation_tools/moderation_tools.js
 create mode 100644 src/components/moderation_tools/moderation_tools.vue
 create mode 100644 src/components/popper/popper.scss

(limited to 'src/components/user_card/user_card.vue')

diff --git a/package.json b/package.json
index 03228133..c80e0f63 100644
--- a/package.json
+++ b/package.json
@@ -24,12 +24,14 @@
     "node-sass": "^3.10.1",
     "object-path": "^0.11.3",
     "phoenix": "^1.3.0",
+    "popper.js": "^1.14.7",
     "sanitize-html": "^1.13.0",
     "sass-loader": "^4.0.2",
     "vue": "^2.5.13",
     "vue-chat-scroll": "^1.2.1",
     "vue-compose": "^0.7.1",
     "vue-i18n": "^7.3.2",
+    "vue-popperjs": "^2.0.3",
     "vue-router": "^3.0.1",
     "vue-template-compiler": "^2.3.4",
     "vue-timeago": "^3.1.2",
diff --git a/src/App.scss b/src/App.scss
index 5fc0dd27..b1c65ade 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -101,6 +101,14 @@ button {
     background-color: $fallback--bg;
     background-color: var(--bg, $fallback--bg)
   }
+
+  &.danger {
+    // TODO: add better color variable
+    color: $fallback--text;
+    color: var(--alertErrorPanelText, $fallback--text);
+    background-color: $fallback--alertError;
+    background-color: var(--alertError, $fallback--alertError);
+  }
 }
 
 label.select {
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index 862a534d..bb593026 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -210,6 +210,7 @@ const getNodeInfo = async ({ store }) => {
 
       const frontendVersion = window.___pleromafe_commit_hash
       store.dispatch('setInstanceOption', { name: 'frontendVersion', value: frontendVersion })
+      store.dispatch('setInstanceOption', { name: 'tagPolicyAvailable', value: metadata.federation.mrf_policies.includes('TagPolicy') })
     } else {
       throw (res)
     }
diff --git a/src/components/delete_button/delete_button.js b/src/components/delete_button/delete_button.js
index f2920666..22f24625 100644
--- a/src/components/delete_button/delete_button.js
+++ b/src/components/delete_button/delete_button.js
@@ -10,7 +10,11 @@ const DeleteButton = {
   },
   computed: {
     currentUser () { return this.$store.state.users.currentUser },
-    canDelete () { return this.currentUser && this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id }
+    canDelete () {
+      if (!this.currentUser) { return }
+      const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin
+      return superuser || this.status.user.id === this.currentUser.id
+    }
   }
 }
 
diff --git a/src/components/dialog_modal/dialog_modal.js b/src/components/dialog_modal/dialog_modal.js
new file mode 100644
index 00000000..f14e3fe9
--- /dev/null
+++ b/src/components/dialog_modal/dialog_modal.js
@@ -0,0 +1,14 @@
+const DialogModal = {
+  props: {
+    darkOverlay: {
+      default: true,
+      type: Boolean
+    },
+    onCancel: {
+      default: () => {},
+      type: Function
+    }
+  }
+}
+
+export default DialogModal
diff --git a/src/components/dialog_modal/dialog_modal.vue b/src/components/dialog_modal/dialog_modal.vue
new file mode 100644
index 00000000..7621fb20
--- /dev/null
+++ b/src/components/dialog_modal/dialog_modal.vue
@@ -0,0 +1,92 @@
+<template>
+  <span v-bind:class="{ 'dark-overlay': darkOverlay }" @click.self.stop='onCancel()'>
+    <div class="dialog-modal panel panel-default" @click.stop=''>
+      <div class="panel-heading dialog-modal-heading">
+        <div class="title">
+          <slot name="header"></slot>
+        </div>
+      </div>
+      <div class="dialog-modal-content">
+        <slot name="default"></slot>
+      </div>
+      <div class="dialog-modal-footer user-interactions panel-footer">
+        <slot name="footer"></slot>
+      </div>
+    </div>
+  </span>
+</template>
+
+<script src="./dialog_modal.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+
+// TODO: unify with other modals.
+.dark-overlay {
+  &::before {
+    bottom: 0;
+    content: " ";
+    display: block;
+    cursor: default;
+    left: 0;
+    position: fixed;
+    right: 0;
+    top: 0;
+    background: rgba(27,31,35,.5);
+    z-index: 99;
+  }
+}
+
+.dialog-modal.panel {
+  top: 0;
+  left: 50%;
+  max-height: 80vh;
+  max-width: 90vw;
+  margin: 15vh auto;
+  position: fixed;
+  transform: translateX(-50%);
+  z-index: 999;
+  cursor: default;
+  display: block;
+  background-color: $fallback--bg;
+  background-color: var(--bg, $fallback--bg);
+
+  .dialog-modal-heading {
+    padding: .5em .5em;
+    margin-right: auto;
+    margin-bottom: 0;
+    white-space: nowrap;
+    color: var(--panelText);
+    background-color: $fallback--fg;
+    background-color: var(--panel, $fallback--fg);
+
+    .title {
+      margin-bottom: 0;
+    }
+  }
+
+  .dialog-modal-content {
+    margin: 0;
+    padding: 1rem 1rem;
+    background-color: $fallback--lightBg;
+    background-color: var(--lightBg, $fallback--lightBg);
+    white-space: normal;
+  }
+
+  .dialog-modal-footer {
+    margin: 0;
+    padding: .5em .5em;
+    background-color: $fallback--lightBg;
+    background-color: var(--lightBg, $fallback--lightBg);
+    border-top: 1px solid $fallback--bg;
+    border-top: 1px solid var(--bg, $fallback--bg);
+    justify-content: flex-end;
+
+    button {
+      width: auto;
+      margin-left: .5rem;
+    }
+  }
+}
+
+</style>
diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js
new file mode 100644
index 00000000..3eedeaa1
--- /dev/null
+++ b/src/components/moderation_tools/moderation_tools.js
@@ -0,0 +1,106 @@
+import DialogModal from '../dialog_modal/dialog_modal.vue'
+import Popper from 'vue-popperjs/src/component/popper.js.vue'
+
+const FORCE_NSFW = 'mrf_tag:media-force-nsfw'
+const STRIP_MEDIA = 'mrf_tag:media-strip'
+const FORCE_UNLISTED = 'mrf_tag:force-unlisted'
+const DISABLE_REMOTE_SUBSCRIPTION = 'mrf_tag:disable-remote-subscription'
+const DISABLE_ANY_SUBSCRIPTION = 'mrf_tag:disable-any-subscription'
+const SANDBOX = 'mrf_tag:sandbox'
+const QUARANTINE = 'mrf_tag:quarantine'
+
+const ModerationTools = {
+  props: [
+    'user'
+  ],
+  data () {
+    return {
+      showDropDown: false,
+      tags: {
+        FORCE_NSFW,
+        STRIP_MEDIA,
+        FORCE_UNLISTED,
+        DISABLE_REMOTE_SUBSCRIPTION,
+        DISABLE_ANY_SUBSCRIPTION,
+        SANDBOX,
+        QUARANTINE
+      },
+      showDeleteUserDialog: false
+    }
+  },
+  components: {
+    DialogModal,
+    Popper
+  },
+  computed: {
+    tagsSet () {
+      return new Set(this.user.tags)
+    },
+    hasTagPolicy () {
+      return this.$store.state.instance.tagPolicyAvailable
+    }
+  },
+  methods: {
+    toggleMenu () {
+      this.showDropDown = !this.showDropDown
+    },
+    hasTag (tagName) {
+      return this.tagsSet.has(tagName)
+    },
+    toggleTag (tag) {
+      const store = this.$store
+      if (this.tagsSet.has(tag)) {
+        store.state.api.backendInteractor.untagUser(this.user, tag).then(response => {
+          if (!response.ok) { return }
+          store.commit('untagUser', {user: this.user, tag})
+        })
+      } else {
+        store.state.api.backendInteractor.tagUser(this.user, tag).then(response => {
+          if (!response.ok) { return }
+          store.commit('tagUser', {user: this.user, tag})
+        })
+      }
+    },
+    toggleRight (right) {
+      const store = this.$store
+      if (this.user.rights[right]) {
+        store.state.api.backendInteractor.deleteRight(this.user, right).then(response => {
+          if (!response.ok) { return }
+          store.commit('updateRight', {user: this.user, right: right, value: false})
+        })
+      } else {
+        store.state.api.backendInteractor.addRight(this.user, right).then(response => {
+          if (!response.ok) { return }
+          store.commit('updateRight', {user: this.user, right: right, value: true})
+        })
+      }
+    },
+    toggleActivationStatus () {
+      const store = this.$store
+      const status = !!this.user.deactivated
+      store.state.api.backendInteractor.setActivationStatus(this.user, status).then(response => {
+        if (!response.ok) { return }
+        store.commit('updateActivationStatus', {user: this.user, status: status})
+      })
+    },
+    deleteUserDialog (show) {
+      this.showDeleteUserDialog = show
+    },
+    deleteUser () {
+      const store = this.$store
+      const user = this.user
+      const {id, name} = user
+      store.state.api.backendInteractor.deleteUser(user)
+        .then(e => {
+          this.$store.dispatch('markStatusesAsDeleted', status => user.id === status.user.id)
+          const isProfile = this.$route.name === 'external-user-profile' || this.$route.name === 'user-profile'
+          const isTargetUser = this.$route.params.name === name || this.$route.params.id === id
+          if (isProfile && isTargetUser) {
+            window.history.back()
+          }
+        })
+    }
+  }
+}
+
+export default ModerationTools
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
new file mode 100644
index 00000000..c24a2280
--- /dev/null
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -0,0 +1,158 @@
+<template>
+<div class='block' style='position: relative'>
+  <Popper
+    trigger="click"
+    @hide='showDropDown = false'
+    append-to-body
+    :options="{
+      placement: 'bottom-end',
+      modifiers: {
+        arrow: { enabled: true },
+        offset: { offset: '0, 5px' },
+      }
+    }">
+    <div class="popper-wrapper">
+      <div class="dropdown-menu">
+        <span v-if='user.is_local'>
+          <button class="dropdown-item" @click='toggleRight("admin")'>
+            {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
+          </button>
+          <button class="dropdown-item" @click='toggleRight("moderator")'>
+            {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
+          </button>
+          <div role="separator" class="dropdown-divider"></div>
+        </span>
+        <button class="dropdown-item" @click='toggleActivationStatus()'>
+          {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
+        </button>
+        <button class="dropdown-item" @click='deleteUserDialog(true)'>
+          {{ $t('user_card.admin_menu.delete_account') }}
+        </button>
+        <div role="separator" class="dropdown-divider" v-if='hasTagPolicy'></div>
+        <span v-if='hasTagPolicy'>
+          <button class="dropdown-item" @click='toggleTag(tags.FORCE_NSFW)'>
+            {{ $t('user_card.admin_menu.force_nsfw') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.STRIP_MEDIA)'>
+            {{ $t('user_card.admin_menu.strip_media') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.FORCE_UNLISTED)'>
+            {{ $t('user_card.admin_menu.force_unlisted') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.SANDBOX)'>
+            {{ $t('user_card.admin_menu.sandbox') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"></span>
+          </button>
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)'>
+            {{ $t('user_card.admin_menu.disable_remote_subscription') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"></span>
+          </button>
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)'>
+            {{ $t('user_card.admin_menu.disable_any_subscription') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"></span>
+          </button>
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.QUARANTINE)'>
+            {{ $t('user_card.admin_menu.quarantine') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"></span>
+          </button>
+        </span>
+      </div>
+    </div>
+    <button slot="reference" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
+      {{ $t('user_card.admin_menu.moderation') }}
+    </button>
+  </Popper>
+  <DialogModal v-if="showDeleteUserDialog" :onCancel='deleteUserDialog.bind(this, false)'>
+    <span slot="header">{{ $t('user_card.admin_menu.delete_user') }}</span>
+    <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
+    <span slot="footer">
+      <button @click='deleteUserDialog(false)'>
+        {{ $t('general.cancel') }}
+      </button>
+      <button class="danger" @click='deleteUser()'>
+        {{ $t('user_card.admin_menu.delete_user') }}
+      </button>
+    </span>
+  </DialogModal>
+</div>
+</template>
+
+<script src="./moderation_tools.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+@import '../popper/popper.scss';
+
+.dropdown-menu {
+  display: block;
+  padding: .5rem 0;
+  font-size: 1rem;
+  text-align: left;
+  list-style: none;
+  max-width: 100vw;
+  z-index: 10;
+  box-shadow: 1px 1px 4px rgba(0,0,0,.6);
+  box-shadow: var(--panelShadow);
+  border: none;
+  border-radius: $fallback--btnRadius;
+  border-radius: var(--btnRadius, $fallback--btnRadius);
+  background-color: $fallback--bg;
+  background-color: var(--bg, $fallback--bg);
+
+  .dropdown-divider {
+    height: 0;
+    margin: .5rem 0;
+    overflow: hidden;
+    border-top: 1px solid $fallback--border;
+    border-top: 1px solid var(--border, $fallback--border);
+  }
+
+  .dropdown-item {
+    line-height: 21px;
+    margin-right: 5px;
+    overflow: auto;
+    display: block;
+    padding: .25rem 1.0rem .25rem 1.5rem;
+    clear: both;
+    font-weight: 400;
+    text-align: inherit;
+    white-space: normal;
+    border: none;
+    border-radius: 0px;
+    background-color: transparent;
+    box-shadow: none;
+    width: 100%;
+    height: 100%;
+
+    &:hover {
+      // TODO: improve the look on breeze themes
+      background-color: $fallback--fg;
+      background-color: var(--btn, $fallback--fg);
+      box-shadow: none;
+    }
+  }
+}
+
+.menu-checkbox {
+  float: right;
+  min-width: 22px;
+  max-width: 22px;
+  min-height: 22px;
+  max-height: 22px;
+  line-height: 22px;
+  text-align: center;
+  border-radius: 0px;
+  background-color: $fallback--fg;
+  background-color: var(--input, $fallback--fg);
+  box-shadow: 0px 0px 2px black inset;
+  box-shadow: var(--inputShadow);
+
+  &.menu-checkbox-checked::after {
+    content: '✔';
+  }
+}
+
+</style>
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index 42a48f3f..6aa6101f 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -21,6 +21,9 @@ const Notification = {
     },
     userProfileLink (user) {
       return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+    },
+    getUser (notification) {
+      return this.$store.state.users.usersObject[notification.action.user.id]
     }
   },
   computed: {
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 8f532747..cac335ce 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -5,7 +5,7 @@
       <UserAvatar :compact="true" :betterShadow="betterShadow" :src="notification.action.user.profile_image_url_original"/>
     </a>
     <div class='notification-right'>
-      <UserCard :user="user" :rounded="true" :bordered="true" v-if="userExpanded"/>
+      <UserCard :user="getUser(notification)" :rounded="true" :bordered="true" v-if="userExpanded"/>
       <span class="notification-details">
         <div class="name-and-action">
           <span class="username" v-if="!!notification.action.user.name_html" :title="'@'+notification.action.user.screen_name" v-html="notification.action.user.name_html"></span>
diff --git a/src/components/popper/popper.scss b/src/components/popper/popper.scss
new file mode 100644
index 00000000..0c30d625
--- /dev/null
+++ b/src/components/popper/popper.scss
@@ -0,0 +1,70 @@
+@import '../../_variables.scss';
+
+.popper-wrapper {
+  z-index: 8;
+}
+
+.popper-wrapper .popper__arrow {
+  width: 0;
+  height: 0;
+  border-style: solid;
+  position: absolute;
+  margin: 5px;
+}
+
+.popper-wrapper[x-placement^="top"] {
+  margin-bottom: 5px;
+}
+
+.popper-wrapper[x-placement^="top"] .popper__arrow {
+  border-width: 5px 5px 0 5px;
+  border-color: $fallback--bg transparent transparent transparent;
+  border-color: var(--bg, $fallback--bg) transparent transparent transparent;
+  bottom: -5px;
+  left: calc(50% - 5px);
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+.popper-wrapper[x-placement^="bottom"] {
+  margin-top: 5px;
+}
+
+.popper-wrapper[x-placement^="bottom"] .popper__arrow {
+  border-width: 0 5px 5px 5px;
+  border-color: transparent transparent $fallback--bg transparent;
+  border-color: transparent transparent var(--bg, $fallback--bg) transparent;
+  top: -5px;
+  left: calc(50% - 5px);
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+.popper-wrapper[x-placement^="right"] {
+  margin-left: 5px;
+}
+
+.popper-wrapper[x-placement^="right"] .popper__arrow {
+  border-width: 5px 5px 5px 0;
+  border-color: transparent $fallback--bg transparent transparent;
+  border-color: transparent var(--bg, $fallback--bg) transparent transparent;
+  left: -5px;
+  top: calc(50% - 5px);
+  margin-left: 0;
+  margin-right: 0;
+}
+
+.popper-wrapper[x-placement^="left"] {
+  margin-right: 5px;
+}
+
+.popper-wrapper[x-placement^="left"] .popper__arrow {
+  border-width: 5px 0 5px 5px;
+  border-color: transparent transparent transparent $fallback--bg;
+  border-color: transparent transparent transparent var(--bg, $fallback--bg);
+  right: -5px;
+  top: calc(50% - 5px);
+  margin-left: 0;
+  margin-right: 0;
+}
+
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 197c61d5..1a100de3 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,5 +1,6 @@
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
+import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -93,15 +94,17 @@ export default {
       }
     },
     visibleRole () {
-      const validRole = (this.user.role === 'admin' || this.user.role === 'moderator')
-      const showRole = this.isOtherUser || this.user.show_role
-
-      return validRole && showRole && this.user.role
+      const rights = this.user.rights
+      if (!rights) { return }
+      const validRole = rights.admin || rights.moderator
+      const roleTitle = rights.admin ? 'admin' : 'moderator'
+      return validRole && roleTitle
     }
   },
   components: {
     UserAvatar,
-    RemoteFollow
+    RemoteFollow,
+    ModerationTools
   },
   methods: {
     followUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 3259d1c5..b5c7fa24 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -99,6 +99,8 @@
             </button>
           </span>
         </div>
+        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'>
+        </ModerationTools>
       </div>
     </div>
   </div>
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 1df06fe6..540de955 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -3,6 +3,7 @@ import get from 'lodash/get'
 import UserCard from '../user_card/user_card.vue'
 import FollowCard from '../follow_card/follow_card.vue'
 import Timeline from '../timeline/timeline.vue'
+import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import withLoadMore from '../../hocs/with_load_more/with_load_more'
 import withList from '../../hocs/with_list/with_list'
 
@@ -155,7 +156,8 @@ const UserProfile = {
     UserCard,
     Timeline,
     FollowerList,
-    FriendList
+    FriendList,
+    ModerationTools
   }
 }
 
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 026546cc..0bb58734 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -22,7 +22,8 @@
     "generic_error": "An error occured",
     "optional": "optional",
     "show_more": "Show more",
-    "show_less": "Show less"
+    "show_less": "Show less",
+    "cancel": "Cancel"
   },
   "image_cropper": {
     "crop_picture": "Crop picture",
@@ -402,7 +403,26 @@
     "block_progress": "Blocking...",
     "unmute": "Unmute",
     "unmute_progress": "Unmuting...",
-    "mute_progress": "Muting..."
+    "mute_progress": "Muting...",
+    "admin_menu": {
+      "moderation": "Moderation",
+      "grant_admin": "Grant Admin",
+      "revoke_admin": "Revoke Admin",
+      "grant_moderator": "Grant Moderator",
+      "revoke_moderator": "Revoke Moderator",
+      "activate_account": "Activate account",
+      "deactivate_account": "Deactivate account",
+      "delete_account": "Delete account",
+      "force_nsfw": "Mark all posts as NSFW",
+      "strip_media": "Remove media from posts",
+      "force_unlisted": "Force posts to be unlisted",
+      "sandbox": "Force posts to be followers-only",
+      "disable_remote_subscription": "Disallow following user from remote instances",
+      "disable_any_subscription": "Disallow following user at all",
+      "quarantine": "Disallow user posts from federating",
+      "delete_user": "Delete user",
+      "delete_user_confirmation": "Are you absolutely sure? This action cannot be undone."
+    }
   },
   "user_profile": {
     "timeline_title": "User Timeline",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
index 89aa43f4..5450f154 100644
--- a/src/i18n/ru.json
+++ b/src/i18n/ru.json
@@ -8,7 +8,8 @@
   },
   "general": {
     "apply": "Применить",
-    "submit": "Отправить"
+    "submit": "Отправить",
+    "cancel": "Отмена"
   },
   "login": {
     "login": "Войти",
@@ -311,7 +312,26 @@
     "muted": "Игнорирую",
     "per_day": "в день",
     "remote_follow": "Читать удалённо",
-    "statuses": "Статусы"
+    "statuses": "Статусы",
+    "admin_menu": {
+      "moderation": "Опции модератора",
+      "grant_admin": "Сделать администратором",
+      "revoke_admin": "Забрать права администратора",
+      "grant_moderator": "Сделать модератором",
+      "revoke_moderator": "Забрать права модератора",
+      "activate_account": "Активировать аккаунт",
+      "deactivate_account": "Деактивировать аккаунт",
+      "delete_account": "Удалить аккаунт",
+      "force_nsfw": "Отмечать посты пользователя как NSFW",
+      "strip_media": "Убирать вложения из постов пользователя",
+      "force_unlisted": "Не добавлять посты в публичные ленты",
+      "sandbox": "Посты доступны только для подписчиков",
+      "disable_remote_subscription": "Запретить подписываться с удаленных серверов",
+      "disable_any_subscription": "Запретить подписываться на пользователя",
+      "quarantine": "Не федерировать посты пользователя",
+      "delete_user": "Удалить пользователя",
+      "delete_user_confirmation": "Вы уверены? Это действие нельзя отменить."
+    }
   },
   "user_profile": {
     "timeline_title": "Лента пользователя"
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 8e0203e3..4007b0fc 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -378,6 +378,13 @@ export const mutations = {
     const newStatus = state.allStatusesObject[status.id]
     newStatus.deleted = true
   },
+  setManyDeleted (state, condition) {
+    Object.values(state.allStatusesObject).forEach(status => {
+      if (condition(status)) {
+        status.deleted = true
+      }
+    })
+  },
   setLoading (state, { timeline, value }) {
     state.timelines[timeline].loading = value
   },
@@ -438,6 +445,9 @@ const statuses = {
       commit('setDeleted', { status })
       apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
     },
+    markStatusesAsDeleted ({ commit }, condition) {
+      commit('setManyDeleted', condition)
+    },
     favorite ({ rootState, commit }, status) {
       // Optimistic favoriting...
       commit('setFavorited', { status, value: true })
diff --git a/src/modules/users.js b/src/modules/users.js
index 1a507d31..5839574b 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -37,6 +37,28 @@ export const mutations = {
     const user = state.usersObject[id]
     set(user, 'muted', muted)
   },
+  tagUser (state, { user: { id }, tag }) {
+    const user = state.usersObject[id]
+    const tags = user.tags || []
+    const newTags = tags.concat([tag])
+    set(user, 'tags', newTags)
+  },
+  untagUser (state, { user: { id }, tag }) {
+    const user = state.usersObject[id]
+    const tags = user.tags || []
+    const newTags = tags.filter(t => t !== tag)
+    set(user, 'tags', newTags)
+  },
+  updateRight (state, { user: { id }, right, value }) {
+    const user = state.usersObject[id]
+    let newRights = user.rights
+    newRights[right] = value
+    set(user, 'rights', newRights)
+  },
+  updateActivationStatus (state, { user: { id }, status }) {
+    const user = state.usersObject[id]
+    set(user, 'deactivated', !status)
+  },
   setCurrentUser (state, user) {
     state.lastLoginName = user.screen_name
     state.currentUser = merge(state.currentUser || {}, user)
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 030c2f5e..bd331062 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -16,6 +16,10 @@ const CHANGE_PASSWORD_URL = '/api/pleroma/change_password'
 const FOLLOW_REQUESTS_URL = '/api/pleroma/friend_requests'
 const APPROVE_USER_URL = '/api/pleroma/friendships/approve'
 const DENY_USER_URL = '/api/pleroma/friendships/deny'
+const TAG_USER_URL = '/api/pleroma/admin/users/tag'
+const PERMISSION_GROUP_URL = '/api/pleroma/admin/permission_group'
+const ACTIVATION_STATUS_URL = '/api/pleroma/admin/activation_status'
+const ADMIN_USER_URL = '/api/pleroma/admin/user'
 const SUGGESTIONS_URL = '/api/v1/suggestions'
 
 const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
@@ -352,6 +356,86 @@ const fetchStatus = ({id, credentials}) => {
     .then((data) => parseStatus(data))
 }
 
+const tagUser = ({tag, credentials, ...options}) => {
+  const screenName = options.screen_name
+  const form = {
+    nicknames: [screenName],
+    tags: [tag]
+  }
+
+  const headers = authHeaders(credentials)
+  headers['Content-Type'] = 'application/json'
+
+  return fetch(TAG_USER_URL, {
+    method: 'PUT',
+    headers: headers,
+    body: JSON.stringify(form)
+  })
+}
+
+const untagUser = ({tag, credentials, ...options}) => {
+  const screenName = options.screen_name
+  const body = {
+    nicknames: [screenName],
+    tags: [tag]
+  }
+
+  const headers = authHeaders(credentials)
+  headers['Content-Type'] = 'application/json'
+
+  return fetch(TAG_USER_URL, {
+    method: 'DELETE',
+    headers: headers,
+    body: JSON.stringify(body)
+  })
+}
+
+const addRight = ({right, credentials, ...user}) => {
+  const screenName = user.screen_name
+
+  return fetch(`${PERMISSION_GROUP_URL}/${screenName}/${right}`, {
+    method: 'POST',
+    headers: authHeaders(credentials),
+    body: {}
+  })
+}
+
+const deleteRight = ({right, credentials, ...user}) => {
+  const screenName = user.screen_name
+
+  return fetch(`${PERMISSION_GROUP_URL}/${screenName}/${right}`, {
+    method: 'DELETE',
+    headers: authHeaders(credentials),
+    body: {}
+  })
+}
+
+const setActivationStatus = ({status, credentials, ...user}) => {
+  const screenName = user.screen_name
+  const body = {
+    status: status
+  }
+
+  const headers = authHeaders(credentials)
+  headers['Content-Type'] = 'application/json'
+
+  return fetch(`${ACTIVATION_STATUS_URL}/${screenName}.json`, {
+    method: 'PUT',
+    headers: headers,
+    body: JSON.stringify(body)
+  })
+}
+
+const deleteUser = ({credentials, ...user}) => {
+  const screenName = user.screen_name
+  const headers = authHeaders(credentials)
+
+  return fetch(`${ADMIN_USER_URL}.json?nickname=${screenName}`, {
+    method: 'DELETE',
+    headers: headers
+  })
+}
+
 const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false, tag = false, withMuted = false}) => {
   const timelineUrls = {
     public: MASTODON_PUBLIC_TIMELINE,
@@ -666,6 +750,12 @@ const apiService = {
   fetchBlocks,
   fetchOAuthTokens,
   revokeOAuthToken,
+  tagUser,
+  untagUser,
+  deleteUser,
+  addRight,
+  deleteRight,
+  setActivationStatus,
   register,
   getCaptcha,
   updateAvatar,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 71e78d2f..badcbb06 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -62,6 +62,30 @@ const backendInteractorService = (credentials) => {
     return timelineFetcherService.startFetching({timeline, store, credentials, userId, tag})
   }
 
+  const tagUser = ({screen_name}, tag) => {
+    return apiService.tagUser({screen_name, tag, credentials})
+  }
+
+  const untagUser = ({screen_name}, tag) => {
+    return apiService.untagUser({screen_name, tag, credentials})
+  }
+
+  const addRight = ({screen_name}, right) => {
+    return apiService.addRight({screen_name, right, credentials})
+  }
+
+  const deleteRight = ({screen_name}, right) => {
+    return apiService.deleteRight({screen_name, right, credentials})
+  }
+
+  const setActivationStatus = ({screen_name}, status) => {
+    return apiService.setActivationStatus({screen_name, status, credentials})
+  }
+
+  const deleteUser = ({screen_name}) => {
+    return apiService.deleteUser({screen_name, credentials})
+  }
+
   const fetchMutes = () => apiService.fetchMutes({credentials})
   const muteUser = (id) => apiService.muteUser({credentials, id})
   const unmuteUser = (id) => apiService.unmuteUser({credentials, id})
@@ -104,6 +128,12 @@ const backendInteractorService = (credentials) => {
     fetchBlocks,
     fetchOAuthTokens,
     revokeOAuthToken,
+    tagUser,
+    untagUser,
+    addRight,
+    deleteRight,
+    deleteUser,
+    setActivationStatus,
     register,
     getCaptcha,
     updateAvatar,
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index ea57e6b2..8aa4b352 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -67,6 +67,11 @@ export const parseUser = (data) => {
         output.statusnet_blocking = relationship.blocking
         output.muted = relationship.muting
       }
+
+      output.rights = {
+        moderator: data.pleroma.is_moderator,
+        admin: data.pleroma.is_admin
+      }
     }
 
     // Missing, trying to recover
@@ -103,7 +108,12 @@ export const parseUser = (data) => {
 
     // QVITTER ONLY FOR NOW
     // Really only applies to logged in user, really.. I THINK
-    output.rights = data.rights
+    if (data.rights) {
+      output.rights = {
+        moderator: data.rights.delete_others_notice,
+        admin: data.rights.admin
+      }
+    }
     output.no_rich_text = data.no_rich_text
     output.default_scope = data.default_scope
     output.hide_follows = data.hide_follows
@@ -125,6 +135,13 @@ export const parseUser = (data) => {
     output.follow_request_count = data.pleroma.follow_request_count
   }
 
+  if (data.pleroma) {
+    output.tags = data.pleroma.tags
+    output.deactivated = data.pleroma.deactivated
+  }
+
+  output.tags = output.tags || []
+
   return output
 }
 
diff --git a/yarn.lock b/yarn.lock
index 0fe45479..58007622 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4831,6 +4831,10 @@ pluralize@^1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
 
+popper.js@^1.14.7:
+  version "1.14.7"
+  resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.7.tgz#e31ec06cfac6a97a53280c3e55e4e0c860e7738e"
+
 posix-character-classes@^0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
@@ -6457,6 +6461,12 @@ vue-loader@^11.1.0:
     vue-style-loader "^2.0.0"
     vue-template-es2015-compiler "^1.2.2"
 
+vue-popperjs@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/vue-popperjs/-/vue-popperjs-2.0.3.tgz#7c446d0ba7c63170ccb33a02669d0df4efc3d8cd"
+  dependencies:
+    popper.js "^1.14.7"
+
 vue-router@^3.0.1:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.2.tgz#dedc67afe6c4e2bc25682c8b1c2a8c0d7c7e56be"
-- 
cgit v1.2.3-70-g09d2


From 6aee2ed63fa479066b2243a03af05cdba68a9ba2 Mon Sep 17 00:00:00 2001
From: Brenden Bice <brenden.next@gmail.com>
Date: Thu, 11 Apr 2019 23:14:45 -0400
Subject: replace pencil with wrench icon

# Conflicts:
#	src/components/user_card/user_card.vue
---
 src/components/user_card/user_card.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index b5c7fa24..a8055621 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -11,7 +11,7 @@
             <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
             <div :title="user.name" class='user-name' v-else>{{user.name}}</div>
             <router-link :to="{ name: 'user-settings' }" v-if="!isOtherUser">
-              <i class="button-icon icon-pencil usersettings" :title="$t('tool_tip.user_settings')"></i>
+              <i class="button-icon icon-wrench usersettings" :title="$t('tool_tip.user_settings')"></i>
             </router-link>
             <a :href="user.statusnet_profile_url" target="_blank" v-if="isOtherUser && !user.is_local">
               <i class="icon-link-ext usersettings"></i>
-- 
cgit v1.2.3-70-g09d2


From 14d506154e844cbae82489dd4edfd1d31c0559db Mon Sep 17 00:00:00 2001
From: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me>
Date: Sat, 20 Apr 2019 21:06:34 +0200
Subject: user_card.vue: Fix .emoji to apply to img

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

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index b5c7fa24..bb95f595 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -162,7 +162,7 @@
       max-width: 100%;
       max-height: 400px;
 
-      .emoji {
+      &.emoji {
         width: 32px;
         height: 32px;
       }
-- 
cgit v1.2.3-70-g09d2


From c44c0483566efc8c48361e4143b25d852cecede4 Mon Sep 17 00:00:00 2001
From: shpuld <shp@cock.li>
Date: Wed, 1 May 2019 17:33:56 +0300
Subject: add title and alt for avatars, fix console errors in avatarlist

---
 src/components/avatar_list/avatar_list.js               |  6 +++---
 src/components/avatar_list/avatar_list.vue              |  4 ++--
 src/components/basic_user_card/basic_user_card.vue      |  6 +++++-
 src/components/notification/notification.vue            |  2 +-
 src/components/status/status.js                         |  6 +++---
 src/components/status/status.vue                        | 17 +++++++++++------
 src/components/user_avatar/user_avatar.js               |  2 +-
 src/components/user_avatar/user_avatar.vue              |  4 +++-
 src/components/user_card/user_card.vue                  |  2 +-
 .../entity_normalizer/entity_normalizer.service.js      |  3 +++
 10 files changed, 33 insertions(+), 19 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/avatar_list/avatar_list.js b/src/components/avatar_list/avatar_list.js
index d65125c2..b9e11aaa 100644
--- a/src/components/avatar_list/avatar_list.js
+++ b/src/components/avatar_list/avatar_list.js
@@ -1,10 +1,10 @@
 import UserAvatar from '../user_avatar/user_avatar.vue'
 
 const AvatarList = {
-  props: ['avatars'],
+  props: ['users'],
   computed: {
-    slicedAvatars () {
-      return this.avatars ? this.avatars.slice(0, 15) : []
+    slicedUsers () {
+      return this.users ? this.users.slice(0, 15) : []
     }
   },
   components: {
diff --git a/src/components/avatar_list/avatar_list.vue b/src/components/avatar_list/avatar_list.vue
index b14474ba..4e0de2c9 100644
--- a/src/components/avatar_list/avatar_list.vue
+++ b/src/components/avatar_list/avatar_list.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="avatars">
-      <div class="avatars-item" v-for="avatar in slicedAvatars">
-        <UserAvatar :src="avatar.profile_image_url" class="avatar-small" />
+      <div class="avatars-item" v-for="user in slicedUsers">
+        <UserAvatar :user="user" class="avatar-small" />
       </div>
   </div>
 </template>
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 25f1fb2a..634d62b3 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -1,7 +1,11 @@
 <template>
   <div class="basic-user-card">
     <router-link :to="userProfileLink(user)">
-      <UserAvatar class="avatar" @click.prevent.native="toggleUserExpanded" :src="user.profile_image_url"/>
+      <UserAvatar
+        class="avatar"
+        :user="user"
+        @click.prevent.native="toggleUserExpanded"
+      />
     </router-link>
     <div class="basic-user-card-expanded-content" v-if="userExpanded">
       <UserCard :user="user" :rounded="true" :bordered="true"/>
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index ae11d692..3427b9c5 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -7,7 +7,7 @@
   </status>
   <div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]" v-else>
     <a class='avatar-container' :href="notification.from_profile.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
-      <UserAvatar :compact="true" :betterShadow="betterShadow" :src="notification.from_profile.profile_image_url_original" />
+      <UserAvatar :compact="true" :betterShadow="betterShadow" :user="notification.from_profile"/>
     </a>
     <div class='notification-right'>
       <UserCard :user="getUser(notification)" :rounded="true" :bordered="true" v-if="userExpanded" />
diff --git a/src/components/status/status.js b/src/components/status/status.js
index f10eb2e4..ff8cbe18 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -263,13 +263,13 @@ const Status = {
       }
       return this.status.summary_html + '<br />' + this.status.statusnet_html
     },
-    combinedFavsAndRepeatsAvatars () {
+    combinedFavsAndRepeatsUsers () {
       // Use the status from the global status repository since favs and repeats are saved in it
-      const combinedAvatars = [].concat(
+      const combinedUsers = [].concat(
         this.statusFromGlobalRepository.favoritedBy,
         this.statusFromGlobalRepository.rebloggedBy
       )
-      return uniqBy(combinedAvatars, 'id')
+      return uniqBy(combinedUsers, 'id')
     }
   },
   components: {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index a5f7429c..43c3030e 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -13,7 +13,7 @@
     </template>
     <template v-else>
       <div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info">
-        <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :src="statusoid.user.profile_image_url_original"/>
+        <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/>
         <div class="media-body faint">
           <span class="user-name">
             <router-link v-if="retweeterHtml" :to="retweeterProfileLink" v-html="retweeterHtml"/>
@@ -27,7 +27,7 @@
       <div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]" :style="[ userStyle ]" class="media status">
         <div v-if="!noHeading" class="media-left">
           <router-link :to="userProfileLink" @click.stop.prevent.capture.native="toggleUserExpanded">
-            <UserAvatar :compact="compact" :betterShadow="betterShadow" :src="status.user.profile_image_url_original"/>
+            <UserAvatar :compact="compact" :betterShadow="betterShadow" :user="status.user"/>
           </router-link>
         </div>
         <div class="status-body">
@@ -91,8 +91,13 @@
           </div>
 
           <div v-if="showPreview" class="status-preview-container">
-            <status class="status-preview" v-if="preview" :isPreview="true" :statusoid="preview" :compact=true></status>
-            <div class="status-preview status-preview-loading" v-else>
+            <status class="status-preview"
+              v-if="preview"
+              :isPreview="true"
+              :statusoid="preview"
+              :compact=true
+            />
+            <div v-else class="status-preview status-preview-loading">
               <i class="icon-spin4 animate-spin"></i>
             </div>
           </div>
@@ -134,7 +139,7 @@
           </div>
 
           <transition name="fade">
-            <div class="favs-repeated-users" v-if="combinedFavsAndRepeatsAvatars.length > 0 && isFocused">
+            <div class="favs-repeated-users" v-if="combinedFavsAndRepeatsUsers.length > 0 && isFocused">
               <div class="stats">
                 <div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0">
                   <a class="stat-title">{{ $t('status.repeats') }}</a>
@@ -145,7 +150,7 @@
                   <div class="stat-number">{{ statusFromGlobalRepository.favoritedBy.length }}</div>
                 </div>
                 <div class="avatar-row">
-                  <AvatarList :avatars='combinedFavsAndRepeatsAvatars'></AvatarList>
+                  <AvatarList :users="combinedFavsAndRepeatsUsers"></AvatarList>
                 </div>
               </div>
             </div>
diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js
index e6fed3b5..a42b9c71 100644
--- a/src/components/user_avatar/user_avatar.js
+++ b/src/components/user_avatar/user_avatar.js
@@ -2,7 +2,7 @@ import StillImage from '../still-image/still-image.vue'
 
 const UserAvatar = {
   props: [
-    'src',
+    'user',
     'betterShadow',
     'compact'
   ],
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index 6bf7123d..e5466fdf 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -1,8 +1,10 @@
 <template>
   <StillImage
     class="avatar"
+    :alt="user.screen_name"
+    :title="user.screen_name"
+    :src="user.profile_image_url_original"
     :class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
-    :src="imgSrc"
     :imageLoadError="imageLoadError"
   />
 </template>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index e1d3ff57..e62b384d 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -4,7 +4,7 @@
     <div class='user-info'>
       <div class='container'>
         <router-link :to="userProfileLink(user)">
-          <UserAvatar :betterShadow="betterShadow" :src="user.profile_image_url_original"/>
+          <UserAvatar :betterShadow="betterShadow" :user="user"/>
         </router-link>
         <div class="name-and-screen-name">
           <div class="top-line">
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index e706e7d9..309aa1e8 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -275,6 +275,9 @@ export const parseStatus = (data) => {
     output.retweeted_status = parseStatus(retweetedStatus)
   }
 
+  output.favoritedBy = []
+  output.rebloggedBy = []
+
   return output
 }
 
-- 
cgit v1.2.3-70-g09d2


From 2cda9010df6192b008515b2138a2e071473bc40b Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 19 Mar 2019 04:53:11 -0400
Subject: add user reporting modal

---
 src/App.js                                         |   4 +-
 src/App.vue                                        |   1 +
 src/components/checkbox/checkbox.js                |  44 ++++++++
 src/components/checkbox/checkbox.scss              |  48 +++++++++
 src/components/user_card/user_card.js              |   3 +
 src/components/user_card/user_card.vue             |  10 +-
 .../user_reporting_modal/user_reporting_modal.js   |  81 +++++++++++++++
 .../user_reporting_modal/user_reporting_modal.vue  | 111 +++++++++++++++++++++
 src/i18n/en.json                                   |   1 +
 src/main.js                                        |   4 +-
 src/modules/reports.js                             |  33 ++++++
 11 files changed, 336 insertions(+), 4 deletions(-)
 create mode 100644 src/components/checkbox/checkbox.js
 create mode 100644 src/components/checkbox/checkbox.scss
 create mode 100644 src/components/user_reporting_modal/user_reporting_modal.js
 create mode 100644 src/components/user_reporting_modal/user_reporting_modal.vue
 create mode 100644 src/modules/reports.js

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/App.js b/src/App.js
index 46145b16..e72c73e3 100644
--- a/src/App.js
+++ b/src/App.js
@@ -10,6 +10,7 @@ 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 MobileNav from './components/mobile_nav/mobile_nav.vue'
+import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
 import { windowWidth } from './services/window_utils/window_utils'
 
 export default {
@@ -26,7 +27,8 @@ export default {
     MediaModal,
     SideDrawer,
     MobilePostStatusModal,
-    MobileNav
+    MobileNav,
+    UserReportingModal
   },
   data: () => ({
     mobileActivePanel: 'timeline',
diff --git a/src/App.vue b/src/App.vue
index 3b8623ad..cb7e8d78 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -46,6 +46,7 @@
       <media-modal></media-modal>
     </div>
     <chat-panel :floating="true" v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
+    <UserReportingModal />
   </div>
 </template>
 
diff --git a/src/components/checkbox/checkbox.js b/src/components/checkbox/checkbox.js
new file mode 100644
index 00000000..324a7597
--- /dev/null
+++ b/src/components/checkbox/checkbox.js
@@ -0,0 +1,44 @@
+// TODO: Template-based functional component is supported in vue-loader 13.3.0+.
+// Also, somehow, props are not provided through 'context' even though they are defined.
+// Need to upgrade vue-loader
+
+import './checkbox.scss'
+
+export default {
+  functional: true,
+  name: 'Checkbox',
+  model: {
+    prop: 'checked',
+    event: 'change'
+  },
+  render (createElement, { data, children }) {
+    const { props = {}, attrs = {}, on = {}, ...rest } = data
+    const { name, checked, disabled, readonly, ...restAttrs } = attrs
+    const { change, ...restListeners } = on
+    const wrapperProps = {
+      attrs: restAttrs,
+      on: restListeners,
+      ...rest
+    }
+    const inputProps = {
+      attrs: {
+        name,
+        checked,
+        disabled,
+        readonly,
+        ...props
+      },
+      on: {}
+    }
+    if (change) {
+      inputProps.on.change = e => change(e.target.checked)
+    }
+    return (
+      <label class="checkbox" {...wrapperProps}>
+        <input type="checkbox" {...inputProps} />
+        <i />
+        {children && <span>{children}</span>}
+      </label>
+    )
+  }
+}
diff --git a/src/components/checkbox/checkbox.scss b/src/components/checkbox/checkbox.scss
new file mode 100644
index 00000000..07b3f39e
--- /dev/null
+++ b/src/components/checkbox/checkbox.scss
@@ -0,0 +1,48 @@
+@import '../../_variables.scss';
+
+.checkbox {
+  position: relative;
+  display: inline-block;
+  padding-left: 1.2em;
+
+  input[type=checkbox] {
+    display: none;
+
+    & + i::before {
+      position: absolute;
+      left: 0;
+      top: 0;
+      display: block;
+      content: '✔';
+      transition: color 200ms;
+      width: 1.1em;
+      height: 1.1em;
+      border-radius: $fallback--checkboxRadius;
+      border-radius: var(--checkboxRadius, $fallback--checkboxRadius);
+      box-shadow: 0px 0px 2px black inset;
+      box-shadow: var(--inputShadow);
+      background-color: $fallback--fg;
+      background-color: var(--input, $fallback--fg);
+      vertical-align: top;
+      text-align: center;
+      line-height: 1.1em;
+      font-size: 1.1em;
+      color: transparent;
+      overflow: hidden;
+      box-sizing: border-box;
+    }
+
+    &:checked + i::before {
+      color: $fallback--text;
+      color: var(--text, $fallback--text);
+    }
+
+    &:disabled + i::before {
+      opacity: .5;
+    }
+  }
+
+  & > span {
+    margin-left: .5em;
+  }
+}
\ No newline at end of file
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 1a100de3..7c6ffa89 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -151,6 +151,9 @@ export default {
     },
     userProfileLink (user) {
       return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+    },
+    reportUser () {
+      this.$store.dispatch('openUserReportingModal', this.user.id)
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index e62b384d..2d02ca03 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -99,8 +99,14 @@
             </button>
           </span>
         </div>
-        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'>
-        </ModerationTools>
+        <div class='block' v-if='isOtherUser && loggedIn'>
+          <span>
+            <button @click="reportUser">
+              {{ $t('user_card.report') }}
+            </button>
+          </span>
+        </div>
+        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'/>
       </div>
     </div>
   </div>
diff --git a/src/components/user_reporting_modal/user_reporting_modal.js b/src/components/user_reporting_modal/user_reporting_modal.js
new file mode 100644
index 00000000..fb9ea16d
--- /dev/null
+++ b/src/components/user_reporting_modal/user_reporting_modal.js
@@ -0,0 +1,81 @@
+
+import Status from '../status/status.vue'
+import Checkbox from '../checkbox/checkbox.js'
+
+const UserReportingModal = {
+  components: {
+    Status,
+    Checkbox
+  },
+  data () {
+    return {
+      comment: '',
+      forward: false,
+      statusIdsToReport: []
+    }
+  },
+  computed: {
+    isLoggedIn () {
+      return !!this.$store.state.users.currentUser
+    },
+    isOpen () {
+      return this.isLoggedIn && this.$store.state.reports.modalActivated
+    },
+    userId () {
+      return this.$store.state.reports.userId
+    },
+    user () {
+      return this.$store.getters.findUser(this.userId)
+    },
+    remoteInstance () {
+      return !this.user.is_local && this.user.screen_name.substr(this.user.screen_name.indexOf('@') + 1)
+    },
+    statuses () {
+      return this.$store.state.reports.statuses
+    }
+  },
+  watch: {
+    userId (value) {
+      this.statusIdsToReport = []
+    }
+  },
+  methods: {
+    closeModal () {
+      this.$store.dispatch('closeUserReportingModal')
+    },
+    reportUser () {
+      const payload = {
+        comment: this.comment,
+        forward: this.forward,
+        statusIdsToReport: this.statusIdsToReport
+      }
+      this.$store.dispatch('reportUser', payload)
+    },
+    isChecked (statusId) {
+      return this.statusIdsToReport.indexOf(statusId) !== -1
+    },
+    toggleStatus (checked, statusId) {
+      if (checked === this.isChecked(statusId)) {
+        return
+      }
+
+      if (checked) {
+        this.statusIdsToReport.push(statusId)
+      } else {
+        this.statusIdsToReport.splice(this.statusIdsToReport.indexOf(statusId), 1)
+      }
+    },
+    resize (e) {
+      const target = e.target || e
+      if (!(target instanceof window.Element)) { return }
+      // Auto is needed to make textbox shrink when removing lines
+      target.style.height = 'auto'
+      target.style.height = `${target.scrollHeight}px`
+      if (target.value === '') {
+        target.style.height = null
+      }
+    }
+  }
+}
+
+export default UserReportingModal
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
new file mode 100644
index 00000000..49839da3
--- /dev/null
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -0,0 +1,111 @@
+<template>
+<div class="modal-view" @click="closeModal" v-if="isOpen">
+  <div class="user-reporting-panel panel" @click.stop="">
+    <div class="panel-heading">Reporting {{user.screen_name}}</div>
+    <div class="panel-body">
+      <div class="user-reporting-panel-left">
+        <div>
+          <p>The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:</p>
+          <textarea
+            v-model="comment"
+            class="form-control"
+            placeholder="Additional comments"
+            rows="1"
+            @input="resize"
+          />
+        </div>
+        <div v-if="!user.is_local">
+          <p>The account is from another server. Send an anonymized copy of the report there as well?</p>
+          <Checkbox v-model="forward">Forward to {{remoteInstance}}</Checkbox>
+        </div>
+        <div>
+          <button class="btn btn-default" @click="reportUser">Submit</button>
+        </div>
+      </div>
+      <div class="user-reporting-panel-right">
+        <div v-for="status in statuses" :key="status.id" class="status-fadein">
+          <Status :inConversation="false" :focused="false" :statusoid="status" />
+          <Checkbox :checked="isChecked(status.id)" @change="checked => toggleStatus(checked, status.id)" />
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+</template>
+
+<script src="./user_reporting_modal.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+
+.user-reporting-panel {
+  width: 90vw;
+  max-width: 700px;
+
+  .panel-body {
+    display: flex;
+    border-top: 1px solid;
+    border-color: $fallback--border;
+    border-color: var(--border, $fallback--border);
+  }
+
+  &-left {
+    width: 50%;
+    padding: 1.1em;
+    border-right: 1px solid;
+    border-color: $fallback--border;
+    border-color: var(--border, $fallback--border);
+    max-width: 320px;
+    line-height: 1.4em;
+    box-sizing: border-box;
+
+    > div {
+      margin-bottom: 2em;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+
+    p {
+      margin-top: 0;
+    }
+
+    textarea.form-control {
+      line-height: 16px;
+      resize: none;
+      overflow: hidden;
+      transition: min-height 200ms 100ms;
+      min-height: 44px;
+      width: 100%;
+    }
+
+    .btn {
+      min-width: 10em;
+      padding: 0 2em;
+    }
+  }
+
+  &-right {
+    width: 50%;
+    flex: 1 1 auto;
+    min-height: 20vh;
+    max-height: 80vh;
+    overflow-y: auto;
+    overflow-x: hidden;
+
+    > div {
+      display: flex;
+      justify-content: space-between;
+      border-bottom-width: 1px;
+      border-bottom-style: solid;
+      border-color: $fallback--border;
+      border-color: var(--border, $fallback--border);
+
+      .checkbox {
+        margin: 0.75em;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index b07af5e5..8292c921 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -420,6 +420,7 @@
     "muted": "Muted",
     "per_day": "per day",
     "remote_follow": "Remote follow",
+    "report": "Report",
     "statuses": "Statuses",
     "unblock": "Unblock",
     "unblock_progress": "Unblocking...",
diff --git a/src/main.js b/src/main.js
index 725f5806..92f843b1 100644
--- a/src/main.js
+++ b/src/main.js
@@ -12,6 +12,7 @@ import chatModule from './modules/chat.js'
 import oauthModule from './modules/oauth.js'
 import mediaViewerModule from './modules/media_viewer.js'
 import oauthTokensModule from './modules/oauth_tokens.js'
+import reportsModule from './modules/reports.js'
 
 import VueTimeago from 'vue-timeago'
 import VueI18n from 'vue-i18n'
@@ -75,7 +76,8 @@ const persistedStateOptions = {
       chat: chatModule,
       oauth: oauthModule,
       mediaViewer: mediaViewerModule,
-      oauthTokens: oauthTokensModule
+      oauthTokens: oauthTokensModule,
+      reports: reportsModule
     },
     plugins: [persistedState, pushNotifications],
     strict: false // Socket modifies itself, let's ignore this for now.
diff --git a/src/modules/reports.js b/src/modules/reports.js
new file mode 100644
index 00000000..b712cfeb
--- /dev/null
+++ b/src/modules/reports.js
@@ -0,0 +1,33 @@
+import filter from 'lodash/filter'
+
+const reports = {
+  state: {
+    userId: null,
+    statuses: [],
+    modalActivated: false
+  },
+  mutations: {
+    openUserReportingModal (state, { userId, statuses }) {
+      state.userId = userId
+      state.statuses = statuses
+      state.modalActivated = true
+    },
+    closeUserReportingModal (state) {
+      state.modalActivated = false
+    }
+  },
+  actions: {
+    openUserReportingModal ({ rootState, commit }, userId) {
+      const statuses = filter(rootState.statuses.allStatuses, status => status.user.id === userId)
+      commit('openUserReportingModal', { userId, statuses })
+    },
+    closeUserReportingModal ({ commit }) {
+      commit('closeUserReportingModal')
+    },
+    reportUser ({ commit }, payload) {
+      console.log('payload', payload)
+    }
+  }
+}
+
+export default reports
-- 
cgit v1.2.3-70-g09d2


From 9adbc2c17fced9328771a5f6e7cfefef54ebfb79 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 15 May 2019 22:01:04 -0400
Subject: make only screen name as link

---
 src/components/user_card/user_card.vue | 71 ++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 33 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 2d02ca03..f21770ce 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -6,7 +6,7 @@
         <router-link :to="userProfileLink(user)">
           <UserAvatar :betterShadow="betterShadow" :user="user"/>
         </router-link>
-        <div class="name-and-screen-name">
+        <div class="user-summary">
           <div class="top-line">
             <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
             <div :title="user.name" class='user-name' v-else>{{user.name}}</div>
@@ -18,12 +18,14 @@
             </a>
           </div>
 
-          <router-link class='user-screen-name' :to="userProfileLink(user)">
-            <span class="handle">@{{user.screen_name}}
+          <div class="bottom-line">
+            <span class="user-screen-name-role">
+              <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
               <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
-            </span><span v-if="user.locked"><i class="icon icon-lock"></i></span>
+            </span>
+            <span v-if="user.locked"><i class="icon icon-lock"></i></span>
             <span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
-          </router-link>
+          </div>
         </div>
       </div>
       <div class="user-meta">
@@ -232,7 +234,7 @@
     opacity: .8;
   }
 
-  .name-and-screen-name {
+  .user-summary {
     display: block;
     margin-left: 0.6em;
     text-align: left;
@@ -249,6 +251,7 @@
       vertical-align: middle;
       object-fit: contain
     }
+
     .top-line {
       display: flex;
     }
@@ -269,40 +272,42 @@
     }
   }
 
-  .user-screen-name {
-    color: $fallback--lightText;
-    color: var(--lightText, $fallback--lightText);
-    display: inline-block;
+  .bottom-line {
+    display: flex;
     font-weight: light;
     font-size: 15px;
     padding-right: 0.1em;
     width: 100%;
-    display: flex;
+  }
 
-    .dailyAvg {
-      min-width: 1px;
-      flex: 0 0 auto;
-      margin-left: 1em;
-      font-size: 0.7em;
-      color: $fallback--text;
-      color: var(--text, $fallback--text);
-    }
+  .user-screen-name-role {
+    min-width: 1px;
+    flex: 0 1 auto;
+    text-overflow: ellipsis;
+    overflow: hidden;
+  }
 
-    .handle {
-      min-width: 1px;
-      flex: 0 1 auto;
-      text-overflow: ellipsis;
-      overflow: hidden;
-    }
+  .user-screen-name {
+    color: $fallback--lightText;
+    color: var(--lightText, $fallback--lightText);
+  }
 
-    // TODO use proper colors
-    .staff {
-      text-transform: capitalize;
-      color: $fallback--text;
-      color: var(--btnText, $fallback--text);
-      background-color: $fallback--fg;
-      background-color: var(--btn, $fallback--fg);
-    }
+  .dailyAvg {
+    min-width: 1px;
+    flex: 0 0 auto;
+    margin-left: 1em;
+    font-size: 0.7em;
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
+  }
+
+  // TODO use proper colors
+  .staff {
+    text-transform: capitalize;
+    color: $fallback--text;
+    color: var(--btnText, $fallback--text);
+    background-color: $fallback--fg;
+    background-color: var(--btn, $fallback--fg);
   }
 
   .user-meta {
-- 
cgit v1.2.3-70-g09d2


From 34ffcb028a9cf195f430a33d8c029ac4cc8b191d Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 15 May 2019 22:01:31 -0400
Subject: refactor css

---
 src/components/user_card/user_card.vue | 54 ++++++++++++++++------------------
 1 file changed, 26 insertions(+), 28 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f21770ce..530f56e0 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -276,38 +276,36 @@
     display: flex;
     font-weight: light;
     font-size: 15px;
-    padding-right: 0.1em;
-    width: 100%;
-  }
 
-  .user-screen-name-role {
-    min-width: 1px;
-    flex: 0 1 auto;
-    text-overflow: ellipsis;
-    overflow: hidden;
-  }
+    .user-screen-name-role {
+      min-width: 1px;
+      flex: 0 1 auto;
+      text-overflow: ellipsis;
+      overflow: hidden;
+    }
 
-  .user-screen-name {
-    color: $fallback--lightText;
-    color: var(--lightText, $fallback--lightText);
-  }
+    .user-screen-name {
+      color: $fallback--lightText;
+      color: var(--lightText, $fallback--lightText);
+    }
 
-  .dailyAvg {
-    min-width: 1px;
-    flex: 0 0 auto;
-    margin-left: 1em;
-    font-size: 0.7em;
-    color: $fallback--text;
-    color: var(--text, $fallback--text);
-  }
+    .dailyAvg {
+      min-width: 1px;
+      flex: 0 0 auto;
+      margin-left: 1em;
+      font-size: 0.7em;
+      color: $fallback--text;
+      color: var(--text, $fallback--text);
+    }
 
-  // TODO use proper colors
-  .staff {
-    text-transform: capitalize;
-    color: $fallback--text;
-    color: var(--btnText, $fallback--text);
-    background-color: $fallback--fg;
-    background-color: var(--btn, $fallback--fg);
+    // TODO use proper colors
+    .staff {
+      text-transform: capitalize;
+      color: $fallback--text;
+      color: var(--btnText, $fallback--text);
+      background-color: $fallback--fg;
+      background-color: var(--btn, $fallback--fg);
+    }
   }
 
   .user-meta {
-- 
cgit v1.2.3-70-g09d2


From 205a9821e630fae9864a518824e52dea4fd0de28 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Sun, 19 May 2019 14:25:02 -0400
Subject: make staff label visible

---
 src/components/user_card/user_card.vue | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 530f56e0..b4495673 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -19,10 +19,8 @@
           </div>
 
           <div class="bottom-line">
-            <span class="user-screen-name-role">
-              <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
-              <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
-            </span>
+            <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
+            <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
             <span v-if="user.locked"><i class="icon icon-lock"></i></span>
             <span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
           </div>
@@ -277,14 +275,11 @@
     font-weight: light;
     font-size: 15px;
 
-    .user-screen-name-role {
+    .user-screen-name {
       min-width: 1px;
       flex: 0 1 auto;
       text-overflow: ellipsis;
       overflow: hidden;
-    }
-
-    .user-screen-name {
       color: $fallback--lightText;
       color: var(--lightText, $fallback--lightText);
     }
@@ -300,6 +295,7 @@
 
     // TODO use proper colors
     .staff {
+      flex: none;
       text-transform: capitalize;
       color: $fallback--text;
       color: var(--btnText, $fallback--text);
-- 
cgit v1.2.3-70-g09d2


From 8d6750d9c2816e33a0444cd978f94009d8b85d47 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 5 Jul 2019 10:17:44 +0300
Subject: eslint --fix --ext .js,.vue src

---
 src/App.vue                                        | 108 ++-
 src/components/about/about.vue                     |   6 +-
 src/components/attachment/attachment.vue           | 100 ++-
 src/components/autosuggest/autosuggest.vue         |  22 +-
 src/components/avatar_list/avatar_list.vue         |   9 +-
 src/components/basic_user_card/basic_user_card.vue |  41 +-
 src/components/block_card/block_card.vue           |  14 +-
 src/components/chat_panel/chat_panel.vue           |  59 +-
 src/components/checkbox/checkbox.vue               |   9 +-
 src/components/color_input/color_input.vue         |  65 +-
 src/components/contrast_ratio/contrast_ratio.vue   |  52 +-
 .../conversation-page/conversation-page.vue        |   4 +-
 src/components/conversation/conversation.vue       |  27 +-
 src/components/dialog_modal/dialog_modal.vue       |  16 +-
 src/components/dm_timeline/dm_timeline.vue         |   6 +-
 src/components/emoji-input/emoji-input.vue         |  44 +-
 src/components/export_import/export_import.vue     |  33 +-
 src/components/exporter/exporter.vue               |  12 +-
 src/components/extra_buttons/extra_buttons.vue     |  39 +-
 src/components/favorite_button/favorite_button.vue |  17 +-
 src/components/features_panel/features_panel.vue   |  22 +-
 src/components/follow_card/follow_card.vue         |  19 +-
 .../follow_request_card/follow_request_card.vue    |  14 +-
 src/components/follow_requests/follow_requests.vue |   9 +-
 src/components/font_control/font_control.vue       |  80 +-
 .../friends_timeline/friends_timeline.vue          |   6 +-
 src/components/gallery/gallery.vue                 |  18 +-
 src/components/image_cropper/image_cropper.vue     |  55 +-
 src/components/importer/importer.vue               |  33 +-
 .../instance_specific_panel.vue                    |   8 +-
 src/components/interactions/interactions.vue       |  30 +-
 .../interface_language_switcher.vue                |  69 +-
 src/components/link-preview/link-preview.vue       |  18 +-
 src/components/list/list.vue                       |  16 +-
 src/components/login_form/login_form.vue           | 114 +--
 src/components/media_modal/media_modal.vue         |  22 +-
 src/components/media_upload/media_upload.vue       |  30 +-
 src/components/mentions/mentions.vue               |   6 +-
 src/components/mfa_form/recovery_form.vue          |  85 ++-
 src/components/mfa_form/totp_form.vue              |  90 ++-
 src/components/mobile_nav/mobile_nav.vue           |  71 +-
 .../mobile_post_status_modal.vue                   |  42 +-
 .../moderation_tools/moderation_tools.vue          | 237 ++++--
 src/components/mute_card/mute_card.vue             |  14 +-
 src/components/nav_panel/nav_panel.vue             |  17 +-
 src/components/notification/notification.vue       |  97 ++-
 src/components/notifications/notifications.vue     |  66 +-
 src/components/opacity_input/opacity_input.vue     |  58 +-
 src/components/poll/poll.vue                       |  39 +-
 src/components/poll/poll_form.vue                  |  65 +-
 .../post_status_form/post_status_form.vue          | 363 +++++----
 src/components/progress_button/progress_button.vue |   5 +-
 .../public_and_external_timeline.vue               |   6 +-
 src/components/public_timeline/public_timeline.vue |   6 +-
 src/components/range_input/range_input.vue         |  79 +-
 src/components/registration/registration.vue       | 222 ++++--
 src/components/remote_follow/remote_follow.vue     |  22 +-
 src/components/retweet_button/retweet_button.vue   |  23 +-
 src/components/scope_selector/scope_selector.vue   |  59 +-
 src/components/selectable_list/selectable_list.vue |  47 +-
 src/components/settings/settings.vue               | 732 +++++++++++-------
 src/components/shadow_control/shadow_control.vue   | 292 +++++---
 src/components/side_drawer/side_drawer.vue         |  97 ++-
 src/components/status/status.vue                   | 409 +++++++---
 src/components/still-image/still-image.vue         |  18 +-
 src/components/style_switcher/preview.vue          | 151 ++--
 src/components/style_switcher/style_switcher.vue   | 825 ++++++++++++++-------
 src/components/tag_timeline/tag_timeline.vue       |   9 +-
 .../terms_of_service_panel.vue                     |   6 +-
 src/components/timeago/timeago.vue                 |  19 +-
 src/components/timeline/timeline.vue               |  57 +-
 src/components/user_avatar/user_avatar.vue         |   2 +-
 src/components/user_card/user_card.vue             | 360 ++++++---
 src/components/user_finder/user_finder.vue         |  37 +-
 src/components/user_panel/user_panel.vue           |  20 +-
 src/components/user_profile/user_profile.vue       | 159 ++--
 .../user_reporting_modal/user_reporting_modal.vue  | 100 ++-
 src/components/user_search/user_search.vue         |  36 +-
 src/components/user_settings/confirm.vue           |  26 +-
 src/components/user_settings/mfa.vue               | 186 +++--
 src/components/user_settings/mfa_backup_codes.vue  |  24 +-
 src/components/user_settings/mfa_totp.vue          |  56 +-
 src/components/user_settings/user_settings.vue     | 523 +++++++++----
 .../video_attachment/video_attachment.vue          |   5 +-
 src/components/who_to_follow/who_to_follow.vue     |   9 +-
 .../who_to_follow_panel/who_to_follow_panel.vue    |  17 +-
 86 files changed, 4910 insertions(+), 2230 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/App.vue b/src/App.vue
index 769e075d..758c9fce 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,53 +1,111 @@
 <template>
-  <div id="app" v-bind:style="bgAppStyle">
-    <div class="app-bg-wrapper" v-bind:style="bgStyle"></div>
+  <div
+    id="app"
+    :style="bgAppStyle"
+  >
+    <div
+      class="app-bg-wrapper"
+      :style="bgStyle"
+    />
     <MobileNav v-if="isMobileLayout" />
-    <nav v-else class='nav-bar container' @click="scrollToTop()" id="nav">
-      <div class='logo' :style='logoBgStyle'>
-        <div class='mask' :style='logoMaskStyle'></div>
-        <img :src='logo' :style='logoStyle'>
+    <nav
+      v-else
+      id="nav"
+      class="nav-bar container"
+      @click="scrollToTop()"
+    >
+      <div
+        class="logo"
+        :style="logoBgStyle"
+      >
+        <div
+          class="mask"
+          :style="logoMaskStyle"
+        />
+        <img
+          :src="logo"
+          :style="logoStyle"
+        >
       </div>
-      <div class='inner-nav'>
-        <div class='item'>
-          <router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
+      <div class="inner-nav">
+        <div class="item">
+          <router-link
+            class="site-name"
+            :to="{ name: 'root' }"
+            active-class="home"
+          >
+            {{ sitename }}
+          </router-link>
         </div>
-        <div class='item right'>
-          <user-finder class="button-icon nav-icon mobile-hidden" @toggled="onFinderToggled"></user-finder>
-          <router-link class="mobile-hidden" :to="{ name: 'settings'}"><i class="button-icon icon-cog nav-icon" :title="$t('nav.preferences')"></i></router-link>
-          <a href="#" class="mobile-hidden" v-if="currentUser" @click.prevent="logout"><i class="button-icon icon-logout nav-icon" :title="$t('login.logout')"></i></a>
+        <div class="item right">
+          <user-finder
+            class="button-icon nav-icon mobile-hidden"
+            @toggled="onFinderToggled"
+          />
+          <router-link
+            class="mobile-hidden"
+            :to="{ name: 'settings'}"
+          >
+            <i
+              class="button-icon icon-cog nav-icon"
+              :title="$t('nav.preferences')"
+            />
+          </router-link>
+          <a
+            v-if="currentUser"
+            href="#"
+            class="mobile-hidden"
+            @click.prevent="logout"
+          ><i
+            class="button-icon icon-logout nav-icon"
+            :title="$t('login.logout')"
+          /></a>
         </div>
       </div>
     </nav>
-    <div class="container" id="content">
+    <div
+      id="content"
+      class="container"
+    >
       <div class="sidebar-flexer mobile-hidden">
         <div class="sidebar-bounds">
           <div class="sidebar-scroller">
             <div class="sidebar">
-              <user-panel></user-panel>
+              <user-panel />
               <div v-if="!isMobileLayout">
-                <nav-panel></nav-panel>
-                <instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
-                <features-panel v-if="!currentUser && showFeaturesPanel"></features-panel>
-                <who-to-follow-panel v-if="currentUser && suggestionsEnabled"></who-to-follow-panel>
-                <notifications v-if="currentUser"></notifications>
+                <nav-panel />
+                <instance-specific-panel v-if="showInstanceSpecificPanel" />
+                <features-panel v-if="!currentUser && showFeaturesPanel" />
+                <who-to-follow-panel v-if="currentUser && suggestionsEnabled" />
+                <notifications v-if="currentUser" />
               </div>
             </div>
           </div>
         </div>
       </div>
       <div class="main">
-        <div v-if="!currentUser" class="login-hint panel panel-default">
-          <router-link :to="{ name: 'login' }" class="panel-body">
+        <div
+          v-if="!currentUser"
+          class="login-hint panel panel-default"
+        >
+          <router-link
+            :to="{ name: 'login' }"
+            class="panel-body"
+          >
             {{ $t("login.hint") }}
           </router-link>
         </div>
         <transition name="fade">
-          <router-view></router-view>
+          <router-view />
         </transition>
       </div>
-      <media-modal></media-modal>
+      <media-modal />
     </div>
-    <chat-panel :floating="true" v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
+    <chat-panel
+      v-if="currentUser && chat"
+      :floating="true"
+      class="floating-chat mobile-hidden"
+    />
     <UserReportingModal />
     <portal-target name="modal" />
   </div>
diff --git a/src/components/about/about.vue b/src/components/about/about.vue
index 13dec87c..62ae16ea 100644
--- a/src/components/about/about.vue
+++ b/src/components/about/about.vue
@@ -1,8 +1,8 @@
 <template>
   <div class="sidebar">
-    <instance-specific-panel></instance-specific-panel>
-    <features-panel v-if="showFeaturesPanel"></features-panel>
-    <terms-of-service-panel></terms-of-service-panel>
+    <instance-specific-panel />
+    <features-panel v-if="showFeaturesPanel" />
+    <terms-of-service-panel />
   </div>
 </template>
 
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index fc9cc7a2..55d81691 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -1,54 +1,104 @@
 <template>
-  <div v-if="usePlaceHolder" @click="openModal">
-    <a class="placeholder"
+  <div
+    v-if="usePlaceHolder"
+    @click="openModal"
+  >
+    <a
       v-if="type !== 'html'"
-      target="_blank" :href="attachment.url"
+      class="placeholder"
+      target="_blank"
+      :href="attachment.url"
     >
-      [{{nsfw ? "NSFW/" : ""}}{{type.toUpperCase()}}]
+      [{{ nsfw ? "NSFW/" : "" }}{{ type.toUpperCase() }}]
     </a>
   </div>
   <div
-    v-else class="attachment"
-    :class="{[type]: true, loading, 'fullwidth': fullwidth, 'nsfw-placeholder': hidden}"
+    v-else
     v-show="!isEmpty"
+    class="attachment"
+    :class="{[type]: true, loading, 'fullwidth': fullwidth, 'nsfw-placeholder': hidden}"
   >
-    <a class="image-attachment" v-if="hidden" :href="attachment.url" @click.prevent="toggleHidden">
-      <img class="nsfw" :key="nsfwImage" :src="nsfwImage" :class="{'small': isSmall}"/>
-      <i v-if="type === 'video'" class="play-icon icon-play-circled"></i>
+    <a
+      v-if="hidden"
+      class="image-attachment"
+      :href="attachment.url"
+      @click.prevent="toggleHidden"
+    >
+      <img
+        :key="nsfwImage"
+        class="nsfw"
+        :src="nsfwImage"
+        :class="{'small': isSmall}"
+      >
+      <i
+        v-if="type === 'video'"
+        class="play-icon icon-play-circled"
+      />
     </a>
-    <div class="hider" v-if="nsfw && hideNsfwLocal && !hidden">
-      <a href="#" @click.prevent="toggleHidden">Hide</a>
+    <div
+      v-if="nsfw && hideNsfwLocal && !hidden"
+      class="hider"
+    >
+      <a
+        href="#"
+        @click.prevent="toggleHidden"
+      >Hide</a>
     </div>
 
-    <a v-if="type === 'image' && (!hidden || preloadImage)"
-      @click="openModal"
+    <a
+      v-if="type === 'image' && (!hidden || preloadImage)"
       class="image-attachment"
       :class="{'hidden': hidden && preloadImage }"
-      :href="attachment.url" target="_blank"
+      :href="attachment.url"
+      target="_blank"
       :title="attachment.description"
+      @click="openModal"
     >
-      <StillImage :referrerpolicy="referrerpolicy" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
+      <StillImage
+        :referrerpolicy="referrerpolicy"
+        :mimetype="attachment.mimetype"
+        :src="attachment.large_thumb_url || attachment.url"
+      />
     </a>
 
-    <a class="video-container"
-      @click="openModal"
+    <a
       v-if="type === 'video' && !hidden"
+      class="video-container"
       :class="{'small': isSmall}"
       :href="allowPlay ? undefined : attachment.url"
+      @click="openModal"
     >
-      <VideoAttachment class="video" :attachment="attachment" :controls="allowPlay" />
-      <i v-if="!allowPlay" class="play-icon icon-play-circled"></i>
+      <VideoAttachment
+        class="video"
+        :attachment="attachment"
+        :controls="allowPlay"
+      />
+      <i
+        v-if="!allowPlay"
+        class="play-icon icon-play-circled"
+      />
     </a>
 
-    <audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
+    <audio
+      v-if="type === 'audio'"
+      :src="attachment.url"
+      controls
+    />
 
-    <div @click.prevent="linkClicked" v-if="type === 'html' && attachment.oembed" class="oembed">
-      <div v-if="attachment.thumb_url" class="image">
-        <img :src="attachment.thumb_url"/>
+    <div
+      v-if="type === 'html' && attachment.oembed"
+      class="oembed"
+      @click.prevent="linkClicked"
+    >
+      <div
+        v-if="attachment.thumb_url"
+        class="image"
+      >
+        <img :src="attachment.thumb_url">
       </div>
       <div class="text">
-        <h1><a :href="attachment.url">{{attachment.oembed.title}}</a></h1>
-        <div v-html="attachment.oembed.oembedHTML"></div>
+        <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
+        <div v-html="attachment.oembed.oembedHTML" />
       </div>
     </div>
   </div>
diff --git a/src/components/autosuggest/autosuggest.vue b/src/components/autosuggest/autosuggest.vue
index 91657a2d..1f86e996 100644
--- a/src/components/autosuggest/autosuggest.vue
+++ b/src/components/autosuggest/autosuggest.vue
@@ -1,8 +1,22 @@
 <template>
-  <div class="autosuggest" v-click-outside="onClickOutside">
-    <input v-model="term" :placeholder="placeholder" @click="onInputClick" class="autosuggest-input" />
-    <div class="autosuggest-results" v-if="resultsVisible && filtered.length > 0">
-      <slot v-for="item in filtered" :item="item" />
+  <div
+    v-click-outside="onClickOutside"
+    class="autosuggest"
+  >
+    <input
+      v-model="term"
+      :placeholder="placeholder"
+      class="autosuggest-input"
+      @click="onInputClick"
+    >
+    <div
+      v-if="resultsVisible && filtered.length > 0"
+      class="autosuggest-results"
+    >
+      <slot
+        v-for="item in filtered"
+        :item="item"
+      />
     </div>
   </div>
 </template>
diff --git a/src/components/avatar_list/avatar_list.vue b/src/components/avatar_list/avatar_list.vue
index 343ef529..e1b6e971 100644
--- a/src/components/avatar_list/avatar_list.vue
+++ b/src/components/avatar_list/avatar_list.vue
@@ -1,12 +1,15 @@
 <template>
   <div class="avatars">
     <router-link
-      :to="userProfileLink(user)"
-      class="avatars-item"
       v-for="user in slicedUsers"
       :key="user.id"
+      :to="userProfileLink(user)"
+      class="avatars-item"
     >
-      <UserAvatar :user="user" class="avatar-small" />
+      <UserAvatar
+        :user="user"
+        class="avatar-small"
+      />
     </router-link>
   </div>
 </template>
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 634d62b3..8ad0da2d 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -7,20 +7,43 @@
         @click.prevent.native="toggleUserExpanded"
       />
     </router-link>
-    <div class="basic-user-card-expanded-content" v-if="userExpanded">
-      <UserCard :user="user" :rounded="true" :bordered="true"/>
+    <div
+      v-if="userExpanded"
+      class="basic-user-card-expanded-content"
+    >
+      <UserCard
+        :user="user"
+        :rounded="true"
+        :bordered="true"
+      />
     </div>
-    <div class="basic-user-card-collapsed-content" v-else>
-      <div :title="user.name" class="basic-user-card-user-name">
-        <span v-if="user.name_html" class="basic-user-card-user-name-value" v-html="user.name_html"></span>
-        <span v-else class="basic-user-card-user-name-value">{{ user.name }}</span>
+    <div
+      v-else
+      class="basic-user-card-collapsed-content"
+    >
+      <div
+        :title="user.name"
+        class="basic-user-card-user-name"
+      >
+        <span
+          v-if="user.name_html"
+          class="basic-user-card-user-name-value"
+          v-html="user.name_html"
+        />
+        <span
+          v-else
+          class="basic-user-card-user-name-value"
+        >{{ user.name }}</span>
       </div>
       <div>
-        <router-link class="basic-user-card-screen-name" :to="userProfileLink(user)">
-          @{{user.screen_name}}
+        <router-link
+          class="basic-user-card-screen-name"
+          :to="userProfileLink(user)"
+        >
+          @{{ user.screen_name }}
         </router-link>
       </div>
-      <slot></slot>
+      <slot />
     </div>
   </div>
 </template>
diff --git a/src/components/block_card/block_card.vue b/src/components/block_card/block_card.vue
index 8eb56e25..5b00b738 100644
--- a/src/components/block_card/block_card.vue
+++ b/src/components/block_card/block_card.vue
@@ -1,7 +1,12 @@
 <template>
   <basic-user-card :user="user">
     <div class="block-card-content-container">
-      <button class="btn btn-default" @click="unblockUser" :disabled="progress" v-if="blocked">
+      <button
+        v-if="blocked"
+        class="btn btn-default"
+        :disabled="progress"
+        @click="unblockUser"
+      >
         <template v-if="progress">
           {{ $t('user_card.unblock_progress') }}
         </template>
@@ -9,7 +14,12 @@
           {{ $t('user_card.unblock') }}
         </template>
       </button>
-      <button class="btn btn-default" @click="blockUser" :disabled="progress" v-else>
+      <button
+        v-else
+        class="btn btn-default"
+        :disabled="progress"
+        @click="blockUser"
+      >
         <template v-if="progress">
           {{ $t('user_card.block_progress') }}
         </template>
diff --git a/src/components/chat_panel/chat_panel.vue b/src/components/chat_panel/chat_panel.vue
index b37469ac..ca2c64a3 100644
--- a/src/components/chat_panel/chat_panel.vue
+++ b/src/components/chat_panel/chat_panel.vue
@@ -1,41 +1,70 @@
 <template>
-  <div class="chat-panel" v-if="!this.collapsed || !this.floating">
+  <div
+    v-if="!this.collapsed || !this.floating"
+    class="chat-panel"
+  >
     <div class="panel panel-default">
-      <div class="panel-heading timeline-heading" :class="{ 'chat-heading': floating }" @click.stop.prevent="togglePanel">
+      <div
+        class="panel-heading timeline-heading"
+        :class="{ 'chat-heading': floating }"
+        @click.stop.prevent="togglePanel"
+      >
         <div class="title">
-          <span>{{$t('chat.title')}}</span>
-          <i class="icon-cancel" v-if="floating"></i>
+          <span>{{ $t('chat.title') }}</span>
+          <i
+            v-if="floating"
+            class="icon-cancel"
+          />
         </div>
       </div>
-      <div class="chat-window" v-chat-scroll>
-        <div class="chat-message" v-for="message in messages" :key="message.id">
+      <div
+        v-chat-scroll
+        class="chat-window"
+      >
+        <div
+          v-for="message in messages"
+          :key="message.id"
+          class="chat-message"
+        >
           <span class="chat-avatar">
-            <img :src="message.author.avatar" />
+            <img :src="message.author.avatar">
           </span>
           <div class="chat-content">
             <router-link
               class="chat-name"
-              :to="userProfileLink(message.author)">
-                {{message.author.username}}
+              :to="userProfileLink(message.author)"
+            >
+              {{ message.author.username }}
             </router-link>
             <br>
             <span class="chat-text">
-              {{message.text}}
+              {{ message.text }}
             </span>
           </div>
         </div>
       </div>
       <div class="chat-input">
-        <textarea @keyup.enter="submit(currentMessage)" v-model="currentMessage" class="chat-input-textarea" rows="1"></textarea>
+        <textarea
+          v-model="currentMessage"
+          class="chat-input-textarea"
+          rows="1"
+          @keyup.enter="submit(currentMessage)"
+        />
       </div>
     </div>
   </div>
-  <div v-else class="chat-panel">
+  <div
+    v-else
+    class="chat-panel"
+  >
     <div class="panel panel-default">
-      <div class="panel-heading stub timeline-heading chat-heading" @click.stop.prevent="togglePanel">
+      <div
+        class="panel-heading stub timeline-heading chat-heading"
+        @click.stop.prevent="togglePanel"
+      >
         <div class="title">
-          <i class="icon-comment-empty"></i>
-          {{$t('chat.title')}}
+          <i class="icon-comment-empty" />
+          {{ $t('chat.title') }}
         </div>
       </div>
     </div>
diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue
index 4152b049..2b822ec3 100644
--- a/src/components/checkbox/checkbox.vue
+++ b/src/components/checkbox/checkbox.vue
@@ -1,8 +1,13 @@
 <template>
   <label class="checkbox">
-    <input type="checkbox" :checked="checked" @change="$emit('change', $event.target.checked)" :indeterminate.prop="indeterminate">
+    <input
+      type="checkbox"
+      :checked="checked"
+      :indeterminate.prop="indeterminate"
+      @change="$emit('change', $event.target.checked)"
+    >
     <i class="checkbox-indicator" />
-    <span v-if="!!$slots.default"><slot></slot></span>
+    <span v-if="!!$slots.default"><slot /></span>
   </label>
 </template>
 
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index 34eec248..9db62e81 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,33 +1,44 @@
 <template>
-<div class="color-control style-control" :class="{ disabled: !present || disabled }">
-  <label :for="name" class="label">
-    {{label}}
-  </label>
-  <input
-    v-if="typeof fallback !== 'undefined'"
-    class="opt exlcude-disabled"
-    :id="name + '-o'"
-    type="checkbox"
-    :checked="present"
-    @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)">
-  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
-  <input
-    :id="name"
-    class="color-input"
-    type="color"
-    :value="value || fallback"
-    :disabled="!present || disabled"
-    @input="$emit('input', $event.target.value)"
+  <div
+    class="color-control style-control"
+    :class="{ disabled: !present || disabled }"
+  >
+    <label
+      :for="name"
+      class="label"
     >
-  <input
-    :id="name + '-t'"
-    class="text-input"
-    type="text"
-    :value="value || fallback"
-    :disabled="!present || disabled"
-    @input="$emit('input', $event.target.value)"
+      {{ label }}
+    </label>
+    <input
+      v-if="typeof fallback !== 'undefined'"
+      :id="name + '-o'"
+      class="opt exlcude-disabled"
+      type="checkbox"
+      :checked="present"
+      @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
     >
-</div>
+    <label
+      v-if="typeof fallback !== 'undefined'"
+      class="opt-l"
+      :for="name + '-o'"
+    />
+    <input
+      :id="name"
+      class="color-input"
+      type="color"
+      :value="value || fallback"
+      :disabled="!present || disabled"
+      @input="$emit('input', $event.target.value)"
+    >
+    <input
+      :id="name + '-t'"
+      class="text-input"
+      type="text"
+      :value="value || fallback"
+      :disabled="!present || disabled"
+      @input="$emit('input', $event.target.value)"
+    >
+  </div>
 </template>
 
 <script>
diff --git a/src/components/contrast_ratio/contrast_ratio.vue b/src/components/contrast_ratio/contrast_ratio.vue
index bd971d00..15a450a2 100644
--- a/src/components/contrast_ratio/contrast_ratio.vue
+++ b/src/components/contrast_ratio/contrast_ratio.vue
@@ -1,28 +1,38 @@
 <template>
-<span  v-if="contrast" class="contrast-ratio">
-  <span :title="hint" class="rating">
-    <span v-if="contrast.aaa">
-      <i class="icon-thumbs-up-alt"/>
+  <span
+    v-if="contrast"
+    class="contrast-ratio"
+  >
+    <span
+      :title="hint"
+      class="rating"
+    >
+      <span v-if="contrast.aaa">
+        <i class="icon-thumbs-up-alt" />
+      </span>
+      <span v-if="!contrast.aaa && contrast.aa">
+        <i class="icon-adjust" />
+      </span>
+      <span v-if="!contrast.aaa && !contrast.aa">
+        <i class="icon-attention" />
+      </span>
     </span>
-    <span v-if="!contrast.aaa && contrast.aa">
-      <i class="icon-adjust"/>
-    </span>
-    <span v-if="!contrast.aaa && !contrast.aa">
-      <i class="icon-attention"/>
-    </span>
-  </span>
-  <span class="rating" v-if="contrast && large" :title="hint_18pt">
-    <span v-if="contrast.laaa">
-      <i class="icon-thumbs-up-alt"/>
-    </span>
-    <span v-if="!contrast.laaa && contrast.laa">
-      <i class="icon-adjust"/>
-    </span>
-    <span v-if="!contrast.laaa && !contrast.laa">
-      <i class="icon-attention"/>
+    <span
+      v-if="contrast && large"
+      class="rating"
+      :title="hint_18pt"
+    >
+      <span v-if="contrast.laaa">
+        <i class="icon-thumbs-up-alt" />
+      </span>
+      <span v-if="!contrast.laaa && contrast.laa">
+        <i class="icon-adjust" />
+      </span>
+      <span v-if="!contrast.laaa && !contrast.laa">
+        <i class="icon-attention" />
+      </span>
     </span>
   </span>
-</span>
 </template>
 
 <script>
diff --git a/src/components/conversation-page/conversation-page.vue b/src/components/conversation-page/conversation-page.vue
index 9e322cf5..532f785c 100644
--- a/src/components/conversation-page/conversation-page.vue
+++ b/src/components/conversation-page/conversation-page.vue
@@ -1,9 +1,9 @@
 <template>
   <conversation
     :collapsable="false"
-    isPage="true"
+    is-page="true"
     :statusoid="statusoid"
-  ></conversation>
+  />
 </template>
 
 <script src="./conversation-page.js"></script>
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 0b4998c3..f5642c73 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -1,25 +1,34 @@
 <template>
-  <div class="timeline panel-default" :class="[isExpanded ? 'panel' : 'panel-disabled']">
-    <div v-if="isExpanded" class="panel-heading conversation-heading">
+  <div
+    class="timeline panel-default"
+    :class="[isExpanded ? 'panel' : 'panel-disabled']"
+  >
+    <div
+      v-if="isExpanded"
+      class="panel-heading conversation-heading"
+    >
       <span class="title"> {{ $t('timeline.conversation') }} </span>
       <span v-if="collapsable">
-        <a href="#" @click.prevent="toggleExpanded">{{ $t('timeline.collapse') }}</a>
+        <a
+          href="#"
+          @click.prevent="toggleExpanded"
+        >{{ $t('timeline.collapse') }}</a>
       </span>
     </div>
     <status
       v-for="status in conversation"
-      @goto="setHighlight"
-      @toggleExpanded="toggleExpanded"
       :key="status.id"
-      :inlineExpanded="collapsable && isExpanded"
+      :inline-expanded="collapsable && isExpanded"
       :statusoid="status"
-      :expandable='!isExpanded'
-      :showPinned="showPinned"
+      :expandable="!isExpanded"
+      :show-pinned="showPinned"
       :focused="focused(status.id)"
-      :inConversation="isExpanded"
+      :in-conversation="isExpanded"
       :highlight="getHighlight()"
       :replies="getReplies(status.id)"
+      @goto="setHighlight"
       class="status-fadein panel-body"
+      @toggleExpanded="toggleExpanded"
     />
   </div>
 </template>
diff --git a/src/components/dialog_modal/dialog_modal.vue b/src/components/dialog_modal/dialog_modal.vue
index 3da543de..55d7a7d2 100644
--- a/src/components/dialog_modal/dialog_modal.vue
+++ b/src/components/dialog_modal/dialog_modal.vue
@@ -1,16 +1,22 @@
 <template>
-  <span v-bind:class="{ 'dark-overlay': darkOverlay }" @click.self.stop='onCancel()'>
-    <div class="dialog-modal panel panel-default" @click.stop=''>
+  <span
+    :class="{ 'dark-overlay': darkOverlay }"
+    @click.self.stop="onCancel()"
+  >
+    <div
+      class="dialog-modal panel panel-default"
+      @click.stop=""
+    >
       <div class="panel-heading dialog-modal-heading">
         <div class="title">
-          <slot name="header"></slot>
+          <slot name="header" />
         </div>
       </div>
       <div class="dialog-modal-content">
-        <slot name="default"></slot>
+        <slot name="default" />
       </div>
       <div class="dialog-modal-footer user-interactions panel-footer">
-        <slot name="footer"></slot>
+        <slot name="footer" />
       </div>
     </div>
   </span>
diff --git a/src/components/dm_timeline/dm_timeline.vue b/src/components/dm_timeline/dm_timeline.vue
index f03da4d3..c4e4d070 100644
--- a/src/components/dm_timeline/dm_timeline.vue
+++ b/src/components/dm_timeline/dm_timeline.vue
@@ -1,5 +1,9 @@
 <template>
-  <Timeline :title="$t('nav.dms')" v-bind:timeline="timeline" v-bind:timeline-name="'dms'"/>
+  <Timeline
+    :title="$t('nav.dms')"
+    :timeline="timeline"
+    :timeline-name="'dms'"
+  />
 </template>
 
 <script src="./dm_timeline.js"></script>
diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue
index b1f7afa5..48739ec8 100644
--- a/src/components/emoji-input/emoji-input.vue
+++ b/src/components/emoji-input/emoji-input.vue
@@ -1,27 +1,34 @@
 <template>
-<div class="emoji-input">
-  <slot></slot>
-  <div ref="panel" class="autocomplete-panel" :class="{ hide: !showPopup }">
-    <div class="autocomplete-panel-body">
-      <div
-        v-for="(suggestion, index) in suggestions"
-        :key="index"
-        @click.stop.prevent="onClick($event, suggestion)"
-        class="autocomplete-item"
-        :class="{ highlighted: suggestion.highlighted }"
+  <div class="emoji-input">
+    <slot />
+    <div
+      ref="panel"
+      class="autocomplete-panel"
+      :class="{ hide: !showPopup }"
+    >
+      <div class="autocomplete-panel-body">
+        <div
+          v-for="(suggestion, index) in suggestions"
+          :key="index"
+          class="autocomplete-item"
+          :class="{ highlighted: suggestion.highlighted }"
+          @click.stop.prevent="onClick($event, suggestion)"
         >
-        <span class="image">
-          <img v-if="suggestion.img":src="suggestion.img" />
-          <span v-else>{{suggestion.replacement}}</span>
-        </span>
-        <div class="label">
-          <span class="displayText">{{suggestion.displayText}}</span>
-          <span class="detailText">{{suggestion.detailText}}</span>
+          <span class="image">
+            <img
+              v-if="suggestion.img"
+              :src="suggestion.img"
+            >
+            <span v-else>{{ suggestion.replacement }}</span>
+          </span>
+          <div class="label">
+            <span class="displayText">{{ suggestion.displayText }}</span>
+            <span class="detailText">{{ suggestion.detailText }}</span>
+          </div>
         </div>
       </div>
     </div>
   </div>
-</div>
 </template>
 
 <script src="./emoji-input.js"></script>
@@ -103,7 +110,6 @@
     }
   }
 
-
   input, textarea {
     flex: 1 0 auto;
   }
diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue
index 451a2668..20c6f569 100644
--- a/src/components/export_import/export_import.vue
+++ b/src/components/export_import/export_import.vue
@@ -1,12 +1,27 @@
 <template>
-<div class="import-export-container">
-  <slot name="before"/>
-  <button class="btn" @click="exportData">{{ exportLabel }}</button>
-  <button class="btn" @click="importData">{{ importLabel }}</button>
-  <slot name="afterButtons"/>
-  <p v-if="importFailed" class="alert error">{{ importFailedText }}</p>
-  <slot name="afterError"/>
-</div>
+  <div class="import-export-container">
+    <slot name="before" />
+    <button
+      class="btn"
+      @click="exportData"
+    >
+      {{ exportLabel }}
+    </button>
+    <button
+      class="btn"
+      @click="importData"
+    >
+      {{ importLabel }}
+    </button>
+    <slot name="afterButtons" />
+    <p
+      v-if="importFailed"
+      class="alert error"
+    >
+      {{ importFailedText }}
+    </p>
+    <slot name="afterError" />
+  </div>
 </template>
 
 <script>
@@ -49,7 +64,7 @@ export default {
         if (event.target.files[0]) {
           // eslint-disable-next-line no-undef
           const reader = new FileReader()
-          reader.onload = ({target}) => {
+          reader.onload = ({ target }) => {
             try {
               const parsed = JSON.parse(target.result)
               const valid = this.validator(parsed)
diff --git a/src/components/exporter/exporter.vue b/src/components/exporter/exporter.vue
index f22e579e..f5126dc1 100644
--- a/src/components/exporter/exporter.vue
+++ b/src/components/exporter/exporter.vue
@@ -1,10 +1,16 @@
 <template>
   <div class="exporter">
     <div v-if="processing">
-      <i class="icon-spin4 animate-spin exporter-processing"></i>
-      <span>{{processingMessage}}</span>
+      <i class="icon-spin4 animate-spin exporter-processing" />
+      <span>{{ processingMessage }}</span>
     </div>
-    <button class="btn btn-default" @click="process" v-else>{{exportButtonLabel}}</button>
+    <button
+      v-else
+      class="btn btn-default"
+      @click="process"
+    >
+      {{ exportButtonLabel }}
+    </button>
   </div>
 </template>
 
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index a761d313..8e24e9a5 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -1,9 +1,8 @@
 <template>
   <Popper
+    v-if="enabled && showPopper"
     trigger="click"
-    @hide='showDropDown = false'
     append-to-body
-    v-if="enabled && showPopper"
     :options="{
       placement: 'top',
       modifiers: {
@@ -11,22 +10,42 @@
         offset: { offset: '0, 5px' },
       }
     }"
+    @hide="showDropDown = false"
   >
     <div class="popper-wrapper">
       <div class="dropdown-menu">
-        <button class="dropdown-item dropdown-item-icon" @click.prevent="pinStatus" v-if="!status.pinned && canPin">
-          <i class="icon-pin"></i><span>{{$t("status.pin")}}</span>
+        <button
+          v-if="!status.pinned && canPin"
+          class="dropdown-item dropdown-item-icon"
+          @click.prevent="pinStatus"
+        >
+          <i class="icon-pin" /><span>{{ $t("status.pin") }}</span>
         </button>
-        <button class="dropdown-item dropdown-item-icon" @click.prevent="unpinStatus" v-if="status.pinned && canPin">
-          <i class="icon-pin"></i><span>{{$t("status.unpin")}}</span>
+        <button
+          v-if="status.pinned && canPin"
+          class="dropdown-item dropdown-item-icon"
+          @click.prevent="unpinStatus"
+        >
+          <i class="icon-pin" /><span>{{ $t("status.unpin") }}</span>
         </button>
-        <button class="dropdown-item dropdown-item-icon" @click.prevent="deleteStatus" v-if="canDelete">
-          <i class="icon-cancel"></i><span>{{$t("status.delete")}}</span>
+        <button
+          v-if="canDelete"
+          class="dropdown-item dropdown-item-icon"
+          @click.prevent="deleteStatus"
+        >
+          <i class="icon-cancel" /><span>{{ $t("status.delete") }}</span>
         </button>
       </div>
     </div>
-    <div class="button-icon" slot="reference" @click="toggleMenu">
-      <i class='icon-ellipsis' :class="{'icon-clicked': showDropDown}"></i>
+    <div
+      slot="reference"
+      class="button-icon"
+      @click="toggleMenu"
+    >
+      <i
+        class="icon-ellipsis"
+        :class="{'icon-clicked': showDropDown}"
+      />
     </div>
   </Popper>
 </template>
diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue
index 05ce6bd0..06ce9983 100644
--- a/src/components/favorite_button/favorite_button.vue
+++ b/src/components/favorite_button/favorite_button.vue
@@ -1,11 +1,20 @@
 <template>
   <div v-if="loggedIn">
-    <i :class='classes' class='button-icon favorite-button fav-active' @click.prevent='favorite()' :title="$t('tool_tip.favorite')"/>
-    <span v-if='!hidePostStatsLocal && status.fave_num > 0'>{{status.fave_num}}</span>
+    <i
+      :class="classes"
+      class="button-icon favorite-button fav-active"
+      :title="$t('tool_tip.favorite')"
+      @click.prevent="favorite()"
+    />
+    <span v-if="!hidePostStatsLocal && status.fave_num > 0">{{ status.fave_num }}</span>
   </div>
   <div v-else>
-    <i :class='classes' class='button-icon favorite-button' :title="$t('tool_tip.favorite')"/>
-    <span v-if='!hidePostStatsLocal && status.fave_num > 0'>{{status.fave_num}}</span>
+    <i
+      :class="classes"
+      class="button-icon favorite-button"
+      :title="$t('tool_tip.favorite')"
+    />
+    <span v-if="!hidePostStatsLocal && status.fave_num > 0">{{ status.fave_num }}</span>
   </div>
 </template>
 
diff --git a/src/components/features_panel/features_panel.vue b/src/components/features_panel/features_panel.vue
index 7a263e01..3e5939a6 100644
--- a/src/components/features_panel/features_panel.vue
+++ b/src/components/features_panel/features_panel.vue
@@ -3,17 +3,25 @@
     <div class="panel panel-default base01-background">
       <div class="panel-heading timeline-heading base02-background base04">
         <div class="title">
-          {{$t('features_panel.title')}}
+          {{ $t('features_panel.title') }}
         </div>
       </div>
       <div class="panel-body features-panel">
         <ul>
-          <li v-if="chat">{{$t('features_panel.chat')}}</li>
-          <li v-if="gopher">{{$t('features_panel.gopher')}}</li>
-          <li v-if="whoToFollow">{{$t('features_panel.who_to_follow')}}</li>
-          <li v-if="mediaProxy">{{$t('features_panel.media_proxy')}}</li>
-          <li>{{$t('features_panel.scope_options')}}</li>
-          <li>{{$t('features_panel.text_limit')}} = {{textlimit}}</li>
+          <li v-if="chat">
+            {{ $t('features_panel.chat') }}
+          </li>
+          <li v-if="gopher">
+            {{ $t('features_panel.gopher') }}
+          </li>
+          <li v-if="whoToFollow">
+            {{ $t('features_panel.who_to_follow') }}
+          </li>
+          <li v-if="mediaProxy">
+            {{ $t('features_panel.media_proxy') }}
+          </li>
+          <li>{{ $t('features_panel.scope_options') }}</li>
+          <li>{{ $t('features_panel.text_limit') }} = {{ textlimit }}</li>
         </ul>
       </div>
     </div>
diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue
index 94e2836f..310fe843 100644
--- a/src/components/follow_card/follow_card.vue
+++ b/src/components/follow_card/follow_card.vue
@@ -1,11 +1,17 @@
 <template>
   <basic-user-card :user="user">
     <div class="follow-card-content-container">
-      <span class="faint" v-if="!noFollowsYou && user.follows_you">
+      <span
+        v-if="!noFollowsYou && user.follows_you"
+        class="faint"
+      >
         {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }}
       </span>
       <template v-if="!loggedIn">
-        <div class="follow-card-follow-button" v-if="!user.following">
+        <div
+          v-if="!user.following"
+          class="follow-card-follow-button"
+        >
           <RemoteFollow :user="user" />
         </div>
       </template>
@@ -13,9 +19,9 @@
         <button
           v-if="!user.following"
           class="btn btn-default follow-card-follow-button"
-          @click="followUser"
           :disabled="inProgress"
           :title="requestSent ? $t('user_card.follow_again') : ''"
+          @click="followUser"
         >
           <template v-if="inProgress">
             {{ $t('user_card.follow_progress') }}
@@ -27,7 +33,12 @@
             {{ $t('user_card.follow') }}
           </template>
         </button>
-        <button v-else class="btn btn-default follow-card-follow-button pressed" @click="unfollowUser" :disabled="inProgress">
+        <button
+          v-else
+          class="btn btn-default follow-card-follow-button pressed"
+          :disabled="inProgress"
+          @click="unfollowUser"
+        >
           <template v-if="inProgress">
             {{ $t('user_card.follow_progress') }}
           </template>
diff --git a/src/components/follow_request_card/follow_request_card.vue b/src/components/follow_request_card/follow_request_card.vue
index 4a3bbba4..b217b8ed 100644
--- a/src/components/follow_request_card/follow_request_card.vue
+++ b/src/components/follow_request_card/follow_request_card.vue
@@ -1,8 +1,18 @@
 <template>
   <basic-user-card :user="user">
     <div class="follow-request-card-content-container">
-      <button class="btn btn-default" @click="approveUser">{{ $t('user_card.approve') }}</button>
-      <button class="btn btn-default" @click="denyUser">{{ $t('user_card.deny') }}</button>
+      <button
+        class="btn btn-default"
+        @click="approveUser"
+      >
+        {{ $t('user_card.approve') }}
+      </button>
+      <button
+        class="btn btn-default"
+        @click="denyUser"
+      >
+        {{ $t('user_card.deny') }}
+      </button>
     </div>
   </basic-user-card>
 </template>
diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue
index 36901fb4..5fa4cf39 100644
--- a/src/components/follow_requests/follow_requests.vue
+++ b/src/components/follow_requests/follow_requests.vue
@@ -1,10 +1,15 @@
 <template>
   <div class="settings panel panel-default">
     <div class="panel-heading">
-      {{$t('nav.friend_requests')}}
+      {{ $t('nav.friend_requests') }}
     </div>
     <div class="panel-body">
-      <FollowRequestCard v-for="request in requests" :key="request.id" :user="request" class="list-item"/>
+      <FollowRequestCard
+        v-for="request in requests"
+        :key="request.id"
+        :user="request"
+        class="list-item"
+      />
     </div>
   </div>
 </template>
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index ed36b280..87644628 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -1,35 +1,55 @@
 <template>
-<div class="font-control style-control" :class="{ custom: isCustom }">
-  <label :for="preset === 'custom' ? name : name + '-font-switcher'" class="label">
-    {{label}}
-  </label>
-  <input
-    v-if="typeof fallback !== 'undefined'"
-    class="opt exlcude-disabled"
-    type="checkbox"
-    :id="name + '-o'"
-    :checked="present"
-    @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)">
-  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
-  <label :for="name + '-font-switcher'" class="select" :disabled="!present">
-    <select
+  <div
+    class="font-control style-control"
+    :class="{ custom: isCustom }"
+  >
+    <label
+      :for="preset === 'custom' ? name : name + '-font-switcher'"
+      class="label"
+    >
+      {{ label }}
+    </label>
+    <input
+      v-if="typeof fallback !== 'undefined'"
+      :id="name + '-o'"
+      class="opt exlcude-disabled"
+      type="checkbox"
+      :checked="present"
+      @input="$emit('input', typeof value === 'undefined' ? fallback : undefined)"
+    >
+    <label
+      v-if="typeof fallback !== 'undefined'"
+      class="opt-l"
+      :for="name + '-o'"
+    />
+    <label
+      :for="name + '-font-switcher'"
+      class="select"
       :disabled="!present"
-      v-model="preset"
-      class="font-switcher"
-      :id="name + '-font-switcher'">
-      <option v-for="option in availableOptions" :value="option">
-        {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
-      </option>
-    </select>
-    <i class="icon-down-open"/>
-  </label>
-  <input
-    v-if="isCustom"
-    class="custom-font"
-    type="text"
-    :id="name"
-    v-model="family">
-</div>
+    >
+      <select
+        :id="name + '-font-switcher'"
+        v-model="preset"
+        :disabled="!present"
+        class="font-switcher"
+      >
+        <option
+          v-for="option in availableOptions"
+          :value="option"
+        >
+          {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
+        </option>
+      </select>
+      <i class="icon-down-open" />
+    </label>
+    <input
+      v-if="isCustom"
+      :id="name"
+      v-model="family"
+      class="custom-font"
+      type="text"
+    >
+  </div>
 </template>
 
 <script src="./font_control.js" ></script>
diff --git a/src/components/friends_timeline/friends_timeline.vue b/src/components/friends_timeline/friends_timeline.vue
index 66c0c058..01a56812 100644
--- a/src/components/friends_timeline/friends_timeline.vue
+++ b/src/components/friends_timeline/friends_timeline.vue
@@ -1,5 +1,9 @@
 <template>
-  <Timeline :title="$t('nav.timeline')" v-bind:timeline="timeline" v-bind:timeline-name="'friends'"/>
+  <Timeline
+    :title="$t('nav.timeline')"
+    :timeline="timeline"
+    :timeline-name="'friends'"
+  />
 </template>
 
 <script src="./friends_timeline.js"></script>
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index f0433f10..577f2144 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -1,13 +1,21 @@
 <template>
-  <div ref="galleryContainer" style="width: 100%;">
-    <div class="gallery-row" v-for="row in rows" :style="rowHeight(row.length)" :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }">
+  <div
+    ref="galleryContainer"
+    style="width: 100%;"
+  >
+    <div
+      v-for="row in rows"
+      class="gallery-row"
+      :style="rowHeight(row.length)"
+      :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
+    >
       <attachment
         v-for="attachment in row"
-        :setMedia="setMedia"
+        :key="attachment.id"
+        :set-media="setMedia"
         :nsfw="nsfw"
         :attachment="attachment"
-        :allowPlay="false"
-        :key="attachment.id"
+        :allow-play="false"
       />
     </div>
   </div>
diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue
index d2b86e9e..4e1b5927 100644
--- a/src/components/image_cropper/image_cropper.vue
+++ b/src/components/image_cropper/image_cropper.vue
@@ -2,20 +2,57 @@
   <div class="image-cropper">
     <div v-if="dataUrl">
       <div class="image-cropper-image-container">
-        <img ref="img" :src="dataUrl" alt="" @load.stop="createCropper" />
+        <img
+          ref="img"
+          :src="dataUrl"
+          alt=""
+          @load.stop="createCropper"
+        >
       </div>
       <div class="image-cropper-buttons-wrapper">
-        <button class="btn" type="button" :disabled="submitting" @click="submit()" v-text="saveText"></button>
-        <button class="btn" type="button" :disabled="submitting" @click="destroy" v-text="cancelText"></button>
-        <button class="btn" type="button" :disabled="submitting" @click="submit(false)" v-text="saveWithoutCroppingText"></button>
-        <i class="icon-spin4 animate-spin" v-if="submitting"></i>
+        <button
+          class="btn"
+          type="button"
+          :disabled="submitting"
+          @click="submit()"
+          v-text="saveText"
+        />
+        <button
+          class="btn"
+          type="button"
+          :disabled="submitting"
+          @click="destroy"
+          v-text="cancelText"
+        />
+        <button
+          class="btn"
+          type="button"
+          :disabled="submitting"
+          @click="submit(false)"
+          v-text="saveWithoutCroppingText"
+        />
+        <i
+          v-if="submitting"
+          class="icon-spin4 animate-spin"
+        />
       </div>
-      <div class="alert error" v-if="submitError">
-        {{submitErrorMsg}}
-        <i class="button-icon icon-cancel" @click="clearError"></i>
+      <div
+        v-if="submitError"
+        class="alert error"
+      >
+        {{ submitErrorMsg }}
+        <i
+          class="button-icon icon-cancel"
+          @click="clearError"
+        />
       </div>
     </div>
-    <input ref="input" type="file" class="image-cropper-img-input" :accept="mimes">
+    <input
+      ref="input"
+      type="file"
+      class="image-cropper-img-input"
+      :accept="mimes"
+    >
   </div>
 </template>
 
diff --git a/src/components/importer/importer.vue b/src/components/importer/importer.vue
index 0c5aa93d..ed923d59 100644
--- a/src/components/importer/importer.vue
+++ b/src/components/importer/importer.vue
@@ -1,17 +1,36 @@
 <template>
   <div class="importer">
     <form>
-      <input type="file" ref="input" v-on:change="change" />
+      <input
+        ref="input"
+        type="file"
+        @change="change"
+      >
     </form>
-    <i class="icon-spin4 animate-spin importer-uploading" v-if="submitting"></i>
-    <button class="btn btn-default" v-else @click="submit">{{submitButtonLabel}}</button>
+    <i
+      v-if="submitting"
+      class="icon-spin4 animate-spin importer-uploading"
+    />
+    <button
+      v-else
+      class="btn btn-default"
+      @click="submit"
+    >
+      {{ submitButtonLabel }}
+    </button>
     <div v-if="success">
-      <i class="icon-cross" @click="dismiss"></i>
-      <p>{{successMessage}}</p>
+      <i
+        class="icon-cross"
+        @click="dismiss"
+      />
+      <p>{{ successMessage }}</p>
     </div>
     <div v-else-if="error">
-      <i class="icon-cross" @click="dismiss"></i>
-      <p>{{errorMessage}}</p>
+      <i
+        class="icon-cross"
+        @click="dismiss"
+      />
+      <p>{{ errorMessage }}</p>
     </div>
   </div>
 </template>
diff --git a/src/components/instance_specific_panel/instance_specific_panel.vue b/src/components/instance_specific_panel/instance_specific_panel.vue
index a7b74667..64ce4f8a 100644
--- a/src/components/instance_specific_panel/instance_specific_panel.vue
+++ b/src/components/instance_specific_panel/instance_specific_panel.vue
@@ -1,9 +1,11 @@
 <template>
-  <div v-if="show" class="instance-specific-panel">
+  <div
+    v-if="show"
+    class="instance-specific-panel"
+  >
     <div class="panel panel-default">
       <div class="panel-body">
-        <div v-html="instanceSpecificPanelContent">
-        </div>
+        <div v-html="instanceSpecificPanelContent" />
       </div>
     </div>
   </div>
diff --git a/src/components/interactions/interactions.vue b/src/components/interactions/interactions.vue
index 38b2670d..d71c99d5 100644
--- a/src/components/interactions/interactions.vue
+++ b/src/components/interactions/interactions.vue
@@ -7,18 +7,30 @@
     </div>
     <tab-switcher
       ref="tabSwitcher"
-      :onSwitch="onModeSwitch"
-      >
-      <span data-tab-dummy data-filter="mentions" :label="$t('nav.mentions')"/>
-      <span data-tab-dummy data-filter="likes+repeats" :label="$t('interactions.favs_repeats')"/>
-      <span data-tab-dummy data-filter="follows" :label="$t('interactions.follows')"/>
+      :on-switch="onModeSwitch"
+    >
+      <span
+        data-tab-dummy
+        data-filter="mentions"
+        :label="$t('nav.mentions')"
+      />
+      <span
+        data-tab-dummy
+        data-filter="likes+repeats"
+        :label="$t('interactions.favs_repeats')"
+      />
+      <span
+        data-tab-dummy
+        data-filter="follows"
+        :label="$t('interactions.follows')"
+      />
     </tab-switcher>
     <Notifications
       ref="notifications"
-      :noHeading="true"
-      :minimalMode="true"
-      :filterMode="filterMode"
-      />
+      :no-heading="true"
+      :minimal-mode="true"
+      :filter-mode="filterMode"
+    />
   </div>
 </template>
 
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
index 9f7877c6..28c811bd 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.vue
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -3,50 +3,59 @@
     <label for="interface-language-switcher">
       {{ $t('settings.interfaceLanguage') }}
     </label>
-    <label for="interface-language-switcher" class='select'>
-      <select id="interface-language-switcher" v-model="language">
-        <option v-for="(langCode, i) in languageCodes" :value="langCode">
+    <label
+      for="interface-language-switcher"
+      class="select"
+    >
+      <select
+        id="interface-language-switcher"
+        v-model="language"
+      >
+        <option
+          v-for="(langCode, i) in languageCodes"
+          :value="langCode"
+        >
           {{ languageNames[i] }}
         </option>
       </select>
-      <i class="icon-down-open"/>
+      <i class="icon-down-open" />
     </label>
   </div>
 </template>
 
 <script>
-  import languagesObject from '../../i18n/messages'
-  import ISO6391 from 'iso-639-1'
-  import _ from 'lodash'
+import languagesObject from '../../i18n/messages'
+import ISO6391 from 'iso-639-1'
+import _ from 'lodash'
 
-  export default {
-    computed: {
-      languageCodes () {
-        return Object.keys(languagesObject)
-      },
+export default {
+  computed: {
+    languageCodes () {
+      return Object.keys(languagesObject)
+    },
 
-      languageNames () {
-        return _.map(this.languageCodes, this.getLanguageName)
-      },
+    languageNames () {
+      return _.map(this.languageCodes, this.getLanguageName)
+    },
 
-      language: {
-        get: function () { return this.$store.state.config.interfaceLanguage },
-        set: function (val) {
-          this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
-          this.$i18n.locale = val
-        }
+    language: {
+      get: function () { return this.$store.state.config.interfaceLanguage },
+      set: function (val) {
+        this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
+        this.$i18n.locale = val
       }
-    },
+    }
+  },
 
-    methods: {
-      getLanguageName (code) {
-        const specialLanguageNames = {
-          'ja': 'Japanese (やさしいにほんご)',
-          'ja_pedantic': 'Japanese (日本語)',
-          'zh': 'Chinese (简体中文)'
-        }
-        return specialLanguageNames[code] || ISO6391.getName(code)
+  methods: {
+    getLanguageName (code) {
+      const specialLanguageNames = {
+        'ja': 'Japanese (やさしいにほんご)',
+        'ja_pedantic': 'Japanese (日本語)',
+        'zh': 'Chinese (简体中文)'
       }
+      return specialLanguageNames[code] || ISO6391.getName(code)
     }
   }
+}
 </script>
diff --git a/src/components/link-preview/link-preview.vue b/src/components/link-preview/link-preview.vue
index 64b1a58b..5041dd1d 100644
--- a/src/components/link-preview/link-preview.vue
+++ b/src/components/link-preview/link-preview.vue
@@ -1,13 +1,25 @@
 <template>
   <div>
-    <a class="link-preview-card" :href="card.url" target="_blank" rel="noopener">
-      <div class="card-image" :class="{ 'small-image': size === 'small' }" v-if="useImage">
+    <a
+      class="link-preview-card"
+      :href="card.url"
+      target="_blank"
+      rel="noopener"
+    >
+      <div
+        v-if="useImage"
+        class="card-image"
+        :class="{ 'small-image': size === 'small' }"
+      >
         <img :src="card.image"></img>
       </div>
       <div class="card-content">
         <span class="card-host faint">{{ card.provider_name }}</span>
         <h4 class="card-title">{{ card.title }}</h4>
-        <p class="card-description" v-if="useDescription">{{ card.description }}</p>
+        <p
+          v-if="useDescription"
+          class="card-description"
+        >{{ card.description }}</p>
       </div>
     </a>
   </div>
diff --git a/src/components/list/list.vue b/src/components/list/list.vue
index 7136915b..a6223cce 100644
--- a/src/components/list/list.vue
+++ b/src/components/list/list.vue
@@ -1,9 +1,19 @@
 <template>
   <div class="list">
-    <div v-for="item in items" class="list-item" :key="getKey(item)">
-      <slot name="item" :item="item" />
+    <div
+      v-for="item in items"
+      :key="getKey(item)"
+      class="list-item"
+    >
+      <slot
+        name="item"
+        :item="item"
+      />
     </div>
-    <div class="list-empty-content faint" v-if="items.length === 0 && !!$slots.empty">
+    <div
+      v-if="items.length === 0 && !!$slots.empty"
+      class="list-empty-content faint"
+    >
       <slot name="empty" />
     </div>
   </div>
diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue
index a2c5cf8f..3ec7fe0c 100644
--- a/src/components/login_form/login_form.vue
+++ b/src/components/login_form/login_form.vue
@@ -1,53 +1,83 @@
 <template>
-<div class="login panel panel-default">
-  <!-- Default panel contents -->
-
-  <div class="panel-heading">{{$t('login.login')}}</div>
-
-  <div class="panel-body">
-    <form class='login-form' @submit.prevent='submit'>
-      <template v-if="isPasswordAuth">
-        <div class='form-group'>
-          <label for='username'>{{$t('login.username')}}</label>
-          <input :disabled="loggingIn" v-model='user.username'
-                 class='form-control' id='username'
-                 :placeholder="$t('login.placeholder')">
-        </div>
-        <div class='form-group'>
-          <label for='password'>{{$t('login.password')}}</label>
-          <input :disabled="loggingIn" v-model='user.password'
-                 ref='passwordInput' class='form-control' id='password' type='password'>
-        </div>
-      </template>
+  <div class="login panel panel-default">
+    <!-- Default panel contents -->
 
-      <div class="form-group" v-if="isTokenAuth">
-        <p>{{$t('login.description')}}</p>
-      </div>
+    <div class="panel-heading">
+      {{ $t('login.login') }}
+    </div>
 
-      <div class='form-group'>
-        <div class='login-bottom'>
-          <div>
-            <router-link :to="{name: 'registration'}"
-                         v-if='registrationOpen'
-                         class='register'>
-              {{$t('login.register')}}
-            </router-link>
+    <div class="panel-body">
+      <form
+        class="login-form"
+        @submit.prevent="submit"
+      >
+        <template v-if="isPasswordAuth">
+          <div class="form-group">
+            <label for="username">{{ $t('login.username') }}</label>
+            <input
+              id="username"
+              v-model="user.username"
+              :disabled="loggingIn"
+              class="form-control"
+              :placeholder="$t('login.placeholder')"
+            >
           </div>
-          <button :disabled="loggingIn" type='submit' class='btn btn-default'>
-            {{$t('login.login')}}
-          </button>
+          <div class="form-group">
+            <label for="password">{{ $t('login.password') }}</label>
+            <input
+              id="password"
+              ref="passwordInput"
+              v-model="user.password"
+              :disabled="loggingIn"
+              class="form-control"
+              type="password"
+            >
+          </div>
+        </template>
+
+        <div
+          v-if="isTokenAuth"
+          class="form-group"
+        >
+          <p>{{ $t('login.description') }}</p>
         </div>
-      </div>
-    </form>
-  </div>
 
-  <div v-if="error" class='form-group'>
-    <div class='alert error'>
-      {{error}}
-      <i class="button-icon icon-cancel" @click="clearError"></i>
+        <div class="form-group">
+          <div class="login-bottom">
+            <div>
+              <router-link
+                v-if="registrationOpen"
+                :to="{name: 'registration'}"
+                class="register"
+              >
+                {{ $t('login.register') }}
+              </router-link>
+            </div>
+            <button
+              :disabled="loggingIn"
+              type="submit"
+              class="btn btn-default"
+            >
+              {{ $t('login.login') }}
+            </button>
+          </div>
+        </div>
+      </form>
+    </div>
+
+    <div
+      v-if="error"
+      class="form-group"
+    >
+      <div class="alert error">
+        {{ error }}
+        <i
+          class="button-icon icon-cancel"
+          @click="clearError"
+        />
+      </div>
     </div>
   </div>
-</div>
 </template>
 
 <script src="./login_form.js" ></script>
diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue
index a4c12d74..f14740f6 100644
--- a/src/components/media_modal/media_modal.vue
+++ b/src/components/media_modal/media_modal.vue
@@ -1,25 +1,33 @@
 <template>
-  <div class="modal-view media-modal-view" v-if="showing" @click.prevent="hide">
-    <img class="modal-image" v-if="type === 'image'" :src="currentMedia.url"></img>
-    <VideoAttachment
+  <div
+    v-if="showing"
+    class="modal-view media-modal-view"
+    @click.prevent="hide"
+  >
+    <img
+      v-if="type === 'image'"
       class="modal-image"
+      :src="currentMedia.url"
+    ></img>
+    <VideoAttachment
       v-if="type === 'video'"
+      class="modal-image"
       :attachment="currentMedia"
       :controls="true"
-      @click.stop.native="">
-    </VideoAttachment>
+      @click.stop.native=""
+    />
     <button
+      v-if="canNavigate"
       :title="$t('media_modal.previous')"
       class="modal-view-button-arrow modal-view-button-arrow--prev"
-      v-if="canNavigate"
       @click.stop.prevent="goPrev"
     >
       <i class="icon-left-open arrow-icon" />
     </button>
     <button
+      v-if="canNavigate"
       :title="$t('media_modal.next')"
       class="modal-view-button-arrow modal-view-button-arrow--next"
-      v-if="canNavigate"
       @click.stop.prevent="goNext"
     >
       <i class="icon-right-open arrow-icon" />
diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue
index eb785735..60ce2d42 100644
--- a/src/components/media_upload/media_upload.vue
+++ b/src/components/media_upload/media_upload.vue
@@ -1,9 +1,29 @@
 <template>
-  <div class="media-upload" @drop.prevent @dragover.prevent="fileDrag" @drop="fileDrop">
-    <label class="btn btn-default" :title="$t('tool_tip.media_upload')">
-      <i class="icon-spin4 animate-spin" v-if="uploading"></i>
-      <i class="icon-upload" v-if="!uploading"></i>
-      <input type="file" v-if="uploadReady" @change="change" style="position: fixed; top: -100em" multiple="true"></input>
+  <div
+    class="media-upload"
+    @drop.prevent
+    @dragover.prevent="fileDrag"
+    @drop="fileDrop"
+  >
+    <label
+      class="btn btn-default"
+      :title="$t('tool_tip.media_upload')"
+    >
+      <i
+        v-if="uploading"
+        class="icon-spin4 animate-spin"
+      />
+      <i
+        v-if="!uploading"
+        class="icon-upload"
+      />
+      <input
+        v-if="uploadReady"
+        type="file"
+        style="position: fixed; top: -100em"
+        multiple="true"
+        @change="change"
+      ></input>
     </label>
   </div>
 </template>
diff --git a/src/components/mentions/mentions.vue b/src/components/mentions/mentions.vue
index 6b4e96e0..70f60baf 100644
--- a/src/components/mentions/mentions.vue
+++ b/src/components/mentions/mentions.vue
@@ -1,5 +1,9 @@
 <template>
-  <Timeline :title="$t('nav.interactions')" v-bind:timeline="timeline" v-bind:timeline-name="'mentions'"/>
+  <Timeline
+    :title="$t('nav.interactions')"
+    :timeline="timeline"
+    :timeline-name="'mentions'"
+  />
 </template>
 
 <script src="./mentions.js"></script>
diff --git a/src/components/mfa_form/recovery_form.vue b/src/components/mfa_form/recovery_form.vue
index e0e2d65b..57294630 100644
--- a/src/components/mfa_form/recovery_form.vue
+++ b/src/components/mfa_form/recovery_form.vue
@@ -1,42 +1,65 @@
 <template>
-<div class="login panel panel-default">
-  <!-- Default panel contents -->
+  <div class="login panel panel-default">
+    <!-- Default panel contents -->
 
-  <div class="panel-heading">{{$t('login.heading.recovery')}}</div>
+    <div class="panel-heading">
+      {{ $t('login.heading.recovery') }}
+    </div>
 
-  <div class="panel-body">
-    <form class='login-form' @submit.prevent='submit'>
-      <div class='form-group'>
-        <label for='code'>{{$t('login.recovery_code')}}</label>
-        <input v-model='code' class='form-control' id='code'>
-      </div>
+    <div class="panel-body">
+      <form
+        class="login-form"
+        @submit.prevent="submit"
+      >
+        <div class="form-group">
+          <label for="code">{{ $t('login.recovery_code') }}</label>
+          <input
+            id="code"
+            v-model="code"
+            class="form-control"
+          >
+        </div>
 
-      <div class='form-group'>
-        <div class='login-bottom'>
-          <div>
-            <a href="#" @click.prevent="requireTOTP">
-              {{$t('login.enter_two_factor_code')}}
-            </a>
-            <br />
-            <a href="#" @click.prevent="abortMFA">
-              {{$t('general.cancel')}}
-            </a>
+        <div class="form-group">
+          <div class="login-bottom">
+            <div>
+              <a
+                href="#"
+                @click.prevent="requireTOTP"
+              >
+                {{ $t('login.enter_two_factor_code') }}
+              </a>
+              <br>
+              <a
+                href="#"
+                @click.prevent="abortMFA"
+              >
+                {{ $t('general.cancel') }}
+              </a>
+            </div>
+            <button
+              type="submit"
+              class="btn btn-default"
+            >
+              {{ $t('general.verify') }}
+            </button>
           </div>
-          <button type='submit' class='btn btn-default'>
-            {{$t('general.verify')}}
-          </button>
         </div>
-      </div>
-
-    </form>
-  </div>
+      </form>
+    </div>
 
-  <div v-if="error" class='form-group'>
-    <div class='alert error'>
-      {{error}}
-      <i class="button-icon icon-cancel" @click="clearError"></i>
+    <div
+      v-if="error"
+      class="form-group"
+    >
+      <div class="alert error">
+        {{ error }}
+        <i
+          class="button-icon icon-cancel"
+          @click="clearError"
+        />
+      </div>
     </div>
   </div>
-</div>
 </template>
 <script src="./recovery_form.js" ></script>
diff --git a/src/components/mfa_form/totp_form.vue b/src/components/mfa_form/totp_form.vue
index c547785e..a344b395 100644
--- a/src/components/mfa_form/totp_form.vue
+++ b/src/components/mfa_form/totp_form.vue
@@ -1,45 +1,67 @@
 <template>
-<div class="login panel panel-default">
-  <!-- Default panel contents -->
+  <div class="login panel panel-default">
+    <!-- Default panel contents -->
 
-  <div class="panel-heading">
-    {{$t('login.heading.totp')}}
-  </div>
+    <div class="panel-heading">
+      {{ $t('login.heading.totp') }}
+    </div>
 
-  <div class="panel-body">
-    <form class='login-form' @submit.prevent='submit'>
-      <div class='form-group'>
-        <label for='code'>
-          {{$t('login.authentication_code')}}
-        </label>
-        <input v-model='code' class='form-control' id='code'>
-      </div>
+    <div class="panel-body">
+      <form
+        class="login-form"
+        @submit.prevent="submit"
+      >
+        <div class="form-group">
+          <label for="code">
+            {{ $t('login.authentication_code') }}
+          </label>
+          <input
+            id="code"
+            v-model="code"
+            class="form-control"
+          >
+        </div>
 
-      <div class='form-group'>
-        <div class='login-bottom'>
-          <div>
-            <a href="#" @click.prevent="requireRecovery">
-              {{$t('login.enter_recovery_code')}}
-            </a>
-            <br />
-            <a href="#" @click.prevent="abortMFA">
-              {{$t('general.cancel')}}
-            </a>
+        <div class="form-group">
+          <div class="login-bottom">
+            <div>
+              <a
+                href="#"
+                @click.prevent="requireRecovery"
+              >
+                {{ $t('login.enter_recovery_code') }}
+              </a>
+              <br>
+              <a
+                href="#"
+                @click.prevent="abortMFA"
+              >
+                {{ $t('general.cancel') }}
+              </a>
+            </div>
+            <button
+              type="submit"
+              class="btn btn-default"
+            >
+              {{ $t('general.verify') }}
+            </button>
           </div>
-          <button type='submit' class='btn btn-default'>
-            {{$t('general.verify')}}
-          </button>
         </div>
-      </div>
-    </form>
-  </div>
+      </form>
+    </div>
 
-  <div v-if="error" class='form-group'>
-    <div class='alert error'>
-      {{error}}
-      <i class="button-icon icon-cancel" @click="clearError"></i>
+    <div
+      v-if="error"
+      class="form-group"
+    >
+      <div class="alert error">
+        {{ error }}
+        <i
+          class="button-icon icon-cancel"
+          @click="clearError"
+        />
+      </div>
     </div>
   </div>
-</div>
 </template>
 <script src="./totp_form.js"></script>
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index dcac440a..f67b7ff8 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -1,38 +1,75 @@
 <template>
   <div>
-    <nav class='nav-bar container' id="nav">
-      <div class='mobile-inner-nav' @click="scrollToTop()">
-        <div class='item'>
-          <a href="#" class="mobile-nav-button" @click.stop.prevent="toggleMobileSidebar()">
-            <i class="button-icon icon-menu"></i>
+    <nav
+      id="nav"
+      class="nav-bar container"
+    >
+      <div
+        class="mobile-inner-nav"
+        @click="scrollToTop()"
+      >
+        <div class="item">
+          <a
+            href="#"
+            class="mobile-nav-button"
+            @click.stop.prevent="toggleMobileSidebar()"
+          >
+            <i class="button-icon icon-menu" />
           </a>
-          <router-link class="site-name" :to="{ name: 'root' }" active-class="home">{{sitename}}</router-link>
+          <router-link
+            class="site-name"
+            :to="{ name: 'root' }"
+            active-class="home"
+          >
+            {{ sitename }}
+          </router-link>
         </div>
-        <div class='item right'>
-          <a class="mobile-nav-button" v-if="currentUser" href="#" @click.stop.prevent="openMobileNotifications()">
-            <i class="button-icon icon-bell-alt"></i>
-            <div class="alert-dot" v-if="unseenNotificationsCount"></div>
+        <div class="item right">
+          <a
+            v-if="currentUser"
+            class="mobile-nav-button"
+            href="#"
+            @click.stop.prevent="openMobileNotifications()"
+          >
+            <i class="button-icon icon-bell-alt" />
+            <div
+              v-if="unseenNotificationsCount"
+              class="alert-dot"
+            />
           </a>
         </div>
       </div>
     </nav>
-    <div v-if="currentUser"
+    <div
+      v-if="currentUser"
       class="mobile-notifications-drawer"
       :class="{ 'closed': !notificationsOpen }"
       @touchstart.stop="notificationsTouchStart"
       @touchmove.stop="notificationsTouchMove"
     >
       <div class="mobile-notifications-header">
-        <span class="title">{{$t('notifications.notifications')}}</span>
-        <a class="mobile-nav-button" @click.stop.prevent="closeMobileNotifications()">
-          <i class="button-icon icon-cancel"/>
+        <span class="title">{{ $t('notifications.notifications') }}</span>
+        <a
+          class="mobile-nav-button"
+          @click.stop.prevent="closeMobileNotifications()"
+        >
+          <i class="button-icon icon-cancel" />
         </a>
       </div>
-      <div class="mobile-notifications" @scroll="onScroll">
-        <Notifications ref="notifications" :noHeading="true"/>
+      <div
+        class="mobile-notifications"
+        @scroll="onScroll"
+      >
+        <Notifications
+          ref="notifications"
+          :no-heading="true"
+        />
       </div>
     </div>
-    <SideDrawer ref="sideDrawer" :logout="logout"/>
+    <SideDrawer
+      ref="sideDrawer"
+      :logout="logout"
+    />
     <MobilePostStatusModal />
   </div>
 </template>
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 c762705b..5db7584b 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,31 @@
 <template>
-<div v-if="currentUser">
-  <div
-    class="post-form-modal-view modal-view"
-    v-show="postFormOpen"
-    @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 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>
+    <button
+      class="new-status-button"
+      :class="{ 'hidden': isHidden }"
+      @click="openPostForm"
+    >
+      <i class="icon-edit" />
+    </button>
   </div>
-  <button
-    class="new-status-button"
-    :class="{ 'hidden': isHidden }"
-    @click="openPostForm"
-  >
-    <i class="icon-edit" />
-  </button>
-</div>
 </template>
 
 <script src="./mobile_post_status_modal.js"></script>
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index 6a5e8cc0..c6f8354b 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -1,85 +1,168 @@
 <template>
-<div class='block' style='position: relative'>
-  <Popper
-    trigger="click"
-    @hide='showDropDown = false'
-    append-to-body
-    :options="{
-      placement: 'bottom-end',
-      modifiers: {
-        arrow: { enabled: true },
-        offset: { offset: '0, 5px' },
-      }
-    }">
-    <div class="popper-wrapper">
-      <div class="dropdown-menu">
-        <span v-if='user.is_local'>
-          <button class="dropdown-item" @click='toggleRight("admin")'>
-            {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
+  <div
+    class="block"
+    style="position: relative"
+  >
+    <Popper
+      trigger="click"
+      append-to-body
+      :options="{
+        placement: 'bottom-end',
+        modifiers: {
+          arrow: { enabled: true },
+          offset: { offset: '0, 5px' },
+        }
+      }"
+      @hide="showDropDown = false"
+    >
+      <div class="popper-wrapper">
+        <div class="dropdown-menu">
+          <span v-if="user.is_local">
+            <button
+              class="dropdown-item"
+              @click="toggleRight(&quot;admin&quot;)"
+            >
+              {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleRight(&quot;moderator&quot;)"
+            >
+              {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
+            </button>
+            <div
+              role="separator"
+              class="dropdown-divider"
+            />
+          </span>
+          <button
+            class="dropdown-item"
+            @click="toggleActivationStatus()"
+          >
+            {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
           </button>
-          <button class="dropdown-item" @click='toggleRight("moderator")'>
-            {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
+          <button
+            class="dropdown-item"
+            @click="deleteUserDialog(true)"
+          >
+            {{ $t('user_card.admin_menu.delete_account') }}
           </button>
-          <div role="separator" class="dropdown-divider"></div>
-        </span>
-        <button class="dropdown-item" @click='toggleActivationStatus()'>
-          {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
-        </button>
-        <button class="dropdown-item" @click='deleteUserDialog(true)'>
-          {{ $t('user_card.admin_menu.delete_account') }}
-        </button>
-        <div role="separator" class="dropdown-divider" v-if='hasTagPolicy'></div>
-        <span v-if='hasTagPolicy'>
-          <button class="dropdown-item" @click='toggleTag(tags.FORCE_NSFW)'>
-            {{ $t('user_card.admin_menu.force_nsfw') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.STRIP_MEDIA)'>
-            {{ $t('user_card.admin_menu.strip_media') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.FORCE_UNLISTED)'>
-            {{ $t('user_card.admin_menu.force_unlisted') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.SANDBOX)'>
-            {{ $t('user_card.admin_menu.sandbox') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)'>
-            {{ $t('user_card.admin_menu.disable_remote_subscription') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)'>
-            {{ $t('user_card.admin_menu.disable_any_subscription') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.QUARANTINE)'>
-            {{ $t('user_card.admin_menu.quarantine') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"></span>
-          </button>
-        </span>
+          <div
+            v-if="hasTagPolicy"
+            role="separator"
+            class="dropdown-divider"
+          />
+          <span v-if="hasTagPolicy">
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.FORCE_NSFW)"
+            >
+              {{ $t('user_card.admin_menu.force_nsfw') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.STRIP_MEDIA)"
+            >
+              {{ $t('user_card.admin_menu.strip_media') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.FORCE_UNLISTED)"
+            >
+              {{ $t('user_card.admin_menu.force_unlisted') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.SANDBOX)"
+            >
+              {{ $t('user_card.admin_menu.sandbox') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)"
+            >
+              {{ $t('user_card.admin_menu.disable_remote_subscription') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)"
+            >
+              {{ $t('user_card.admin_menu.disable_any_subscription') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.QUARANTINE)"
+            >
+              {{ $t('user_card.admin_menu.quarantine') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"
+              />
+            </button>
+          </span>
+        </div>
       </div>
-    </div>
-    <button slot="reference" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
-      {{ $t('user_card.admin_menu.moderation') }}
-    </button>
-  </Popper>
-  <portal to="modal">
-    <DialogModal v-if="showDeleteUserDialog" :onCancel='deleteUserDialog.bind(this, false)'>
-      <template slot="header">{{ $t('user_card.admin_menu.delete_user') }}</template>
-      <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
-      <template slot="footer">
-        <button class="btn btn-default" @click='deleteUserDialog(false)'>
-          {{ $t('general.cancel') }}
-        </button>
-        <button class="btn btn-default danger" @click='deleteUser()'>
+      <button
+        slot="reference"
+        :class="{ pressed: showDropDown }"
+        @click="toggleMenu"
+      >
+        {{ $t('user_card.admin_menu.moderation') }}
+      </button>
+    </Popper>
+    <portal to="modal">
+      <DialogModal
+        v-if="showDeleteUserDialog"
+        :on-cancel="deleteUserDialog.bind(this, false)"
+      >
+        <template slot="header">
           {{ $t('user_card.admin_menu.delete_user') }}
-        </button>
-      </template>
-    </DialogModal>
-  </portal>
-</div>
+        </template>
+        <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
+        <template slot="footer">
+          <button
+            class="btn btn-default"
+            @click="deleteUserDialog(false)"
+          >
+            {{ $t('general.cancel') }}
+          </button>
+          <button
+            class="btn btn-default danger"
+            @click="deleteUser()"
+          >
+            {{ $t('user_card.admin_menu.delete_user') }}
+          </button>
+        </template>
+      </DialogModal>
+    </portal>
+  </div>
 </template>
 
 <script src="./moderation_tools.js"></script>
diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue
index a4edff03..9611fb82 100644
--- a/src/components/mute_card/mute_card.vue
+++ b/src/components/mute_card/mute_card.vue
@@ -1,7 +1,12 @@
 <template>
   <basic-user-card :user="user">
     <div class="mute-card-content-container">
-      <button class="btn btn-default" @click="unmuteUser" :disabled="progress" v-if="muted">
+      <button
+        v-if="muted"
+        class="btn btn-default"
+        :disabled="progress"
+        @click="unmuteUser"
+      >
         <template v-if="progress">
           {{ $t('user_card.unmute_progress') }}
         </template>
@@ -9,7 +14,12 @@
           {{ $t('user_card.unmute') }}
         </template>
       </button>
-      <button class="btn btn-default" @click="muteUser" :disabled="progress" v-else>
+      <button
+        v-else
+        class="btn btn-default"
+        :disabled="progress"
+        @click="muteUser"
+      >
         <template v-if="progress">
           {{ $t('user_card.mute_progress') }}
         </template>
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
index e6e0f074..614fadf4 100644
--- a/src/components/nav_panel/nav_panel.vue
+++ b/src/components/nav_panel/nav_panel.vue
@@ -2,26 +2,29 @@
   <div class="nav-panel">
     <div class="panel panel-default">
       <ul>
-        <li v-if='currentUser'>
+        <li v-if="currentUser">
           <router-link :to="{ name: 'friends' }">
             {{ $t("nav.timeline") }}
           </router-link>
         </li>
-        <li v-if='currentUser'>
+        <li v-if="currentUser">
           <router-link :to="{ name: 'interactions', params: { username: currentUser.screen_name } }">
             {{ $t("nav.interactions") }}
           </router-link>
         </li>
-        <li v-if='currentUser'>
+        <li v-if="currentUser">
           <router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
             {{ $t("nav.dms") }}
           </router-link>
         </li>
-        <li v-if='currentUser && currentUser.locked'>
+        <li v-if="currentUser && currentUser.locked">
           <router-link :to="{ name: 'friend-requests' }">
-            {{ $t("nav.friend_requests")}}
-            <span v-if='followRequestCount > 0' class="badge follow-request-count">
-              {{followRequestCount}}
+            {{ $t("nav.friend_requests") }}
+            <span
+              v-if="followRequestCount > 0"
+              class="badge follow-request-count"
+            >
+              {{ followRequestCount }}
             </span>
           </router-link>
         </li>
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 5ad365ad..88f4e886 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -3,49 +3,102 @@
     v-if="notification.type === 'mention'"
     :compact="true"
     :statusoid="notification.status"
+  />
+  <div
+    v-else
+    class="non-mention"
+    :class="[userClass, { highlighted: userStyle }]"
+    :style="[ userStyle ]"
   >
-  </status>
-  <div class="non-mention" :class="[userClass, { highlighted: userStyle }]" :style="[ userStyle ]" v-else>
-    <a class='avatar-container' :href="notification.from_profile.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
-      <UserAvatar :compact="true" :betterShadow="betterShadow" :user="notification.from_profile"/>
+    <a
+      class="avatar-container"
+      :href="notification.from_profile.statusnet_profile_url"
+      @click.stop.prevent.capture="toggleUserExpanded"
+    >
+      <UserAvatar
+        :compact="true"
+        :better-shadow="betterShadow"
+        :user="notification.from_profile"
+      />
     </a>
-    <div class='notification-right'>
-      <UserCard :user="getUser(notification)" :rounded="true" :bordered="true" v-if="userExpanded" />
+    <div class="notification-right">
+      <UserCard
+        v-if="userExpanded"
+        :user="getUser(notification)"
+        :rounded="true"
+        :bordered="true"
+      />
       <span class="notification-details">
         <div class="name-and-action">
-          <span class="username" v-if="!!notification.from_profile.name_html" :title="'@'+notification.from_profile.screen_name" v-html="notification.from_profile.name_html"></span>
-          <span class="username" v-else :title="'@'+notification.from_profile.screen_name">{{ notification.from_profile.name }}</span>
+          <span
+            v-if="!!notification.from_profile.name_html"
+            class="username"
+            :title="'@'+notification.from_profile.screen_name"
+            v-html="notification.from_profile.name_html"
+          />
+          <span
+            v-else
+            class="username"
+            :title="'@'+notification.from_profile.screen_name"
+          >{{ notification.from_profile.name }}</span>
           <span v-if="notification.type === 'like'">
-            <i class="fa icon-star lit"></i>
-            <small>{{$t('notifications.favorited_you')}}</small>
+            <i class="fa icon-star lit" />
+            <small>{{ $t('notifications.favorited_you') }}</small>
           </span>
           <span v-if="notification.type === 'repeat'">
-            <i class="fa icon-retweet lit" :title="$t('tool_tip.repeat')"></i>
-            <small>{{$t('notifications.repeated_you')}}</small>
+            <i
+              class="fa icon-retweet lit"
+              :title="$t('tool_tip.repeat')"
+            />
+            <small>{{ $t('notifications.repeated_you') }}</small>
           </span>
           <span v-if="notification.type === 'follow'">
-            <i class="fa icon-user-plus lit"></i>
-            <small>{{$t('notifications.followed_you')}}</small>
+            <i class="fa icon-user-plus lit" />
+            <small>{{ $t('notifications.followed_you') }}</small>
           </span>
         </div>
-        <div class="timeago" v-if="notification.type === 'follow'">
+        <div
+          v-if="notification.type === 'follow'"
+          class="timeago"
+        >
           <span class="faint">
-            <Timeago :time="notification.created_at" :auto-update="240"></Timeago>
+            <Timeago
+              :time="notification.created_at"
+              :auto-update="240"
+            />
           </span>
         </div>
-        <div class="timeago" v-else>
-          <router-link v-if="notification.status" :to="{ name: 'conversation', params: { id: notification.status.id } }" class="faint-link">
-            <Timeago :time="notification.created_at" :auto-update="240"></Timeago>
+        <div
+          v-else
+          class="timeago"
+        >
+          <router-link
+            v-if="notification.status"
+            :to="{ name: 'conversation', params: { id: notification.status.id } }"
+            class="faint-link"
+          >
+            <Timeago
+              :time="notification.created_at"
+              :auto-update="240"
+            />
           </router-link>
         </div>
       </span>
-      <div class="follow-text" v-if="notification.type === 'follow'">
+      <div
+        v-if="notification.type === 'follow'"
+        class="follow-text"
+      >
         <router-link :to="userProfileLink(notification.from_profile)">
-          @{{notification.from_profile.screen_name}}
+          @{{ notification.from_profile.screen_name }}
         </router-link>
       </div>
       <template v-else>
-        <status class="faint" :compact="true" :statusoid="notification.action" :noHeading="true"></status>
+        <status
+          class="faint"
+          :compact="true"
+          :statusoid="notification.action"
+          :no-heading="true"
+        />
       </template>
     </div>
   </div>
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index c71499b2..c42c35e6 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -1,33 +1,67 @@
 <template>
-  <div :class="{ minimal: minimalMode }" class="notifications">
+  <div
+    :class="{ minimal: minimalMode }"
+    class="notifications"
+  >
     <div :class="mainClass">
-      <div v-if="!noHeading" class="panel-heading">
+      <div
+        v-if="!noHeading"
+        class="panel-heading"
+      >
         <div class="title">
-          {{$t('notifications.notifications')}}
-          <span class="badge badge-notification unseen-count" v-if="unseenCount">{{unseenCount}}</span>
+          {{ $t('notifications.notifications') }}
+          <span
+            v-if="unseenCount"
+            class="badge badge-notification unseen-count"
+          >{{ unseenCount }}</span>
         </div>
-        <div @click.prevent class="loadmore-error alert error" v-if="error">
-          {{$t('timeline.error_fetching')}}
+        <div
+          v-if="error"
+          class="loadmore-error alert error"
+          @click.prevent
+        >
+          {{ $t('timeline.error_fetching') }}
         </div>
-        <button v-if="unseenCount" @click.prevent="markAsSeen" class="read-button">{{$t('notifications.read')}}</button>
+        <button
+          v-if="unseenCount"
+          class="read-button"
+          @click.prevent="markAsSeen"
+        >
+          {{ $t('notifications.read') }}
+        </button>
       </div>
       <div class="panel-body">
-        <div v-for="notification in visibleNotifications" :key="notification.id" class="notification" :class='{"unseen": !minimalMode && !notification.seen}'>
-          <div class="notification-overlay"></div>
-          <notification :notification="notification"></notification>
+        <div
+          v-for="notification in visibleNotifications"
+          :key="notification.id"
+          class="notification"
+          :class="{&quot;unseen&quot;: !minimalMode && !notification.seen}"
+        >
+          <div class="notification-overlay" />
+          <notification :notification="notification" />
         </div>
       </div>
       <div class="panel-footer">
-        <div v-if="bottomedOut" class="new-status-notification text-center panel-footer faint">
-          {{$t('notifications.no_more_notifications')}}
+        <div
+          v-if="bottomedOut"
+          class="new-status-notification text-center panel-footer faint"
+        >
+          {{ $t('notifications.no_more_notifications') }}
         </div>
-        <a v-else-if="!loading" href="#" v-on:click.prevent="fetchOlderNotifications()">
+        <a
+          v-else-if="!loading"
+          href="#"
+          @click.prevent="fetchOlderNotifications()"
+        >
           <div class="new-status-notification text-center panel-footer">
-            {{ minimalMode ? $t('interactions.load_older') : $t('notifications.load_older')}}
+            {{ minimalMode ? $t('interactions.load_older') : $t('notifications.load_older') }}
           </div>
         </a>
-        <div v-else class="new-status-notification text-center panel-footer">
-          <i class="icon-spin3 animate-spin"/>
+        <div
+          v-else
+          class="new-status-notification text-center panel-footer"
+        >
+          <i class="icon-spin3 animate-spin" />
         </div>
       </div>
     </div>
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index 3926915b..c677f18c 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -1,27 +1,39 @@
 <template>
-<div class="opacity-control style-control" :class="{ disabled: !present || disabled }">
-  <label :for="name" class="label">
-    {{$t('settings.style.common.opacity')}}
-  </label>
-  <input
-    v-if="typeof fallback !== 'undefined'"
-    class="opt exclude-disabled"
-    :id="name + '-o'"
-    type="checkbox"
-    :checked="present"
-    @input="$emit('input', !present ? fallback : undefined)">
-  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
-  <input
-    :id="name"
-    class="input-number"
-    type="number"
-    :value="value || fallback"
-    :disabled="!present || disabled"
-    @input="$emit('input', $event.target.value)"
-    max="1"
-    min="0"
-    step=".05">
-</div>
+  <div
+    class="opacity-control style-control"
+    :class="{ disabled: !present || disabled }"
+  >
+    <label
+      :for="name"
+      class="label"
+    >
+      {{ $t('settings.style.common.opacity') }}
+    </label>
+    <input
+      v-if="typeof fallback !== 'undefined'"
+      :id="name + '-o'"
+      class="opt exclude-disabled"
+      type="checkbox"
+      :checked="present"
+      @input="$emit('input', !present ? fallback : undefined)"
+    >
+    <label
+      v-if="typeof fallback !== 'undefined'"
+      class="opt-l"
+      :for="name + '-o'"
+    />
+    <input
+      :id="name"
+      class="input-number"
+      type="number"
+      :value="value || fallback"
+      :disabled="!present || disabled"
+      max="1"
+      min="0"
+      step=".05"
+      @input="$emit('input', $event.target.value)"
+    >
+  </div>
 </template>
 
 <script>
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index bb67101a..0fc81b46 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -1,24 +1,33 @@
 <template>
-  <div class="poll" v-bind:class="containerClass">
+  <div
+    class="poll"
+    :class="containerClass"
+  >
     <div
-      class="poll-option"
       v-for="(option, index) in options"
       :key="index"
+      class="poll-option"
     >
-      <div v-if="showResults" :title="resultTitle(option)" class="option-result">
+      <div
+        v-if="showResults"
+        :title="resultTitle(option)"
+        class="option-result"
+      >
         <div class="option-result-label">
           <span class="result-percentage">
-            {{percentageForOption(option.votes_count)}}%
+            {{ percentageForOption(option.votes_count) }}%
           </span>
-          <span>{{option.title}}</span>
+          <span>{{ option.title }}</span>
         </div>
         <div
           class="result-fill"
           :style="{ 'width': `${percentageForOption(option.votes_count)}%` }"
-        >     
-        </div> 
+        />
       </div>
-      <div v-else @click="activateOption(index)">
+      <div
+        v-else
+        @click="activateOption(index)"
+      >
         <input
           v-if="poll.multiple"
           type="checkbox"
@@ -32,7 +41,7 @@
           :value="index"
         >
         <label class="option-vote">
-          <div>{{option.title}}</div>
+          <div>{{ option.title }}</div>
         </label>
       </div>
     </div>
@@ -41,16 +50,20 @@
         v-if="!showResults"
         class="btn btn-default poll-vote-button"
         type="button"
-        @click="vote"
         :disabled="isDisabled"
+        @click="vote"
       >
-        {{$t('polls.vote')}}
+        {{ $t('polls.vote') }}
       </button>
       <div class="total">
-        {{totalVotesCount}} {{ $t("polls.votes") }}&nbsp;·&nbsp;
+        {{ totalVotesCount }} {{ $t("polls.votes") }}&nbsp;·&nbsp;
       </div>
       <i18n :path="expired ? 'polls.expired' : 'polls.expires_in'">
-        <Timeago :time="this.expiresAt" :auto-update="60" :now-threshold="0" />
+        <Timeago
+          :time="this.expiresAt"
+          :auto-update="60"
+          :now-threshold="0"
+        />
       </i18n>
     </div>
   </div>
diff --git a/src/components/poll/poll_form.vue b/src/components/poll/poll_form.vue
index 0bc6006d..2bd3d058 100644
--- a/src/components/poll/poll_form.vue
+++ b/src/components/poll/poll_form.vue
@@ -1,20 +1,33 @@
 <template>
-  <div class="poll-form" v-if="visible">
-    <div class="poll-option" v-for="(option, index) in options" :key="index">
+  <div
+    v-if="visible"
+    class="poll-form"
+  >
+    <div
+      v-for="(option, index) in options"
+      :key="index"
+      class="poll-option"
+    >
       <div class="input-container">
         <input
+          :id="`poll-${index}`"
+          v-model="options[index]"
           class="poll-option-input"
           type="text"
           :placeholder="$t('polls.option')"
           :maxlength="maxLength"
-          :id="`poll-${index}`"
-          v-model="options[index]"
           @change="updatePollToParent"
           @keydown.enter.stop.prevent="nextOption(index)"
         >
       </div>
-      <div class="icon-container" v-if="options.length > 2">
-        <i class="icon-cancel" @click="deleteOption(index)"></i>
+      <div
+        v-if="options.length > 2"
+        class="icon-container"
+      >
+        <i
+          class="icon-cancel"
+          @click="deleteOption(index)"
+        />
       </div>
     </div>
     <a
@@ -26,34 +39,50 @@
       {{ $t("polls.add_option") }}
     </a>
     <div class="poll-type-expiry">
-      <div class="poll-type" :title="$t('polls.type')">
-        <label for="poll-type-selector" class="select">
-          <select class="select" v-model="pollType" @change="updatePollToParent">
-            <option value="single">{{$t('polls.single_choice')}}</option>
-            <option value="multiple">{{$t('polls.multiple_choices')}}</option>
+      <div
+        class="poll-type"
+        :title="$t('polls.type')"
+      >
+        <label
+          for="poll-type-selector"
+          class="select"
+        >
+          <select
+            v-model="pollType"
+            class="select"
+            @change="updatePollToParent"
+          >
+            <option value="single">{{ $t('polls.single_choice') }}</option>
+            <option value="multiple">{{ $t('polls.multiple_choices') }}</option>
           </select>
-          <i class="icon-down-open"/>
+          <i class="icon-down-open" />
         </label>
       </div>
-      <div class="poll-expiry" :title="$t('polls.expiry')">
-        <input 
+      <div
+        class="poll-expiry"
+        :title="$t('polls.expiry')"
+      >
+        <input
+          v-model="expiryAmount"
           type="number"
           class="expiry-amount hide-number-spinner"
           :min="minExpirationInCurrentUnit"
           :max="maxExpirationInCurrentUnit"
-          v-model="expiryAmount"
           @change="expiryAmountChange"
         >
         <label class="expiry-unit select">
-          <select 
+          <select
             v-model="expiryUnit"
             @change="expiryAmountChange"
           >
-            <option v-for="unit in expiryUnits" :value="unit">
+            <option
+              v-for="unit in expiryUnits"
+              :value="unit"
+            >
               {{ $t(`time.${unit}_short`, ['']) }}
             </option>
           </select>
-          <i class="icon-down-open"/>
+          <i class="icon-down-open" />
         </label>
       </div>
     </div>
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 67cdc721..bc63d90f 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -1,147 +1,253 @@
 <template>
-<div class="post-status-form">
-  <form @submit.prevent="postStatus(newStatus)" autocomplete="off">
-    <div class="form-group" >
-      <i18n
-        v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private'"
-        path="post_status.account_not_locked_warning"
-        tag="p"
-        class="visibility-notice">
-        <router-link :to="{ name: 'user-settings' }">{{ $t('post_status.account_not_locked_warning_link') }}</router-link>
-      </i18n>
-      <p v-if="!hideScopeNotice && newStatus.visibility === 'public'" class="visibility-notice notice-dismissible">
-        <span>{{ $t('post_status.scope_notice.public') }}</span>
-        <a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
-          <i class='icon-cancel'></i>
-        </a>
-      </p>
-      <p v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'" class="visibility-notice notice-dismissible">
-        <span>{{ $t('post_status.scope_notice.unlisted') }}</span>
-        <a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
-          <i class='icon-cancel'></i>
-        </a>
-      </p>
-      <p v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked" class="visibility-notice notice-dismissible">
-        <span>{{ $t('post_status.scope_notice.private') }}</span>
-        <a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
-          <i class='icon-cancel'></i>
-        </a>
-      </p>
-      <p v-else-if="newStatus.visibility === 'direct'" class="visibility-notice">
-        <span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
-        <span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
-      </p>
-      <EmojiInput
-        v-if="newStatus.spoilerText || alwaysShowSubject"
-        :suggest="emojiSuggestor"
-        v-model="newStatus.spoilerText"
-        class="form-control"
+  <div class="post-status-form">
+    <form
+      autocomplete="off"
+      @submit.prevent="postStatus(newStatus)"
+    >
+      <div class="form-group">
+        <i18n
+          v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private'"
+          path="post_status.account_not_locked_warning"
+          tag="p"
+          class="visibility-notice"
         >
-        <input
-
-          type="text"
-          :placeholder="$t('post_status.content_warning')"
-          v-model="newStatus.spoilerText"
-          class="form-post-subject"
-          />
-      </EmojiInput>
-      <EmojiInput
-        :suggest="emojiUserSuggestor"
-        v-model="newStatus.status"
-        class="form-control main-input"
+          <router-link :to="{ name: 'user-settings' }">
+            {{ $t('post_status.account_not_locked_warning_link') }}
+          </router-link>
+        </i18n>
+        <p
+          v-if="!hideScopeNotice && newStatus.visibility === 'public'"
+          class="visibility-notice notice-dismissible"
         >
-        <textarea
-          ref="textarea"
-          v-model="newStatus.status"
-          :placeholder="$t('post_status.default')"
-          rows="1"
-          @keydown.meta.enter="postStatus(newStatus)"
-          @keyup.ctrl.enter="postStatus(newStatus)"
-          @drop="fileDrop"
-          @dragover.prevent="fileDrag"
-          @input="resize"
-          @paste="paste"
-          :disabled="posting"
-          class="form-post-body"
+          <span>{{ $t('post_status.scope_notice.public') }}</span>
+          <a
+            class="button-icon dismiss"
+            @click.prevent="dismissScopeNotice()"
+          >
+            <i class="icon-cancel" />
+          </a>
+        </p>
+        <p
+          v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'"
+          class="visibility-notice notice-dismissible"
         >
-        </textarea>
+          <span>{{ $t('post_status.scope_notice.unlisted') }}</span>
+          <a
+            class="button-icon dismiss"
+            @click.prevent="dismissScopeNotice()"
+          >
+            <i class="icon-cancel" />
+          </a>
+        </p>
+        <p
+          v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked"
+          class="visibility-notice notice-dismissible"
+        >
+          <span>{{ $t('post_status.scope_notice.private') }}</span>
+          <a
+            class="button-icon dismiss"
+            @click.prevent="dismissScopeNotice()"
+          >
+            <i class="icon-cancel" />
+          </a>
+        </p>
         <p
-          v-if="hasStatusLengthLimit"
-          class="character-counter faint"
-          :class="{ error: isOverLengthLimit }"
+          v-else-if="newStatus.visibility === 'direct'"
+          class="visibility-notice"
         >
-          {{ charactersLeft }}
+          <span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
+          <span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
         </p>
-      </EmojiInput>
-      <div class="visibility-tray">
-        <div class="text-format" v-if="postFormats.length > 1">
-          <label for="post-content-type" class="select">
-            <select id="post-content-type" v-model="newStatus.contentType" class="form-control">
-              <option v-for="postFormat in postFormats" :key="postFormat" :value="postFormat">
-                {{$t(`post_status.content_type["${postFormat}"]`)}}
-              </option>
-            </select>
-            <i class="icon-down-open"></i>
-          </label>
+        <EmojiInput
+          v-if="newStatus.spoilerText || alwaysShowSubject"
+          v-model="newStatus.spoilerText"
+          :suggest="emojiSuggestor"
+          class="form-control"
+        >
+          <input
+
+            v-model="newStatus.spoilerText"
+            type="text"
+            :placeholder="$t('post_status.content_warning')"
+            class="form-post-subject"
+          >
+        </EmojiInput>
+        <EmojiInput
+          v-model="newStatus.status"
+          :suggest="emojiUserSuggestor"
+          class="form-control main-input"
+        >
+          <textarea
+            ref="textarea"
+            v-model="newStatus.status"
+            :placeholder="$t('post_status.default')"
+            rows="1"
+            :disabled="posting"
+            class="form-post-body"
+            @keydown.meta.enter="postStatus(newStatus)"
+            @keyup.ctrl.enter="postStatus(newStatus)"
+            @drop="fileDrop"
+            @dragover.prevent="fileDrag"
+            @input="resize"
+            @paste="paste"
+          />
+          <p
+            v-if="hasStatusLengthLimit"
+            class="character-counter faint"
+            :class="{ error: isOverLengthLimit }"
+          >
+            {{ charactersLeft }}
+          </p>
+        </EmojiInput>
+        <div class="visibility-tray">
+          <div
+            v-if="postFormats.length > 1"
+            class="text-format"
+          >
+            <label
+              for="post-content-type"
+              class="select"
+            >
+              <select
+                id="post-content-type"
+                v-model="newStatus.contentType"
+                class="form-control"
+              >
+                <option
+                  v-for="postFormat in postFormats"
+                  :key="postFormat"
+                  :value="postFormat"
+                >
+                  {{ $t(`post_status.content_type["${postFormat}"]`) }}
+                </option>
+              </select>
+              <i class="icon-down-open" />
+            </label>
+          </div>
+          <div
+            v-if="postFormats.length === 1"
+            class="text-format"
+          >
+            <span class="only-format">
+              {{ $t(`post_status.content_type["${postFormats[0]}"]`) }}
+            </span>
+          </div>
+
+          <scope-selector
+            :show-all="showAllScopes"
+            :user-default="userDefaultScope"
+            :original-scope="copyMessageScope"
+            :initial-scope="newStatus.visibility"
+            :on-scope-change="changeVis"
+          />
         </div>
-        <div class="text-format" v-if="postFormats.length === 1">
-          <span class="only-format">
-            {{$t(`post_status.content_type["${postFormats[0]}"]`)}}
-          </span>
+      </div>
+      <poll-form
+        v-if="pollsAvailable"
+        ref="pollForm"
+        :visible="pollFormVisible"
+        @update-poll="setPoll"
+      />
+      <div class="form-bottom">
+        <div class="form-bottom-left">
+          <media-upload
+            ref="mediaUpload"
+            :drop-files="dropFiles"
+            @uploading="disableSubmit"
+            @uploaded="addMediaFile"
+            @upload-failed="uploadFailed"
+          />
+          <div
+            v-if="pollsAvailable"
+            class="poll-icon"
+          >
+            <i
+              :title="$t('polls.add_poll')"
+              class="icon-chart-bar btn btn-default"
+              :class="pollFormVisible && 'selected'"
+              @click="togglePollForm"
+            />
+          </div>
         </div>
 
-        <scope-selector
-          :showAll="showAllScopes"
-          :userDefault="userDefaultScope"
-          :originalScope="copyMessageScope"
-          :initialScope="newStatus.visibility"
-          :onScopeChange="changeVis"/>
+        <button
+          v-if="posting"
+          disabled
+          class="btn btn-default"
+        >
+          {{ $t('post_status.posting') }}
+        </button>
+        <button
+          v-else-if="isOverLengthLimit"
+          disabled
+          class="btn btn-default"
+        >
+          {{ $t('general.submit') }}
+        </button>
+        <button
+          v-else
+          :disabled="submitDisabled"
+          type="submit"
+          class="btn btn-default"
+        >
+          {{ $t('general.submit') }}
+        </button>
+      </div>
+      <div
+        v-if="error"
+        class="alert error"
+      >
+        Error: {{ error }}
+        <i
+          class="button-icon icon-cancel"
+          @click="clearError"
+        />
       </div>
-    </div>
-    <poll-form
-      ref="pollForm"
-      v-if="pollsAvailable"
-      :visible="pollFormVisible"
-      @update-poll="setPoll"
-    />
-    <div class='form-bottom'>
-      <div class='form-bottom-left'>
-        <media-upload ref="mediaUpload" @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="uploadFailed" :drop-files="dropFiles"></media-upload>
-        <div v-if="pollsAvailable" class="poll-icon">
+      <div class="attachments">
+        <div
+          v-for="file in newStatus.files"
+          class="media-upload-wrapper"
+        >
           <i
-            :title="$t('polls.add_poll')"
-            @click="togglePollForm"
-            class="icon-chart-bar btn btn-default"
-            :class="pollFormVisible && 'selected'"
+            class="fa button-icon icon-cancel"
+            @click="removeMediaFile(file)"
           />
+          <div class="media-upload-container attachment">
+            <img
+              v-if="type(file) === 'image'"
+              class="thumbnail media-upload"
+              :src="file.url"
+            ></img>
+            <video
+              v-if="type(file) === 'video'"
+              :src="file.url"
+              controls
+            />
+            <audio
+              v-if="type(file) === 'audio'"
+              :src="file.url"
+              controls
+            />
+            <a
+              v-if="type(file) === 'unknown'"
+              :href="file.url"
+            >{{ file.url }}</a>
+          </div>
         </div>
       </div>
-
-      <button v-if="posting" disabled class="btn btn-default">{{$t('post_status.posting')}}</button>
-      <button v-else-if="isOverLengthLimit" disabled class="btn btn-default">{{$t('general.submit')}}</button>
-      <button v-else :disabled="submitDisabled" type="submit" class="btn btn-default">{{$t('general.submit')}}</button>
-    </div>
-    <div class='alert error' v-if="error">
-      Error: {{ error }}
-      <i class="button-icon icon-cancel" @click="clearError"></i>
-    </div>
-    <div class="attachments">
-      <div class="media-upload-wrapper" v-for="file in newStatus.files">
-        <i class="fa button-icon icon-cancel" @click="removeMediaFile(file)"></i>
-        <div class="media-upload-container attachment">
-          <img class="thumbnail media-upload" :src="file.url" v-if="type(file) === 'image'"></img>
-          <video v-if="type(file) === 'video'" :src="file.url" controls></video>
-          <audio v-if="type(file) === 'audio'" :src="file.url" controls></audio>
-          <a v-if="type(file) === 'unknown'" :href="file.url">{{file.url}}</a>
-        </div>
+      <div
+        v-if="newStatus.files.length > 0"
+        class="upload_settings"
+      >
+        <input
+          id="filesSensitive"
+          v-model="newStatus.nsfw"
+          type="checkbox"
+        >
+        <label for="filesSensitive">{{ $t('post_status.attachments_sensitive') }}</label>
       </div>
-    </div>
-    <div class="upload_settings" v-if="newStatus.files.length > 0">
-      <input type="checkbox" id="filesSensitive" v-model="newStatus.nsfw">
-      <label for="filesSensitive">{{$t('post_status.attachments_sensitive')}}</label>
-    </div>
-  </form>
-</div>
+    </form>
+  </div>
 </template>
 
 <script src="./post_status_form.js"></script>
@@ -217,7 +323,6 @@
   .icon-chart-bar {
     cursor: pointer;
   }
-  
 
   .error {
     text-align: center;
diff --git a/src/components/progress_button/progress_button.vue b/src/components/progress_button/progress_button.vue
index 737360bb..d19aa97d 100644
--- a/src/components/progress_button/progress_button.vue
+++ b/src/components/progress_button/progress_button.vue
@@ -1,5 +1,8 @@
 <template>
-  <button :disabled="progress || disabled" @click="onClick">
+  <button
+    :disabled="progress || disabled"
+    @click="onClick"
+  >
     <template v-if="progress">
       <slot name="progress" />
     </template>
diff --git a/src/components/public_and_external_timeline/public_and_external_timeline.vue b/src/components/public_and_external_timeline/public_and_external_timeline.vue
index 6be9f955..fcd915ac 100644
--- a/src/components/public_and_external_timeline/public_and_external_timeline.vue
+++ b/src/components/public_and_external_timeline/public_and_external_timeline.vue
@@ -1,5 +1,9 @@
 <template>
-  <Timeline :title="$t('nav.twkn')" v-bind:timeline="timeline" v-bind:timeline-name="'publicAndExternal'"/>
+  <Timeline
+    :title="$t('nav.twkn')"
+    :timeline="timeline"
+    :timeline-name="'publicAndExternal'"
+  />
 </template>
 
 <script src="./public_and_external_timeline.js"></script>
diff --git a/src/components/public_timeline/public_timeline.vue b/src/components/public_timeline/public_timeline.vue
index 85d42cca..5720068d 100644
--- a/src/components/public_timeline/public_timeline.vue
+++ b/src/components/public_timeline/public_timeline.vue
@@ -1,5 +1,9 @@
 <template>
-  <Timeline :title="$t('nav.public_tl')" v-bind:timeline="timeline" v-bind:timeline-name="'public'"/>
+  <Timeline
+    :title="$t('nav.public_tl')"
+    :timeline="timeline"
+    :timeline-name="'public'"
+  />
 </template>
 
 <script src="./public_timeline.js"></script>
diff --git a/src/components/range_input/range_input.vue b/src/components/range_input/range_input.vue
index 3e50664b..aaa2ed26 100644
--- a/src/components/range_input/range_input.vue
+++ b/src/components/range_input/range_input.vue
@@ -1,37 +1,50 @@
 <template>
-<div class="range-control style-control" :class="{ disabled: !present || disabled }">
-  <label :for="name" class="label">
-    {{label}}
-  </label>
-  <input
-    v-if="typeof fallback !== 'undefined'"
-    class="opt exclude-disabled"
-    :id="name + '-o'"
-    type="checkbox"
-    :checked="present"
-    @input="$emit('input', !present ? fallback : undefined)">
-  <label v-if="typeof fallback !== 'undefined'" class="opt-l" :for="name + '-o'"></label>
-  <input
-    :id="name"
-    class="input-number"
-    type="range"
-    :value="value || fallback"
-    :disabled="!present || disabled"
-    @input="$emit('input', $event.target.value)"
-    :max="max || hardMax || 100"
-    :min="min || hardMin || 0"
-    :step="step || 1">
-  <input
-    :id="name"
-    class="input-number"
-    type="number"
-    :value="value || fallback"
-    :disabled="!present || disabled"
-    @input="$emit('input', $event.target.value)"
-    :max="hardMax"
-    :min="hardMin"
-    :step="step || 1">
-</div>
+  <div
+    class="range-control style-control"
+    :class="{ disabled: !present || disabled }"
+  >
+    <label
+      :for="name"
+      class="label"
+    >
+      {{ label }}
+    </label>
+    <input
+      v-if="typeof fallback !== 'undefined'"
+      :id="name + '-o'"
+      class="opt exclude-disabled"
+      type="checkbox"
+      :checked="present"
+      @input="$emit('input', !present ? fallback : undefined)"
+    >
+    <label
+      v-if="typeof fallback !== 'undefined'"
+      class="opt-l"
+      :for="name + '-o'"
+    />
+    <input
+      :id="name"
+      class="input-number"
+      type="range"
+      :value="value || fallback"
+      :disabled="!present || disabled"
+      :max="max || hardMax || 100"
+      :min="min || hardMin || 0"
+      :step="step || 1"
+      @input="$emit('input', $event.target.value)"
+    >
+    <input
+      :id="name"
+      class="input-number"
+      type="number"
+      :value="value || fallback"
+      :disabled="!present || disabled"
+      :max="hardMax"
+      :min="hardMin"
+      :step="step || 1"
+      @input="$emit('input', $event.target.value)"
+    >
+  </div>
 </template>
 
 <script>
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue
index 110b27bf..8cc4ba56 100644
--- a/src/components/registration/registration.vue
+++ b/src/components/registration/registration.vue
@@ -1,109 +1,231 @@
 <template>
   <div class="settings panel panel-default">
     <div class="panel-heading">
-      {{$t('registration.registration')}}
+      {{ $t('registration.registration') }}
     </div>
     <div class="panel-body">
-      <form v-on:submit.prevent='submit(user)' class='registration-form'>
-        <div class='container'>
-          <div class='text-fields'>
-            <div class='form-group' :class="{ 'form-group--error': $v.user.username.$error }">
-              <label class='form--label' for='sign-up-username'>{{$t('login.username')}}</label>
-              <input :disabled="isPending" v-model.trim='$v.user.username.$model' class='form-control' id='sign-up-username' :placeholder="$t('registration.username_placeholder')">
+      <form
+        class="registration-form"
+        @submit.prevent="submit(user)"
+      >
+        <div class="container">
+          <div class="text-fields">
+            <div
+              class="form-group"
+              :class="{ 'form-group--error': $v.user.username.$error }"
+            >
+              <label
+                class="form--label"
+                for="sign-up-username"
+              >{{ $t('login.username') }}</label>
+              <input
+                id="sign-up-username"
+                v-model.trim="$v.user.username.$model"
+                :disabled="isPending"
+                class="form-control"
+                :placeholder="$t('registration.username_placeholder')"
+              >
             </div>
-            <div class="form-error" v-if="$v.user.username.$dirty">
+            <div
+              v-if="$v.user.username.$dirty"
+              class="form-error"
+            >
               <ul>
                 <li v-if="!$v.user.username.required">
-                  <span>{{$t('registration.validations.username_required')}}</span>
+                  <span>{{ $t('registration.validations.username_required') }}</span>
                 </li>
               </ul>
             </div>
 
-            <div class='form-group' :class="{ 'form-group--error': $v.user.fullname.$error }">
-              <label class='form--label' for='sign-up-fullname'>{{$t('registration.fullname')}}</label>
-              <input :disabled="isPending" v-model.trim='$v.user.fullname.$model' class='form-control' id='sign-up-fullname' :placeholder="$t('registration.fullname_placeholder')">
+            <div
+              class="form-group"
+              :class="{ 'form-group--error': $v.user.fullname.$error }"
+            >
+              <label
+                class="form--label"
+                for="sign-up-fullname"
+              >{{ $t('registration.fullname') }}</label>
+              <input
+                id="sign-up-fullname"
+                v-model.trim="$v.user.fullname.$model"
+                :disabled="isPending"
+                class="form-control"
+                :placeholder="$t('registration.fullname_placeholder')"
+              >
             </div>
-            <div class="form-error" v-if="$v.user.fullname.$dirty">
+            <div
+              v-if="$v.user.fullname.$dirty"
+              class="form-error"
+            >
               <ul>
                 <li v-if="!$v.user.fullname.required">
-                  <span>{{$t('registration.validations.fullname_required')}}</span>
+                  <span>{{ $t('registration.validations.fullname_required') }}</span>
                 </li>
               </ul>
             </div>
 
-            <div class='form-group' :class="{ 'form-group--error': $v.user.email.$error }">
-              <label class='form--label' for='email'>{{$t('registration.email')}}</label>
-              <input :disabled="isPending" v-model='$v.user.email.$model' class='form-control' id='email' type="email">
+            <div
+              class="form-group"
+              :class="{ 'form-group--error': $v.user.email.$error }"
+            >
+              <label
+                class="form--label"
+                for="email"
+              >{{ $t('registration.email') }}</label>
+              <input
+                id="email"
+                v-model="$v.user.email.$model"
+                :disabled="isPending"
+                class="form-control"
+                type="email"
+              >
             </div>
-            <div class="form-error" v-if="$v.user.email.$dirty">
+            <div
+              v-if="$v.user.email.$dirty"
+              class="form-error"
+            >
               <ul>
                 <li v-if="!$v.user.email.required">
-                  <span>{{$t('registration.validations.email_required')}}</span>
+                  <span>{{ $t('registration.validations.email_required') }}</span>
                 </li>
               </ul>
             </div>
 
-            <div class='form-group'>
-              <label class='form--label' for='bio'>{{$t('registration.bio')}} ({{$t('general.optional')}})</label>
-              <textarea :disabled="isPending" v-model='user.bio' class='form-control' id='bio' :placeholder="bioPlaceholder"></textarea>
+            <div class="form-group">
+              <label
+                class="form--label"
+                for="bio"
+              >{{ $t('registration.bio') }} ({{ $t('general.optional') }})</label>
+              <textarea
+                id="bio"
+                v-model="user.bio"
+                :disabled="isPending"
+                class="form-control"
+                :placeholder="bioPlaceholder"
+              />
             </div>
 
-            <div class='form-group' :class="{ 'form-group--error': $v.user.password.$error }">
-              <label class='form--label' for='sign-up-password'>{{$t('login.password')}}</label>
-              <input :disabled="isPending" v-model='user.password' class='form-control' id='sign-up-password' type='password'>
+            <div
+              class="form-group"
+              :class="{ 'form-group--error': $v.user.password.$error }"
+            >
+              <label
+                class="form--label"
+                for="sign-up-password"
+              >{{ $t('login.password') }}</label>
+              <input
+                id="sign-up-password"
+                v-model="user.password"
+                :disabled="isPending"
+                class="form-control"
+                type="password"
+              >
             </div>
-            <div class="form-error" v-if="$v.user.password.$dirty">
+            <div
+              v-if="$v.user.password.$dirty"
+              class="form-error"
+            >
               <ul>
                 <li v-if="!$v.user.password.required">
-                  <span>{{$t('registration.validations.password_required')}}</span>
+                  <span>{{ $t('registration.validations.password_required') }}</span>
                 </li>
               </ul>
             </div>
 
-            <div class='form-group' :class="{ 'form-group--error': $v.user.confirm.$error }">
-              <label class='form--label' for='sign-up-password-confirmation'>{{$t('registration.password_confirm')}}</label>
-              <input :disabled="isPending" v-model='user.confirm' class='form-control' id='sign-up-password-confirmation' type='password'>
+            <div
+              class="form-group"
+              :class="{ 'form-group--error': $v.user.confirm.$error }"
+            >
+              <label
+                class="form--label"
+                for="sign-up-password-confirmation"
+              >{{ $t('registration.password_confirm') }}</label>
+              <input
+                id="sign-up-password-confirmation"
+                v-model="user.confirm"
+                :disabled="isPending"
+                class="form-control"
+                type="password"
+              >
             </div>
-            <div class="form-error" v-if="$v.user.confirm.$dirty">
+            <div
+              v-if="$v.user.confirm.$dirty"
+              class="form-error"
+            >
               <ul>
                 <li v-if="!$v.user.confirm.required">
-                  <span>{{$t('registration.validations.password_confirmation_required')}}</span>
+                  <span>{{ $t('registration.validations.password_confirmation_required') }}</span>
                 </li>
                 <li v-if="!$v.user.confirm.sameAsPassword">
-                  <span>{{$t('registration.validations.password_confirmation_match')}}</span>
+                  <span>{{ $t('registration.validations.password_confirmation_match') }}</span>
                 </li>
               </ul>
             </div>
 
-            <div class="form-group" id="captcha-group" v-if="captcha.type != 'none'">
-              <label class='form--label' for='captcha-label'>{{$t('captcha')}}</label>
+            <div
+              v-if="captcha.type != 'none'"
+              id="captcha-group"
+              class="form-group"
+            >
+              <label
+                class="form--label"
+                for="captcha-label"
+              >{{ $t('captcha') }}</label>
 
               <template v-if="captcha.type == 'kocaptcha'">
-                <img v-bind:src="captcha.url" v-on:click="setCaptcha">
+                <img
+                  :src="captcha.url"
+                  @click="setCaptcha"
+                >
 
-                <sub>{{$t('registration.new_captcha')}}</sub>
+                <sub>{{ $t('registration.new_captcha') }}</sub>
 
-                <input :disabled="isPending"
-                  v-model='captcha.solution'
-                  class='form-control' id='captcha-answer' type='text' autocomplete="off">
+                <input
+                  id="captcha-answer"
+                  v-model="captcha.solution"
+                  :disabled="isPending"
+                  class="form-control"
+                  type="text"
+                  autocomplete="off"
+                >
               </template>
             </div>
 
-            <div class='form-group' v-if='token' >
-              <label for='token'>{{$t('registration.token')}}</label>
-              <input disabled='true' v-model='token' class='form-control' id='token' type='text'>
+            <div
+              v-if="token"
+              class="form-group"
+            >
+              <label for="token">{{ $t('registration.token') }}</label>
+              <input
+                id="token"
+                v-model="token"
+                disabled="true"
+                class="form-control"
+                type="text"
+              >
             </div>
-            <div class='form-group'>
-              <button :disabled="isPending" type='submit' class='btn btn-default'>{{$t('general.submit')}}</button>
+            <div class="form-group">
+              <button
+                :disabled="isPending"
+                type="submit"
+                class="btn btn-default"
+              >
+                {{ $t('general.submit') }}
+              </button>
             </div>
           </div>
 
-          <div class='terms-of-service' v-html="termsOfService">
-          </div>
+          <div
+            class="terms-of-service"
+            v-html="termsOfService"
+          />
         </div>
-        <div v-if="serverValidationErrors.length" class='form-group'>
-          <div class='alert error'>
-            <span v-for="error in serverValidationErrors">{{error}}</span>
+        <div
+          v-if="serverValidationErrors.length"
+          class="form-group"
+        >
+          <div class="alert error">
+            <span v-for="error in serverValidationErrors">{{ error }}</span>
           </div>
         </div>
       </form>
diff --git a/src/components/remote_follow/remote_follow.vue b/src/components/remote_follow/remote_follow.vue
index fb2147bd..cb1c2a1b 100644
--- a/src/components/remote_follow/remote_follow.vue
+++ b/src/components/remote_follow/remote_follow.vue
@@ -1,9 +1,23 @@
 <template>
   <div class="remote-follow">
-    <form method="POST" :action='subscribeUrl'>
-      <input type="hidden" name="nickname" :value="user.screen_name">
-      <input type="hidden" name="profile" value="">
-      <button click="submit" class="remote-button">
+    <form
+      method="POST"
+      :action="subscribeUrl"
+    >
+      <input
+        type="hidden"
+        name="nickname"
+        :value="user.screen_name"
+      >
+      <input
+        type="hidden"
+        name="profile"
+        value=""
+      >
+      <button
+        click="submit"
+        class="remote-button"
+      >
         {{ $t('user_card.remote_follow') }}
       </button>
     </form>
diff --git a/src/components/retweet_button/retweet_button.vue b/src/components/retweet_button/retweet_button.vue
index 6370f9dc..d58a7f8c 100644
--- a/src/components/retweet_button/retweet_button.vue
+++ b/src/components/retweet_button/retweet_button.vue
@@ -1,16 +1,29 @@
 <template>
   <div v-if="loggedIn">
     <template v-if="visibility !== 'private' && visibility !== 'direct'">
-      <i :class='classes' class='button-icon retweet-button icon-retweet rt-active' v-on:click.prevent='retweet()' :title="$t('tool_tip.repeat')"></i>
-      <span v-if='!hidePostStatsLocal && status.repeat_num > 0'>{{status.repeat_num}}</span>
+      <i
+        :class="classes"
+        class="button-icon retweet-button icon-retweet rt-active"
+        :title="$t('tool_tip.repeat')"
+        @click.prevent="retweet()"
+      />
+      <span v-if="!hidePostStatsLocal && status.repeat_num > 0">{{ status.repeat_num }}</span>
     </template>
     <template v-else>
-      <i :class='classes' class='button-icon icon-lock' :title="$t('timeline.no_retweet_hint')"></i>
+      <i
+        :class="classes"
+        class="button-icon icon-lock"
+        :title="$t('timeline.no_retweet_hint')"
+      />
     </template>
   </div>
   <div v-else-if="!loggedIn">
-    <i :class='classes' class='button-icon icon-retweet' :title="$t('tool_tip.repeat')"></i>
-    <span v-if='!hidePostStatsLocal && status.repeat_num > 0'>{{status.repeat_num}}</span>
+    <i
+      :class="classes"
+      class="button-icon icon-retweet"
+      :title="$t('tool_tip.repeat')"
+    />
+    <span v-if="!hidePostStatsLocal && status.repeat_num > 0">{{ status.repeat_num }}</span>
   </div>
 </template>
 
diff --git a/src/components/scope_selector/scope_selector.vue b/src/components/scope_selector/scope_selector.vue
index 5ebb5d56..291236f2 100644
--- a/src/components/scope_selector/scope_selector.vue
+++ b/src/components/scope_selector/scope_selector.vue
@@ -1,30 +1,37 @@
 <template>
-<div v-if="!showNothing" class="scope-selector">
-  <i class="icon-mail-alt"
-     :class="css.direct"
-     :title="$t('post_status.scope.direct')"
-     v-if="showDirect"
-     @click="changeVis('direct')">
-  </i>
-  <i class="icon-lock"
-     :class="css.private"
-     :title="$t('post_status.scope.private')"
-     v-if="showPrivate"
-     v-on:click="changeVis('private')">
-  </i>
-  <i class="icon-lock-open-alt"
-     :class="css.unlisted"
-     :title="$t('post_status.scope.unlisted')"
-     v-if="showUnlisted"
-     @click="changeVis('unlisted')">
-  </i>
-  <i class="icon-globe"
-     :class="css.public"
-     :title="$t('post_status.scope.public')"
-     v-if="showPublic"
-     @click="changeVis('public')">
-  </i>
-</div>
+  <div
+    v-if="!showNothing"
+    class="scope-selector"
+  >
+    <i
+      v-if="showDirect"
+      class="icon-mail-alt"
+      :class="css.direct"
+      :title="$t('post_status.scope.direct')"
+      @click="changeVis('direct')"
+    />
+    <i
+      v-if="showPrivate"
+      class="icon-lock"
+      :class="css.private"
+      :title="$t('post_status.scope.private')"
+      @click="changeVis('private')"
+    />
+    <i
+      v-if="showUnlisted"
+      class="icon-lock-open-alt"
+      :class="css.unlisted"
+      :title="$t('post_status.scope.unlisted')"
+      @click="changeVis('unlisted')"
+    />
+    <i
+      v-if="showPublic"
+      class="icon-globe"
+      :class="css.public"
+      :title="$t('post_status.scope.public')"
+      @click="changeVis('public')"
+    />
+  </div>
 </template>
 
 <script src="./scope_selector.js"></script>
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index 3f16c921..d9ec7ece 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -1,23 +1,52 @@
 <template>
   <div class="selectable-list">
-    <div class="selectable-list-header" v-if="items.length > 0">
+    <div
+      v-if="items.length > 0"
+      class="selectable-list-header"
+    >
       <div class="selectable-list-checkbox-wrapper">
-        <Checkbox :checked="allSelected" @change="toggleAll" :indeterminate="someSelected">{{ $t('selectable_list.select_all') }}</Checkbox>
+        <Checkbox
+          :checked="allSelected"
+          :indeterminate="someSelected"
+          @change="toggleAll"
+        >
+          {{ $t('selectable_list.select_all') }}
+        </Checkbox>
       </div>
       <div class="selectable-list-header-actions">
-        <slot name="header" :selected="filteredSelected" />
+        <slot
+          name="header"
+          :selected="filteredSelected"
+        />
       </div>
     </div>
-    <List :items="items" :getKey="getKey">
-      <template slot="item" slot-scope="{item}">
-        <div class="selectable-list-item-inner" :class="{ 'selectable-list-item-selected-inner': isSelected(item) }">
+    <List
+      :items="items"
+      :get-key="getKey"
+    >
+      <template
+        slot="item"
+        slot-scope="{item}"
+      >
+        <div
+          class="selectable-list-item-inner"
+          :class="{ 'selectable-list-item-selected-inner': isSelected(item) }"
+        >
           <div class="selectable-list-checkbox-wrapper">
-            <Checkbox :checked="isSelected(item)" @change="checked => toggle(checked, item)" />
+            <Checkbox
+              :checked="isSelected(item)"
+              @change="checked => toggle(checked, item)"
+            />
           </div>
-          <slot name="item" :item="item" />
+          <slot
+            name="item"
+            :item="item"
+          />
         </div>
       </template>
-      <template slot="empty"><slot name="empty" /></template>
+      <template slot="empty">
+        <slot name="empty" />
+      </template>
     </List>
   </div>
 </template>
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 528c13cc..744ec566 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -1,305 +1,483 @@
 <template>
-<div class="settings panel panel-default">
-  <div class="panel-heading">
-    <div class="title">
-      {{$t('settings.settings')}}
-    </div>
+  <div class="settings panel panel-default">
+    <div class="panel-heading">
+      <div class="title">
+        {{ $t('settings.settings') }}
+      </div>
 
-    <transition name="fade">
-      <template v-if="currentSaveStateNotice">
-        <div @click.prevent class="alert error" v-if="currentSaveStateNotice.error">
-          {{ $t('settings.saving_err') }}
-        </div>
+      <transition name="fade">
+        <template v-if="currentSaveStateNotice">
+          <div
+            v-if="currentSaveStateNotice.error"
+            class="alert error"
+            @click.prevent
+          >
+            {{ $t('settings.saving_err') }}
+          </div>
 
-        <div @click.prevent class="alert transparent" v-if="!currentSaveStateNotice.error">
-          {{ $t('settings.saving_ok') }}
-        </div>
-      </template>
-    </transition>
-  </div>
-  <div class="panel-body">
-<keep-alive>
-    <tab-switcher>
-      <div :label="$t('settings.general')" >
-        <div class="setting-item">
-          <h2>{{ $t('settings.interface') }}</h2>
-          <ul class="setting-list">
-            <li>
-              <interface-language-switcher />
-            </li>
-            <li v-if="instanceSpecificPanelPresent">
-              <input type="checkbox" id="hideISP" v-model="hideISPLocal">
-              <label for="hideISP">{{$t('settings.hide_isp')}}</label>
-            </li>
-          </ul>
-        </div>
-        <div class="setting-item">
-          <h2>{{$t('nav.timeline')}}</h2>
-          <ul class="setting-list">
-            <li>
-              <input type="checkbox" id="hideMutedPosts" v-model="hideMutedPostsLocal">
-              <label for="hideMutedPosts">{{$t('settings.hide_muted_posts')}} {{$t('settings.instance_default', { value: hideMutedPostsDefault })}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="collapseMessageWithSubject" v-model="collapseMessageWithSubjectLocal">
-              <label for="collapseMessageWithSubject">{{$t('settings.collapse_subject')}} {{$t('settings.instance_default', { value: collapseMessageWithSubjectDefault })}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="streaming" v-model="streamingLocal">
-              <label for="streaming">{{$t('settings.streaming')}}</label>
-              <ul class="setting-list suboptions" :class="[{disabled: !streamingLocal}]">
+          <div
+            v-if="!currentSaveStateNotice.error"
+            class="alert transparent"
+            @click.prevent
+          >
+            {{ $t('settings.saving_ok') }}
+          </div>
+        </template>
+      </transition>
+    </div>
+    <div class="panel-body">
+      <keep-alive>
+        <tab-switcher>
+          <div :label="$t('settings.general')">
+            <div class="setting-item">
+              <h2>{{ $t('settings.interface') }}</h2>
+              <ul class="setting-list">
                 <li>
-                  <input :disabled="!streamingLocal" type="checkbox" id="pauseOnUnfocused" v-model="pauseOnUnfocusedLocal">
-                  <label for="pauseOnUnfocused">{{$t('settings.pause_on_unfocused')}}</label>
+                  <interface-language-switcher />
+                </li>
+                <li v-if="instanceSpecificPanelPresent">
+                  <input
+                    id="hideISP"
+                    v-model="hideISPLocal"
+                    type="checkbox"
+                  >
+                  <label for="hideISP">{{ $t('settings.hide_isp') }}</label>
                 </li>
               </ul>
-            </li>
-            <li>
-              <input type="checkbox" id="autoload" v-model="autoLoadLocal">
-              <label for="autoload">{{$t('settings.autoload')}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal">
-              <label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label>
-            </li>
-          </ul>
-        </div>
-
-        <div class="setting-item">
-          <h2>{{$t('settings.composing')}}</h2>
-          <ul class="setting-list">
-            <li>
-              <input type="checkbox" id="scopeCopy" v-model="scopeCopyLocal">
-              <label for="scopeCopy">
-                {{$t('settings.scope_copy')}} {{$t('settings.instance_default', { value: scopeCopyDefault })}}
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="subjectHide" v-model="alwaysShowSubjectInputLocal">
-              <label for="subjectHide">
-                {{$t('settings.subject_input_always_show')}} {{$t('settings.instance_default', { value: alwaysShowSubjectInputDefault })}}
-              </label>
-            </li>
-            <li>
-              <div>
-                {{$t('settings.subject_line_behavior')}}
-                <label for="subjectLineBehavior" class="select">
-                  <select id="subjectLineBehavior" v-model="subjectLineBehaviorLocal">
-                    <option value="email">
-                      {{$t('settings.subject_line_email')}}
-                      {{subjectLineBehaviorDefault == 'email' ? $t('settings.instance_default_simple') : ''}}
-                    </option>
-                    <option value="masto">
-                      {{$t('settings.subject_line_mastodon')}}
-                      {{subjectLineBehaviorDefault == 'mastodon' ? $t('settings.instance_default_simple') : ''}}
-                    </option>
-                    <option value="noop">
-                      {{$t('settings.subject_line_noop')}}
-                      {{subjectLineBehaviorDefault == 'noop' ? $t('settings.instance_default_simple') : ''}}
-                    </option>
-                  </select>
-                  <i class="icon-down-open"/>
-                </label>
-              </div>
-            </li>
-            <li v-if="postFormats.length > 0">
-              <div>
-                {{$t('settings.post_status_content_type')}}
-                <label for="postContentType" class="select">
-                  <select id="postContentType" v-model="postContentTypeLocal">
-                    <option v-for="postFormat in postFormats" :key="postFormat" :value="postFormat">
-                      {{$t(`post_status.content_type["${postFormat}"]`)}}
-                      {{postContentTypeDefault === postFormat ? $t('settings.instance_default_simple') : ''}}
-                    </option>
-                  </select>
-                  <i class="icon-down-open"/>
-                </label>
-              </div>
-            </li>
-            <li>
-              <input type="checkbox" id="minimalScopesMode" v-model="minimalScopesModeLocal">
-              <label for="minimalScopesMode">
-                {{$t('settings.minimal_scopes_mode')}} {{$t('settings.instance_default', { value: minimalScopesModeDefault })}}
-              </label>
-            </li>
-            <li>
-              <input type="checkbox" id="autohideFloatingPostButton" v-model="autohideFloatingPostButtonLocal">
-              <label for="autohideFloatingPostButton">{{$t('settings.autohide_floating_post_button')}}</label>
-            </li>
-          </ul>
-        </div>
+            </div>
+            <div class="setting-item">
+              <h2>{{ $t('nav.timeline') }}</h2>
+              <ul class="setting-list">
+                <li>
+                  <input
+                    id="hideMutedPosts"
+                    v-model="hideMutedPostsLocal"
+                    type="checkbox"
+                  >
+                  <label for="hideMutedPosts">{{ $t('settings.hide_muted_posts') }} {{ $t('settings.instance_default', { value: hideMutedPostsDefault }) }}</label>
+                </li>
+                <li>
+                  <input
+                    id="collapseMessageWithSubject"
+                    v-model="collapseMessageWithSubjectLocal"
+                    type="checkbox"
+                  >
+                  <label for="collapseMessageWithSubject">{{ $t('settings.collapse_subject') }} {{ $t('settings.instance_default', { value: collapseMessageWithSubjectDefault }) }}</label>
+                </li>
+                <li>
+                  <input
+                    id="streaming"
+                    v-model="streamingLocal"
+                    type="checkbox"
+                  >
+                  <label for="streaming">{{ $t('settings.streaming') }}</label>
+                  <ul
+                    class="setting-list suboptions"
+                    :class="[{disabled: !streamingLocal}]"
+                  >
+                    <li>
+                      <input
+                        id="pauseOnUnfocused"
+                        v-model="pauseOnUnfocusedLocal"
+                        :disabled="!streamingLocal"
+                        type="checkbox"
+                      >
+                      <label for="pauseOnUnfocused">{{ $t('settings.pause_on_unfocused') }}</label>
+                    </li>
+                  </ul>
+                </li>
+                <li>
+                  <input
+                    id="autoload"
+                    v-model="autoLoadLocal"
+                    type="checkbox"
+                  >
+                  <label for="autoload">{{ $t('settings.autoload') }}</label>
+                </li>
+                <li>
+                  <input
+                    id="hoverPreview"
+                    v-model="hoverPreviewLocal"
+                    type="checkbox"
+                  >
+                  <label for="hoverPreview">{{ $t('settings.reply_link_preview') }}</label>
+                </li>
+              </ul>
+            </div>
 
-        <div class="setting-item">
-          <h2>{{$t('settings.attachments')}}</h2>
-          <ul class="setting-list">
-            <li>
-              <input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal">
-              <label for="hideAttachments">{{$t('settings.hide_attachments_in_tl')}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="hideAttachmentsInConv" v-model="hideAttachmentsInConvLocal">
-              <label for="hideAttachmentsInConv">{{$t('settings.hide_attachments_in_convo')}}</label>
-            </li>
-            <li>
-              <label for="maxThumbnails">{{$t('settings.max_thumbnails')}}</label>
-              <input class="number-input" type="number" id="maxThumbnails" v-model.number="maxThumbnails" min="0" step="1">
-            </li>
-            <li>
-              <input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal">
-              <label for="hideNsfw">{{$t('settings.nsfw_clickthrough')}}</label>
-            </li>
-            <ul class="setting-list suboptions" >
-              <li>
-                <input :disabled="!hideNsfwLocal" type="checkbox" id="preloadImage" v-model="preloadImage">
-                <label for="preloadImage">{{$t('settings.preload_images')}}</label>
-              </li>
-              <li>
-                <input :disabled="!hideNsfwLocal" type="checkbox" id="useOneClickNsfw" v-model="useOneClickNsfw">
-                <label for="useOneClickNsfw">{{$t('settings.use_one_click_nsfw')}}</label>
-              </li>
-            </ul>
-            <li>
-              <input type="checkbox" id="stopGifs" v-model="stopGifs">
-              <label for="stopGifs">{{$t('settings.stop_gifs')}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="loopVideo" v-model="loopVideoLocal">
-              <label for="loopVideo">{{$t('settings.loop_video')}}</label>
-              <ul class="setting-list suboptions" :class="[{disabled: !streamingLocal}]">
+            <div class="setting-item">
+              <h2>{{ $t('settings.composing') }}</h2>
+              <ul class="setting-list">
                 <li>
-                  <input :disabled="!loopVideoLocal || !loopSilentAvailable" type="checkbox" id="loopVideoSilentOnly" v-model="loopVideoSilentOnlyLocal">
-                  <label for="loopVideoSilentOnly">{{$t('settings.loop_video_silent_only')}}</label>
-                  <div v-if="!loopSilentAvailable" class="unavailable">
-                    <i class="icon-globe"/>! {{$t('settings.limited_availability')}}
+                  <input
+                    id="scopeCopy"
+                    v-model="scopeCopyLocal"
+                    type="checkbox"
+                  >
+                  <label for="scopeCopy">
+                    {{ $t('settings.scope_copy') }} {{ $t('settings.instance_default', { value: scopeCopyDefault }) }}
+                  </label>
+                </li>
+                <li>
+                  <input
+                    id="subjectHide"
+                    v-model="alwaysShowSubjectInputLocal"
+                    type="checkbox"
+                  >
+                  <label for="subjectHide">
+                    {{ $t('settings.subject_input_always_show') }} {{ $t('settings.instance_default', { value: alwaysShowSubjectInputDefault }) }}
+                  </label>
+                </li>
+                <li>
+                  <div>
+                    {{ $t('settings.subject_line_behavior') }}
+                    <label
+                      for="subjectLineBehavior"
+                      class="select"
+                    >
+                      <select
+                        id="subjectLineBehavior"
+                        v-model="subjectLineBehaviorLocal"
+                      >
+                        <option value="email">
+                          {{ $t('settings.subject_line_email') }}
+                          {{ subjectLineBehaviorDefault == 'email' ? $t('settings.instance_default_simple') : '' }}
+                        </option>
+                        <option value="masto">
+                          {{ $t('settings.subject_line_mastodon') }}
+                          {{ subjectLineBehaviorDefault == 'mastodon' ? $t('settings.instance_default_simple') : '' }}
+                        </option>
+                        <option value="noop">
+                          {{ $t('settings.subject_line_noop') }}
+                          {{ subjectLineBehaviorDefault == 'noop' ? $t('settings.instance_default_simple') : '' }}
+                        </option>
+                      </select>
+                      <i class="icon-down-open" />
+                    </label>
                   </div>
                 </li>
+                <li v-if="postFormats.length > 0">
+                  <div>
+                    {{ $t('settings.post_status_content_type') }}
+                    <label
+                      for="postContentType"
+                      class="select"
+                    >
+                      <select
+                        id="postContentType"
+                        v-model="postContentTypeLocal"
+                      >
+                        <option
+                          v-for="postFormat in postFormats"
+                          :key="postFormat"
+                          :value="postFormat"
+                        >
+                          {{ $t(`post_status.content_type["${postFormat}"]`) }}
+                          {{ postContentTypeDefault === postFormat ? $t('settings.instance_default_simple') : '' }}
+                        </option>
+                      </select>
+                      <i class="icon-down-open" />
+                    </label>
+                  </div>
+                </li>
+                <li>
+                  <input
+                    id="minimalScopesMode"
+                    v-model="minimalScopesModeLocal"
+                    type="checkbox"
+                  >
+                  <label for="minimalScopesMode">
+                    {{ $t('settings.minimal_scopes_mode') }} {{ $t('settings.instance_default', { value: minimalScopesModeDefault }) }}
+                  </label>
+                </li>
+                <li>
+                  <input
+                    id="autohideFloatingPostButton"
+                    v-model="autohideFloatingPostButtonLocal"
+                    type="checkbox"
+                  >
+                  <label for="autohideFloatingPostButton">{{ $t('settings.autohide_floating_post_button') }}</label>
+                </li>
               </ul>
-            </li>
-            <li>
-              <input type="checkbox" id="playVideosInModal" v-model="playVideosInModal">
-              <label for="playVideosInModal">{{$t('settings.play_videos_in_modal')}}</label>
-            </li>
-            <li>
-              <input type="checkbox" id="useContainFit" v-model="useContainFit">
-              <label for="useContainFit">{{$t('settings.use_contain_fit')}}</label>
-            </li>
-          </ul>
-        </div>
+            </div>
 
-       <div class="setting-item">
-          <h2>{{$t('settings.notifications')}}</h2>
-          <ul class="setting-list">
-            <li>
-              <input type="checkbox" id="webPushNotifications" v-model="webPushNotificationsLocal">
-              <label for="webPushNotifications">
-                {{$t('settings.enable_web_push_notifications')}}
-              </label>
-            </li>
-          </ul>
-        </div>
-      </div>
+            <div class="setting-item">
+              <h2>{{ $t('settings.attachments') }}</h2>
+              <ul class="setting-list">
+                <li>
+                  <input
+                    id="hideAttachments"
+                    v-model="hideAttachmentsLocal"
+                    type="checkbox"
+                  >
+                  <label for="hideAttachments">{{ $t('settings.hide_attachments_in_tl') }}</label>
+                </li>
+                <li>
+                  <input
+                    id="hideAttachmentsInConv"
+                    v-model="hideAttachmentsInConvLocal"
+                    type="checkbox"
+                  >
+                  <label for="hideAttachmentsInConv">{{ $t('settings.hide_attachments_in_convo') }}</label>
+                </li>
+                <li>
+                  <label for="maxThumbnails">{{ $t('settings.max_thumbnails') }}</label>
+                  <input
+                    id="maxThumbnails"
+                    v-model.number="maxThumbnails"
+                    class="number-input"
+                    type="number"
+                    min="0"
+                    step="1"
+                  >
+                </li>
+                <li>
+                  <input
+                    id="hideNsfw"
+                    v-model="hideNsfwLocal"
+                    type="checkbox"
+                  >
+                  <label for="hideNsfw">{{ $t('settings.nsfw_clickthrough') }}</label>
+                </li>
+                <ul class="setting-list suboptions">
+                  <li>
+                    <input
+                      id="preloadImage"
+                      v-model="preloadImage"
+                      :disabled="!hideNsfwLocal"
+                      type="checkbox"
+                    >
+                    <label for="preloadImage">{{ $t('settings.preload_images') }}</label>
+                  </li>
+                  <li>
+                    <input
+                      id="useOneClickNsfw"
+                      v-model="useOneClickNsfw"
+                      :disabled="!hideNsfwLocal"
+                      type="checkbox"
+                    >
+                    <label for="useOneClickNsfw">{{ $t('settings.use_one_click_nsfw') }}</label>
+                  </li>
+                </ul>
+                <li>
+                  <input
+                    id="stopGifs"
+                    v-model="stopGifs"
+                    type="checkbox"
+                  >
+                  <label for="stopGifs">{{ $t('settings.stop_gifs') }}</label>
+                </li>
+                <li>
+                  <input
+                    id="loopVideo"
+                    v-model="loopVideoLocal"
+                    type="checkbox"
+                  >
+                  <label for="loopVideo">{{ $t('settings.loop_video') }}</label>
+                  <ul
+                    class="setting-list suboptions"
+                    :class="[{disabled: !streamingLocal}]"
+                  >
+                    <li>
+                      <input
+                        id="loopVideoSilentOnly"
+                        v-model="loopVideoSilentOnlyLocal"
+                        :disabled="!loopVideoLocal || !loopSilentAvailable"
+                        type="checkbox"
+                      >
+                      <label for="loopVideoSilentOnly">{{ $t('settings.loop_video_silent_only') }}</label>
+                      <div
+                        v-if="!loopSilentAvailable"
+                        class="unavailable"
+                      >
+                        <i class="icon-globe" />! {{ $t('settings.limited_availability') }}
+                      </div>
+                    </li>
+                  </ul>
+                </li>
+                <li>
+                  <input
+                    id="playVideosInModal"
+                    v-model="playVideosInModal"
+                    type="checkbox"
+                  >
+                  <label for="playVideosInModal">{{ $t('settings.play_videos_in_modal') }}</label>
+                </li>
+                <li>
+                  <input
+                    id="useContainFit"
+                    v-model="useContainFit"
+                    type="checkbox"
+                  >
+                  <label for="useContainFit">{{ $t('settings.use_contain_fit') }}</label>
+                </li>
+              </ul>
+            </div>
 
-      <div :label="$t('settings.theme')" >
-        <div class="setting-item">
-          <style-switcher></style-switcher>
-        </div>
-      </div>
+            <div class="setting-item">
+              <h2>{{ $t('settings.notifications') }}</h2>
+              <ul class="setting-list">
+                <li>
+                  <input
+                    id="webPushNotifications"
+                    v-model="webPushNotificationsLocal"
+                    type="checkbox"
+                  >
+                  <label for="webPushNotifications">
+                    {{ $t('settings.enable_web_push_notifications') }}
+                  </label>
+                </li>
+              </ul>
+            </div>
+          </div>
 
-      <div :label="$t('settings.filtering')" >
-        <div class="setting-item">
-          <div class="select-multiple">
-            <span class="label">{{$t('settings.notification_visibility')}}</span>
-            <ul class="option-list">
-              <li>
-                <input type="checkbox" id="notification-visibility-likes" v-model="notificationVisibilityLocal.likes">
-                <label for="notification-visibility-likes">
-                  {{$t('settings.notification_visibility_likes')}}
+          <div :label="$t('settings.theme')">
+            <div class="setting-item">
+              <style-switcher />
+            </div>
+          </div>
+
+          <div :label="$t('settings.filtering')">
+            <div class="setting-item">
+              <div class="select-multiple">
+                <span class="label">{{ $t('settings.notification_visibility') }}</span>
+                <ul class="option-list">
+                  <li>
+                    <input
+                      id="notification-visibility-likes"
+                      v-model="notificationVisibilityLocal.likes"
+                      type="checkbox"
+                    >
+                    <label for="notification-visibility-likes">
+                      {{ $t('settings.notification_visibility_likes') }}
+                    </label>
+                  </li>
+                  <li>
+                    <input
+                      id="notification-visibility-repeats"
+                      v-model="notificationVisibilityLocal.repeats"
+                      type="checkbox"
+                    >
+                    <label for="notification-visibility-repeats">
+                      {{ $t('settings.notification_visibility_repeats') }}
+                    </label>
+                  </li>
+                  <li>
+                    <input
+                      id="notification-visibility-follows"
+                      v-model="notificationVisibilityLocal.follows"
+                      type="checkbox"
+                    >
+                    <label for="notification-visibility-follows">
+                      {{ $t('settings.notification_visibility_follows') }}
+                    </label>
+                  </li>
+                  <li>
+                    <input
+                      id="notification-visibility-mentions"
+                      v-model="notificationVisibilityLocal.mentions"
+                      type="checkbox"
+                    >
+                    <label for="notification-visibility-mentions">
+                      {{ $t('settings.notification_visibility_mentions') }}
+                    </label>
+                  </li>
+                </ul>
+              </div>
+              <div>
+                {{ $t('settings.replies_in_timeline') }}
+                <label
+                  for="replyVisibility"
+                  class="select"
+                >
+                  <select
+                    id="replyVisibility"
+                    v-model="replyVisibilityLocal"
+                  >
+                    <option
+                      value="all"
+                      selected
+                    >{{ $t('settings.reply_visibility_all') }}</option>
+                    <option value="following">{{ $t('settings.reply_visibility_following') }}</option>
+                    <option value="self">{{ $t('settings.reply_visibility_self') }}</option>
+                  </select>
+                  <i class="icon-down-open" />
                 </label>
-              </li>
-              <li>
-                <input type="checkbox" id="notification-visibility-repeats" v-model="notificationVisibilityLocal.repeats">
-                <label for="notification-visibility-repeats">
-                {{$t('settings.notification_visibility_repeats')}}
+              </div>
+              <div>
+                <input
+                  id="hidePostStats"
+                  v-model="hidePostStatsLocal"
+                  type="checkbox"
+                >
+                <label for="hidePostStats">
+                  {{ $t('settings.hide_post_stats') }} {{ $t('settings.instance_default', { value: hidePostStatsDefault }) }}
                 </label>
-              </li>
-              <li>
-                <input type="checkbox" id="notification-visibility-follows" v-model="notificationVisibilityLocal.follows">
-                <label for="notification-visibility-follows">
-                {{$t('settings.notification_visibility_follows')}}
+              </div>
+              <div>
+                <input
+                  id="hideUserStats"
+                  v-model="hideUserStatsLocal"
+                  type="checkbox"
+                >
+                <label for="hideUserStats">
+                  {{ $t('settings.hide_user_stats') }} {{ $t('settings.instance_default', { value: hideUserStatsDefault }) }}
                 </label>
-              </li>
-              <li>
-                <input type="checkbox" id="notification-visibility-mentions" v-model="notificationVisibilityLocal.mentions">
-                <label for="notification-visibility-mentions">
-                {{$t('settings.notification_visibility_mentions')}}
+              </div>
+            </div>
+            <div class="setting-item">
+              <div>
+                <p>{{ $t('settings.filtering_explanation') }}</p>
+                <textarea
+                  id="muteWords"
+                  v-model="muteWordsString"
+                />
+              </div>
+              <div>
+                <input
+                  id="hideFilteredStatuses"
+                  v-model="hideFilteredStatusesLocal"
+                  type="checkbox"
+                >
+                <label for="hideFilteredStatuses">
+                  {{ $t('settings.hide_filtered_statuses') }} {{ $t('settings.instance_default', { value: hideFilteredStatusesDefault }) }}
                 </label>
-              </li>
-            </ul>
-          </div>
-          <div>
-            {{$t('settings.replies_in_timeline')}}
-            <label for="replyVisibility" class="select">
-              <select id="replyVisibility" v-model="replyVisibilityLocal">
-                <option value="all" selected>{{$t('settings.reply_visibility_all')}}</option>
-                <option value="following">{{$t('settings.reply_visibility_following')}}</option>
-                <option value="self">{{$t('settings.reply_visibility_self')}}</option>
-              </select>
-              <i class="icon-down-open"/>
-            </label>
-          </div>
-          <div>
-            <input type="checkbox" id="hidePostStats" v-model="hidePostStatsLocal">
-            <label for="hidePostStats">
-              {{$t('settings.hide_post_stats')}} {{$t('settings.instance_default', { value: hidePostStatsDefault })}}
-            </label>
-          </div>
-          <div>
-            <input type="checkbox" id="hideUserStats" v-model="hideUserStatsLocal">
-            <label for="hideUserStats">
-              {{$t('settings.hide_user_stats')}} {{$t('settings.instance_default', { value: hideUserStatsDefault })}}
-            </label>
-          </div>
-        </div>
-        <div class="setting-item">
-          <div>
-            <p>{{$t('settings.filtering_explanation')}}</p>
-            <textarea id="muteWords" v-model="muteWordsString"></textarea>
-          </div>
-          <div>
-            <input type="checkbox" id="hideFilteredStatuses" v-model="hideFilteredStatusesLocal">
-            <label for="hideFilteredStatuses">
-              {{$t('settings.hide_filtered_statuses')}} {{$t('settings.instance_default', { value: hideFilteredStatusesDefault })}}
-            </label>
+              </div>
+            </div>
           </div>
-        </div>
-      </div>
-      <div :label="$t('settings.version.title')" >
-        <div class="setting-item">
-          <ul class="setting-list">
-            <li>
-              <p>{{$t('settings.version.backend_version')}}</p>
-              <ul class="option-list">
+          <div :label="$t('settings.version.title')">
+            <div class="setting-item">
+              <ul class="setting-list">
                 <li>
-                  <a :href="backendVersionLink" target="_blank">{{backendVersion}}</a>
+                  <p>{{ $t('settings.version.backend_version') }}</p>
+                  <ul class="option-list">
+                    <li>
+                      <a
+                        :href="backendVersionLink"
+                        target="_blank"
+                      >{{ backendVersion }}</a>
+                    </li>
+                  </ul>
                 </li>
-              </ul>
-            </li>
-            <li>
-              <p>{{$t('settings.version.frontend_version')}}</p>
-              <ul class="option-list">
                 <li>
-                  <a :href="frontendVersionLink" target="_blank">{{frontendVersion}}</a>
+                  <p>{{ $t('settings.version.frontend_version') }}</p>
+                  <ul class="option-list">
+                    <li>
+                      <a
+                        :href="frontendVersionLink"
+                        target="_blank"
+                      >{{ frontendVersion }}</a>
+                    </li>
+                  </ul>
                 </li>
               </ul>
-            </li>
-          </ul>
-        </div>
-      </div>
-    </tab-switcher>
-</keep-alive>
+            </div>
+          </div>
+        </tab-switcher>
+      </keep-alive>
+    </div>
   </div>
-</div>
 </template>
 
 <script src="./settings.js">
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index 744925d4..faefe1ff 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -1,134 +1,206 @@
 <template>
-<div class="shadow-control" :class="{ disabled: !present }">
-  <div class="shadow-preview-container">
-    <div :disabled="!present" class="y-shift-control">
-      <input
-        v-model="selected.y"
+  <div
+    class="shadow-control"
+    :class="{ disabled: !present }"
+  >
+    <div class="shadow-preview-container">
+      <div
         :disabled="!present"
-        class="input-number"
-        type="number">
-      <div class="wrap">
+        class="y-shift-control"
+      >
         <input
           v-model="selected.y"
           :disabled="!present"
-          class="input-range"
-          type="range"
-          max="20"
-          min="-20">
+          class="input-number"
+          type="number"
+        >
+        <div class="wrap">
+          <input
+            v-model="selected.y"
+            :disabled="!present"
+            class="input-range"
+            type="range"
+            max="20"
+            min="-20"
+          >
+        </div>
       </div>
-    </div>
-    <div class="preview-window">
-      <div class="preview-block" :style="style"></div>
-    </div>
-    <div :disabled="!present" class="x-shift-control">
-      <input
-        v-model="selected.x"
+      <div class="preview-window">
+        <div
+          class="preview-block"
+          :style="style"
+        />
+      </div>
+      <div
         :disabled="!present"
-        class="input-number"
-        type="number">
-      <div class="wrap">
+        class="x-shift-control"
+      >
         <input
           v-model="selected.x"
           :disabled="!present"
-          class="input-range"
-          type="range"
-          max="20"
-          min="-20">
+          class="input-number"
+          type="number"
+        >
+        <div class="wrap">
+          <input
+            v-model="selected.x"
+            :disabled="!present"
+            class="input-range"
+            type="range"
+            max="20"
+            min="-20"
+          >
+        </div>
       </div>
     </div>
-  </div>
 
-  <div class="shadow-tweak">
-    <div :disabled="usingFallback" class="id-control style-control">
-      <label for="shadow-switcher" class="select" :disabled="!ready || usingFallback">
-        <select
-          v-model="selectedId" class="shadow-switcher"
+    <div class="shadow-tweak">
+      <div
+        :disabled="usingFallback"
+        class="id-control style-control"
+      >
+        <label
+          for="shadow-switcher"
+          class="select"
           :disabled="!ready || usingFallback"
-          id="shadow-switcher">
-          <option v-for="(shadow, index) in cValue" :value="index">
-            {{$t('settings.style.shadows.shadow_id', { value: index })}}
-          </option>
-        </select>
-        <i class="icon-down-open"/>
-      </label>
-      <button class="btn btn-default" :disabled="!ready || !present" @click="del">
-        <i class="icon-cancel"/>
-      </button>
-      <button class="btn btn-default" :disabled="!moveUpValid" @click="moveUp">
-        <i class="icon-up-open"/>
-      </button>
-      <button class="btn btn-default" :disabled="!moveDnValid" @click="moveDn">
-        <i class="icon-down-open"/>
-      </button>
-      <button class="btn btn-default" :disabled="usingFallback" @click="add">
-        <i class="icon-plus"/>
-      </button>
-    </div>
-    <div :disabled="!present" class="inset-control style-control">
-      <label for="inset" class="label">
-        {{$t('settings.style.shadows.inset')}}
-      </label>
-      <input
-        v-model="selected.inset"
+        >
+          <select
+            id="shadow-switcher"
+            v-model="selectedId"
+            class="shadow-switcher"
+            :disabled="!ready || usingFallback"
+          >
+            <option
+              v-for="(shadow, index) in cValue"
+              :value="index"
+            >
+              {{ $t('settings.style.shadows.shadow_id', { value: index }) }}
+            </option>
+          </select>
+          <i class="icon-down-open" />
+        </label>
+        <button
+          class="btn btn-default"
+          :disabled="!ready || !present"
+          @click="del"
+        >
+          <i class="icon-cancel" />
+        </button>
+        <button
+          class="btn btn-default"
+          :disabled="!moveUpValid"
+          @click="moveUp"
+        >
+          <i class="icon-up-open" />
+        </button>
+        <button
+          class="btn btn-default"
+          :disabled="!moveDnValid"
+          @click="moveDn"
+        >
+          <i class="icon-down-open" />
+        </button>
+        <button
+          class="btn btn-default"
+          :disabled="usingFallback"
+          @click="add"
+        >
+          <i class="icon-plus" />
+        </button>
+      </div>
+      <div
         :disabled="!present"
-        name="inset"
-        id="inset"
-        class="input-inset"
-        type="checkbox">
-      <label class="checkbox-label" for="inset"></label>
-    </div>
-    <div :disabled="!present" class="blur-control style-control">
-      <label for="spread" class="label">
-        {{$t('settings.style.shadows.blur')}}
-      </label>
-      <input
-        v-model="selected.blur"
+        class="inset-control style-control"
+      >
+        <label
+          for="inset"
+          class="label"
+        >
+          {{ $t('settings.style.shadows.inset') }}
+        </label>
+        <input
+          id="inset"
+          v-model="selected.inset"
+          :disabled="!present"
+          name="inset"
+          class="input-inset"
+          type="checkbox"
+        >
+        <label
+          class="checkbox-label"
+          for="inset"
+        />
+      </div>
+      <div
         :disabled="!present"
-        name="blur"
-        id="blur"
-        class="input-range"
-        type="range"
-        max="20"
-        min="0">
-      <input
-        v-model="selected.blur"
+        class="blur-control style-control"
+      >
+        <label
+          for="spread"
+          class="label"
+        >
+          {{ $t('settings.style.shadows.blur') }}
+        </label>
+        <input
+          id="blur"
+          v-model="selected.blur"
+          :disabled="!present"
+          name="blur"
+          class="input-range"
+          type="range"
+          max="20"
+          min="0"
+        >
+        <input
+          v-model="selected.blur"
+          :disabled="!present"
+          class="input-number"
+          type="number"
+          min="0"
+        >
+      </div>
+      <div
         :disabled="!present"
-        class="input-number"
-        type="number"
-        min="0">
-    </div>
-    <div :disabled="!present" class="spread-control style-control">
-      <label for="spread" class="label">
-        {{$t('settings.style.shadows.spread')}}
-      </label>
-      <input
-        v-model="selected.spread"
+        class="spread-control style-control"
+      >
+        <label
+          for="spread"
+          class="label"
+        >
+          {{ $t('settings.style.shadows.spread') }}
+        </label>
+        <input
+          id="spread"
+          v-model="selected.spread"
+          :disabled="!present"
+          name="spread"
+          class="input-range"
+          type="range"
+          max="20"
+          min="-20"
+        >
+        <input
+          v-model="selected.spread"
+          :disabled="!present"
+          class="input-number"
+          type="number"
+        >
+      </div>
+      <ColorInput
+        v-model="selected.color"
         :disabled="!present"
-        name="spread"
-        id="spread"
-        class="input-range"
-        type="range"
-        max="20"
-        min="-20">
-      <input
-        v-model="selected.spread"
+        :label="$t('settings.style.common.color')"
+        name="shadow"
+      />
+      <OpacityInput
+        v-model="selected.alpha"
         :disabled="!present"
-        class="input-number"
-        type="number">
+      />
+      <p>
+        {{ $t('settings.style.shadows.hint') }}
+      </p>
     </div>
-    <ColorInput
-      v-model="selected.color"
-      :disabled="!present"
-      :label="$t('settings.style.common.color')"
-      name="shadow"/>
-    <OpacityInput
-      v-model="selected.alpha"
-      :disabled="!present"/>
-    <p>
-      {{$t('settings.style.shadows.hint')}}
-    </p>
   </div>
-</div>
 </template>
 
 <script src="./shadow_control.js" ></script>
diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue
index 6428b1b0..80b75ce5 100644
--- a/src/components/side_drawer/side_drawer.vue
+++ b/src/components/side_drawer/side_drawer.vue
@@ -1,63 +1,98 @@
 <template>
-  <div class="side-drawer-container"
+  <div
+    class="side-drawer-container"
     :class="{ 'side-drawer-container-closed': closed, 'side-drawer-container-open': !closed }"
   >
-    <div class="side-drawer-darken" :class="{ 'side-drawer-darken-closed': closed}" />
-    <div class="side-drawer"
+    <div
+      class="side-drawer-darken"
+      :class="{ 'side-drawer-darken-closed': closed}"
+    />
+    <div
+      class="side-drawer"
       :class="{'side-drawer-closed': closed}"
       @touchstart="touchStart"
       @touchmove="touchMove"
     >
-      <div class="side-drawer-heading" @click="toggleDrawer">
-        <UserCard :user="currentUser" :hideBio="true" v-if="currentUser"/>
-        <div class="side-drawer-logo-wrapper" v-else>
-          <img :src="logo"/>
-          <span>{{sitename}}</span>
+      <div
+        class="side-drawer-heading"
+        @click="toggleDrawer"
+      >
+        <UserCard
+          v-if="currentUser"
+          :user="currentUser"
+          :hide-bio="true"
+        />
+        <div
+          v-else
+          class="side-drawer-logo-wrapper"
+        >
+          <img :src="logo">
+          <span>{{ sitename }}</span>
         </div>
       </div>
       <ul>
-        <li v-if="!currentUser" @click="toggleDrawer">
+        <li
+          v-if="!currentUser"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'login' }">
             {{ $t("login.login") }}
           </router-link>
         </li>
-        <li v-if="currentUser" @click="toggleDrawer">
+        <li
+          v-if="currentUser"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
             {{ $t("nav.dms") }}
           </router-link>
         </li>
-        <li v-if="currentUser" @click="toggleDrawer">
+        <li
+          v-if="currentUser"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'interactions', params: { username: currentUser.screen_name } }">
             {{ $t("nav.interactions") }}
           </router-link>
         </li>
       </ul>
       <ul>
-        <li v-if="currentUser" @click="toggleDrawer">
+        <li
+          v-if="currentUser"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'friends' }">
             {{ $t("nav.timeline") }}
           </router-link>
         </li>
-        <li v-if="currentUser && currentUser.locked" @click="toggleDrawer">
-          <router-link to='/friend-requests'>
+        <li
+          v-if="currentUser && currentUser.locked"
+          @click="toggleDrawer"
+        >
+          <router-link to="/friend-requests">
             {{ $t("nav.friend_requests") }}
-            <span v-if='followRequestCount > 0' class="badge follow-request-count">
-              {{followRequestCount}}
+            <span
+              v-if="followRequestCount > 0"
+              class="badge follow-request-count"
+            >
+              {{ followRequestCount }}
             </span>
-
           </router-link>
         </li>
         <li @click="toggleDrawer">
-          <router-link to='/main/public'>
+          <router-link to="/main/public">
             {{ $t("nav.public_tl") }}
           </router-link>
         </li>
         <li @click="toggleDrawer">
-          <router-link to='/main/all'>
+          <router-link to="/main/all">
             {{ $t("nav.twkn") }}
           </router-link>
         </li>
-        <li v-if="currentUser && chat" @click="toggleDrawer">
+        <li
+          v-if="currentUser && chat"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'chat' }">
             {{ $t("nav.chat") }}
           </router-link>
@@ -69,7 +104,10 @@
             {{ $t("nav.user_search") }}
           </router-link>
         </li>
-        <li v-if="currentUser && suggestionsEnabled" @click="toggleDrawer">
+        <li
+          v-if="currentUser && suggestionsEnabled"
+          @click="toggleDrawer"
+        >
           <router-link :to="{ name: 'who-to-follow' }">
             {{ $t("nav.who_to_follow") }}
           </router-link>
@@ -84,17 +122,24 @@
             {{ $t("nav.about") }}
           </router-link>
         </li>
-        <li v-if="currentUser" @click="toggleDrawer">
-          <a @click="doLogout" href="#">
+        <li
+          v-if="currentUser"
+          @click="toggleDrawer"
+        >
+          <a
+            href="#"
+            @click="doLogout"
+          >
             {{ $t("login.logout") }}
           </a>
         </li>
       </ul>
     </div>
-    <div class="side-drawer-click-outside"
-      @click.stop.prevent="toggleDrawer"
+    <div
+      class="side-drawer-click-outside"
       :class="{'side-drawer-click-outside-closed': closed}"
-    ></div>
+      @click.stop.prevent="toggleDrawer"
+    />
   </div>
 </template>
 
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 440e1957..e482cfd8 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -1,187 +1,424 @@
 <template>
-  <div class="status-el" v-if="!hideStatus" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
-    <div v-if="error" class="alert error">
-      {{error}}
-      <i class="button-icon icon-cancel" @click="clearError"></i>
+  <div
+    v-if="!hideStatus"
+    class="status-el"
+    :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]"
+  >
+    <div
+      v-if="error"
+      class="alert error"
+    >
+      {{ error }}
+      <i
+        class="button-icon icon-cancel"
+        @click="clearError"
+      />
     </div>
     <template v-if="muted && !isPreview">
       <div class="media status container muted">
         <small>
           <router-link :to="userProfileLink">
-            {{status.user.screen_name}}
+            {{ status.user.screen_name }}
           </router-link>
         </small>
-        <small class="muteWords">{{muteWordHits.join(', ')}}</small>
-        <a href="#" class="unmute" @click.prevent="toggleMute"><i class="button-icon icon-eye-off"></i></a>
+        <small class="muteWords">{{ muteWordHits.join(', ') }}</small>
+        <a
+          href="#"
+          class="unmute"
+          @click.prevent="toggleMute"
+        ><i class="button-icon icon-eye-off" /></a>
       </div>
     </template>
     <template v-else>
-      <div v-if="showPinned && statusoid.pinned" class="status-pin">
-        <i class="fa icon-pin faint"></i>
-        <span class="faint">{{$t('status.pinned')}}</span>
+      <div
+        v-if="showPinned && statusoid.pinned"
+        class="status-pin"
+      >
+        <i class="fa icon-pin faint" />
+        <span class="faint">{{ $t('status.pinned') }}</span>
       </div>
-      <div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info">
-        <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/>
+      <div
+        v-if="retweet && !noHeading && !inConversation"
+        :class="[repeaterClass, { highlighted: repeaterStyle }]"
+        :style="[repeaterStyle]"
+        class="media container retweet-info"
+      >
+        <UserAvatar
+          v-if="retweet"
+          class="media-left"
+          :better-shadow="betterShadow"
+          :user="statusoid.user"
+        />
         <div class="media-body faint">
           <span class="user-name">
-            <router-link v-if="retweeterHtml" :to="retweeterProfileLink" v-html="retweeterHtml"/>
-            <router-link v-else :to="retweeterProfileLink">{{retweeter}}</router-link>
+            <router-link
+              v-if="retweeterHtml"
+              :to="retweeterProfileLink"
+              v-html="retweeterHtml"
+            />
+            <router-link
+              v-else
+              :to="retweeterProfileLink"
+            >{{ retweeter }}</router-link>
           </span>
-          <i class='fa icon-retweet retweeted' :title="$t('tool_tip.repeat')"></i>
-          {{$t('timeline.repeated')}}
+          <i
+            class="fa icon-retweet retweeted"
+            :title="$t('tool_tip.repeat')"
+          />
+          {{ $t('timeline.repeated') }}
         </div>
       </div>
 
-      <div :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]" :style="[ userStyle ]" class="media status" :data-tags="tags">
-        <div v-if="!noHeading" class="media-left">
-          <router-link :to="userProfileLink" @click.stop.prevent.capture.native="toggleUserExpanded">
-            <UserAvatar :compact="compact" :betterShadow="betterShadow" :user="status.user"/>
+      <div
+        :class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]"
+        :style="[ userStyle ]"
+        class="media status"
+        :data-tags="tags"
+      >
+        <div
+          v-if="!noHeading"
+          class="media-left"
+        >
+          <router-link
+            :to="userProfileLink"
+            @click.stop.prevent.capture.native="toggleUserExpanded"
+          >
+            <UserAvatar
+              :compact="compact"
+              :better-shadow="betterShadow"
+              :user="status.user"
+            />
           </router-link>
         </div>
         <div class="status-body">
-          <UserCard :user="status.user" :rounded="true" :bordered="true" class="status-usercard" v-if="userExpanded"/>
-          <div v-if="!noHeading" class="media-heading">
+          <UserCard
+            v-if="userExpanded"
+            :user="status.user"
+            :rounded="true"
+            :bordered="true"
+            class="status-usercard"
+          />
+          <div
+            v-if="!noHeading"
+            class="media-heading"
+          >
             <div class="heading-name-row">
               <div class="name-and-account-name">
-                <h4 class="user-name" v-if="status.user.name_html" v-html="status.user.name_html"></h4>
-                <h4 class="user-name" v-else>{{status.user.name}}</h4>
-                <router-link class="account-name" :to="userProfileLink">
-                  {{status.user.screen_name}}
+                <h4
+                  v-if="status.user.name_html"
+                  class="user-name"
+                  v-html="status.user.name_html"
+                />
+                <h4
+                  v-else
+                  class="user-name"
+                >
+                  {{ status.user.name }}
+                </h4>
+                <router-link
+                  class="account-name"
+                  :to="userProfileLink"
+                >
+                  {{ status.user.screen_name }}
                 </router-link>
               </div>
 
               <span class="heading-right">
-                <router-link class="timeago faint-link" :to="{ name: 'conversation', params: { id: status.id } }">
-                  <Timeago :time="status.created_at" :auto-update="60"></Timeago>
+                <router-link
+                  class="timeago faint-link"
+                  :to="{ name: 'conversation', params: { id: status.id } }"
+                >
+                  <Timeago
+                    :time="status.created_at"
+                    :auto-update="60"
+                  />
                 </router-link>
-                <div class="button-icon visibility-icon" v-if="status.visibility">
-                  <i :class="visibilityIcon(status.visibility)" :title="status.visibility | capitalize"></i>
+                <div
+                  v-if="status.visibility"
+                  class="button-icon visibility-icon"
+                >
+                  <i
+                    :class="visibilityIcon(status.visibility)"
+                    :title="status.visibility | capitalize"
+                  />
                 </div>
-                <a :href="status.external_url" target="_blank" v-if="!status.is_local && !isPreview" class="source_url" title="Source">
-                  <i class="button-icon icon-link-ext-alt"></i>
+                <a
+                  v-if="!status.is_local && !isPreview"
+                  :href="status.external_url"
+                  target="_blank"
+                  class="source_url"
+                  title="Source"
+                >
+                  <i class="button-icon icon-link-ext-alt" />
                 </a>
                 <template v-if="expandable && !isPreview">
-                  <a href="#" @click.prevent="toggleExpanded" title="Expand">
-                    <i class="button-icon icon-plus-squared"></i>
+                  <a
+                    href="#"
+                    title="Expand"
+                    @click.prevent="toggleExpanded"
+                  >
+                    <i class="button-icon icon-plus-squared" />
                   </a>
                 </template>
-                <a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="button-icon icon-eye-off"></i></a>
+                <a
+                  v-if="unmuted"
+                  href="#"
+                  @click.prevent="toggleMute"
+                ><i class="button-icon icon-eye-off" /></a>
               </span>
             </div>
 
             <div class="heading-reply-row">
-              <div v-if="isReply" class="reply-to-and-accountname">
-                <a class="reply-to"
-                  href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)"
+              <div
+                v-if="isReply"
+                class="reply-to-and-accountname"
+              >
+                <a
+                  class="reply-to"
+                  href="#"
                   :aria-label="$t('tool_tip.reply')"
+                  @click.prevent="gotoOriginal(status.in_reply_to_status_id)"
                   @mouseenter.prevent.stop="replyEnter(status.in_reply_to_status_id, $event)"
                   @mouseleave.prevent.stop="replyLeave()"
                 >
-                  <i class="button-icon icon-reply" v-if="!isPreview"></i>
-                  <span class="faint-link reply-to-text">{{$t('status.reply_to')}}</span>
+                  <i
+                    v-if="!isPreview"
+                    class="button-icon icon-reply"
+                  />
+                  <span class="faint-link reply-to-text">{{ $t('status.reply_to') }}</span>
                 </a>
                 <router-link :to="replyProfileLink">
-                  {{replyToName}}
+                  {{ replyToName }}
                 </router-link>
-                <span class="faint replies-separator" v-if="replies && replies.length">
+                <span
+                  v-if="replies && replies.length"
+                  class="faint replies-separator"
+                >
                   -
                 </span>
               </div>
-              <div class="replies" v-if="inConversation && !isPreview">
-                <span class="faint" v-if="replies && replies.length">{{$t('status.replies_list')}}</span>
-                <span class="reply-link faint" v-if="replies" v-for="reply in replies">
-                  <a href="#" @click.prevent="gotoOriginal(reply.id)" @mouseenter="replyEnter(reply.id, $event)" @mouseout="replyLeave()">{{reply.name}}</a>
+              <div
+                v-if="inConversation && !isPreview"
+                class="replies"
+              >
+                <span
+                  v-if="replies && replies.length"
+                  class="faint"
+                >{{ $t('status.replies_list') }}</span>
+                <span
+                  v-for="reply in replies"
+                  v-if="replies"
+                  class="reply-link faint"
+                >
+                  <a
+                    href="#"
+                    @click.prevent="gotoOriginal(reply.id)"
+                    @mouseenter="replyEnter(reply.id, $event)"
+                    @mouseout="replyLeave()"
+                  >{{ reply.name }}</a>
                 </span>
               </div>
             </div>
-
-
           </div>
 
-          <div v-if="showPreview" class="status-preview-container">
-            <status class="status-preview"
+          <div
+            v-if="showPreview"
+            class="status-preview-container"
+          >
+            <status
               v-if="preview"
-              :isPreview="true"
+              class="status-preview"
+              :is-preview="true"
               :statusoid="preview"
               :compact="true"
             />
-            <div v-else class="status-preview status-preview-loading">
-              <i class="icon-spin4 animate-spin"></i>
+            <div
+              v-else
+              class="status-preview status-preview-loading"
+            >
+              <i class="icon-spin4 animate-spin" />
             </div>
           </div>
 
-          <div class="status-content-wrapper" :class="{ 'tall-status': !showingLongSubject }" v-if="longSubject">
-            <a class="tall-status-hider" :class="{ 'tall-status-hider_focused': isFocused }" v-if="!showingLongSubject" href="#" @click.prevent="showingLongSubject=true">{{$t("general.show_more")}}</a>
-            <div @click.prevent="linkClicked" class="status-content media-body" v-html="contentHtml"></div>
-            <a v-if="showingLongSubject" href="#" class="status-unhider" @click.prevent="showingLongSubject=false">{{$t("general.show_less")}}</a>
+          <div
+            v-if="longSubject"
+            class="status-content-wrapper"
+            :class="{ 'tall-status': !showingLongSubject }"
+          >
+            <a
+              v-if="!showingLongSubject"
+              class="tall-status-hider"
+              :class="{ 'tall-status-hider_focused': isFocused }"
+              href="#"
+              @click.prevent="showingLongSubject=true"
+            >{{ $t("general.show_more") }}</a>
+            <div
+              class="status-content media-body"
+              @click.prevent="linkClicked"
+              v-html="contentHtml"
+            />
+            <a
+              v-if="showingLongSubject"
+              href="#"
+              class="status-unhider"
+              @click.prevent="showingLongSubject=false"
+            >{{ $t("general.show_less") }}</a>
           </div>
-          <div :class="{'tall-status': hideTallStatus}" class="status-content-wrapper" v-else>
-            <a class="tall-status-hider" :class="{ 'tall-status-hider_focused': isFocused }" v-if="hideTallStatus" href="#" @click.prevent="toggleShowMore">{{$t("general.show_more")}}</a>
-            <div @click.prevent="linkClicked" class="status-content media-body" v-html="contentHtml" v-if="!hideSubjectStatus"></div>
-            <div @click.prevent="linkClicked" class="status-content media-body" v-html="status.summary_html" v-else></div>
-            <a v-if="hideSubjectStatus" href="#" class="cw-status-hider" @click.prevent="toggleShowMore">{{$t("general.show_more")}}</a>
-            <a v-if="showingMore" href="#" class="status-unhider" @click.prevent="toggleShowMore">{{$t("general.show_less")}}</a>
+          <div
+            v-else
+            :class="{'tall-status': hideTallStatus}"
+            class="status-content-wrapper"
+          >
+            <a
+              v-if="hideTallStatus"
+              class="tall-status-hider"
+              :class="{ 'tall-status-hider_focused': isFocused }"
+              href="#"
+              @click.prevent="toggleShowMore"
+            >{{ $t("general.show_more") }}</a>
+            <div
+              v-if="!hideSubjectStatus"
+              class="status-content media-body"
+              @click.prevent="linkClicked"
+              v-html="contentHtml"
+            />
+            <div
+              v-else
+              class="status-content media-body"
+              @click.prevent="linkClicked"
+              v-html="status.summary_html"
+            />
+            <a
+              v-if="hideSubjectStatus"
+              href="#"
+              class="cw-status-hider"
+              @click.prevent="toggleShowMore"
+            >{{ $t("general.show_more") }}</a>
+            <a
+              v-if="showingMore"
+              href="#"
+              class="status-unhider"
+              @click.prevent="toggleShowMore"
+            >{{ $t("general.show_less") }}</a>
           </div>
 
           <div v-if="status.poll && status.poll.options">
             <poll :base-poll="status.poll" />
           </div>
 
-          <div v-if="status.attachments && (!hideSubjectStatus || showingLongSubject)" class="attachments media-body">
+          <div
+            v-if="status.attachments && (!hideSubjectStatus || showingLongSubject)"
+            class="attachments media-body"
+          >
             <attachment
-              class="non-gallery"
               v-for="attachment in nonGalleryAttachments"
+              :key="attachment.id"
+              class="non-gallery"
               :size="attachmentSize"
               :nsfw="nsfwClickthrough"
               :attachment="attachment"
-              :allowPlay="true"
-              :setMedia="setMedia()"
-              :key="attachment.id"
+              :allow-play="true"
+              :set-media="setMedia()"
             />
             <gallery
               v-if="galleryAttachments.length > 0"
               :nsfw="nsfwClickthrough"
               :attachments="galleryAttachments"
-              :setMedia="setMedia()"
+              :set-media="setMedia()"
             />
           </div>
 
-          <div v-if="status.card && !hideSubjectStatus && !noHeading" class="link-preview media-body">
-            <link-preview :card="status.card" :size="attachmentSize" :nsfw="nsfwClickthrough" />
+          <div
+            v-if="status.card && !hideSubjectStatus && !noHeading"
+            class="link-preview media-body"
+          >
+            <link-preview
+              :card="status.card"
+              :size="attachmentSize"
+              :nsfw="nsfwClickthrough"
+            />
           </div>
 
           <transition name="fade">
-            <div class="favs-repeated-users" v-if="isFocused && combinedFavsAndRepeatsUsers.length > 0">
+            <div
+              v-if="isFocused && combinedFavsAndRepeatsUsers.length > 0"
+              class="favs-repeated-users"
+            >
               <div class="stats">
-                <div class="stat-count" v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0">
+                <div
+                  v-if="statusFromGlobalRepository.rebloggedBy && statusFromGlobalRepository.rebloggedBy.length > 0"
+                  class="stat-count"
+                >
                   <a class="stat-title">{{ $t('status.repeats') }}</a>
-                  <div class="stat-number">{{ statusFromGlobalRepository.rebloggedBy.length }}</div>
+                  <div class="stat-number">
+                    {{ statusFromGlobalRepository.rebloggedBy.length }}
+                  </div>
                 </div>
-                <div class="stat-count" v-if="statusFromGlobalRepository.favoritedBy && statusFromGlobalRepository.favoritedBy.length > 0">
+                <div
+                  v-if="statusFromGlobalRepository.favoritedBy && statusFromGlobalRepository.favoritedBy.length > 0"
+                  class="stat-count"
+                >
                   <a class="stat-title">{{ $t('status.favorites') }}</a>
-                  <div class="stat-number">{{ statusFromGlobalRepository.favoritedBy.length }}</div>
+                  <div class="stat-number">
+                    {{ statusFromGlobalRepository.favoritedBy.length }}
+                  </div>
                 </div>
                 <div class="avatar-row">
-                  <AvatarList :users="combinedFavsAndRepeatsUsers"></AvatarList>
+                  <AvatarList :users="combinedFavsAndRepeatsUsers" />
                 </div>
               </div>
             </div>
           </transition>
 
-          <div v-if="!noHeading && !isPreview" class='status-actions media-body'>
+          <div
+            v-if="!noHeading && !isPreview"
+            class="status-actions media-body"
+          >
             <div>
-              <i class="button-icon icon-reply" v-on:click.prevent="toggleReplying" :title="$t('tool_tip.reply')" :class="{'button-icon-active': replying}" v-if="loggedIn"/>
-              <i class="button-icon button-icon-disabled icon-reply" :title="$t('tool_tip.reply')" v-else />
-              <span v-if="status.replies_count > 0">{{status.replies_count}}</span>
+              <i
+                v-if="loggedIn"
+                class="button-icon icon-reply"
+                :title="$t('tool_tip.reply')"
+                :class="{'button-icon-active': replying}"
+                @click.prevent="toggleReplying"
+              />
+              <i
+                v-else
+                class="button-icon button-icon-disabled icon-reply"
+                :title="$t('tool_tip.reply')"
+              />
+              <span v-if="status.replies_count > 0">{{ status.replies_count }}</span>
             </div>
-            <retweet-button :visibility='status.visibility' :loggedIn='loggedIn' :status='status'></retweet-button>
-            <favorite-button :loggedIn='loggedIn' :status='status'></favorite-button>
-            <extra-buttons :status="status" @onError="showError" @onSuccess="clearError"></extra-buttons>
+            <retweet-button
+              :visibility="status.visibility"
+              :logged-in="loggedIn"
+              :status="status"
+            />
+            <favorite-button
+              :logged-in="loggedIn"
+              :status="status"
+            />
+            <extra-buttons
+              :status="status"
+              @onError="showError"
+              @onSuccess="clearError"
+            />
           </div>
         </div>
       </div>
-      <div class="container" v-if="replying">
-        <post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" :copy-message-scope="status.visibility" :subject="replySubject" v-on:posted="toggleReplying"/>
+      <div
+        v-if="replying"
+        class="container"
+      >
+        <post-status-form
+          class="reply-body"
+          :reply-to="status.id"
+          :attentions="status.attentions"
+          :replied-user="status.user"
+          :copy-message-scope="status.visibility"
+          :subject="replySubject"
+          @posted="toggleReplying"
+        />
       </div>
     </template>
   </div>
diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue
index af824fa2..3fff63f9 100644
--- a/src/components/still-image/still-image.vue
+++ b/src/components/still-image/still-image.vue
@@ -1,7 +1,19 @@
 <template>
-  <div class='still-image' :class='{ animated: animated }' >
-    <canvas ref="canvas" v-if="animated"></canvas>
-    <img ref="src" :src="src" :referrerpolicy="referrerpolicy" v-on:load="onLoad" @error="onError"/>
+  <div
+    class="still-image"
+    :class="{ animated: animated }"
+  >
+    <canvas
+      v-if="animated"
+      ref="canvas"
+    />
+    <img
+      ref="src"
+      :src="src"
+      :referrerpolicy="referrerpolicy"
+      @load="onLoad"
+      @error="onError"
+    >
   </div>
 </template>
 
diff --git a/src/components/style_switcher/preview.vue b/src/components/style_switcher/preview.vue
index 634f5b35..101a32bd 100644
--- a/src/components/style_switcher/preview.vue
+++ b/src/components/style_switcher/preview.vue
@@ -1,78 +1,101 @@
 <template>
-<div class="panel dummy">
-  <div class="panel-heading">
-    <div class="title">
-      {{$t('settings.style.preview.header')}}
-      <span class="badge badge-notification">
-        99
+  <div class="panel dummy">
+    <div class="panel-heading">
+      <div class="title">
+        {{ $t('settings.style.preview.header') }}
+        <span class="badge badge-notification">
+          99
+        </span>
+      </div>
+      <span class="faint">
+        {{ $t('settings.style.preview.header_faint') }}
+      </span>
+      <span class="alert error">
+        {{ $t('settings.style.preview.error') }}
       </span>
+      <button class="btn">
+        {{ $t('settings.style.preview.button') }}
+      </button>
     </div>
-    <span class="faint">
-      {{$t('settings.style.preview.header_faint')}}
-    </span>
-    <span class="alert error">
-      {{$t('settings.style.preview.error')}}
-    </span>
-    <button class="btn">
-      {{$t('settings.style.preview.button')}}
-    </button>
-  </div>
-  <div class="panel-body theme-preview-content">
-    <div class="post">
-      <div class="avatar">
-        ( ͡° ͜ʖ ͡°)
-      </div>
-      <div class="content">
-        <h4>
-          {{$t('settings.style.preview.content')}}
-        </h4>
+    <div class="panel-body theme-preview-content">
+      <div class="post">
+        <div class="avatar">
+          ( ͡° ͜ʖ ͡°)
+        </div>
+        <div class="content">
+          <h4>
+            {{ $t('settings.style.preview.content') }}
+          </h4>
 
-        <i18n path="settings.style.preview.text">
-          <code style="font-family: var(--postCodeFont)">
-            {{$t('settings.style.preview.mono')}}
-          </code>
-          <a style="color: var(--link)">
-            {{$t('settings.style.preview.link')}}
-          </a>
-        </i18n>
+          <i18n path="settings.style.preview.text">
+            <code style="font-family: var(--postCodeFont)">
+              {{ $t('settings.style.preview.mono') }}
+            </code>
+            <a style="color: var(--link)">
+              {{ $t('settings.style.preview.link') }}
+            </a>
+          </i18n>
 
-        <div class="icons">
-          <i style="color: var(--cBlue)" class="button-icon icon-reply"/>
-          <i style="color: var(--cGreen)" class="button-icon icon-retweet"/>
-          <i style="color: var(--cOrange)" class="button-icon icon-star"/>
-          <i style="color: var(--cRed)" class="button-icon icon-cancel"/>
+          <div class="icons">
+            <i
+              style="color: var(--cBlue)"
+              class="button-icon icon-reply"
+            />
+            <i
+              style="color: var(--cGreen)"
+              class="button-icon icon-retweet"
+            />
+            <i
+              style="color: var(--cOrange)"
+              class="button-icon icon-star"
+            />
+            <i
+              style="color: var(--cRed)"
+              class="button-icon icon-cancel"
+            />
+          </div>
         </div>
       </div>
-    </div>
 
-    <div class="after-post">
-      <div class="avatar-alt">
-        :^)
-      </div>
-      <div class="content">
-        <i18n path="settings.style.preview.fine_print" tag="span" class="faint">
-          <a style="color: var(--faintLink)">
-            {{$t('settings.style.preview.faint_link')}}
-          </a>
-        </i18n>
+      <div class="after-post">
+        <div class="avatar-alt">
+          :^)
+        </div>
+        <div class="content">
+          <i18n
+            path="settings.style.preview.fine_print"
+            tag="span"
+            class="faint"
+          >
+            <a style="color: var(--faintLink)">
+              {{ $t('settings.style.preview.faint_link') }}
+            </a>
+          </i18n>
+        </div>
       </div>
-    </div>
-    <div class="separator"></div>
-
-    <span class="alert error">
-      {{$t('settings.style.preview.error')}}
-    </span>
-    <input :value="$t('settings.style.preview.input')" type="text">
+      <div class="separator" />
 
-    <div class="actions">
-      <span class="checkbox">
-        <input checked="very yes" type="checkbox" id="preview_checkbox">
-        <label for="preview_checkbox">{{$t('settings.style.preview.checkbox')}}</label>
+      <span class="alert error">
+        {{ $t('settings.style.preview.error') }}
       </span>
-      <button class="btn">
-        {{$t('settings.style.preview.button')}}
-      </button>
+      <input
+        :value="$t('settings.style.preview.input')"
+        type="text"
+      >
+
+      <div class="actions">
+        <span class="checkbox">
+          <input
+            id="preview_checkbox"
+            checked="very yes"
+            type="checkbox"
+          >
+          <label for="preview_checkbox">{{ $t('settings.style.preview.checkbox') }}</label>
+        </span>
+        <button class="btn">
+          {{ $t('settings.style.preview.button') }}
+        </button>
+      </div>
     </div>
   </div>
-</div>
 </template>
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 84963c81..97dba99d 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -1,274 +1,591 @@
 <template>
-<div class="style-switcher">
-  <div class="presets-container">
-    <div class="save-load">
-      <export-import
-        :exportObject='exportedTheme'
-        :exportLabel='$t("settings.export_theme")'
-        :importLabel='$t("settings.import_theme")'
-        :importFailedText='$t("settings.invalid_theme_imported")'
-        :onImport='onImport'
-        :validator='importValidator'>
-        <template slot="before">
-          <div class="presets">
-            {{$t('settings.presets')}}
-            <label for="preset-switcher" class='select'>
-              <select id="preset-switcher" v-model="selected" class="preset-switcher">
-                <option v-for="style in availableStyles"
-                        :value="style"
-                        :style="{
-                                backgroundColor: style[1] || style.theme.colors.bg,
-                                color: style[3] || style.theme.colors.text
-                                }">
-                  {{style[0] || style.name}}
-                </option>
-              </select>
-              <i class="icon-down-open"/>
-            </label>
-          </div>
-        </template>
-      </export-import>
-    </div>
-    <div class="save-load-options">
-      <span class="keep-option">
-        <input
-          id="keep-color"
-          type="checkbox"
-          v-model="keepColor">
-        <label for="keep-color">{{$t('settings.style.switcher.keep_color')}}</label>
-      </span>
-      <span class="keep-option">
-        <input
-          id="keep-shadows"
-          type="checkbox"
-          v-model="keepShadows">
-        <label for="keep-shadows">{{$t('settings.style.switcher.keep_shadows')}}</label>
-      </span>
-      <span class="keep-option">
-        <input
-          id="keep-opacity"
-          type="checkbox"
-          v-model="keepOpacity">
-        <label for="keep-opacity">{{$t('settings.style.switcher.keep_opacity')}}</label>
-      </span>
-      <span class="keep-option">
-        <input
-          id="keep-roundness"
-          type="checkbox"
-          v-model="keepRoundness">
-        <label for="keep-roundness">{{$t('settings.style.switcher.keep_roundness')}}</label>
-      </span>
-      <span class="keep-option">
-        <input
-          id="keep-fonts"
-          type="checkbox"
-          v-model="keepFonts">
-        <label for="keep-fonts">{{$t('settings.style.switcher.keep_fonts')}}</label>
-      </span>
-      <p>{{$t('settings.style.switcher.save_load_hint')}}</p>
+  <div class="style-switcher">
+    <div class="presets-container">
+      <div class="save-load">
+        <export-import
+          :export-object="exportedTheme"
+          :export-label="$t(&quot;settings.export_theme&quot;)"
+          :import-label="$t(&quot;settings.import_theme&quot;)"
+          :import-failed-text="$t(&quot;settings.invalid_theme_imported&quot;)"
+          :on-import="onImport"
+          :validator="importValidator"
+        >
+          <template slot="before">
+            <div class="presets">
+              {{ $t('settings.presets') }}
+              <label
+                for="preset-switcher"
+                class="select"
+              >
+                <select
+                  id="preset-switcher"
+                  v-model="selected"
+                  class="preset-switcher"
+                >
+                  <option
+                    v-for="style in availableStyles"
+                    :value="style"
+                    :style="{
+                      backgroundColor: style[1] || style.theme.colors.bg,
+                      color: style[3] || style.theme.colors.text
+                    }"
+                  >
+                    {{ style[0] || style.name }}
+                  </option>
+                </select>
+                <i class="icon-down-open" />
+              </label>
+            </div>
+          </template>
+        </export-import>
+      </div>
+      <div class="save-load-options">
+        <span class="keep-option">
+          <input
+            id="keep-color"
+            v-model="keepColor"
+            type="checkbox"
+          >
+          <label for="keep-color">{{ $t('settings.style.switcher.keep_color') }}</label>
+        </span>
+        <span class="keep-option">
+          <input
+            id="keep-shadows"
+            v-model="keepShadows"
+            type="checkbox"
+          >
+          <label for="keep-shadows">{{ $t('settings.style.switcher.keep_shadows') }}</label>
+        </span>
+        <span class="keep-option">
+          <input
+            id="keep-opacity"
+            v-model="keepOpacity"
+            type="checkbox"
+          >
+          <label for="keep-opacity">{{ $t('settings.style.switcher.keep_opacity') }}</label>
+        </span>
+        <span class="keep-option">
+          <input
+            id="keep-roundness"
+            v-model="keepRoundness"
+            type="checkbox"
+          >
+          <label for="keep-roundness">{{ $t('settings.style.switcher.keep_roundness') }}</label>
+        </span>
+        <span class="keep-option">
+          <input
+            id="keep-fonts"
+            v-model="keepFonts"
+            type="checkbox"
+          >
+          <label for="keep-fonts">{{ $t('settings.style.switcher.keep_fonts') }}</label>
+        </span>
+        <p>{{ $t('settings.style.switcher.save_load_hint') }}</p>
+      </div>
     </div>
-  </div>
 
-  <div class="preview-container">
-    <preview :style="previewRules"/>
-  </div>
+    <div class="preview-container">
+      <preview :style="previewRules" />
+    </div>
 
-  <keep-alive>
-    <tab-switcher key="style-tweak">
-      <div :label="$t('settings.style.common_colors._tab_label')" class="color-container">
-        <div class="tab-header">
-          <p>{{$t('settings.theme_help')}}</p>
-          <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
-          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
-        </div>
-        <p>{{$t('settings.theme_help_v2_1')}}</p>
-        <h4>{{ $t('settings.style.common_colors.main') }}</h4>
-        <div class="color-item">
-          <ColorInput name="bgColor" v-model="bgColorLocal" :label="$t('settings.background')"/>
-          <OpacityInput name="bgOpacity" v-model="bgOpacityLocal" :fallback="previewTheme.opacity.bg || 1"/>
-          <ColorInput name="textColor" v-model="textColorLocal" :label="$t('settings.text')"/>
-          <ContrastRatio :contrast="previewContrast.bgText"/>
-          <ColorInput name="linkColor" v-model="linkColorLocal" :label="$t('settings.links')"/>
-          <ContrastRatio :contrast="previewContrast.bgLink"/>
-        </div>
-        <div class="color-item">
-          <ColorInput name="fgColor" v-model="fgColorLocal" :label="$t('settings.foreground')"/>
-          <ColorInput name="fgTextColor" v-model="fgTextColorLocal" :label="$t('settings.text')" :fallback="previewTheme.colors.fgText"/>
-          <ColorInput name="fgLinkColor" v-model="fgLinkColorLocal" :label="$t('settings.links')" :fallback="previewTheme.colors.fgLink"/>
-          <p>{{ $t('settings.style.common_colors.foreground_hint') }}</p>
-        </div>
-        <h4>{{ $t('settings.style.common_colors.rgbo') }}</h4>
-        <div class="color-item">
-          <ColorInput name="cRedColor" v-model="cRedColorLocal" :label="$t('settings.cRed')"/>
-          <ContrastRatio :contrast="previewContrast.bgRed"/>
-          <ColorInput name="cBlueColor" v-model="cBlueColorLocal" :label="$t('settings.cBlue')"/>
-          <ContrastRatio :contrast="previewContrast.bgBlue"/>
-        </div>
-        <div class="color-item">
-          <ColorInput name="cGreenColor" v-model="cGreenColorLocal" :label="$t('settings.cGreen')"/>
-          <ContrastRatio :contrast="previewContrast.bgGreen"/>
-          <ColorInput name="cOrangeColor" v-model="cOrangeColorLocal" :label="$t('settings.cOrange')"/>
-          <ContrastRatio :contrast="previewContrast.bgOrange"/>
+    <keep-alive>
+      <tab-switcher key="style-tweak">
+        <div
+          :label="$t('settings.style.common_colors._tab_label')"
+          class="color-container"
+        >
+          <div class="tab-header">
+            <p>{{ $t('settings.theme_help') }}</p>
+            <button
+              class="btn"
+              @click="clearOpacity"
+            >
+              {{ $t('settings.style.switcher.clear_opacity') }}
+            </button>
+            <button
+              class="btn"
+              @click="clearV1"
+            >
+              {{ $t('settings.style.switcher.clear_all') }}
+            </button>
+          </div>
+          <p>{{ $t('settings.theme_help_v2_1') }}</p>
+          <h4>{{ $t('settings.style.common_colors.main') }}</h4>
+          <div class="color-item">
+            <ColorInput
+              v-model="bgColorLocal"
+              name="bgColor"
+              :label="$t('settings.background')"
+            />
+            <OpacityInput
+              v-model="bgOpacityLocal"
+              name="bgOpacity"
+              :fallback="previewTheme.opacity.bg || 1"
+            />
+            <ColorInput
+              v-model="textColorLocal"
+              name="textColor"
+              :label="$t('settings.text')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgText" />
+            <ColorInput
+              v-model="linkColorLocal"
+              name="linkColor"
+              :label="$t('settings.links')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgLink" />
+          </div>
+          <div class="color-item">
+            <ColorInput
+              v-model="fgColorLocal"
+              name="fgColor"
+              :label="$t('settings.foreground')"
+            />
+            <ColorInput
+              v-model="fgTextColorLocal"
+              name="fgTextColor"
+              :label="$t('settings.text')"
+              :fallback="previewTheme.colors.fgText"
+            />
+            <ColorInput
+              v-model="fgLinkColorLocal"
+              name="fgLinkColor"
+              :label="$t('settings.links')"
+              :fallback="previewTheme.colors.fgLink"
+            />
+            <p>{{ $t('settings.style.common_colors.foreground_hint') }}</p>
+          </div>
+          <h4>{{ $t('settings.style.common_colors.rgbo') }}</h4>
+          <div class="color-item">
+            <ColorInput
+              v-model="cRedColorLocal"
+              name="cRedColor"
+              :label="$t('settings.cRed')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgRed" />
+            <ColorInput
+              v-model="cBlueColorLocal"
+              name="cBlueColor"
+              :label="$t('settings.cBlue')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgBlue" />
+          </div>
+          <div class="color-item">
+            <ColorInput
+              v-model="cGreenColorLocal"
+              name="cGreenColor"
+              :label="$t('settings.cGreen')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgGreen" />
+            <ColorInput
+              v-model="cOrangeColorLocal"
+              name="cOrangeColor"
+              :label="$t('settings.cOrange')"
+            />
+            <ContrastRatio :contrast="previewContrast.bgOrange" />
+          </div>
+          <p>{{ $t('settings.theme_help_v2_2') }}</p>
         </div>
-        <p>{{$t('settings.theme_help_v2_2')}}</p>
-      </div>
 
-      <div :label="$t('settings.style.advanced_colors._tab_label')" class="color-container">
-        <div class="tab-header">
-          <p>{{$t('settings.theme_help')}}</p>
-          <button class="btn" @click="clearOpacity">{{$t('settings.style.switcher.clear_opacity')}}</button>
-          <button class="btn" @click="clearV1">{{$t('settings.style.switcher.clear_all')}}</button>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
-          <ColorInput name="alertError" v-model="alertErrorColorLocal" :label="$t('settings.style.advanced_colors.alert_error')" :fallback="previewTheme.colors.alertError"/>
-          <ContrastRatio :contrast="previewContrast.alertError"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
-          <ColorInput name="badgeNotification" v-model="badgeNotificationColorLocal" :label="$t('settings.style.advanced_colors.badge_notification')" :fallback="previewTheme.colors.badgeNotification"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.panel_header') }}</h4>
-          <ColorInput name="panelColor" v-model="panelColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-          <OpacityInput name="panelOpacity" v-model="panelOpacityLocal" :fallback="previewTheme.opacity.panel || 1"/>
-          <ColorInput name="panelTextColor" v-model="panelTextColorLocal" :fallback="previewTheme.colors.panelText" :label="$t('settings.text')"/>
-          <ContrastRatio :contrast="previewContrast.panelText" large="1"/>
-          <ColorInput name="panelLinkColor" v-model="panelLinkColorLocal" :fallback="previewTheme.colors.panelLink" :label="$t('settings.links')"/>
-          <ContrastRatio :contrast="previewContrast.panelLink" large="1"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.top_bar') }}</h4>
-          <ColorInput name="topBarColor" v-model="topBarColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-          <ColorInput name="topBarTextColor" v-model="topBarTextColorLocal" :fallback="previewTheme.colors.topBarText" :label="$t('settings.text')"/>
-          <ContrastRatio :contrast="previewContrast.topBarText"/>
-          <ColorInput name="topBarLinkColor" v-model="topBarLinkColorLocal" :fallback="previewTheme.colors.topBarLink" :label="$t('settings.links')"/>
-          <ContrastRatio :contrast="previewContrast.topBarLink"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.inputs') }}</h4>
-          <ColorInput name="inputColor" v-model="inputColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-          <OpacityInput name="inputOpacity" v-model="inputOpacityLocal" :fallback="previewTheme.opacity.input || 1"/>
-          <ColorInput name="inputTextColor" v-model="inputTextColorLocal" :fallback="previewTheme.colors.inputText" :label="$t('settings.text')"/>
-          <ContrastRatio :contrast="previewContrast.inputText"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.buttons') }}</h4>
-          <ColorInput name="btnColor" v-model="btnColorLocal" :fallback="fgColorLocal" :label="$t('settings.background')"/>
-          <OpacityInput name="btnOpacity" v-model="btnOpacityLocal" :fallback="previewTheme.opacity.btn || 1"/>
-          <ColorInput name="btnTextColor" v-model="btnTextColorLocal" :fallback="previewTheme.colors.btnText" :label="$t('settings.text')"/>
-          <ContrastRatio :contrast="previewContrast.btnText"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
-          <ColorInput name="borderColor" v-model="borderColorLocal" :fallback="previewTheme.colors.border" :label="$t('settings.style.common.color')"/>
-          <OpacityInput name="borderOpacity" v-model="borderOpacityLocal" :fallback="previewTheme.opacity.border || 1"/>
-        </div>
-        <div class="color-item">
-          <h4>{{ $t('settings.style.advanced_colors.faint_text') }}</h4>
-          <ColorInput name="faintColor" v-model="faintColorLocal" :fallback="previewTheme.colors.faint || 1" :label="$t('settings.text')"/>
-          <ColorInput name="faintLinkColor" v-model="faintLinkColorLocal" :fallback="previewTheme.colors.faintLink" :label="$t('settings.links')"/>
-          <ColorInput name="panelFaintColor" v-model="panelFaintColorLocal" :fallback="previewTheme.colors.panelFaint" :label="$t('settings.style.advanced_colors.panel_header')"/>
-          <OpacityInput name="faintOpacity" v-model="faintOpacityLocal" :fallback="previewTheme.opacity.faint || 0.5"/>
+        <div
+          :label="$t('settings.style.advanced_colors._tab_label')"
+          class="color-container"
+        >
+          <div class="tab-header">
+            <p>{{ $t('settings.theme_help') }}</p>
+            <button
+              class="btn"
+              @click="clearOpacity"
+            >
+              {{ $t('settings.style.switcher.clear_opacity') }}
+            </button>
+            <button
+              class="btn"
+              @click="clearV1"
+            >
+              {{ $t('settings.style.switcher.clear_all') }}
+            </button>
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.alert') }}</h4>
+            <ColorInput
+              v-model="alertErrorColorLocal"
+              name="alertError"
+              :label="$t('settings.style.advanced_colors.alert_error')"
+              :fallback="previewTheme.colors.alertError"
+            />
+            <ContrastRatio :contrast="previewContrast.alertError" />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.badge') }}</h4>
+            <ColorInput
+              v-model="badgeNotificationColorLocal"
+              name="badgeNotification"
+              :label="$t('settings.style.advanced_colors.badge_notification')"
+              :fallback="previewTheme.colors.badgeNotification"
+            />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.panel_header') }}</h4>
+            <ColorInput
+              v-model="panelColorLocal"
+              name="panelColor"
+              :fallback="fgColorLocal"
+              :label="$t('settings.background')"
+            />
+            <OpacityInput
+              v-model="panelOpacityLocal"
+              name="panelOpacity"
+              :fallback="previewTheme.opacity.panel || 1"
+            />
+            <ColorInput
+              v-model="panelTextColorLocal"
+              name="panelTextColor"
+              :fallback="previewTheme.colors.panelText"
+              :label="$t('settings.text')"
+            />
+            <ContrastRatio
+              :contrast="previewContrast.panelText"
+              large="1"
+            />
+            <ColorInput
+              v-model="panelLinkColorLocal"
+              name="panelLinkColor"
+              :fallback="previewTheme.colors.panelLink"
+              :label="$t('settings.links')"
+            />
+            <ContrastRatio
+              :contrast="previewContrast.panelLink"
+              large="1"
+            />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.top_bar') }}</h4>
+            <ColorInput
+              v-model="topBarColorLocal"
+              name="topBarColor"
+              :fallback="fgColorLocal"
+              :label="$t('settings.background')"
+            />
+            <ColorInput
+              v-model="topBarTextColorLocal"
+              name="topBarTextColor"
+              :fallback="previewTheme.colors.topBarText"
+              :label="$t('settings.text')"
+            />
+            <ContrastRatio :contrast="previewContrast.topBarText" />
+            <ColorInput
+              v-model="topBarLinkColorLocal"
+              name="topBarLinkColor"
+              :fallback="previewTheme.colors.topBarLink"
+              :label="$t('settings.links')"
+            />
+            <ContrastRatio :contrast="previewContrast.topBarLink" />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.inputs') }}</h4>
+            <ColorInput
+              v-model="inputColorLocal"
+              name="inputColor"
+              :fallback="fgColorLocal"
+              :label="$t('settings.background')"
+            />
+            <OpacityInput
+              v-model="inputOpacityLocal"
+              name="inputOpacity"
+              :fallback="previewTheme.opacity.input || 1"
+            />
+            <ColorInput
+              v-model="inputTextColorLocal"
+              name="inputTextColor"
+              :fallback="previewTheme.colors.inputText"
+              :label="$t('settings.text')"
+            />
+            <ContrastRatio :contrast="previewContrast.inputText" />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.buttons') }}</h4>
+            <ColorInput
+              v-model="btnColorLocal"
+              name="btnColor"
+              :fallback="fgColorLocal"
+              :label="$t('settings.background')"
+            />
+            <OpacityInput
+              v-model="btnOpacityLocal"
+              name="btnOpacity"
+              :fallback="previewTheme.opacity.btn || 1"
+            />
+            <ColorInput
+              v-model="btnTextColorLocal"
+              name="btnTextColor"
+              :fallback="previewTheme.colors.btnText"
+              :label="$t('settings.text')"
+            />
+            <ContrastRatio :contrast="previewContrast.btnText" />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.borders') }}</h4>
+            <ColorInput
+              v-model="borderColorLocal"
+              name="borderColor"
+              :fallback="previewTheme.colors.border"
+              :label="$t('settings.style.common.color')"
+            />
+            <OpacityInput
+              v-model="borderOpacityLocal"
+              name="borderOpacity"
+              :fallback="previewTheme.opacity.border || 1"
+            />
+          </div>
+          <div class="color-item">
+            <h4>{{ $t('settings.style.advanced_colors.faint_text') }}</h4>
+            <ColorInput
+              v-model="faintColorLocal"
+              name="faintColor"
+              :fallback="previewTheme.colors.faint || 1"
+              :label="$t('settings.text')"
+            />
+            <ColorInput
+              v-model="faintLinkColorLocal"
+              name="faintLinkColor"
+              :fallback="previewTheme.colors.faintLink"
+              :label="$t('settings.links')"
+            />
+            <ColorInput
+              v-model="panelFaintColorLocal"
+              name="panelFaintColor"
+              :fallback="previewTheme.colors.panelFaint"
+              :label="$t('settings.style.advanced_colors.panel_header')"
+            />
+            <OpacityInput
+              v-model="faintOpacityLocal"
+              name="faintOpacity"
+              :fallback="previewTheme.opacity.faint || 0.5"
+            />
+          </div>
         </div>
-      </div>
 
-      <div :label="$t('settings.style.radii._tab_label')" class="radius-container">
-        <div class="tab-header">
-          <p>{{$t('settings.radii_help')}}</p>
-          <button class="btn" @click="clearRoundness">{{$t('settings.style.switcher.clear_all')}}</button>
+        <div
+          :label="$t('settings.style.radii._tab_label')"
+          class="radius-container"
+        >
+          <div class="tab-header">
+            <p>{{ $t('settings.radii_help') }}</p>
+            <button
+              class="btn"
+              @click="clearRoundness"
+            >
+              {{ $t('settings.style.switcher.clear_all') }}
+            </button>
+          </div>
+          <RangeInput
+            v-model="btnRadiusLocal"
+            name="btnRadius"
+            :label="$t('settings.btnRadius')"
+            :fallback="previewTheme.radii.btn"
+            max="16"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="inputRadiusLocal"
+            name="inputRadius"
+            :label="$t('settings.inputRadius')"
+            :fallback="previewTheme.radii.input"
+            max="9"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="checkboxRadiusLocal"
+            name="checkboxRadius"
+            :label="$t('settings.checkboxRadius')"
+            :fallback="previewTheme.radii.checkbox"
+            max="16"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="panelRadiusLocal"
+            name="panelRadius"
+            :label="$t('settings.panelRadius')"
+            :fallback="previewTheme.radii.panel"
+            max="50"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="avatarRadiusLocal"
+            name="avatarRadius"
+            :label="$t('settings.avatarRadius')"
+            :fallback="previewTheme.radii.avatar"
+            max="28"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="avatarAltRadiusLocal"
+            name="avatarAltRadius"
+            :label="$t('settings.avatarAltRadius')"
+            :fallback="previewTheme.radii.avatarAlt"
+            max="28"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="attachmentRadiusLocal"
+            name="attachmentRadius"
+            :label="$t('settings.attachmentRadius')"
+            :fallback="previewTheme.radii.attachment"
+            max="50"
+            hard-min="0"
+          />
+          <RangeInput
+            v-model="tooltipRadiusLocal"
+            name="tooltipRadius"
+            :label="$t('settings.tooltipRadius')"
+            :fallback="previewTheme.radii.tooltip"
+            max="50"
+            hard-min="0"
+          />
         </div>
-        <RangeInput name="btnRadius" :label="$t('settings.btnRadius')" v-model="btnRadiusLocal" :fallback="previewTheme.radii.btn" max="16" hardMin="0"/>
-        <RangeInput name="inputRadius" :label="$t('settings.inputRadius')" v-model="inputRadiusLocal" :fallback="previewTheme.radii.input" max="9" hardMin="0"/>
-        <RangeInput name="checkboxRadius" :label="$t('settings.checkboxRadius')" v-model="checkboxRadiusLocal" :fallback="previewTheme.radii.checkbox" max="16" hardMin="0"/>
-        <RangeInput name="panelRadius" :label="$t('settings.panelRadius')" v-model="panelRadiusLocal" :fallback="previewTheme.radii.panel" max="50" hardMin="0"/>
-        <RangeInput name="avatarRadius" :label="$t('settings.avatarRadius')" v-model="avatarRadiusLocal" :fallback="previewTheme.radii.avatar" max="28" hardMin="0"/>
-        <RangeInput name="avatarAltRadius" :label="$t('settings.avatarAltRadius')" v-model="avatarAltRadiusLocal" :fallback="previewTheme.radii.avatarAlt" max="28" hardMin="0"/>
-        <RangeInput name="attachmentRadius" :label="$t('settings.attachmentRadius')" v-model="attachmentRadiusLocal" :fallback="previewTheme.radii.attachment" max="50" hardMin="0"/>
-        <RangeInput name="tooltipRadius" :label="$t('settings.tooltipRadius')" v-model="tooltipRadiusLocal" :fallback="previewTheme.radii.tooltip" max="50" hardMin="0"/>
-      </div>
 
-      <div :label="$t('settings.style.shadows._tab_label')" class="shadow-container">
-        <div class="tab-header shadow-selector">
-          <div class="select-container">
-            {{$t('settings.style.shadows.component')}}
-            <label for="shadow-switcher" class="select">
-              <select id="shadow-switcher" v-model="shadowSelected" class="shadow-switcher">
-                <option v-for="shadow in shadowsAvailable"
-                        :value="shadow">
-                  {{$t('settings.style.shadows.components.' + shadow)}}
-                </option>
-              </select>
-              <i class="icon-down-open"/>
-            </label>
+        <div
+          :label="$t('settings.style.shadows._tab_label')"
+          class="shadow-container"
+        >
+          <div class="tab-header shadow-selector">
+            <div class="select-container">
+              {{ $t('settings.style.shadows.component') }}
+              <label
+                for="shadow-switcher"
+                class="select"
+              >
+                <select
+                  id="shadow-switcher"
+                  v-model="shadowSelected"
+                  class="shadow-switcher"
+                >
+                  <option
+                    v-for="shadow in shadowsAvailable"
+                    :value="shadow"
+                  >
+                    {{ $t('settings.style.shadows.components.' + shadow) }}
+                  </option>
+                </select>
+                <i class="icon-down-open" />
+              </label>
+            </div>
+            <div class="override">
+              <label
+                for="override"
+                class="label"
+              >
+                {{ $t('settings.style.shadows.override') }}
+              </label>
+              <input
+                id="override"
+                v-model="currentShadowOverriden"
+                name="override"
+                class="input-override"
+                type="checkbox"
+              >
+              <label
+                class="checkbox-label"
+                for="override"
+              />
+            </div>
+            <button
+              class="btn"
+              @click="clearShadows"
+            >
+              {{ $t('settings.style.switcher.clear_all') }}
+            </button>
           </div>
-          <div class="override">
-            <label for="override" class="label">
-              {{$t('settings.style.shadows.override')}}
-            </label>
-            <input
-              v-model="currentShadowOverriden"
-              name="override"
-              id="override"
-              class="input-override"
-              type="checkbox">
-            <label class="checkbox-label" for="override"></label>
+          <shadow-control
+            v-model="currentShadow"
+            :ready="!!currentShadowFallback"
+            :fallback="currentShadowFallback"
+          />
+          <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
+            <i18n
+              path="settings.style.shadows.filter_hint.always_drop_shadow"
+              tag="p"
+            >
+              <code>filter: drop-shadow()</code>
+            </i18n>
+            <p>{{ $t('settings.style.shadows.filter_hint.avatar_inset') }}</p>
+            <i18n
+              path="settings.style.shadows.filter_hint.drop_shadow_syntax"
+              tag="p"
+            >
+              <code>drop-shadow</code>
+              <code>spread-radius</code>
+              <code>inset</code>
+            </i18n>
+            <i18n
+              path="settings.style.shadows.filter_hint.inset_classic"
+              tag="p"
+            >
+              <code>box-shadow</code>
+            </i18n>
+            <p>{{ $t('settings.style.shadows.filter_hint.spread_zero') }}</p>
           </div>
-          <button class="btn" @click="clearShadows">{{$t('settings.style.switcher.clear_all')}}</button>
         </div>
-        <shadow-control :ready="!!currentShadowFallback" :fallback="currentShadowFallback" v-model="currentShadow"/>
-        <div v-if="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'">
-          <i18n path="settings.style.shadows.filter_hint.always_drop_shadow" tag="p">
-            <code>filter: drop-shadow()</code>
-          </i18n>
-          <p>{{$t('settings.style.shadows.filter_hint.avatar_inset')}}</p>
-          <i18n path="settings.style.shadows.filter_hint.drop_shadow_syntax" tag="p">
-            <code>drop-shadow</code>
-            <code>spread-radius</code>
-            <code>inset</code>
-          </i18n>
-          <i18n path="settings.style.shadows.filter_hint.inset_classic" tag="p">
-            <code>box-shadow</code>
-          </i18n>
-          <p>{{$t('settings.style.shadows.filter_hint.spread_zero')}}</p>
-        </div>
-      </div>
 
-      <div :label="$t('settings.style.fonts._tab_label')" class="fonts-container">
-        <div class="tab-header">
-          <p>{{$t('settings.style.fonts.help')}}</p>
-          <button class="btn" @click="clearFonts">{{$t('settings.style.switcher.clear_all')}}</button>
+        <div
+          :label="$t('settings.style.fonts._tab_label')"
+          class="fonts-container"
+        >
+          <div class="tab-header">
+            <p>{{ $t('settings.style.fonts.help') }}</p>
+            <button
+              class="btn"
+              @click="clearFonts"
+            >
+              {{ $t('settings.style.switcher.clear_all') }}
+            </button>
+          </div>
+          <FontControl
+            v-model="fontsLocal.interface"
+            name="ui"
+            :label="$t('settings.style.fonts.components.interface')"
+            :fallback="previewTheme.fonts.interface"
+            no-inherit="1"
+          />
+          <FontControl
+            v-model="fontsLocal.input"
+            name="input"
+            :label="$t('settings.style.fonts.components.input')"
+            :fallback="previewTheme.fonts.input"
+          />
+          <FontControl
+            v-model="fontsLocal.post"
+            name="post"
+            :label="$t('settings.style.fonts.components.post')"
+            :fallback="previewTheme.fonts.post"
+          />
+          <FontControl
+            v-model="fontsLocal.postCode"
+            name="postCode"
+            :label="$t('settings.style.fonts.components.postCode')"
+            :fallback="previewTheme.fonts.postCode"
+          />
         </div>
-        <FontControl
-          name="ui"
-          v-model="fontsLocal.interface"
-          :label="$t('settings.style.fonts.components.interface')"
-          :fallback="previewTheme.fonts.interface"
-          no-inherit="1"/>
-        <FontControl
-          name="input"
-          v-model="fontsLocal.input"
-          :label="$t('settings.style.fonts.components.input')"
-          :fallback="previewTheme.fonts.input"/>
-        <FontControl
-          name="post"
-          v-model="fontsLocal.post"
-          :label="$t('settings.style.fonts.components.post')"
-          :fallback="previewTheme.fonts.post"/>
-        <FontControl
-          name="postCode"
-          v-model="fontsLocal.postCode"
-          :label="$t('settings.style.fonts.components.postCode')"
-          :fallback="previewTheme.fonts.postCode"/>
-      </div>
-    </tab-switcher>
-  </keep-alive>
+      </tab-switcher>
+    </keep-alive>
 
-  <div class="apply-container">
-    <button class="btn submit" :disabled="!themeValid" @click="setCustomTheme">{{$t('general.apply')}}</button>
-    <button class="btn" @click="clearAll">{{$t('settings.style.switcher.reset')}}</button>
+    <div class="apply-container">
+      <button
+        class="btn submit"
+        :disabled="!themeValid"
+        @click="setCustomTheme"
+      >
+        {{ $t('general.apply') }}
+      </button>
+      <button
+        class="btn"
+        @click="clearAll"
+      >
+        {{ $t('settings.style.switcher.reset') }}
+      </button>
+    </div>
   </div>
-</div>
 </template>
 
 <script src="./style_switcher.js"></script>
diff --git a/src/components/tag_timeline/tag_timeline.vue b/src/components/tag_timeline/tag_timeline.vue
index 62bb579a..ace96c3f 100644
--- a/src/components/tag_timeline/tag_timeline.vue
+++ b/src/components/tag_timeline/tag_timeline.vue
@@ -1,5 +1,10 @@
 <template>
-  <Timeline :title="tag" :timeline="timeline" :timeline-name="'tag'" :tag="tag" />
+  <Timeline
+    :title="tag"
+    :timeline="timeline"
+    :timeline-name="'tag'"
+    :tag="tag"
+  />
 </template>
 
-<script src='./tag_timeline.js'></script>
\ No newline at end of file
+<script src='./tag_timeline.js'></script>
diff --git a/src/components/terms_of_service_panel/terms_of_service_panel.vue b/src/components/terms_of_service_panel/terms_of_service_panel.vue
index eb0f2527..f79345cb 100644
--- a/src/components/terms_of_service_panel/terms_of_service_panel.vue
+++ b/src/components/terms_of_service_panel/terms_of_service_panel.vue
@@ -2,8 +2,10 @@
   <div>
     <div class="panel panel-default">
       <div class="panel-body">
-        <div v-html="content" class="tos-content">
-        </div>
+        <div
+          class="tos-content"
+          v-html="content"
+        />
       </div>
     </div>
   </div>
diff --git a/src/components/timeago/timeago.vue b/src/components/timeago/timeago.vue
index 3f185a2d..6df0524d 100644
--- a/src/components/timeago/timeago.vue
+++ b/src/components/timeago/timeago.vue
@@ -1,5 +1,8 @@
 <template>
-  <time :datetime="time" :title="localeDateString">
+  <time
+    :datetime="time"
+    :title="localeDateString"
+  >
     {{ $t(relativeTime.key, [relativeTime.num]) }}
   </time>
 </template>
@@ -16,12 +19,6 @@ export default {
       interval: null
     }
   },
-  created () {
-    this.refreshRelativeTimeObject()
-  },
-  destroyed () {
-    clearTimeout(this.interval)
-  },
   computed: {
     localeDateString () {
       return typeof this.time === 'string'
@@ -29,6 +26,12 @@ export default {
         : this.time.toLocaleString()
     }
   },
+  created () {
+    this.refreshRelativeTimeObject()
+  },
+  destroyed () {
+    clearTimeout(this.interval)
+  },
   methods: {
     refreshRelativeTimeObject () {
       const nowThreshold = typeof this.nowThreshold === 'number' ? this.nowThreshold : 1
@@ -45,4 +48,4 @@ export default {
     }
   }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index e6a8d458..1fc52083 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -2,41 +2,66 @@
   <div :class="classes.root">
     <div :class="classes.header">
       <div class="title">
-        {{title}}
+        {{ title }}
       </div>
-      <div @click.prevent class="loadmore-error alert error" v-if="timelineError">
-        {{$t('timeline.error_fetching')}}
+      <div
+        v-if="timelineError"
+        class="loadmore-error alert error"
+        @click.prevent
+      >
+        {{ $t('timeline.error_fetching') }}
       </div>
-      <button @click.prevent="showNewStatuses" class="loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
-        {{$t('timeline.show_new')}}{{newStatusCountStr}}
+      <button
+        v-if="timeline.newStatusCount > 0 && !timelineError"
+        class="loadmore-button"
+        @click.prevent="showNewStatuses"
+      >
+        {{ $t('timeline.show_new') }}{{ newStatusCountStr }}
       </button>
-      <div @click.prevent class="loadmore-text faint" v-if="!timeline.newStatusCount > 0 && !timelineError">
-        {{$t('timeline.up_to_date')}}
+      <div
+        v-if="!timeline.newStatusCount > 0 && !timelineError"
+        class="loadmore-text faint"
+        @click.prevent
+      >
+        {{ $t('timeline.up_to_date') }}
       </div>
     </div>
     <div :class="classes.body">
       <div class="timeline">
         <conversation
           v-for="status in timeline.visibleStatuses"
-          class="status-fadein"
           :key="status.id"
+          class="status-fadein"
           :statusoid="status"
           :collapsable="true"
         />
       </div>
     </div>
     <div :class="classes.footer">
-      <div v-if="count===0" class="new-status-notification text-center panel-footer faint">
-        {{$t('timeline.no_statuses')}}
+      <div
+        v-if="count===0"
+        class="new-status-notification text-center panel-footer faint"
+      >
+        {{ $t('timeline.no_statuses') }}
       </div>
-      <div v-else-if="bottomedOut" class="new-status-notification text-center panel-footer faint">
-        {{$t('timeline.no_more_statuses')}}
+      <div
+        v-else-if="bottomedOut"
+        class="new-status-notification text-center panel-footer faint"
+      >
+        {{ $t('timeline.no_more_statuses') }}
       </div>
-      <a v-else-if="!timeline.loading" href="#" v-on:click.prevent='fetchOlderStatuses()'>
-        <div class="new-status-notification text-center panel-footer">{{$t('timeline.load_older')}}</div>
+      <a
+        v-else-if="!timeline.loading"
+        href="#"
+        @click.prevent="fetchOlderStatuses()"
+      >
+        <div class="new-status-notification text-center panel-footer">{{ $t('timeline.load_older') }}</div>
       </a>
-      <div v-else class="new-status-notification text-center panel-footer">
-        <i class="icon-spin3 animate-spin"/>
+      <div
+        v-else
+        class="new-status-notification text-center panel-footer"
+      >
+        <i class="icon-spin3 animate-spin" />
       </div>
     </div>
   </div>
diff --git a/src/components/user_avatar/user_avatar.vue b/src/components/user_avatar/user_avatar.vue
index e5466fdf..811efd3c 100644
--- a/src/components/user_avatar/user_avatar.vue
+++ b/src/components/user_avatar/user_avatar.vue
@@ -5,7 +5,7 @@
     :title="user.screen_name"
     :src="user.profile_image_url_original"
     :class="{ 'avatar-compact': compact, 'better-shadow': betterShadow }"
-    :imageLoadError="imageLoadError"
+    :image-load-error="imageLoadError"
   />
 </template>
 
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index b4495673..7ad8aa1d 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -1,134 +1,256 @@
 <template>
-<div class="user-card" :class="classes" :style="style">
-  <div class="panel-heading">
-    <div class='user-info'>
-      <div class='container'>
-        <router-link :to="userProfileLink(user)">
-          <UserAvatar :betterShadow="betterShadow" :user="user"/>
-        </router-link>
-        <div class="user-summary">
-          <div class="top-line">
-            <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
-            <div :title="user.name" class='user-name' v-else>{{user.name}}</div>
-            <router-link :to="{ name: 'user-settings' }" v-if="!isOtherUser">
-              <i class="button-icon icon-wrench usersettings" :title="$t('tool_tip.user_settings')"></i>
-            </router-link>
-            <a :href="user.statusnet_profile_url" target="_blank" v-if="isOtherUser && !user.is_local">
-              <i class="icon-link-ext usersettings"></i>
-            </a>
-          </div>
-
-          <div class="bottom-line">
-            <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
-            <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
-            <span v-if="user.locked"><i class="icon icon-lock"></i></span>
-            <span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
+  <div
+    class="user-card"
+    :class="classes"
+    :style="style"
+  >
+    <div class="panel-heading">
+      <div class="user-info">
+        <div class="container">
+          <router-link :to="userProfileLink(user)">
+            <UserAvatar
+              :better-shadow="betterShadow"
+              :user="user"
+            />
+          </router-link>
+          <div class="user-summary">
+            <div class="top-line">
+              <div
+                v-if="user.name_html"
+                :title="user.name"
+                class="user-name"
+                v-html="user.name_html"
+              />
+              <div
+                v-else
+                :title="user.name"
+                class="user-name"
+              >
+                {{ user.name }}
+              </div>
+              <router-link
+                v-if="!isOtherUser"
+                :to="{ name: 'user-settings' }"
+              >
+                <i
+                  class="button-icon icon-wrench usersettings"
+                  :title="$t('tool_tip.user_settings')"
+                />
+              </router-link>
+              <a
+                v-if="isOtherUser && !user.is_local"
+                :href="user.statusnet_profile_url"
+                target="_blank"
+              >
+                <i class="icon-link-ext usersettings" />
+              </a>
+            </div>
+
+            <div class="bottom-line">
+              <router-link
+                class="user-screen-name"
+                :to="userProfileLink(user)"
+              >
+                @{{ user.screen_name }}
+              </router-link>
+              <span
+                v-if="!hideBio && !!visibleRole"
+                class="alert staff"
+              >{{ visibleRole }}</span>
+              <span v-if="user.locked"><i class="icon icon-lock" /></span>
+              <span
+                v-if="!hideUserStatsLocal && !hideBio"
+                class="dailyAvg"
+              >{{ dailyAvg }} {{ $t('user_card.per_day') }}</span>
+            </div>
           </div>
         </div>
-      </div>
-      <div class="user-meta">
-        <div v-if="user.follows_you && loggedIn && isOtherUser" class="following">
-          {{ $t('user_card.follows_you') }}
+        <div class="user-meta">
+          <div
+            v-if="user.follows_you && loggedIn && isOtherUser"
+            class="following"
+          >
+            {{ $t('user_card.follows_you') }}
+          </div>
+          <div
+            v-if="isOtherUser && (loggedIn || !switcher)"
+            class="highlighter"
+          >
+            <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
+            <input
+              v-if="userHighlightType !== 'disabled'"
+              :id="'userHighlightColorTx'+user.id"
+              v-model="userHighlightColor"
+              class="userHighlightText"
+              type="text"
+            >
+            <input
+              v-if="userHighlightType !== 'disabled'"
+              :id="'userHighlightColor'+user.id"
+              v-model="userHighlightColor"
+              class="userHighlightCl"
+              type="color"
+            >
+            <label
+              for="style-switcher"
+              class="userHighlightSel select"
+            >
+              <select
+                :id="'userHighlightSel'+user.id"
+                v-model="userHighlightType"
+                class="userHighlightSel"
+              >
+                <option value="disabled">No highlight</option>
+                <option value="solid">Solid bg</option>
+                <option value="striped">Striped bg</option>
+                <option value="side">Side stripe</option>
+              </select>
+              <i class="icon-down-open" />
+            </label>
+          </div>
         </div>
-        <div class="highlighter" v-if="isOtherUser && (loggedIn || !switcher)">
-          <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
-          <input class="userHighlightText" type="text" :id="'userHighlightColorTx'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
-          <input class="userHighlightCl" type="color" :id="'userHighlightColor'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
-          <label for="style-switcher" class='userHighlightSel select'>
-            <select class="userHighlightSel" :id="'userHighlightSel'+user.id" v-model="userHighlightType">
-              <option value="disabled">No highlight</option>
-              <option value="solid">Solid bg</option>
-              <option value="striped">Striped bg</option>
-              <option value="side">Side stripe</option>
-            </select>
-            <i class="icon-down-open"/>
-          </label>
+        <div
+          v-if="isOtherUser"
+          class="user-interactions"
+        >
+          <div
+            v-if="loggedIn"
+            class="follow"
+          >
+            <span v-if="user.following">
+              <!--Following them!-->
+              <button
+                class="pressed"
+                :disabled="followRequestInProgress"
+                :title="$t('user_card.follow_unfollow')"
+                @click="unfollowUser"
+              >
+                <template v-if="followRequestInProgress">
+                  {{ $t('user_card.follow_progress') }}
+                </template>
+                <template v-else>
+                  {{ $t('user_card.following') }}
+                </template>
+              </button>
+            </span>
+            <span v-if="!user.following">
+              <button
+                :disabled="followRequestInProgress"
+                :title="followRequestSent ? $t('user_card.follow_again') : ''"
+                @click="followUser"
+              >
+                <template v-if="followRequestInProgress">
+                  {{ $t('user_card.follow_progress') }}
+                </template>
+                <template v-else-if="followRequestSent">
+                  {{ $t('user_card.follow_sent') }}
+                </template>
+                <template v-else>
+                  {{ $t('user_card.follow') }}
+                </template>
+              </button>
+            </span>
+          </div>
+          <div
+            v-if="isOtherUser && loggedIn"
+            class="mute"
+          >
+            <span v-if="user.muted">
+              <button
+                class="pressed"
+                @click="unmuteUser"
+              >
+                {{ $t('user_card.muted') }}
+              </button>
+            </span>
+            <span v-if="!user.muted">
+              <button @click="muteUser">
+                {{ $t('user_card.mute') }}
+              </button>
+            </span>
+          </div>
+          <div v-if="!loggedIn && user.is_local">
+            <RemoteFollow :user="user" />
+          </div>
+          <div
+            v-if="isOtherUser && loggedIn"
+            class="block"
+          >
+            <span v-if="user.statusnet_blocking">
+              <button
+                class="pressed"
+                @click="unblockUser"
+              >
+                {{ $t('user_card.blocked') }}
+              </button>
+            </span>
+            <span v-if="!user.statusnet_blocking">
+              <button @click="blockUser">
+                {{ $t('user_card.block') }}
+              </button>
+            </span>
+          </div>
+          <div
+            v-if="isOtherUser && loggedIn"
+            class="block"
+          >
+            <span>
+              <button @click="reportUser">
+                {{ $t('user_card.report') }}
+              </button>
+            </span>
+          </div>
+          <ModerationTools
+            v-if="loggedIn.role === &quot;admin&quot;"
+            :user="user"
+          />
         </div>
       </div>
-      <div v-if="isOtherUser" class="user-interactions">
-        <div class="follow" v-if="loggedIn">
-          <span v-if="user.following">
-            <!--Following them!-->
-            <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')">
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.following') }}
-              </template>
-            </button>
-          </span>
-          <span v-if="!user.following">
-            <button @click="followUser" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''">
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else-if="followRequestSent">
-                {{ $t('user_card.follow_sent') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.follow') }}
-              </template>
-            </button>
-          </span>
-        </div>
-        <div class='mute' v-if='isOtherUser && loggedIn'>
-          <span v-if='user.muted'>
-            <button @click="unmuteUser" class="pressed">
-              {{ $t('user_card.muted') }}
-            </button>
-          </span>
-          <span v-if='!user.muted'>
-            <button @click="muteUser">
-              {{ $t('user_card.mute') }}
-            </button>
-          </span>
-        </div>
-        <div v-if='!loggedIn && user.is_local'>
-          <RemoteFollow :user="user" />
+    </div>
+    <div
+      v-if="!hideBio"
+      class="panel-body"
+    >
+      <div
+        v-if="!hideUserStatsLocal && switcher"
+        class="user-counts"
+      >
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('statuses')"
+        >
+          <h5>{{ $t('user_card.statuses') }}</h5>
+          <span>{{ user.statuses_count }} <br></span>
         </div>
-        <div class='block' v-if='isOtherUser && loggedIn'>
-          <span v-if='user.statusnet_blocking'>
-            <button @click="unblockUser" class="pressed">
-              {{ $t('user_card.blocked') }}
-            </button>
-          </span>
-          <span v-if='!user.statusnet_blocking'>
-            <button @click="blockUser">
-              {{ $t('user_card.block') }}
-            </button>
-          </span>
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('friends')"
+        >
+          <h5>{{ $t('user_card.followees') }}</h5>
+          <span>{{ user.friends_count }}</span>
         </div>
-        <div class='block' v-if='isOtherUser && loggedIn'>
-          <span>
-            <button @click="reportUser">
-              {{ $t('user_card.report') }}
-            </button>
-          </span>
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('followers')"
+        >
+          <h5>{{ $t('user_card.followers') }}</h5>
+          <span>{{ user.followers_count }}</span>
         </div>
-        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'/>
-      </div>
-    </div>
-  </div>
-  <div class="panel-body" v-if="!hideBio">
-    <div v-if="!hideUserStatsLocal && switcher" class="user-counts">
-      <div class="user-count" v-on:click.prevent="setProfileView('statuses')">
-        <h5>{{ $t('user_card.statuses') }}</h5>
-        <span>{{user.statuses_count}} <br></span>
-      </div>
-      <div class="user-count" v-on:click.prevent="setProfileView('friends')">
-        <h5>{{ $t('user_card.followees') }}</h5>
-        <span>{{user.friends_count}}</span>
-      </div>
-      <div class="user-count" v-on:click.prevent="setProfileView('followers')">
-        <h5>{{ $t('user_card.followers') }}</h5>
-        <span>{{user.followers_count}}</span>
       </div>
+      <p
+        v-if="!hideBio && user.description_html"
+        class="user-card-bio"
+        @click.prevent="linkClicked"
+        v-html="user.description_html"
+      />
+      <p
+        v-else-if="!hideBio"
+        class="user-card-bio"
+      >
+        {{ user.description }}
+      </p>
     </div>
-    <p @click.prevent="linkClicked" v-if="!hideBio && user.description_html" class="user-card-bio" v-html="user.description_html"></p>
-    <p v-else-if="!hideBio" class="user-card-bio">{{ user.description }}</p>
   </div>
-</div>
 </template>
 
 <script src="./user_card.js"></script>
diff --git a/src/components/user_finder/user_finder.vue b/src/components/user_finder/user_finder.vue
index a118ffe2..39d49237 100644
--- a/src/components/user_finder/user_finder.vue
+++ b/src/components/user_finder/user_finder.vue
@@ -1,14 +1,38 @@
 <template>
   <div>
     <div class="user-finder-container">
-      <i class="icon-spin4 user-finder-icon animate-spin-slow" v-if="loading" />
-      <a href="#" v-if="hidden" :title="$t('finder.find_user')"><i class="icon-user-plus user-finder-icon" @click.prevent.stop="toggleHidden" /></a>
+      <i
+        v-if="loading"
+        class="icon-spin4 user-finder-icon animate-spin-slow"
+      />
+      <a
+        v-if="hidden"
+        href="#"
+        :title="$t('finder.find_user')"
+      ><i
+        class="icon-user-plus user-finder-icon"
+        @click.prevent.stop="toggleHidden"
+      /></a>
       <template v-else>
-        <input class="user-finder-input" ref="userSearchInput" @keyup.enter="findUser(username)" v-model="username" :placeholder="$t('finder.find_user')" id="user-finder-input" type="text"/>
-        <button class="btn search-button" @click="findUser(username)">
-          <i class="icon-search"/>
+        <input
+          id="user-finder-input"
+          ref="userSearchInput"
+          v-model="username"
+          class="user-finder-input"
+          :placeholder="$t('finder.find_user')"
+          type="text"
+          @keyup.enter="findUser(username)"
+        >
+        <button
+          class="btn search-button"
+          @click="findUser(username)"
+        >
+          <i class="icon-search" />
         </button>
-        <i class="button-icon icon-cancel user-finder-icon" @click.prevent.stop="toggleHidden"/>
+        <i
+          class="button-icon icon-cancel user-finder-icon"
+          @click.prevent.stop="toggleHidden"
+        />
       </template>
     </div>
   </div>
@@ -25,7 +49,6 @@
   align-items: baseline;
   vertical-align: baseline;
 
-
   .user-finder-input,
   .search-button {
     height: 29px;
diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index 37e28ca5..c92630e3 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -1,13 +1,23 @@
 <template>
   <div class="user-panel">
-
-    <div v-if="signedIn" key="user-panel" class="panel panel-default signed-in">
-      <UserCard :user="user" :hideBio="true" rounded="top"/>
+    <div
+      v-if="signedIn"
+      key="user-panel"
+      class="panel panel-default signed-in"
+    >
+      <UserCard
+        :user="user"
+        :hide-bio="true"
+        rounded="top"
+      />
       <div class="panel-footer">
-        <post-status-form v-if='user'></post-status-form>
+        <post-status-form v-if="user" />
       </div>
     </div>
-    <auth-form v-else key="user-panel"/>
+    <auth-form
+      v-else
+      key="user-panel"
+    />
   </div>
 </template>
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 84a159da..4ea0a869 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -1,75 +1,110 @@
 <template>
-<div>
-  <div v-if="user" class="user-profile panel panel-default">
-    <UserCard :user="user" :switcher="true" :selected="timeline.viewing" rounded="top"/>
-    <tab-switcher :renderOnlyFocused="true" ref="tabSwitcher">
-      <div :label="$t('user_card.statuses')">
-        <div class="timeline">
-          <template v-for="statusId in user.pinnedStatuseIds">
-            <Conversation
-              v-if="timeline.statusesObject[statusId]"
-              class="status-fadein"
-              :key="statusId"
-              :statusoid="timeline.statusesObject[statusId]"
-              :collapsable="true"
-              :showPinned="true"
-            />
-          </template>
+  <div>
+    <div
+      v-if="user"
+      class="user-profile panel panel-default"
+    >
+      <UserCard
+        :user="user"
+        :switcher="true"
+        :selected="timeline.viewing"
+        rounded="top"
+      />
+      <tab-switcher
+        ref="tabSwitcher"
+        :render-only-focused="true"
+      >
+        <div :label="$t('user_card.statuses')">
+          <div class="timeline">
+            <template v-for="statusId in user.pinnedStatuseIds">
+              <Conversation
+                v-if="timeline.statusesObject[statusId]"
+                :key="statusId"
+                class="status-fadein"
+                :statusoid="timeline.statusesObject[statusId]"
+                :collapsable="true"
+                :show-pinned="true"
+              />
+            </template>
+          </div>
+          <Timeline
+            :count="user.statuses_count"
+            :embedded="true"
+            :title="$t('user_profile.timeline_title')"
+            :timeline="timeline"
+            :timeline-name="'user'"
+            :user-id="userId"
+          />
+        </div>
+        <div
+          v-if="followsTabVisible"
+          :label="$t('user_card.followees')"
+          :disabled="!user.friends_count"
+        >
+          <FriendList :user-id="userId">
+            <template
+              slot="item"
+              slot-scope="{item}"
+            >
+              <FollowCard :user="item" />
+            </template>
+          </FriendList>
+        </div>
+        <div
+          v-if="followersTabVisible"
+          :label="$t('user_card.followers')"
+          :disabled="!user.followers_count"
+        >
+          <FollowerList :user-id="userId">
+            <template
+              slot="item"
+              slot-scope="{item}"
+            >
+              <FollowCard
+                :user="item"
+                :no-follows-you="isUs"
+              />
+            </template>
+          </FollowerList>
         </div>
         <Timeline
-          :count="user.statuses_count"
+          :label="$t('user_card.media')"
+          :disabled="!media.visibleStatuses.length"
           :embedded="true"
-          :title="$t('user_profile.timeline_title')"
-          :timeline="timeline"
-          :timeline-name="'user'"
+          :title="$t('user_card.media')"
+          timeline-name="media"
+          :timeline="media"
           :user-id="userId"
         />
+        <Timeline
+          v-if="isUs"
+          :label="$t('user_card.favorites')"
+          :disabled="!favorites.visibleStatuses.length"
+          :embedded="true"
+          :title="$t('user_card.favorites')"
+          timeline-name="favorites"
+          :timeline="favorites"
+        />
+      </tab-switcher>
+    </div>
+    <div
+      v-else
+      class="panel user-profile-placeholder"
+    >
+      <div class="panel-heading">
+        <div class="title">
+          {{ $t('settings.profile_tab') }}
+        </div>
       </div>
-      <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
-        <FriendList :userId="userId">
-          <template slot="item" slot-scope="{item}">
-            <FollowCard :user="item" />
-          </template>
-        </FriendList>
-      </div>
-      <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
-        <FollowerList :userId="userId">
-          <template slot="item" slot-scope="{item}">
-            <FollowCard :user="item" :noFollowsYou="isUs" />
-          </template>
-        </FollowerList>
-      </div>
-      <Timeline
-        :label="$t('user_card.media')"
-        :disabled="!media.visibleStatuses.length"
-        :embedded="true" :title="$t('user_card.media')"
-        timeline-name="media"
-        :timeline="media"
-        :user-id="userId"
-      />
-      <Timeline
-        v-if="isUs"
-        :label="$t('user_card.favorites')"
-        :disabled="!favorites.visibleStatuses.length"
-        :embedded="true"
-        :title="$t('user_card.favorites')"
-        timeline-name="favorites"
-        :timeline="favorites"
-      />
-    </tab-switcher>
-  </div>
-  <div v-else class="panel user-profile-placeholder">
-    <div class="panel-heading">
-      <div class="title">
-        {{ $t('settings.profile_tab') }}
+      <div class="panel-body">
+        <span v-if="error">{{ error }}</span>
+        <i
+          v-else
+          class="icon-spin3 animate-spin"
+        />
       </div>
     </div>
-    <div class="panel-body">
-      <span v-if="error">{{ error }}</span>
-      <i class="icon-spin3 animate-spin" v-else></i>
-    </div>
   </div>
-</div>
 </template>
 
 <script src="./user_profile.js"></script>
diff --git a/src/components/user_reporting_modal/user_reporting_modal.vue b/src/components/user_reporting_modal/user_reporting_modal.vue
index 432dd14d..c79a3707 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.vue
+++ b/src/components/user_reporting_modal/user_reporting_modal.vue
@@ -1,45 +1,75 @@
 <template>
-<div class="modal-view" @click="closeModal" v-if="isOpen">
-  <div class="user-reporting-panel panel" @click.stop="">
-    <div class="panel-heading">
-      <div class="title">{{$t('user_reporting.title', [user.screen_name])}}</div>
-    </div>
-    <div class="panel-body">
-      <div class="user-reporting-panel-left">
-        <div>
-          <p>{{$t('user_reporting.add_comment_description')}}</p>
-          <textarea
-            v-model="comment"
-            class="form-control"
-            :placeholder="$t('user_reporting.additional_comments')"
-            rows="1"
-            @input="resize"
-          />
-        </div>
-        <div v-if="!user.is_local">
-          <p>{{$t('user_reporting.forward_description')}}</p>
-          <Checkbox v-model="forward">{{$t('user_reporting.forward_to', [remoteInstance])}}</Checkbox>
-        </div>
-        <div>
-          <button class="btn btn-default" @click="reportUser" :disabled="processing">{{$t('user_reporting.submit')}}</button>
-          <div class="alert error" v-if="error">
-            {{$t('user_reporting.generic_error')}}
-          </div>
+  <div
+    v-if="isOpen"
+    class="modal-view"
+    @click="closeModal"
+  >
+    <div
+      class="user-reporting-panel panel"
+      @click.stop=""
+    >
+      <div class="panel-heading">
+        <div class="title">
+          {{ $t('user_reporting.title', [user.screen_name]) }}
         </div>
       </div>
-      <div class="user-reporting-panel-right">
-        <List :items="statuses">
-          <template slot="item" slot-scope="{item}">
-            <div class="status-fadein user-reporting-panel-sitem">
-              <Status :inConversation="false" :focused="false" :statusoid="item" />
-              <Checkbox :checked="isChecked(item.id)" @change="checked => toggleStatus(checked, item.id)" />
+      <div class="panel-body">
+        <div class="user-reporting-panel-left">
+          <div>
+            <p>{{ $t('user_reporting.add_comment_description') }}</p>
+            <textarea
+              v-model="comment"
+              class="form-control"
+              :placeholder="$t('user_reporting.additional_comments')"
+              rows="1"
+              @input="resize"
+            />
+          </div>
+          <div v-if="!user.is_local">
+            <p>{{ $t('user_reporting.forward_description') }}</p>
+            <Checkbox v-model="forward">
+              {{ $t('user_reporting.forward_to', [remoteInstance]) }}
+            </Checkbox>
+          </div>
+          <div>
+            <button
+              class="btn btn-default"
+              :disabled="processing"
+              @click="reportUser"
+            >
+              {{ $t('user_reporting.submit') }}
+            </button>
+            <div
+              v-if="error"
+              class="alert error"
+            >
+              {{ $t('user_reporting.generic_error') }}
             </div>
-          </template>
-        </List>
+          </div>
+        </div>
+        <div class="user-reporting-panel-right">
+          <List :items="statuses">
+            <template
+              slot="item"
+              slot-scope="{item}"
+            >
+              <div class="status-fadein user-reporting-panel-sitem">
+                <Status
+                  :in-conversation="false"
+                  :focused="false"
+                  :statusoid="item"
+                />
+                <Checkbox
+                  :checked="isChecked(item.id)"
+                  @change="checked => toggleStatus(checked, item.id)"
+                />
+              </div>
+            </template>
+          </List>
+        </div>
       </div>
     </div>
   </div>
-</div>
 </template>
 
 <script src="./user_reporting_modal.js"></script>
diff --git a/src/components/user_search/user_search.vue b/src/components/user_search/user_search.vue
index 890b3c13..e1c6074c 100644
--- a/src/components/user_search/user_search.vue
+++ b/src/components/user_search/user_search.vue
@@ -1,19 +1,39 @@
 <template>
   <div class="user-search panel panel-default">
     <div class="panel-heading">
-      {{$t('nav.user_search')}}
+      {{ $t('nav.user_search') }}
     </div>
     <div class="user-search-input-container">
-      <input class="user-finder-input" ref="userSearchInput" @keyup.enter="newQuery(username)" v-model="username" :placeholder="$t('finder.find_user')"/>
-      <button class="btn search-button" @click="newQuery(username)">
-        <i class="icon-search"/>
+      <input
+        ref="userSearchInput"
+        v-model="username"
+        class="user-finder-input"
+        :placeholder="$t('finder.find_user')"
+        @keyup.enter="newQuery(username)"
+      >
+      <button
+        class="btn search-button"
+        @click="newQuery(username)"
+      >
+        <i class="icon-search" />
       </button>
     </div>
-    <div v-if="loading" class="text-center loading-icon">
-      <i class="icon-spin3 animate-spin"/>
+    <div
+      v-if="loading"
+      class="text-center loading-icon"
+    >
+      <i class="icon-spin3 animate-spin" />
     </div>
-    <div v-else class="panel-body">
-      <FollowCard v-for="user in users" :key="user.id" :user="user" class="list-item"/>
+    <div
+      v-else
+      class="panel-body"
+    >
+      <FollowCard
+        v-for="user in users"
+        :key="user.id"
+        :user="user"
+        class="list-item"
+      />
     </div>
   </div>
 </template>
diff --git a/src/components/user_settings/confirm.vue b/src/components/user_settings/confirm.vue
index 46a42e38..69b3811b 100644
--- a/src/components/user_settings/confirm.vue
+++ b/src/components/user_settings/confirm.vue
@@ -1,13 +1,21 @@
 <template>
-<div>
-  <slot></slot>
-  <button class="btn btn-default" @click="confirm" :disabled="disabled">
-    {{$t('general.confirm')}}
-  </button>
-  <button class="btn btn-default" @click="cancel" :disabled="disabled">
-    {{$t('general.cancel')}}
-  </button>
-</div>
+  <div>
+    <slot />
+    <button
+      class="btn btn-default"
+      :disabled="disabled"
+      @click="confirm"
+    >
+      {{ $t('general.confirm') }}
+    </button>
+    <button
+      class="btn btn-default"
+      :disabled="disabled"
+      @click="cancel"
+    >
+      {{ $t('general.cancel') }}
+    </button>
+  </div>
 </template>
 
 <script src="./confirm.js">
diff --git a/src/components/user_settings/mfa.vue b/src/components/user_settings/mfa.vue
index 1f1be60d..14ea10a1 100644
--- a/src/components/user_settings/mfa.vue
+++ b/src/components/user_settings/mfa.vue
@@ -1,86 +1,138 @@
 <template>
-<div class="setting-item mfa-settings" v-if="readyInit && settings.available">
-
-  <div class="mfa-heading">
-    <h2>{{$t('settings.mfa.title')}}</h2>
-  </div>
-
-  <div>
-    <div class="setting-item" v-if="!setupInProgress">
-      <!-- Enabled methods -->
-      <h3>{{$t('settings.mfa.authentication_methods')}}</h3>
-      <totp-item :settings="settings" @deactivate="fetchSettings" @activate="activateOTP"/>
-      <br />
-
-      <div v-if="settings.enabled"> <!-- backup codes block-->
-        <recovery-codes :backup-codes="backupCodes" v-if="!confirmNewBackupCodes" />
-        <button class="btn btn-default" @click="getBackupCodes" v-if="!confirmNewBackupCodes">
-          {{$t('settings.mfa.generate_new_recovery_codes')}}
-        </button>
+  <div
+    v-if="readyInit && settings.available"
+    class="setting-item mfa-settings"
+  >
+    <div class="mfa-heading">
+      <h2>{{ $t('settings.mfa.title') }}</h2>
+    </div>
 
-        <div v-if="confirmNewBackupCodes">
-          <confirm @confirm="confirmBackupCodes" @cancel="cancelBackupCodes"
-                   :disabled="backupCodes.inProgress">
-            <p class="warning">{{$t('settings.mfa.warning_of_generate_new_codes')}}</p>
-          </confirm>
+    <div>
+      <div
+        v-if="!setupInProgress"
+        class="setting-item"
+      >
+        <!-- Enabled methods -->
+        <h3>{{ $t('settings.mfa.authentication_methods') }}</h3>
+        <totp-item
+          :settings="settings"
+          @deactivate="fetchSettings"
+          @activate="activateOTP"
+        />
+        <br>
+
+        <div v-if="settings.enabled">
+          <!-- backup codes block-->
+          <recovery-codes
+            v-if="!confirmNewBackupCodes"
+            :backup-codes="backupCodes"
+          />
+          <button
+            v-if="!confirmNewBackupCodes"
+            class="btn btn-default"
+            @click="getBackupCodes"
+          >
+            {{ $t('settings.mfa.generate_new_recovery_codes') }}
+          </button>
+
+          <div v-if="confirmNewBackupCodes">
+            <confirm
+              :disabled="backupCodes.inProgress"
+              @confirm="confirmBackupCodes"
+              @cancel="cancelBackupCodes"
+            >
+              <p class="warning">
+                {{ $t('settings.mfa.warning_of_generate_new_codes') }}
+              </p>
+            </confirm>
+          </div>
         </div>
       </div>
-    </div>
-
-    <div v-if="setupInProgress"> <!-- setup block-->
 
-      <h3>{{$t('settings.mfa.setup_otp')}}</h3>
+      <div v-if="setupInProgress">
+        <!-- setup block-->
 
-      <recovery-codes :backup-codes="backupCodes" v-if="!setupOTPInProgress"/>
+        <h3>{{ $t('settings.mfa.setup_otp') }}</h3>
 
+        <recovery-codes
+          v-if="!setupOTPInProgress"
+          :backup-codes="backupCodes"
+        />
 
-      <button class="btn btn-default" @click="cancelSetup" v-if="canSetupOTP">
-        {{$t('general.cancel')}}
-      </button>
-
-      <button class="btn btn-default" v-if="canSetupOTP" @click="setupOTP">
-        {{$t('settings.mfa.setup_otp')}}
-      </button>
-
-      <template v-if="setupOTPInProgress">
-        <i v-if="prepareOTP">{{$t('settings.mfa.wait_pre_setup_otp')}}</i>
+        <button
+          v-if="canSetupOTP"
+          class="btn btn-default"
+          @click="cancelSetup"
+        >
+          {{ $t('general.cancel') }}
+        </button>
 
-        <div v-if="confirmOTP">
-          <div class="setup-otp">
-            <div class="qr-code">
-              <h4>{{$t('settings.mfa.scan.title')}}</h4>
-              <p>{{$t('settings.mfa.scan.desc')}}</p>
-              <qrcode :value="otpSettings.provisioning_uri" :options="{ width: 200 }"></qrcode>
-              <p>
-                {{$t('settings.mfa.scan.secret_code')}}:
-                {{otpSettings.key}}
-              </p>
-            </div>
+        <button
+          v-if="canSetupOTP"
+          class="btn btn-default"
+          @click="setupOTP"
+        >
+          {{ $t('settings.mfa.setup_otp') }}
+        </button>
 
-            <div class="verify">
-              <h4>{{$t('general.verify')}}</h4>
-              <p>{{$t('settings.mfa.verify.desc')}}</p>
-              <input type="text" v-model="otpConfirmToken">
+        <template v-if="setupOTPInProgress">
+          <i v-if="prepareOTP">{{ $t('settings.mfa.wait_pre_setup_otp') }}</i>
+
+          <div v-if="confirmOTP">
+            <div class="setup-otp">
+              <div class="qr-code">
+                <h4>{{ $t('settings.mfa.scan.title') }}</h4>
+                <p>{{ $t('settings.mfa.scan.desc') }}</p>
+                <qrcode
+                  :value="otpSettings.provisioning_uri"
+                  :options="{ width: 200 }"
+                />
+                <p>
+                  {{ $t('settings.mfa.scan.secret_code') }}:
+                  {{ otpSettings.key }}
+                </p>
+              </div>
 
-              <p>{{$t('settings.enter_current_password_to_confirm')}}:</p>
-              <input type="password" v-model="currentPassword">
-              <div class="confirm-otp-actions">
-                <button class="btn btn-default" @click="doConfirmOTP">
-                  {{$t('settings.mfa.confirm_and_enable')}}
-                </button>
-                <button class="btn btn-default" @click="cancelSetup">
-                  {{$t('general.cancel')}}
-                </button>
+              <div class="verify">
+                <h4>{{ $t('general.verify') }}</h4>
+                <p>{{ $t('settings.mfa.verify.desc') }}</p>
+                <input
+                  v-model="otpConfirmToken"
+                  type="text"
+                >
+
+                <p>{{ $t('settings.enter_current_password_to_confirm') }}:</p>
+                <input
+                  v-model="currentPassword"
+                  type="password"
+                >
+                <div class="confirm-otp-actions">
+                  <button
+                    class="btn btn-default"
+                    @click="doConfirmOTP"
+                  >
+                    {{ $t('settings.mfa.confirm_and_enable') }}
+                  </button>
+                  <button
+                    class="btn btn-default"
+                    @click="cancelSetup"
+                  >
+                    {{ $t('general.cancel') }}
+                  </button>
+                </div>
+                <div
+                  v-if="error"
+                  class="alert error"
+                >
+                  {{ error }}
+                </div>
               </div>
-              <div class="alert error" v-if="error">{{error}}</div>
             </div>
           </div>
-        </div>
-      </template>
+        </template>
+      </div>
     </div>
-
   </div>
-</div>
 </template>
 
 <script src="./mfa.js"></script>
diff --git a/src/components/user_settings/mfa_backup_codes.vue b/src/components/user_settings/mfa_backup_codes.vue
index c275bd63..62542839 100644
--- a/src/components/user_settings/mfa_backup_codes.vue
+++ b/src/components/user_settings/mfa_backup_codes.vue
@@ -1,12 +1,20 @@
 <template>
-<div>
-  <h4 v-if="displayTitle">{{$t('settings.mfa.recovery_codes')}}</h4>
-  <i v-if="inProgress">{{$t('settings.mfa.waiting_a_recovery_codes')}}</i>
-  <template v-if="ready">
-    <p class="alert warning">{{$t('settings.mfa.recovery_codes_warning')}}</p>
-    <ul class="backup-codes"><li v-for="code in backupCodes.codes">{{code}}</li></ul>
-  </template>
-</div>
+  <div>
+    <h4 v-if="displayTitle">
+      {{ $t('settings.mfa.recovery_codes') }}
+    </h4>
+    <i v-if="inProgress">{{ $t('settings.mfa.waiting_a_recovery_codes') }}</i>
+    <template v-if="ready">
+      <p class="alert warning">
+        {{ $t('settings.mfa.recovery_codes_warning') }}
+      </p>
+      <ul class="backup-codes">
+        <li v-for="code in backupCodes.codes">
+          {{ code }}
+        </li>
+      </ul>
+    </template>
+  </div>
 </template>
 <script src="./mfa_backup_codes.js"></script>
 <style lang="scss">
diff --git a/src/components/user_settings/mfa_totp.vue b/src/components/user_settings/mfa_totp.vue
index 6b73c8f4..c6f2cc7b 100644
--- a/src/components/user_settings/mfa_totp.vue
+++ b/src/components/user_settings/mfa_totp.vue
@@ -1,23 +1,43 @@
 <template>
-<div>
-  <div class="method-item">
-    <strong>{{$t('settings.mfa.otp')}}</strong>
-    <button class="btn btn-default" v-if="!isActivated" @click="doActivate">
-      {{$t('general.enable')}}
-    </button>
+  <div>
+    <div class="method-item">
+      <strong>{{ $t('settings.mfa.otp') }}</strong>
+      <button
+        v-if="!isActivated"
+        class="btn btn-default"
+        @click="doActivate"
+      >
+        {{ $t('general.enable') }}
+      </button>
 
-    <button class="btn btn-default" :disabled="deactivate" @click="doDeactivate"
-            v-if="isActivated">
-      {{$t('general.disable')}}
-    </button>
-  </div>
+      <button
+        v-if="isActivated"
+        class="btn btn-default"
+        :disabled="deactivate"
+        @click="doDeactivate"
+      >
+        {{ $t('general.disable') }}
+      </button>
+    </div>
 
-  <confirm @confirm="confirmDeactivate" @cancel="cancelDeactivate"
-           :disabled="inProgress" v-if="deactivate">
-    {{$t('settings.enter_current_password_to_confirm')}}:
-    <input type="password" v-model="currentPassword">
-  </confirm>
-  <div class="alert error" v-if="error">{{error}}</div>
-</div>
+    <confirm
+      v-if="deactivate"
+      :disabled="inProgress"
+      @confirm="confirmDeactivate"
+      @cancel="cancelDeactivate"
+    >
+      {{ $t('settings.enter_current_password_to_confirm') }}:
+      <input
+        v-model="currentPassword"
+        type="password"
+      >
+    </confirm>
+    <div
+      v-if="error"
+      class="alert error"
+    >
+      {{ error }}
+    </div>
+  </div>
 </template>
 <script src="./mfa_totp.js"></script>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 94f1b1f1..34ea8569 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -2,15 +2,23 @@
   <div class="settings panel panel-default">
     <div class="panel-heading">
       <div class="title">
-        {{$t('settings.user_settings')}}
+        {{ $t('settings.user_settings') }}
       </div>
       <transition name="fade">
         <template v-if="currentSaveStateNotice">
-          <div @click.prevent class="alert error" v-if="currentSaveStateNotice.error">
+          <div
+            v-if="currentSaveStateNotice.error"
+            class="alert error"
+            @click.prevent
+          >
             {{ $t('settings.saving_err') }}
           </div>
 
-          <div @click.prevent class="alert transparent" v-if="!currentSaveStateNotice.error">
+          <div
+            v-if="!currentSaveStateNotice.error"
+            class="alert transparent"
+            @click.prevent
+          >
             {{ $t('settings.saving_ok') }}
           </div>
         </template>
@@ -19,135 +27,267 @@
     <div class="panel-body profile-edit">
       <tab-switcher>
         <div :label="$t('settings.profile_tab')">
-          <div class="setting-item" >
-            <h2>{{$t('settings.name_bio')}}</h2>
-            <p>{{$t('settings.name')}}</p>
-            <EmojiInput :suggest="emojiSuggestor" v-model="newName">
+          <div class="setting-item">
+            <h2>{{ $t('settings.name_bio') }}</h2>
+            <p>{{ $t('settings.name') }}</p>
+            <EmojiInput
+              v-model="newName"
+              :suggest="emojiSuggestor"
+            >
               <input
-                v-model="newName"
                 id="username"
+                v-model="newName"
                 classname="name-changer"
-              />
+              >
             </EmojiInput>
-            <p>{{$t('settings.bio')}}</p>
-            <EmojiInput :suggest="emojiUserSuggestor" v-model="newBio">
+            <p>{{ $t('settings.bio') }}</p>
+            <EmojiInput
+              v-model="newBio"
+              :suggest="emojiUserSuggestor"
+            >
               <textarea
                 v-model="newBio"
                 classname="bio"
-                />
+              />
             </EmojiInput>
             <p>
-              <input type="checkbox" v-model="newLocked" id="account-locked">
-              <label for="account-locked">{{$t('settings.lock_account_description')}}</label>
+              <input
+                id="account-locked"
+                v-model="newLocked"
+                type="checkbox"
+              >
+              <label for="account-locked">{{ $t('settings.lock_account_description') }}</label>
             </p>
             <div>
-              <label for="default-vis">{{$t('settings.default_vis')}}</label>
-              <div id="default-vis" class="visibility-tray">
+              <label for="default-vis">{{ $t('settings.default_vis') }}</label>
+              <div
+                id="default-vis"
+                class="visibility-tray"
+              >
                 <scope-selector
-                  :showAll="true"
-                  :userDefault="newDefaultScope"
-                  :initialScope="newDefaultScope"
-                  :onScopeChange="changeVis"/>
+                  :show-all="true"
+                  :user-default="newDefaultScope"
+                  :initial-scope="newDefaultScope"
+                  :on-scope-change="changeVis"
+                />
               </div>
             </div>
             <p>
-              <input type="checkbox" v-model="newNoRichText" id="account-no-rich-text">
-              <label for="account-no-rich-text">{{$t('settings.no_rich_text_description')}}</label>
+              <input
+                id="account-no-rich-text"
+                v-model="newNoRichText"
+                type="checkbox"
+              >
+              <label for="account-no-rich-text">{{ $t('settings.no_rich_text_description') }}</label>
             </p>
             <p>
-              <input type="checkbox" v-model="hideFollows" id="account-hide-follows">
-              <label for="account-hide-follows">{{$t('settings.hide_follows_description')}}</label>
+              <input
+                id="account-hide-follows"
+                v-model="hideFollows"
+                type="checkbox"
+              >
+              <label for="account-hide-follows">{{ $t('settings.hide_follows_description') }}</label>
             </p>
             <p>
-              <input type="checkbox" v-model="hideFollowers" id="account-hide-followers">
-              <label for="account-hide-followers">{{$t('settings.hide_followers_description')}}</label>
+              <input
+                id="account-hide-followers"
+                v-model="hideFollowers"
+                type="checkbox"
+              >
+              <label for="account-hide-followers">{{ $t('settings.hide_followers_description') }}</label>
             </p>
             <p>
-              <input type="checkbox" v-model="showRole" id="account-show-role">
-              <label for="account-show-role" v-if="role === 'admin'">{{$t('settings.show_admin_badge')}}</label>
-              <label for="account-show-role" v-if="role === 'moderator'">{{$t('settings.show_moderator_badge')}}</label>
+              <input
+                id="account-show-role"
+                v-model="showRole"
+                type="checkbox"
+              >
+              <label
+                v-if="role === 'admin'"
+                for="account-show-role"
+              >{{ $t('settings.show_admin_badge') }}</label>
+              <label
+                v-if="role === 'moderator'"
+                for="account-show-role"
+              >{{ $t('settings.show_moderator_badge') }}</label>
             </p>
-            <button :disabled='newName && newName.length === 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
+            <button
+              :disabled="newName && newName.length === 0"
+              class="btn btn-default"
+              @click="updateProfile"
+            >
+              {{ $t('general.submit') }}
+            </button>
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.avatar')}}</h2>
-            <p class="visibility-notice">{{$t('settings.avatar_size_instruction')}}</p>
-            <p>{{$t('settings.current_avatar')}}</p>
-            <img :src="user.profile_image_url_original" class="current-avatar" />
-            <p>{{$t('settings.set_new_avatar')}}</p>
-            <button class="btn" type="button" id="pick-avatar" v-show="pickAvatarBtnVisible">{{$t('settings.upload_a_photo')}}</button>
-            <image-cropper trigger="#pick-avatar" :submitHandler="submitAvatar" @open="pickAvatarBtnVisible=false" @close="pickAvatarBtnVisible=true" />
+            <h2>{{ $t('settings.avatar') }}</h2>
+            <p class="visibility-notice">
+              {{ $t('settings.avatar_size_instruction') }}
+            </p>
+            <p>{{ $t('settings.current_avatar') }}</p>
+            <img
+              :src="user.profile_image_url_original"
+              class="current-avatar"
+            >
+            <p>{{ $t('settings.set_new_avatar') }}</p>
+            <button
+              v-show="pickAvatarBtnVisible"
+              id="pick-avatar"
+              class="btn"
+              type="button"
+            >
+              {{ $t('settings.upload_a_photo') }}
+            </button>
+            <image-cropper
+              trigger="#pick-avatar"
+              :submit-handler="submitAvatar"
+              @open="pickAvatarBtnVisible=false"
+              @close="pickAvatarBtnVisible=true"
+            />
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.profile_banner')}}</h2>
-            <p>{{$t('settings.current_profile_banner')}}</p>
-            <img :src="user.cover_photo" class="banner" />
-            <p>{{$t('settings.set_new_profile_banner')}}</p>
-            <img class="banner" v-bind:src="bannerPreview" v-if="bannerPreview" />
+            <h2>{{ $t('settings.profile_banner') }}</h2>
+            <p>{{ $t('settings.current_profile_banner') }}</p>
+            <img
+              :src="user.cover_photo"
+              class="banner"
+            >
+            <p>{{ $t('settings.set_new_profile_banner') }}</p>
+            <img
+              v-if="bannerPreview"
+              class="banner"
+              :src="bannerPreview"
+            >
             <div>
-              <input type="file" @change="uploadFile('banner', $event)" />
+              <input
+                type="file"
+                @change="uploadFile('banner', $event)"
+              >
             </div>
-            <i class=" icon-spin4 animate-spin uploading" v-if="bannerUploading"></i>
-            <button class="btn btn-default" v-else-if="bannerPreview" @click="submitBanner">{{$t('general.submit')}}</button>
-            <div class='alert error' v-if="bannerUploadError">
+            <i
+              v-if="bannerUploading"
+              class=" icon-spin4 animate-spin uploading"
+            />
+            <button
+              v-else-if="bannerPreview"
+              class="btn btn-default"
+              @click="submitBanner"
+            >
+              {{ $t('general.submit') }}
+            </button>
+            <div
+              v-if="bannerUploadError"
+              class="alert error"
+            >
               Error: {{ bannerUploadError }}
-              <i class="button-icon icon-cancel" @click="clearUploadError('banner')"></i>
+              <i
+                class="button-icon icon-cancel"
+                @click="clearUploadError('banner')"
+              />
             </div>
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.profile_background')}}</h2>
-            <p>{{$t('settings.set_new_profile_background')}}</p>
-            <img class="bg" v-bind:src="backgroundPreview" v-if="backgroundPreview" />
+            <h2>{{ $t('settings.profile_background') }}</h2>
+            <p>{{ $t('settings.set_new_profile_background') }}</p>
+            <img
+              v-if="backgroundPreview"
+              class="bg"
+              :src="backgroundPreview"
+            >
             <div>
-              <input type="file" @change="uploadFile('background', $event)" />
+              <input
+                type="file"
+                @change="uploadFile('background', $event)"
+              >
             </div>
-            <i class=" icon-spin4 animate-spin uploading" v-if="backgroundUploading"></i>
-            <button class="btn btn-default" v-else-if="backgroundPreview" @click="submitBg">{{$t('general.submit')}}</button>
-            <div class='alert error' v-if="backgroundUploadError">
+            <i
+              v-if="backgroundUploading"
+              class=" icon-spin4 animate-spin uploading"
+            />
+            <button
+              v-else-if="backgroundPreview"
+              class="btn btn-default"
+              @click="submitBg"
+            >
+              {{ $t('general.submit') }}
+            </button>
+            <div
+              v-if="backgroundUploadError"
+              class="alert error"
+            >
               Error: {{ backgroundUploadError }}
-              <i class="button-icon icon-cancel" @click="clearUploadError('background')"></i>
+              <i
+                class="button-icon icon-cancel"
+                @click="clearUploadError('background')"
+              />
             </div>
           </div>
         </div>
 
         <div :label="$t('settings.security_tab')">
           <div class="setting-item">
-            <h2>{{$t('settings.change_password')}}</h2>
+            <h2>{{ $t('settings.change_password') }}</h2>
             <div>
-              <p>{{$t('settings.current_password')}}</p>
-              <input type="password" v-model="changePasswordInputs[0]">
+              <p>{{ $t('settings.current_password') }}</p>
+              <input
+                v-model="changePasswordInputs[0]"
+                type="password"
+              >
             </div>
             <div>
-              <p>{{$t('settings.new_password')}}</p>
-              <input type="password" v-model="changePasswordInputs[1]">
+              <p>{{ $t('settings.new_password') }}</p>
+              <input
+                v-model="changePasswordInputs[1]"
+                type="password"
+              >
             </div>
             <div>
-              <p>{{$t('settings.confirm_new_password')}}</p>
-              <input type="password" v-model="changePasswordInputs[2]">
+              <p>{{ $t('settings.confirm_new_password') }}</p>
+              <input
+                v-model="changePasswordInputs[2]"
+                type="password"
+              >
             </div>
-            <button class="btn btn-default" @click="changePassword">{{$t('general.submit')}}</button>
-            <p v-if="changedPassword">{{$t('settings.changed_password')}}</p>
-            <p v-else-if="changePasswordError !== false">{{$t('settings.change_password_error')}}</p>
-            <p v-if="changePasswordError">{{changePasswordError}}</p>
+            <button
+              class="btn btn-default"
+              @click="changePassword"
+            >
+              {{ $t('general.submit') }}
+            </button>
+            <p v-if="changedPassword">
+              {{ $t('settings.changed_password') }}
+            </p>
+            <p v-else-if="changePasswordError !== false">
+              {{ $t('settings.change_password_error') }}
+            </p>
+            <p v-if="changePasswordError">
+              {{ changePasswordError }}
+            </p>
           </div>
 
           <div class="setting-item">
-            <h2>{{$t('settings.oauth_tokens')}}</h2>
+            <h2>{{ $t('settings.oauth_tokens') }}</h2>
             <table class="oauth-tokens">
               <thead>
                 <tr>
-                  <th>{{$t('settings.app_name')}}</th>
-                  <th>{{$t('settings.valid_until')}}</th>
-                  <th></th>
+                  <th>{{ $t('settings.app_name') }}</th>
+                  <th>{{ $t('settings.valid_until') }}</th>
+                  <th />
                 </tr>
               </thead>
               <tbody>
-                <tr v-for="oauthToken in oauthTokens" :key="oauthToken.id">
-                  <td>{{oauthToken.appName}}</td>
-                  <td>{{oauthToken.validUntil}}</td>
+                <tr
+                  v-for="oauthToken in oauthTokens"
+                  :key="oauthToken.id"
+                >
+                  <td>{{ oauthToken.appName }}</td>
+                  <td>{{ oauthToken.validUntil }}</td>
                   <td class="actions">
-                    <button class="btn btn-default" @click="revokeToken(oauthToken.id)">
-                      {{$t('settings.revoke_token')}}
+                    <button
+                      class="btn btn-default"
+                      @click="revokeToken(oauthToken.id)"
+                    >
+                      {{ $t('settings.revoke_token') }}
                     </button>
                   </td>
                 </tr>
@@ -156,123 +296,250 @@
           </div>
           <mfa />
           <div class="setting-item">
-            <h2>{{$t('settings.delete_account')}}</h2>
-            <p v-if="!deletingAccount">{{$t('settings.delete_account_description')}}</p>
+            <h2>{{ $t('settings.delete_account') }}</h2>
+            <p v-if="!deletingAccount">
+              {{ $t('settings.delete_account_description') }}
+            </p>
             <div v-if="deletingAccount">
-              <p>{{$t('settings.delete_account_instructions')}}</p>
-              <p>{{$t('login.password')}}</p>
-              <input type="password" v-model="deleteAccountConfirmPasswordInput">
-              <button class="btn btn-default" @click="deleteAccount">{{$t('settings.delete_account')}}</button>
+              <p>{{ $t('settings.delete_account_instructions') }}</p>
+              <p>{{ $t('login.password') }}</p>
+              <input
+                v-model="deleteAccountConfirmPasswordInput"
+                type="password"
+              >
+              <button
+                class="btn btn-default"
+                @click="deleteAccount"
+              >
+                {{ $t('settings.delete_account') }}
+              </button>
             </div>
-            <p v-if="deleteAccountError !== false">{{$t('settings.delete_account_error')}}</p>
-            <p v-if="deleteAccountError">{{deleteAccountError}}</p>
-            <button class="btn btn-default" v-if="!deletingAccount" @click="confirmDelete">{{$t('general.submit')}}</button>
+            <p v-if="deleteAccountError !== false">
+              {{ $t('settings.delete_account_error') }}
+            </p>
+            <p v-if="deleteAccountError">
+              {{ deleteAccountError }}
+            </p>
+            <button
+              v-if="!deletingAccount"
+              class="btn btn-default"
+              @click="confirmDelete"
+            >
+              {{ $t('general.submit') }}
+            </button>
           </div>
         </div>
 
-        <div :label="$t('settings.notifications')" v-if="pleromaBackend">
+        <div
+          v-if="pleromaBackend"
+          :label="$t('settings.notifications')"
+        >
           <div class="setting-item">
             <div class="select-multiple">
-              <span class="label">{{$t('settings.notification_setting')}}</span>
+              <span class="label">{{ $t('settings.notification_setting') }}</span>
               <ul class="option-list">
                 <li>
-                  <input type="checkbox" id="notification-setting-follows" v-model="notificationSettings.follows">
+                  <input
+                    id="notification-setting-follows"
+                    v-model="notificationSettings.follows"
+                    type="checkbox"
+                  >
                   <label for="notification-setting-follows">
-                  {{$t('settings.notification_setting_follows')}}
+                    {{ $t('settings.notification_setting_follows') }}
                   </label>
                 </li>
                 <li>
-                  <input type="checkbox" id="notification-setting-followers" v-model="notificationSettings.followers">
+                  <input
+                    id="notification-setting-followers"
+                    v-model="notificationSettings.followers"
+                    type="checkbox"
+                  >
                   <label for="notification-setting-followers">
-                  {{$t('settings.notification_setting_followers')}}
+                    {{ $t('settings.notification_setting_followers') }}
                   </label>
                 </li>
                 <li>
-                  <input type="checkbox" id="notification-setting-non-follows" v-model="notificationSettings.non_follows">
+                  <input
+                    id="notification-setting-non-follows"
+                    v-model="notificationSettings.non_follows"
+                    type="checkbox"
+                  >
                   <label for="notification-setting-non-follows">
-                  {{$t('settings.notification_setting_non_follows')}}
+                    {{ $t('settings.notification_setting_non_follows') }}
                   </label>
                 </li>
                 <li>
-                  <input type="checkbox" id="notification-setting-non-followers" v-model="notificationSettings.non_followers">
+                  <input
+                    id="notification-setting-non-followers"
+                    v-model="notificationSettings.non_followers"
+                    type="checkbox"
+                  >
                   <label for="notification-setting-non-followers">
-                  {{$t('settings.notification_setting_non_followers')}}
+                    {{ $t('settings.notification_setting_non_followers') }}
                   </label>
                 </li>
               </ul>
             </div>
-            <p>{{$t('settings.notification_mutes')}}</p>
-            <p>{{$t('settings.notification_blocks')}}</p>
-            <button class="btn btn-default" @click="updateNotificationSettings">{{$t('general.submit')}}</button>
+            <p>{{ $t('settings.notification_mutes') }}</p>
+            <p>{{ $t('settings.notification_blocks') }}</p>
+            <button
+              class="btn btn-default"
+              @click="updateNotificationSettings"
+            >
+              {{ $t('general.submit') }}
+            </button>
           </div>
         </div>
 
-        <div :label="$t('settings.data_import_export_tab')" v-if="pleromaBackend">
+        <div
+          v-if="pleromaBackend"
+          :label="$t('settings.data_import_export_tab')"
+        >
           <div class="setting-item">
-            <h2>{{$t('settings.follow_import')}}</h2>
-            <p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
-            <Importer :submitHandler="importFollows" :successMessage="$t('settings.follows_imported')" :errorMessage="$t('settings.follow_import_error')" />
+            <h2>{{ $t('settings.follow_import') }}</h2>
+            <p>{{ $t('settings.import_followers_from_a_csv_file') }}</p>
+            <Importer
+              :submit-handler="importFollows"
+              :success-message="$t('settings.follows_imported')"
+              :error-message="$t('settings.follow_import_error')"
+            />
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.follow_export')}}</h2>
-            <Exporter :getContent="getFollowsContent" filename="friends.csv" :exportButtonLabel="$t('settings.follow_export_button')" />
+            <h2>{{ $t('settings.follow_export') }}</h2>
+            <Exporter
+              :get-content="getFollowsContent"
+              filename="friends.csv"
+              :export-button-label="$t('settings.follow_export_button')"
+            />
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.block_import')}}</h2>
-            <p>{{$t('settings.import_blocks_from_a_csv_file')}}</p>
-            <Importer :submitHandler="importBlocks" :successMessage="$t('settings.blocks_imported')" :errorMessage="$t('settings.block_import_error')" />
+            <h2>{{ $t('settings.block_import') }}</h2>
+            <p>{{ $t('settings.import_blocks_from_a_csv_file') }}</p>
+            <Importer
+              :submit-handler="importBlocks"
+              :success-message="$t('settings.blocks_imported')"
+              :error-message="$t('settings.block_import_error')"
+            />
           </div>
           <div class="setting-item">
-            <h2>{{$t('settings.block_export')}}</h2>
-            <Exporter :getContent="getBlocksContent" filename="blocks.csv" :exportButtonLabel="$t('settings.block_export_button')" />
+            <h2>{{ $t('settings.block_export') }}</h2>
+            <Exporter
+              :get-content="getBlocksContent"
+              filename="blocks.csv"
+              :export-button-label="$t('settings.block_export_button')"
+            />
           </div>
         </div>
 
         <div :label="$t('settings.blocks_tab')">
           <div class="profile-edit-usersearch-wrapper">
-            <Autosuggest :filter="filterUnblockedUsers" :query="queryUserIds" :placeholder="$t('settings.search_user_to_block')">
-              <BlockCard slot-scope="row" :userId="row.item"/>
+            <Autosuggest
+              :filter="filterUnblockedUsers"
+              :query="queryUserIds"
+              :placeholder="$t('settings.search_user_to_block')"
+            >
+              <BlockCard
+                slot-scope="row"
+                :user-id="row.item"
+              />
             </Autosuggest>
           </div>
-          <BlockList :refresh="true" :getKey="identity">
-            <template slot="header" slot-scope="{selected}">
+          <BlockList
+            :refresh="true"
+            :get-key="identity"
+          >
+            <template
+              slot="header"
+              slot-scope="{selected}"
+            >
               <div class="profile-edit-bulk-actions">
-                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => blockUsers(selected)">
+                <ProgressButton
+                  v-if="selected.length > 0"
+                  class="btn btn-default"
+                  :click="() => blockUsers(selected)"
+                >
                   {{ $t('user_card.block') }}
-                  <template slot="progress">{{ $t('user_card.block_progress') }}</template>
+                  <template slot="progress">
+                    {{ $t('user_card.block_progress') }}
+                  </template>
                 </ProgressButton>
-                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => unblockUsers(selected)">
+                <ProgressButton
+                  v-if="selected.length > 0"
+                  class="btn btn-default"
+                  :click="() => unblockUsers(selected)"
+                >
                   {{ $t('user_card.unblock') }}
-                  <template slot="progress">{{ $t('user_card.unblock_progress') }}</template>
+                  <template slot="progress">
+                    {{ $t('user_card.unblock_progress') }}
+                  </template>
                 </ProgressButton>
               </div>
             </template>
-            <template slot="item" slot-scope="{item}"><BlockCard :userId="item" /></template>
-            <template slot="empty">{{$t('settings.no_blocks')}}</template>
+            <template
+              slot="item"
+              slot-scope="{item}"
+            >
+              <BlockCard :user-id="item" />
+            </template>
+            <template slot="empty">
+              {{ $t('settings.no_blocks') }}
+            </template>
           </BlockList>
         </div>
 
         <div :label="$t('settings.mutes_tab')">
           <div class="profile-edit-usersearch-wrapper">
-            <Autosuggest :filter="filterUnMutedUsers" :query="queryUserIds" :placeholder="$t('settings.search_user_to_mute')">
-              <MuteCard slot-scope="row" :userId="row.item"/>
+            <Autosuggest
+              :filter="filterUnMutedUsers"
+              :query="queryUserIds"
+              :placeholder="$t('settings.search_user_to_mute')"
+            >
+              <MuteCard
+                slot-scope="row"
+                :user-id="row.item"
+              />
             </Autosuggest>
           </div>
-          <MuteList :refresh="true" :getKey="identity">
-            <template slot="header" slot-scope="{selected}">
+          <MuteList
+            :refresh="true"
+            :get-key="identity"
+          >
+            <template
+              slot="header"
+              slot-scope="{selected}"
+            >
               <div class="profile-edit-bulk-actions">
-                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => muteUsers(selected)">
+                <ProgressButton
+                  v-if="selected.length > 0"
+                  class="btn btn-default"
+                  :click="() => muteUsers(selected)"
+                >
                   {{ $t('user_card.mute') }}
-                  <template slot="progress">{{ $t('user_card.mute_progress') }}</template>
+                  <template slot="progress">
+                    {{ $t('user_card.mute_progress') }}
+                  </template>
                 </ProgressButton>
-                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => unmuteUsers(selected)">
+                <ProgressButton
+                  v-if="selected.length > 0"
+                  class="btn btn-default"
+                  :click="() => unmuteUsers(selected)"
+                >
                   {{ $t('user_card.unmute') }}
-                  <template slot="progress">{{ $t('user_card.unmute_progress') }}</template>
+                  <template slot="progress">
+                    {{ $t('user_card.unmute_progress') }}
+                  </template>
                 </ProgressButton>
               </div>
             </template>
-            <template slot="item" slot-scope="{item}"><MuteCard :userId="item" /></template>
-            <template slot="empty">{{$t('settings.no_mutes')}}</template>
+            <template
+              slot="item"
+              slot-scope="{item}"
+            >
+              <MuteCard :user-id="item" />
+            </template>
+            <template slot="empty">
+              {{ $t('settings.no_mutes') }}
+            </template>
           </MuteList>
         </div>
       </tab-switcher>
diff --git a/src/components/video_attachment/video_attachment.vue b/src/components/video_attachment/video_attachment.vue
index 68de201e..97ddf1cd 100644
--- a/src/components/video_attachment/video_attachment.vue
+++ b/src/components/video_attachment/video_attachment.vue
@@ -1,10 +1,11 @@
 <template>
-  <video class="video"
-    @loadeddata="onVideoDataLoad"
+  <video
+    class="video"
     :src="attachment.url"
     :loop="loopVideo"
     :controls="controls"
     playsinline
+    @loadeddata="onVideoDataLoad"
   />
 </template>
 
diff --git a/src/components/who_to_follow/who_to_follow.vue b/src/components/who_to_follow/who_to_follow.vue
index 8bc9a728..3a17d0e2 100644
--- a/src/components/who_to_follow/who_to_follow.vue
+++ b/src/components/who_to_follow/who_to_follow.vue
@@ -1,10 +1,15 @@
 <template>
   <div class="panel panel-default">
     <div class="panel-heading">
-      {{$t('who_to_follow.who_to_follow')}}
+      {{ $t('who_to_follow.who_to_follow') }}
     </div>
     <div class="panel-body">
-      <FollowCard v-for="user in users" :key="user.id" :user="user" class="list-item"/>
+      <FollowCard
+        v-for="user in users"
+        :key="user.id"
+        :user="user"
+        class="list-item"
+      />
     </div>
   </div>
 </template>
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.vue b/src/components/who_to_follow_panel/who_to_follow_panel.vue
index 74e82789..b26e5f4f 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.vue
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.vue
@@ -3,19 +3,22 @@
     <div class="panel panel-default base01-background">
       <div class="panel-heading timeline-heading base02-background base04">
         <div class="title">
-          {{$t('who_to_follow.who_to_follow')}}
+          {{ $t('who_to_follow.who_to_follow') }}
         </div>
       </div>
       <div class="who-to-follow">
-        <p v-for="user in usersToFollow" class="who-to-follow-items">
-          <img v-bind:src="user.img" />
-            <router-link v-bind:to="userProfileLink(user.id, user.name)">
-              {{user.name}}
-            </router-link><br />
+        <p
+          v-for="user in usersToFollow"
+          class="who-to-follow-items"
+        >
+          <img :src="user.img">
+          <router-link :to="userProfileLink(user.id, user.name)">
+            {{ user.name }}
+          </router-link><br>
         </p>
         <p class="who-to-follow-more">
           <router-link :to="{ name: 'who-to-follow' }">
-            {{$t('who_to_follow.more')}}
+            {{ $t('who_to_follow.more') }}
           </router-link>
         </p>
       </div>
-- 
cgit v1.2.3-70-g09d2


From 020c6d1bcfaf67ccb9ecdab13a39a1ddea868bb6 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 7 Jul 2019 00:54:17 +0300
Subject: all the manual fixes

---
 .eslintrc.js                                       | 22 +----------------
 src/components/attachment/attachment.vue           |  2 ++
 src/components/basic_user_card/basic_user_card.vue |  2 ++
 src/components/chat_panel/chat_panel.vue           |  2 +-
 src/components/conversation/conversation.js        |  1 +
 src/components/font_control/font_control.vue       |  1 +
 src/components/gallery/gallery.vue                 |  3 ++-
 .../instance_specific_panel.vue                    |  2 ++
 .../interface_language_switcher.vue                |  1 +
 src/components/link-preview/link-preview.vue       |  2 +-
 src/components/media_modal/media_modal.vue         |  2 +-
 src/components/media_upload/media_upload.vue       |  2 +-
 src/components/notification/notification.vue       |  2 ++
 src/components/poll/poll.vue                       |  2 +-
 src/components/poll/poll_form.vue                  |  1 +
 .../post_status_form/post_status_form.vue          |  3 ++-
 src/components/registration/registration.vue       |  7 +++++-
 src/components/shadow_control/shadow_control.vue   |  1 +
 src/components/status/status.js                    |  2 +-
 src/components/status/status.vue                   | 28 ++++++++++++----------
 src/components/style_switcher/style_switcher.vue   |  2 ++
 .../terms_of_service_panel.vue                     |  2 ++
 src/components/user_card/user_card.js              |  4 ++--
 src/components/user_card/user_card.vue             |  4 ++++
 src/components/user_settings/mfa_backup_codes.vue  |  5 +++-
 .../who_to_follow_panel/who_to_follow_panel.vue    |  1 +
 src/modules/auth_flow.js                           |  1 +
 src/modules/users.js                               |  8 +++----
 .../backend_interactor_service.js                  |  6 +++++
 test/unit/karma.conf.js                            |  4 ++--
 .../entity_normalizer/entity_normalizer.spec.js    |  6 -----
 31 files changed, 74 insertions(+), 57 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/.eslintrc.js b/.eslintrc.js
index 7d090208..3c48baa8 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -21,26 +21,6 @@ module.exports = {
     'generator-star-spacing': 0,
     // allow debugger during development
     'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
-    // Webpack 4 update commit, most of these probably should be fixed and removed in a separate MR
-    // A lot of errors come from .vue files that are now properly linted
-    'vue/valid-v-if': 1,
-    'vue/use-v-on-exact': 1,
-    'vue/no-parsing-error': 1,
-    'vue/require-v-for-key': 1,
-    'vue/valid-v-for': 1,
-    'vue/require-prop-types': 1,
-    'vue/no-use-v-if-with-v-for': 1,
-    'indent': 1,
-    'import/first': 1,
-    'object-curly-spacing': 1,
-    'prefer-promise-reject-errors': 1,
-    'eol-last': 1,
-    'no-return-await': 1,
-    'no-multi-spaces': 1,
-    'no-trailing-spaces': 1,
-    'no-unused-expressions': 1,
-    'no-mixed-operators': 1,
-    'camelcase': 1,
-    'no-multiple-empty-lines': 1
+    'vue/require-prop-types': 0
   }
 }
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 55d81691..108dc36e 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -97,8 +97,10 @@
         <img :src="attachment.thumb_url">
       </div>
       <div class="text">
+        <!-- eslint-disable vue/no-v-html -->
         <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
         <div v-html="attachment.oembed.oembedHTML" />
+        <!-- eslint-enabled vue/no-v-html -->
       </div>
     </div>
   </div>
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 8ad0da2d..568e9359 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -25,11 +25,13 @@
         :title="user.name"
         class="basic-user-card-user-name"
       >
+        <!-- eslint-disable vue/no-v-html -->
         <span
           v-if="user.name_html"
           class="basic-user-card-user-name-value"
           v-html="user.name_html"
         />
+        <!-- eslint-enable vue/no-v-html -->
         <span
           v-else
           class="basic-user-card-user-name-value"
diff --git a/src/components/chat_panel/chat_panel.vue b/src/components/chat_panel/chat_panel.vue
index ca2c64a3..3677722f 100644
--- a/src/components/chat_panel/chat_panel.vue
+++ b/src/components/chat_panel/chat_panel.vue
@@ -1,6 +1,6 @@
 <template>
   <div
-    v-if="!this.collapsed || !this.floating"
+    v-if="!collapsed || !floating"
     class="chat-panel"
   >
     <div class="panel panel-default">
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index cc0b0b41..a2b3aeab 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -86,6 +86,7 @@ const conversation = {
     },
     replies () {
       let i = 1
+      // eslint-disable-next-line camelcase
       return reduce(this.conversation, (result, { id, in_reply_to_status_id }) => {
         /* eslint-disable camelcase */
         const irid = in_reply_to_status_id
diff --git a/src/components/font_control/font_control.vue b/src/components/font_control/font_control.vue
index 87644628..61f0384b 100644
--- a/src/components/font_control/font_control.vue
+++ b/src/components/font_control/font_control.vue
@@ -35,6 +35,7 @@
       >
         <option
           v-for="option in availableOptions"
+          :key="option"
           :value="option"
         >
           {{ option === 'custom' ? $t('settings.style.fonts.custom') : option }}
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 577f2144..6adfb76c 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -4,7 +4,8 @@
     style="width: 100%;"
   >
     <div
-      v-for="row in rows"
+      v-for="(row, index) in rows"
+      :key="index"
       class="gallery-row"
       :style="rowHeight(row.length)"
       :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
diff --git a/src/components/instance_specific_panel/instance_specific_panel.vue b/src/components/instance_specific_panel/instance_specific_panel.vue
index 64ce4f8a..a7cf6b48 100644
--- a/src/components/instance_specific_panel/instance_specific_panel.vue
+++ b/src/components/instance_specific_panel/instance_specific_panel.vue
@@ -5,7 +5,9 @@
   >
     <div class="panel panel-default">
       <div class="panel-body">
+        <!-- eslint-disable vue/no-v-html -->
         <div v-html="instanceSpecificPanelContent" />
+        <!-- eslint-enable vue/no-v-html -->
       </div>
     </div>
   </div>
diff --git a/src/components/interface_language_switcher/interface_language_switcher.vue b/src/components/interface_language_switcher/interface_language_switcher.vue
index 28c811bd..83df9a0b 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.vue
+++ b/src/components/interface_language_switcher/interface_language_switcher.vue
@@ -13,6 +13,7 @@
       >
         <option
           v-for="(langCode, i) in languageCodes"
+          :key="langCode"
           :value="langCode"
         >
           {{ languageNames[i] }}
diff --git a/src/components/link-preview/link-preview.vue b/src/components/link-preview/link-preview.vue
index 5041dd1d..493774c2 100644
--- a/src/components/link-preview/link-preview.vue
+++ b/src/components/link-preview/link-preview.vue
@@ -11,7 +11,7 @@
         class="card-image"
         :class="{ 'small-image': size === 'small' }"
       >
-        <img :src="card.image"></img>
+        <img :src="card.image">
       </div>
       <div class="card-content">
         <span class="card-host faint">{{ card.provider_name }}</span>
diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue
index f14740f6..0543e677 100644
--- a/src/components/media_modal/media_modal.vue
+++ b/src/components/media_modal/media_modal.vue
@@ -8,7 +8,7 @@
       v-if="type === 'image'"
       class="modal-image"
       :src="currentMedia.url"
-    ></img>
+    >
     <VideoAttachment
       v-if="type === 'video'"
       class="modal-image"
diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue
index 60ce2d42..ac32ae83 100644
--- a/src/components/media_upload/media_upload.vue
+++ b/src/components/media_upload/media_upload.vue
@@ -23,7 +23,7 @@
         style="position: fixed; top: -100em"
         multiple="true"
         @change="change"
-      ></input>
+      >
     </label>
   </div>
 </template>
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 88f4e886..bafcd026 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -30,12 +30,14 @@
       />
       <span class="notification-details">
         <div class="name-and-action">
+          <!-- eslint-disable vue/no-v-html -->
           <span
             v-if="!!notification.from_profile.name_html"
             class="username"
             :title="'@'+notification.from_profile.screen_name"
             v-html="notification.from_profile.name_html"
           />
+          <!-- eslint-enable vue/no-v-html -->
           <span
             v-else
             class="username"
diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue
index 0fc81b46..db8e33b3 100644
--- a/src/components/poll/poll.vue
+++ b/src/components/poll/poll.vue
@@ -60,7 +60,7 @@
       </div>
       <i18n :path="expired ? 'polls.expired' : 'polls.expires_in'">
         <Timeago
-          :time="this.expiresAt"
+          :time="expiresAt"
           :auto-update="60"
           :now-threshold="0"
         />
diff --git a/src/components/poll/poll_form.vue b/src/components/poll/poll_form.vue
index 2bd3d058..d53f3837 100644
--- a/src/components/poll/poll_form.vue
+++ b/src/components/poll/poll_form.vue
@@ -77,6 +77,7 @@
           >
             <option
               v-for="unit in expiryUnits"
+              :key="unit"
               :value="unit"
             >
               {{ $t(`time.${unit}_short`, ['']) }}
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 379c9f3b..1f389eda 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -206,6 +206,7 @@
       <div class="attachments">
         <div
           v-for="file in newStatus.files"
+          :key="file.url"
           class="media-upload-wrapper"
         >
           <i
@@ -217,7 +218,7 @@
               v-if="type(file) === 'image'"
               class="thumbnail media-upload"
               :src="file.url"
-            ></img>
+            >
             <video
               v-if="type(file) === 'video'"
               :src="file.url"
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue
index 8cc4ba56..e0fa214a 100644
--- a/src/components/registration/registration.vue
+++ b/src/components/registration/registration.vue
@@ -215,17 +215,22 @@
             </div>
           </div>
 
+          <!-- eslint-disable vue/no-v-html -->
           <div
             class="terms-of-service"
             v-html="termsOfService"
           />
+          <!-- eslint-enable vue/no-v-html -->
         </div>
         <div
           v-if="serverValidationErrors.length"
           class="form-group"
         >
           <div class="alert error">
-            <span v-for="error in serverValidationErrors">{{ error }}</span>
+            <span
+              v-for="error in serverValidationErrors"
+              :key="error"
+            >{{ error }}</span>
           </div>
         </div>
       </form>
diff --git a/src/components/shadow_control/shadow_control.vue b/src/components/shadow_control/shadow_control.vue
index faefe1ff..de8a42d1 100644
--- a/src/components/shadow_control/shadow_control.vue
+++ b/src/components/shadow_control/shadow_control.vue
@@ -72,6 +72,7 @@
           >
             <option
               v-for="(shadow, index) in cValue"
+              :key="index"
               :value="index"
             >
               {{ $t('settings.style.shadows.shadow_id', { value: index }) }}
diff --git a/src/components/status/status.js b/src/components/status/status.js
index d2452935..199351cb 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -221,7 +221,7 @@ const Status = {
         ? this.$store.state.instance.subjectLineBehavior
         : this.$store.state.config.subjectLineBehavior
       const startsWithRe = decodedSummary.match(/^re[: ]/i)
-      if (behavior !== 'noop' && startsWithRe || behavior === 'masto') {
+      if ((behavior !== 'noop' && startsWithRe) || behavior === 'masto') {
         return decodedSummary
       } else if (behavior === 'email') {
         return 're: '.concat(decodedSummary)
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index e482cfd8..6f7f826b 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -1,4 +1,5 @@
 <template>
+  <!-- eslint-disable vue/no-v-html -->
   <div
     v-if="!hideStatus"
     class="status-el"
@@ -205,18 +206,20 @@
                   v-if="replies && replies.length"
                   class="faint"
                 >{{ $t('status.replies_list') }}</span>
-                <span
-                  v-for="reply in replies"
-                  v-if="replies"
-                  class="reply-link faint"
-                >
-                  <a
-                    href="#"
-                    @click.prevent="gotoOriginal(reply.id)"
-                    @mouseenter="replyEnter(reply.id, $event)"
-                    @mouseout="replyLeave()"
-                  >{{ reply.name }}</a>
-                </span>
+                <template v-if="replies">
+                  <span
+                    v-for="reply in replies"
+                    :key="reply.id"
+                    class="reply-link faint"
+                  >
+                    <a
+                      href="#"
+                      @click.prevent="gotoOriginal(reply.id)"
+                      @mouseenter="replyEnter(reply.id, $event)"
+                      @mouseout="replyLeave()"
+                    >{{ reply.name }}</a>
+                  </span>
+                </template>
               </div>
             </div>
           </div>
@@ -422,6 +425,7 @@
       </div>
     </template>
   </div>
+<!-- eslint-enable vue/no-v-html -->
 </template>
 
 <script src="./status.js" ></script>
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
index 97dba99d..d24394a4 100644
--- a/src/components/style_switcher/style_switcher.vue
+++ b/src/components/style_switcher/style_switcher.vue
@@ -24,6 +24,7 @@
                 >
                   <option
                     v-for="style in availableStyles"
+                    :key="style.name"
                     :value="style"
                     :style="{
                       backgroundColor: style[1] || style.theme.colors.bg,
@@ -463,6 +464,7 @@
                 >
                   <option
                     v-for="shadow in shadowsAvailable"
+                    :key="shadow"
                     :value="shadow"
                   >
                     {{ $t('settings.style.shadows.components.' + shadow) }}
diff --git a/src/components/terms_of_service_panel/terms_of_service_panel.vue b/src/components/terms_of_service_panel/terms_of_service_panel.vue
index f79345cb..63dc58b8 100644
--- a/src/components/terms_of_service_panel/terms_of_service_panel.vue
+++ b/src/components/terms_of_service_panel/terms_of_service_panel.vue
@@ -2,10 +2,12 @@
   <div>
     <div class="panel panel-default">
       <div class="panel-body">
+        <!-- eslint-disable vue/no-v-html -->
         <div
           class="tos-content"
           v-html="content"
         />
+      <!-- eslint-enable vue/no-v-html -->
       </div>
     </div>
   </div>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 63dfa6ed..92cd0e54 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -73,12 +73,12 @@ export default {
     userHighlightType: {
       get () {
         const data = this.$store.state.config.highlight[this.user.screen_name]
-        return data && data.type || 'disabled'
+        return (data && data.type) || 'disabled'
       },
       set (type) {
         const data = this.$store.state.config.highlight[this.user.screen_name]
         if (type !== 'disabled') {
-          this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: data && data.color || '#FFFFFF', type })
+          this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: (data && data.color) || '#FFFFFF', type })
         } else {
           this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: undefined })
         }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 7ad8aa1d..5a5a4881 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -15,12 +15,14 @@
           </router-link>
           <div class="user-summary">
             <div class="top-line">
+              <!-- eslint-disable vue/no-v-html -->
               <div
                 v-if="user.name_html"
                 :title="user.name"
                 class="user-name"
                 v-html="user.name_html"
               />
+              <!-- eslint-enable vue/no-v-html -->
               <div
                 v-else
                 :title="user.name"
@@ -237,12 +239,14 @@
           <span>{{ user.followers_count }}</span>
         </div>
       </div>
+      <!-- eslint-disable vue/no-v-html -->
       <p
         v-if="!hideBio && user.description_html"
         class="user-card-bio"
         @click.prevent="linkClicked"
         v-html="user.description_html"
       />
+      <!-- eslint-enable vue/no-v-html -->
       <p
         v-else-if="!hideBio"
         class="user-card-bio"
diff --git a/src/components/user_settings/mfa_backup_codes.vue b/src/components/user_settings/mfa_backup_codes.vue
index 62542839..e6c8ede2 100644
--- a/src/components/user_settings/mfa_backup_codes.vue
+++ b/src/components/user_settings/mfa_backup_codes.vue
@@ -9,7 +9,10 @@
         {{ $t('settings.mfa.recovery_codes_warning') }}
       </p>
       <ul class="backup-codes">
-        <li v-for="code in backupCodes.codes">
+        <li
+          v-for="code in backupCodes.codes"
+          :key="code"
+        >
           {{ code }}
         </li>
       </ul>
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.vue b/src/components/who_to_follow_panel/who_to_follow_panel.vue
index b26e5f4f..518acd97 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.vue
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.vue
@@ -9,6 +9,7 @@
       <div class="who-to-follow">
         <p
           v-for="user in usersToFollow"
+          :key="user.id"
           class="who-to-follow-items"
         >
           <img :src="user.img">
diff --git a/src/modules/auth_flow.js b/src/modules/auth_flow.js
index 34e15053..d0a90feb 100644
--- a/src/modules/auth_flow.js
+++ b/src/modules/auth_flow.js
@@ -73,6 +73,7 @@ const mutations = {
 
 // actions
 const actions = {
+  // eslint-disable-next-line camelcase
   async login ({ state, dispatch, commit }, { access_token }) {
     commit('setToken', access_token, { root: true })
     await dispatch('loginUser', access_token, { root: true })
diff --git a/src/modules/users.js b/src/modules/users.js
index 3cd38d56..d06e77c7 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -393,7 +393,7 @@ const users = {
       }
     },
     async getCaptcha (store) {
-      return await store.rootState.api.backendInteractor.getCaptcha()
+      return store.rootState.api.backendInteractor.getCaptcha()
     },
 
     logout (store) {
@@ -451,9 +451,9 @@ const users = {
               // Authentication failed
               commit('endLogin')
               if (response.status === 401) {
-                reject('Wrong username or password')
+                reject(new Error('Wrong username or password'))
               } else {
-                reject('An error occurred, please try again')
+                reject(new Error('An error occurred, please try again'))
               }
             }
             commit('endLogin')
@@ -462,7 +462,7 @@ const users = {
           .catch((error) => {
             console.log(error)
             commit('endLogin')
-            reject('Failed to connect to server, try again')
+            reject(new Error('Failed to connect to server, try again'))
           })
       })
     }
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index e095d3d2..3550aafd 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -63,26 +63,32 @@ const backendInteractorService = credentials => {
     return notificationsFetcher.startFetching({ store, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const tagUser = ({ screen_name }, tag) => {
     return apiService.tagUser({ screen_name, tag, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const untagUser = ({ screen_name }, tag) => {
     return apiService.untagUser({ screen_name, tag, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const addRight = ({ screen_name }, right) => {
     return apiService.addRight({ screen_name, right, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const deleteRight = ({ screen_name }, right) => {
     return apiService.deleteRight({ screen_name, right, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const setActivationStatus = ({ screen_name }, status) => {
     return apiService.setActivationStatus({ screen_name, status, credentials })
   }
 
+  // eslint-disable-next-line camelcase
   const deleteUser = ({ screen_name }) => {
     return apiService.deleteUser({ screen_name, credentials })
   }
diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js
index f9500ce8..8af05c24 100644
--- a/test/unit/karma.conf.js
+++ b/test/unit/karma.conf.js
@@ -3,12 +3,12 @@
 // we are also using it with karma-webpack
 //   https://github.com/webpack/karma-webpack
 
-var path = require('path')
+// var path = require('path')
 var merge = require('webpack-merge')
 var baseConfig = require('../../build/webpack.base.conf')
 var utils = require('../../build/utils')
 var webpack = require('webpack')
-var projectRoot = path.resolve(__dirname, '../../')
+// var projectRoot = path.resolve(__dirname, '../../')
 
 var webpackConfig = merge(baseConfig, {
   // use inline sourcemap for karma-sourcemap-loader
diff --git a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
index 556049b8..4ec643e2 100644
--- a/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
+++ b/test/unit/specs/services/entity_normalizer/entity_normalizer.spec.js
@@ -163,12 +163,6 @@ const makeMockEmojiMasto = (overrides = [{}]) => {
   ]
 }
 
-parseNotification
-parseUser
-parseStatus
-makeMockStatusQvitter
-makeMockUserQvitter
-
 describe('API Entities normalizer', () => {
   describe('parseStatus', () => {
     describe('QVitter preprocessing', () => {
-- 
cgit v1.2.3-70-g09d2


From d5e8315e83327c7b8dda71eca5dd1c9d7d0a23dc Mon Sep 17 00:00:00 2001
From: jared <jaredrmain@gmail.com>
Date: Tue, 16 Apr 2019 10:13:26 -0400
Subject: #482 - add subscribe button

---
 .../subscribe_button/subscribe_button.js           |  26 ++
 .../subscribe_button/subscribe_button.vue          |  22 ++
 src/components/user_card/user_card.js              |   4 +-
 src/components/user_card/user_card.vue             | 365 +++++++--------------
 src/modules/users.js                               |   1 +
 5 files changed, 172 insertions(+), 246 deletions(-)
 create mode 100644 src/components/subscribe_button/subscribe_button.js
 create mode 100644 src/components/subscribe_button/subscribe_button.vue

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/subscribe_button/subscribe_button.js b/src/components/subscribe_button/subscribe_button.js
new file mode 100644
index 00000000..e3a2842c
--- /dev/null
+++ b/src/components/subscribe_button/subscribe_button.js
@@ -0,0 +1,26 @@
+export default {
+  props: [ 'user' ],
+  data () {
+    return {
+      inProgress: false
+    }
+  },
+  methods: {
+    subscribe () {
+      this.inProgress = true
+      this.$store.state.api.backendInteractor.subscribeUser(this.user.id)
+        .then((updated) => {
+          console.log(updated)
+          this.inProgress = false
+        })
+    },
+    unsubscribe () {
+      this.inProgress = true
+      this.$store.state.api.backendInteractor.unsubscribeUser(this.user.id)
+        .then((updated) => {
+          console.log(updated)
+          this.inProgress = false
+        })
+    }
+  }
+}
diff --git a/src/components/subscribe_button/subscribe_button.vue b/src/components/subscribe_button/subscribe_button.vue
new file mode 100644
index 00000000..f7dd8c61
--- /dev/null
+++ b/src/components/subscribe_button/subscribe_button.vue
@@ -0,0 +1,22 @@
+<template>
+  <div>
+    <button
+      @click.prevent="subscribe"
+      class="btn btn-default follow-card-follow-button"
+      :disabled="inProgress"
+      v-if="!user.subscribing"
+    >
+      Subscribe
+    </button>
+    <button
+      @click.prevent="unsubscribe"
+      class="btn btn-default follow-card-follow-button pressed"
+      :disabled="inProgress"
+      v-else
+    >
+      Subscribing!
+    </button>
+  </div>
+</template>
+
+<script src="./subscribe_button.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 92cd0e54..bab1a654 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,5 +1,6 @@
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
+import SubscribeButton from '../subscribe_button/subscribe_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
@@ -104,7 +105,8 @@ export default {
   components: {
     UserAvatar,
     RemoteFollow,
-    ModerationTools
+    ModerationTools,
+    SubscribeButton
   },
   methods: {
     followUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 5a5a4881..18ec6e94 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -1,260 +1,135 @@
 <template>
-  <div
-    class="user-card"
-    :class="classes"
-    :style="style"
-  >
-    <div class="panel-heading">
-      <div class="user-info">
-        <div class="container">
-          <router-link :to="userProfileLink(user)">
-            <UserAvatar
-              :better-shadow="betterShadow"
-              :user="user"
-            />
-          </router-link>
-          <div class="user-summary">
-            <div class="top-line">
-              <!-- eslint-disable vue/no-v-html -->
-              <div
-                v-if="user.name_html"
-                :title="user.name"
-                class="user-name"
-                v-html="user.name_html"
-              />
-              <!-- eslint-enable vue/no-v-html -->
-              <div
-                v-else
-                :title="user.name"
-                class="user-name"
-              >
-                {{ user.name }}
-              </div>
-              <router-link
-                v-if="!isOtherUser"
-                :to="{ name: 'user-settings' }"
-              >
-                <i
-                  class="button-icon icon-wrench usersettings"
-                  :title="$t('tool_tip.user_settings')"
-                />
-              </router-link>
-              <a
-                v-if="isOtherUser && !user.is_local"
-                :href="user.statusnet_profile_url"
-                target="_blank"
-              >
-                <i class="icon-link-ext usersettings" />
-              </a>
-            </div>
-
-            <div class="bottom-line">
-              <router-link
-                class="user-screen-name"
-                :to="userProfileLink(user)"
-              >
-                @{{ user.screen_name }}
-              </router-link>
-              <span
-                v-if="!hideBio && !!visibleRole"
-                class="alert staff"
-              >{{ visibleRole }}</span>
-              <span v-if="user.locked"><i class="icon icon-lock" /></span>
-              <span
-                v-if="!hideUserStatsLocal && !hideBio"
-                class="dailyAvg"
-              >{{ dailyAvg }} {{ $t('user_card.per_day') }}</span>
-            </div>
+<div class="user-card" :class="classes" :style="style">
+  <div class="panel-heading">
+    <div class='user-info'>
+      <div class='container'>
+        <router-link :to="userProfileLink(user)">
+          <UserAvatar :betterShadow="betterShadow" :user="user"/>
+        </router-link>
+        <div class="user-summary">
+          <div class="top-line">
+            <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
+            <div :title="user.name" class='user-name' v-else>{{user.name}}</div>
+            <router-link :to="{ name: 'user-settings' }" v-if="!isOtherUser">
+              <i class="button-icon icon-wrench usersettings" :title="$t('tool_tip.user_settings')"></i>
+            </router-link>
+            <a :href="user.statusnet_profile_url" target="_blank" v-if="isOtherUser && !user.is_local">
+              <i class="icon-link-ext usersettings"></i>
+            </a>
           </div>
-        </div>
-        <div class="user-meta">
-          <div
-            v-if="user.follows_you && loggedIn && isOtherUser"
-            class="following"
-          >
-            {{ $t('user_card.follows_you') }}
-          </div>
-          <div
-            v-if="isOtherUser && (loggedIn || !switcher)"
-            class="highlighter"
-          >
-            <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
-            <input
-              v-if="userHighlightType !== 'disabled'"
-              :id="'userHighlightColorTx'+user.id"
-              v-model="userHighlightColor"
-              class="userHighlightText"
-              type="text"
-            >
-            <input
-              v-if="userHighlightType !== 'disabled'"
-              :id="'userHighlightColor'+user.id"
-              v-model="userHighlightColor"
-              class="userHighlightCl"
-              type="color"
-            >
-            <label
-              for="style-switcher"
-              class="userHighlightSel select"
-            >
-              <select
-                :id="'userHighlightSel'+user.id"
-                v-model="userHighlightType"
-                class="userHighlightSel"
-              >
-                <option value="disabled">No highlight</option>
-                <option value="solid">Solid bg</option>
-                <option value="striped">Striped bg</option>
-                <option value="side">Side stripe</option>
-              </select>
-              <i class="icon-down-open" />
-            </label>
+
+          <div class="bottom-line">
+            <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
+            <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
+            <span v-if="user.locked"><i class="icon icon-lock"></i></span>
+            <span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
           </div>
         </div>
-        <div
-          v-if="isOtherUser"
-          class="user-interactions"
-        >
-          <div
-            v-if="loggedIn"
-            class="follow"
-          >
-            <span v-if="user.following">
-              <!--Following them!-->
-              <button
-                class="pressed"
-                :disabled="followRequestInProgress"
-                :title="$t('user_card.follow_unfollow')"
-                @click="unfollowUser"
-              >
-                <template v-if="followRequestInProgress">
-                  {{ $t('user_card.follow_progress') }}
-                </template>
-                <template v-else>
-                  {{ $t('user_card.following') }}
-                </template>
-              </button>
-            </span>
-            <span v-if="!user.following">
-              <button
-                :disabled="followRequestInProgress"
-                :title="followRequestSent ? $t('user_card.follow_again') : ''"
-                @click="followUser"
-              >
-                <template v-if="followRequestInProgress">
-                  {{ $t('user_card.follow_progress') }}
-                </template>
-                <template v-else-if="followRequestSent">
-                  {{ $t('user_card.follow_sent') }}
-                </template>
-                <template v-else>
-                  {{ $t('user_card.follow') }}
-                </template>
-              </button>
-            </span>
-          </div>
-          <div
-            v-if="isOtherUser && loggedIn"
-            class="mute"
-          >
-            <span v-if="user.muted">
-              <button
-                class="pressed"
-                @click="unmuteUser"
-              >
-                {{ $t('user_card.muted') }}
-              </button>
-            </span>
-            <span v-if="!user.muted">
-              <button @click="muteUser">
-                {{ $t('user_card.mute') }}
-              </button>
-            </span>
-          </div>
-          <div v-if="!loggedIn && user.is_local">
-            <RemoteFollow :user="user" />
-          </div>
-          <div
-            v-if="isOtherUser && loggedIn"
-            class="block"
-          >
-            <span v-if="user.statusnet_blocking">
-              <button
-                class="pressed"
-                @click="unblockUser"
-              >
-                {{ $t('user_card.blocked') }}
-              </button>
-            </span>
-            <span v-if="!user.statusnet_blocking">
-              <button @click="blockUser">
-                {{ $t('user_card.block') }}
-              </button>
-            </span>
-          </div>
-          <div
-            v-if="isOtherUser && loggedIn"
-            class="block"
-          >
-            <span>
-              <button @click="reportUser">
-                {{ $t('user_card.report') }}
-              </button>
-            </span>
-          </div>
-          <ModerationTools
-            v-if="loggedIn.role === &quot;admin&quot;"
-            :user="user"
-          />
+      </div>
+      <div class="user-meta">
+        <div v-if="user.follows_you && loggedIn && isOtherUser" class="following">
+          {{ $t('user_card.follows_you') }}
+        </div>
+        <div class="highlighter" v-if="isOtherUser && (loggedIn || !switcher)">
+          <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
+          <input class="userHighlightText" type="text" :id="'userHighlightColorTx'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
+          <input class="userHighlightCl" type="color" :id="'userHighlightColor'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
+          <label for="style-switcher" class='userHighlightSel select'>
+            <select class="userHighlightSel" :id="'userHighlightSel'+user.id" v-model="userHighlightType">
+              <option value="disabled">No highlight</option>
+              <option value="solid">Solid bg</option>
+              <option value="striped">Striped bg</option>
+              <option value="side">Side stripe</option>
+            </select>
+            <i class="icon-down-open"/>
+          </label>
         </div>
       </div>
-    </div>
-    <div
-      v-if="!hideBio"
-      class="panel-body"
-    >
-      <div
-        v-if="!hideUserStatsLocal && switcher"
-        class="user-counts"
-      >
-        <div
-          class="user-count"
-          @click.prevent="setProfileView('statuses')"
-        >
-          <h5>{{ $t('user_card.statuses') }}</h5>
-          <span>{{ user.statuses_count }} <br></span>
+      <div v-if="isOtherUser" class="user-interactions">
+        <div class="follow" v-if="loggedIn">
+          <span v-if="user.following">
+            <!--Following them!-->
+            <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')">
+              <template v-if="followRequestInProgress">
+                {{ $t('user_card.follow_progress') }}
+              </template>
+              <template v-else>
+                {{ $t('user_card.following') }}
+              </template>
+            </button>
+          </span>
+          <span v-if="!user.following">
+            <button @click="followUser" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''">
+              <template v-if="followRequestInProgress">
+                {{ $t('user_card.follow_progress') }}
+              </template>
+              <template v-else-if="followRequestSent">
+                {{ $t('user_card.follow_sent') }}
+              </template>
+              <template v-else>
+                {{ $t('user_card.follow') }}
+              </template>
+            </button>
+          </span>
+        </div>
+        <SubscribeButton :user="user" />
+        <div class='mute' v-if='isOtherUser && loggedIn'>
+          <span v-if='user.muted'>
+            <button @click="unmuteUser" class="pressed">
+              {{ $t('user_card.muted') }}
+            </button>
+          </span>
+          <span v-if='!user.muted'>
+            <button @click="muteUser">
+              {{ $t('user_card.mute') }}
+            </button>
+          </span>
         </div>
-        <div
-          class="user-count"
-          @click.prevent="setProfileView('friends')"
-        >
-          <h5>{{ $t('user_card.followees') }}</h5>
-          <span>{{ user.friends_count }}</span>
+        <div v-if='!loggedIn && user.is_local'>
+          <RemoteFollow :user="user" />
         </div>
-        <div
-          class="user-count"
-          @click.prevent="setProfileView('followers')"
-        >
-          <h5>{{ $t('user_card.followers') }}</h5>
-          <span>{{ user.followers_count }}</span>
+        <div class='block' v-if='isOtherUser && loggedIn'>
+          <span v-if='user.statusnet_blocking'>
+            <button @click="unblockUser" class="pressed">
+              {{ $t('user_card.blocked') }}
+            </button>
+          </span>
+          <span v-if='!user.statusnet_blocking'>
+            <button @click="blockUser">
+              {{ $t('user_card.block') }}
+            </button>
+          </span>
         </div>
+        <div class='block' v-if='isOtherUser && loggedIn'>
+          <span>
+            <button @click="reportUser">
+              {{ $t('user_card.report') }}
+            </button>
+          </span>
+        </div>
+        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'/>
+      </div>
+    </div>
+  </div>
+  <div class="panel-body" v-if="!hideBio">
+    <div v-if="!hideUserStatsLocal && switcher" class="user-counts">
+      <div class="user-count" v-on:click.prevent="setProfileView('statuses')">
+        <h5>{{ $t('user_card.statuses') }}</h5>
+        <span>{{user.statuses_count}} <br></span>
+      </div>
+      <div class="user-count" v-on:click.prevent="setProfileView('friends')">
+        <h5>{{ $t('user_card.followees') }}</h5>
+        <span>{{user.friends_count}}</span>
+      </div>
+      <div class="user-count" v-on:click.prevent="setProfileView('followers')">
+        <h5>{{ $t('user_card.followers') }}</h5>
+        <span>{{user.followers_count}}</span>
       </div>
-      <!-- eslint-disable vue/no-v-html -->
-      <p
-        v-if="!hideBio && user.description_html"
-        class="user-card-bio"
-        @click.prevent="linkClicked"
-        v-html="user.description_html"
-      />
-      <!-- eslint-enable vue/no-v-html -->
-      <p
-        v-else-if="!hideBio"
-        class="user-card-bio"
-      >
-        {{ user.description }}
-      </p>
     </div>
+    <p @click.prevent="linkClicked" v-if="!hideBio && user.description_html" class="user-card-bio" v-html="user.description_html"></p>
+    <p v-else-if="!hideBio" class="user-card-bio">{{ user.description }}</p>
   </div>
+</div>
 </template>
 
 <script src="./user_card.js"></script>
diff --git a/src/modules/users.js b/src/modules/users.js
index 453a6899..f9b609b4 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -135,6 +135,7 @@ export const mutations = {
         user.following = relationship.following
         user.muted = relationship.muting
         user.statusnet_blocking = relationship.blocking
+        user.subscribing = relationship.subscribing
       }
     })
   },
-- 
cgit v1.2.3-70-g09d2


From 4cf402ff21c26fa9b82d2ea956ceb7ce8533146a Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 04:19:22 -0400
Subject: migrate SubscribeButton to the existing common component

---
 .../subscribe_button/subscribe_button.js           | 26 ----------------------
 .../subscribe_button/subscribe_button.vue          | 22 ------------------
 src/components/user_card/user_card.js              | 10 +++++++--
 src/components/user_card/user_card.vue             |  9 +++++++-
 4 files changed, 16 insertions(+), 51 deletions(-)
 delete mode 100644 src/components/subscribe_button/subscribe_button.js
 delete mode 100644 src/components/subscribe_button/subscribe_button.vue

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/subscribe_button/subscribe_button.js b/src/components/subscribe_button/subscribe_button.js
deleted file mode 100644
index e3a2842c..00000000
--- a/src/components/subscribe_button/subscribe_button.js
+++ /dev/null
@@ -1,26 +0,0 @@
-export default {
-  props: [ 'user' ],
-  data () {
-    return {
-      inProgress: false
-    }
-  },
-  methods: {
-    subscribe () {
-      this.inProgress = true
-      this.$store.state.api.backendInteractor.subscribeUser(this.user.id)
-        .then((updated) => {
-          console.log(updated)
-          this.inProgress = false
-        })
-    },
-    unsubscribe () {
-      this.inProgress = true
-      this.$store.state.api.backendInteractor.unsubscribeUser(this.user.id)
-        .then((updated) => {
-          console.log(updated)
-          this.inProgress = false
-        })
-    }
-  }
-}
diff --git a/src/components/subscribe_button/subscribe_button.vue b/src/components/subscribe_button/subscribe_button.vue
deleted file mode 100644
index f7dd8c61..00000000
--- a/src/components/subscribe_button/subscribe_button.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-<template>
-  <div>
-    <button
-      @click.prevent="subscribe"
-      class="btn btn-default follow-card-follow-button"
-      :disabled="inProgress"
-      v-if="!user.subscribing"
-    >
-      Subscribe
-    </button>
-    <button
-      @click.prevent="unsubscribe"
-      class="btn btn-default follow-card-follow-button pressed"
-      :disabled="inProgress"
-      v-else
-    >
-      Subscribing!
-    </button>
-  </div>
-</template>
-
-<script src="./subscribe_button.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index bab1a654..d7fe71d0 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,6 +1,6 @@
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
-import SubscribeButton from '../subscribe_button/subscribe_button.vue'
+import ProgressButton from '../progress_button/progress_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
@@ -106,7 +106,7 @@ export default {
     UserAvatar,
     RemoteFollow,
     ModerationTools,
-    SubscribeButton
+    ProgressButton
   },
   methods: {
     followUser () {
@@ -137,6 +137,12 @@ export default {
     unmuteUser () {
       this.$store.dispatch('unmuteUser', this.user.id)
     },
+    subscribeUser () {
+      return this.$store.state.api.backendInteractor.subscribeUser(this.user.id)
+    },
+    unsubscribeUser () {
+      return this.$store.state.api.backendInteractor.unsubscribeUser(this.user.id)
+    },
     setProfileView (v) {
       if (this.switcher) {
         const store = this.$store
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 18ec6e94..e1d3f48f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -72,7 +72,14 @@
             </button>
           </span>
         </div>
-        <SubscribeButton :user="user" />
+        <div>
+          <ProgressButton :click="subscribeUser" v-if="!user.subscribing">
+            Subscribe
+          </ProgressButton>
+          <ProgressButton class="pressed" :click="unsubscribeUser" v-else>
+            Subscribing!
+          </ProgressButton>
+        </div>
         <div class='mute' v-if='isOtherUser && loggedIn'>
           <span v-if='user.muted'>
             <button @click="unmuteUser" class="pressed">
-- 
cgit v1.2.3-70-g09d2


From deee07d6fbf950b34770143c61dbe6dd20b66ce5 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 04:33:18 -0400
Subject: show subscribe button only if user is logged in

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

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index e1d3f48f..f185b8b9 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -72,7 +72,7 @@
             </button>
           </span>
         </div>
-        <div>
+        <div v-if="loggedIn">
           <ProgressButton :click="subscribeUser" v-if="!user.subscribing">
             Subscribe
           </ProgressButton>
-- 
cgit v1.2.3-70-g09d2


From ace3b399ffe21459b1fbd7a3b0023f2c58c12b03 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 04:40:37 -0400
Subject: support i18n

---
 src/components/user_card/user_card.vue | 4 ++--
 src/i18n/en.json                       | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f185b8b9..cbf32db4 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -74,10 +74,10 @@
         </div>
         <div v-if="loggedIn">
           <ProgressButton :click="subscribeUser" v-if="!user.subscribing">
-            Subscribe
+            {{ $t('user_card.subscribe') }}
           </ProgressButton>
           <ProgressButton class="pressed" :click="unsubscribeUser" v-else>
-            Subscribing!
+            {{ $t('user_card.subscribing') }}
           </ProgressButton>
         </div>
         <div class='mute' v-if='isOtherUser && loggedIn'>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index dd34a95d..5a85bf9b 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -529,6 +529,8 @@
     "remote_follow": "Remote follow",
     "report": "Report",
     "statuses": "Statuses",
+    "subscribe": "Subscribe",
+    "subscribing": "Subscribing!",
     "unblock": "Unblock",
     "unblock_progress": "Unblocking...",
     "block_progress": "Blocking...",
-- 
cgit v1.2.3-70-g09d2


From 0c52d69a525aa200f03650e52f21d7b52a3918ca Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 12:32:26 -0400
Subject: update copy

---
 src/components/user_card/user_card.vue | 2 +-
 src/i18n/en.json                       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index cbf32db4..720415f0 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -77,7 +77,7 @@
             {{ $t('user_card.subscribe') }}
           </ProgressButton>
           <ProgressButton class="pressed" :click="unsubscribeUser" v-else>
-            {{ $t('user_card.subscribing') }}
+            {{ $t('user_card.subscribed') }}
           </ProgressButton>
         </div>
         <div class='mute' v-if='isOtherUser && loggedIn'>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 5a85bf9b..03455cce 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -530,7 +530,7 @@
     "report": "Report",
     "statuses": "Statuses",
     "subscribe": "Subscribe",
-    "subscribing": "Subscribing!",
+    "subscribed": "Subscribed",
     "unblock": "Unblock",
     "unblock_progress": "Unblocking...",
     "block_progress": "Blocking...",
-- 
cgit v1.2.3-70-g09d2


From 670cbfdd1c262ddd34717b88f879d5fb80280b60 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 12:33:50 -0400
Subject: change subscribing to subscribed

---
 src/components/user_card/user_card.vue                      | 2 +-
 src/modules/users.js                                        | 2 +-
 src/services/entity_normalizer/entity_normalizer.service.js | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 720415f0..5d23bf1e 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -73,7 +73,7 @@
           </span>
         </div>
         <div v-if="loggedIn">
-          <ProgressButton :click="subscribeUser" v-if="!user.subscribing">
+          <ProgressButton :click="subscribeUser" v-if="!user.subscribed">
             {{ $t('user_card.subscribe') }}
           </ProgressButton>
           <ProgressButton class="pressed" :click="unsubscribeUser" v-else>
diff --git a/src/modules/users.js b/src/modules/users.js
index c7ebbc85..57d3a3e3 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -135,7 +135,7 @@ export const mutations = {
         user.following = relationship.following
         user.muted = relationship.muting
         user.statusnet_blocking = relationship.blocking
-        user.subscribing = relationship.subscribing
+        user.subscribed = relationship.subscribing
       }
     })
   },
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 60c6285a..de6664d1 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -68,7 +68,7 @@ export const parseUser = (data) => {
         output.following = relationship.following
         output.statusnet_blocking = relationship.blocking
         output.muted = relationship.muting
-        output.subscribing = relationship.subscribing
+        output.subscribed = relationship.subscribing
       }
 
       output.hide_follows = data.pleroma.hide_follows
-- 
cgit v1.2.3-70-g09d2


From dbe2decc59d9e61a630b242edebe36c0669732c1 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 23:32:56 -0400
Subject: clean up UserCard template

---
 src/components/user_card/user_card.vue | 63 ++++++++++++++++------------------
 1 file changed, 29 insertions(+), 34 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 5d23bf1e..89b20e77 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -45,34 +45,29 @@
           </label>
         </div>
       </div>
-      <div v-if="isOtherUser" class="user-interactions">
-        <div class="follow" v-if="loggedIn">
-          <span v-if="user.following">
-            <!--Following them!-->
-            <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')">
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.following') }}
-              </template>
-            </button>
-          </span>
-          <span v-if="!user.following">
-            <button @click="followUser" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''">
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else-if="followRequestSent">
-                {{ $t('user_card.follow_sent') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.follow') }}
-              </template>
-            </button>
-          </span>
+      <div v-if="loggedIn && isOtherUser" class="user-interactions">
+        <div class="follow">
+          <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
+            <template v-if="followRequestInProgress">
+              {{ $t('user_card.follow_progress') }}
+            </template>
+            <template v-else>
+              {{ $t('user_card.following') }}
+            </template>
+          </button>
+          <button @click="followUser" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''" v-else>
+            <template v-if="followRequestInProgress">
+              {{ $t('user_card.follow_progress') }}
+            </template>
+            <template v-else-if="followRequestSent">
+              {{ $t('user_card.follow_sent') }}
+            </template>
+            <template v-else>
+              {{ $t('user_card.follow') }}
+            </template>
+          </button>
         </div>
-        <div v-if="loggedIn">
+        <div>
           <ProgressButton :click="subscribeUser" v-if="!user.subscribed">
             {{ $t('user_card.subscribe') }}
           </ProgressButton>
@@ -80,7 +75,7 @@
             {{ $t('user_card.subscribed') }}
           </ProgressButton>
         </div>
-        <div class='mute' v-if='isOtherUser && loggedIn'>
+        <div class='mute'>
           <span v-if='user.muted'>
             <button @click="unmuteUser" class="pressed">
               {{ $t('user_card.muted') }}
@@ -92,10 +87,7 @@
             </button>
           </span>
         </div>
-        <div v-if='!loggedIn && user.is_local'>
-          <RemoteFollow :user="user" />
-        </div>
-        <div class='block' v-if='isOtherUser && loggedIn'>
+        <div class='block'>
           <span v-if='user.statusnet_blocking'>
             <button @click="unblockUser" class="pressed">
               {{ $t('user_card.blocked') }}
@@ -107,14 +99,17 @@
             </button>
           </span>
         </div>
-        <div class='block' v-if='isOtherUser && loggedIn'>
+        <div class='block'>
           <span>
             <button @click="reportUser">
               {{ $t('user_card.report') }}
             </button>
           </span>
         </div>
-        <ModerationTools :user='user' v-if='loggedIn.role === "admin"'/>
+        <ModerationTools :user='user' v-if='loggedIn.role === "admin"' />
+      </div>
+      <div class="user-interactions" v-if="!loggedIn && user.is_local">
+        <RemoteFollow :user="user" />
       </div>
     </div>
   </div>
-- 
cgit v1.2.3-70-g09d2


From 0fc154d9d48caf21981699d46e4e649785877ac2 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Apr 2019 23:35:11 -0400
Subject: clean up UserCard css

---
 src/components/user_card/user_card.vue | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 89b20e77..eedb67b5 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -46,7 +46,7 @@
         </div>
       </div>
       <div v-if="loggedIn && isOtherUser" class="user-interactions">
-        <div class="follow">
+        <div>
           <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
             <template v-if="followRequestInProgress">
               {{ $t('user_card.follow_progress') }}
@@ -75,7 +75,7 @@
             {{ $t('user_card.subscribed') }}
           </ProgressButton>
         </div>
-        <div class='mute'>
+        <div>
           <span v-if='user.muted'>
             <button @click="unmuteUser" class="pressed">
               {{ $t('user_card.muted') }}
@@ -87,7 +87,7 @@
             </button>
           </span>
         </div>
-        <div class='block'>
+        <div>
           <span v-if='user.statusnet_blocking'>
             <button @click="unblockUser" class="pressed">
               {{ $t('user_card.blocked') }}
@@ -364,26 +364,15 @@
     display: flex;
     flex-flow: row wrap;
     justify-content: space-between;
-
     margin-right: -.75em;
 
-    div {
+    > div {
       flex: 1 0 0;
       margin-right: .75em;
       margin-bottom: .6em;
       white-space: nowrap;
     }
 
-    .mute {
-      max-width: 220px;
-      min-height: 28px;
-    }
-
-    .follow {
-      max-width: 220px;
-      min-height: 28px;
-    }
-
     button {
       width: 100%;
       height: 100%;
-- 
cgit v1.2.3-70-g09d2


From e1d6e56e1b5b189f0738fb174c23965b51bcd8f2 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 26 Apr 2019 00:39:43 -0400
Subject: clean up layout

---
 .../moderation_tools/moderation_tools.vue          | 244 +++++++--------------
 src/components/user_card/user_card.vue             |  75 +++----
 src/components/user_profile/user_profile.js        |   2 -
 3 files changed, 118 insertions(+), 203 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index c6f8354b..785fe7ba 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -1,168 +1,85 @@
 <template>
-  <div
-    class="block"
-    style="position: relative"
-  >
-    <Popper
-      trigger="click"
-      append-to-body
-      :options="{
-        placement: 'bottom-end',
-        modifiers: {
-          arrow: { enabled: true },
-          offset: { offset: '0, 5px' },
-        }
-      }"
-      @hide="showDropDown = false"
-    >
-      <div class="popper-wrapper">
-        <div class="dropdown-menu">
-          <span v-if="user.is_local">
-            <button
-              class="dropdown-item"
-              @click="toggleRight(&quot;admin&quot;)"
-            >
-              {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
-            </button>
-            <button
-              class="dropdown-item"
-              @click="toggleRight(&quot;moderator&quot;)"
-            >
-              {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
-            </button>
-            <div
-              role="separator"
-              class="dropdown-divider"
-            />
-          </span>
-          <button
-            class="dropdown-item"
-            @click="toggleActivationStatus()"
-          >
-            {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
+<div>
+  <Popper
+    trigger="click"
+    @hide='showDropDown = false'
+    append-to-body
+    :options="{
+      placement: 'bottom-end',
+      modifiers: {
+        arrow: { enabled: true },
+        offset: { offset: '0, 5px' },
+      }
+    }">
+    <div class="popper-wrapper">
+      <div class="dropdown-menu">
+        <span v-if='user.is_local'>
+          <button class="dropdown-item" @click='toggleRight("admin")'>
+            {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
           </button>
-          <button
-            class="dropdown-item"
-            @click="deleteUserDialog(true)"
-          >
-            {{ $t('user_card.admin_menu.delete_account') }}
+          <button class="dropdown-item" @click='toggleRight("moderator")'>
+            {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
           </button>
-          <div
-            v-if="hasTagPolicy"
-            role="separator"
-            class="dropdown-divider"
-          />
-          <span v-if="hasTagPolicy">
-            <button
-              class="dropdown-item"
-              @click="toggleTag(tags.FORCE_NSFW)"
-            >
-              {{ $t('user_card.admin_menu.force_nsfw') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"
-              />
-            </button>
-            <button
-              class="dropdown-item"
-              @click="toggleTag(tags.STRIP_MEDIA)"
-            >
-              {{ $t('user_card.admin_menu.strip_media') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"
-              />
-            </button>
-            <button
-              class="dropdown-item"
-              @click="toggleTag(tags.FORCE_UNLISTED)"
-            >
-              {{ $t('user_card.admin_menu.force_unlisted') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"
-              />
-            </button>
-            <button
-              class="dropdown-item"
-              @click="toggleTag(tags.SANDBOX)"
-            >
-              {{ $t('user_card.admin_menu.sandbox') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"
-              />
-            </button>
-            <button
-              v-if="user.is_local"
-              class="dropdown-item"
-              @click="toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)"
-            >
-              {{ $t('user_card.admin_menu.disable_remote_subscription') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"
-              />
-            </button>
-            <button
-              v-if="user.is_local"
-              class="dropdown-item"
-              @click="toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)"
-            >
-              {{ $t('user_card.admin_menu.disable_any_subscription') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"
-              />
-            </button>
-            <button
-              v-if="user.is_local"
-              class="dropdown-item"
-              @click="toggleTag(tags.QUARANTINE)"
-            >
-              {{ $t('user_card.admin_menu.quarantine') }}
-              <span
-                class="menu-checkbox"
-                :class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"
-              />
-            </button>
-          </span>
-        </div>
-      </div>
-      <button
-        slot="reference"
-        :class="{ pressed: showDropDown }"
-        @click="toggleMenu"
-      >
-        {{ $t('user_card.admin_menu.moderation') }}
-      </button>
-    </Popper>
-    <portal to="modal">
-      <DialogModal
-        v-if="showDeleteUserDialog"
-        :on-cancel="deleteUserDialog.bind(this, false)"
-      >
-        <template slot="header">
-          {{ $t('user_card.admin_menu.delete_user') }}
-        </template>
-        <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
-        <template slot="footer">
-          <button
-            class="btn btn-default"
-            @click="deleteUserDialog(false)"
-          >
-            {{ $t('general.cancel') }}
+          <div role="separator" class="dropdown-divider"></div>
+        </span>
+        <button class="dropdown-item" @click='toggleActivationStatus()'>
+          {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
+        </button>
+        <button class="dropdown-item" @click='deleteUserDialog(true)'>
+          {{ $t('user_card.admin_menu.delete_account') }}
+        </button>
+        <div role="separator" class="dropdown-divider" v-if='hasTagPolicy'></div>
+        <span v-if='hasTagPolicy'>
+          <button class="dropdown-item" @click='toggleTag(tags.FORCE_NSFW)'>
+            {{ $t('user_card.admin_menu.force_nsfw') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.STRIP_MEDIA)'>
+            {{ $t('user_card.admin_menu.strip_media') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.FORCE_UNLISTED)'>
+            {{ $t('user_card.admin_menu.force_unlisted') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"></span>
+          </button>
+          <button class="dropdown-item" @click='toggleTag(tags.SANDBOX)'>
+            {{ $t('user_card.admin_menu.sandbox') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"></span>
+          </button>
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)'>
+            {{ $t('user_card.admin_menu.disable_remote_subscription') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"></span>
           </button>
-          <button
-            class="btn btn-default danger"
-            @click="deleteUser()"
-          >
-            {{ $t('user_card.admin_menu.delete_user') }}
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)'>
+            {{ $t('user_card.admin_menu.disable_any_subscription') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"></span>
           </button>
-        </template>
-      </DialogModal>
-    </portal>
-  </div>
+          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.QUARANTINE)'>
+            {{ $t('user_card.admin_menu.quarantine') }}
+            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"></span>
+          </button>
+        </span>
+      </div>
+    </div>
+    <button slot="reference" class="btn btn-default moderation-toggle-btn" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
+      {{ $t('user_card.admin_menu.moderation') }}
+    </button>
+  </Popper>
+  <portal to="modal">
+    <DialogModal v-if="showDeleteUserDialog" :onCancel='deleteUserDialog.bind(this, false)'>
+      <template slot="header">{{ $t('user_card.admin_menu.delete_user') }}</template>
+      <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
+      <template slot="footer">
+        <button class="btn btn-default" @click='deleteUserDialog(false)'>
+          {{ $t('general.cancel') }}
+        </button>
+        <button class="btn btn-default danger" @click='deleteUser()'>
+          {{ $t('user_card.admin_menu.delete_user') }}
+        </button>
+      </template>
+    </DialogModal>
+  </portal>
+</div>
 </template>
 
 <script src="./moderation_tools.js"></script>
@@ -190,4 +107,11 @@
   }
 }
 
+.moderation-toggle-btn {
+  &#{&} {
+    margin: 0;
+    width: 100%;
+  }
+}
+
 </style>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index eedb67b5..2f2f9e5f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -47,7 +47,7 @@
       </div>
       <div v-if="loggedIn && isOtherUser" class="user-interactions">
         <div>
-          <button @click="unfollowUser" class="pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
+          <button @click="unfollowUser" class="btn btn-default pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
             <template v-if="followRequestInProgress">
               {{ $t('user_card.follow_progress') }}
             </template>
@@ -55,7 +55,7 @@
               {{ $t('user_card.following') }}
             </template>
           </button>
-          <button @click="followUser" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''" v-else>
+          <button @click="followUser" class="btn btn-default" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''" v-else>
             <template v-if="followRequestInProgress">
               {{ $t('user_card.follow_progress') }}
             </template>
@@ -67,45 +67,40 @@
             </template>
           </button>
         </div>
+
         <div>
-          <ProgressButton :click="subscribeUser" v-if="!user.subscribed">
+          <ProgressButton class="btn btn-default" :click="subscribeUser" v-if="!user.subscribed">
             {{ $t('user_card.subscribe') }}
           </ProgressButton>
-          <ProgressButton class="pressed" :click="unsubscribeUser" v-else>
+          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" v-else>
             {{ $t('user_card.subscribed') }}
           </ProgressButton>
         </div>
+
         <div>
-          <span v-if='user.muted'>
-            <button @click="unmuteUser" class="pressed">
-              {{ $t('user_card.muted') }}
-            </button>
-          </span>
-          <span v-if='!user.muted'>
-            <button @click="muteUser">
-              {{ $t('user_card.mute') }}
-            </button>
-          </span>
+          <button @click="unmuteUser" class="btn btn-default pressed" v-if="user.muted">
+            {{ $t('user_card.muted') }}
+          </button>
+          <button @click="muteUser" class="btn btn-default" v-else>
+            {{ $t('user_card.mute') }}
+          </button>
         </div>
+
         <div>
-          <span v-if='user.statusnet_blocking'>
-            <button @click="unblockUser" class="pressed">
-              {{ $t('user_card.blocked') }}
-            </button>
-          </span>
-          <span v-if='!user.statusnet_blocking'>
-            <button @click="blockUser">
-              {{ $t('user_card.block') }}
-            </button>
-          </span>
+          <button @click="unblockUser" class="btn btn-default pressed" v-if="user.statusnet_blocking">
+            {{ $t('user_card.blocked') }}
+          </button>
+          <button @click="blockUser" class="btn btn-default" v-else>
+            {{ $t('user_card.block') }}
+          </button>
         </div>
-        <div class='block'>
-          <span>
-            <button @click="reportUser">
-              {{ $t('user_card.report') }}
-            </button>
-          </span>
+
+        <div>
+          <button @click="reportUser">
+            {{ $t('user_card.report') }}
+          </button>
         </div>
+
         <ModerationTools :user='user' v-if='loggedIn.role === "admin"' />
       </div>
       <div class="user-interactions" v-if="!loggedIn && user.is_local">
@@ -366,25 +361,23 @@
     justify-content: space-between;
     margin-right: -.75em;
 
-    > div {
+    > * {
       flex: 1 0 0;
-      margin-right: .75em;
-      margin-bottom: .6em;
+      margin: 0 .75em .6em 0;
       white-space: nowrap;
-    }
 
-    button {
-      width: 100%;
-      height: 100%;
-      margin: 0;
+      > button {
+        margin: 0;
+        width: 100%;
+      }
     }
 
     .remote-button {
-      height: 28px !important;
-      width: 92%;
+      height: 28px;
+      margin: 0;
     }
 
-    .pressed {
+    button.pressed {
       border-bottom-color: rgba(255, 255, 255, 0.2);
       border-top-color: rgba(0, 0, 0, 0.2);
     }
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 7eb4ed3a..39b99dac 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -3,7 +3,6 @@ import UserCard from '../user_card/user_card.vue'
 import FollowCard from '../follow_card/follow_card.vue'
 import Timeline from '../timeline/timeline.vue'
 import Conversation from '../conversation/conversation.vue'
-import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import List from '../list/list.vue'
 import withLoadMore from '../../hocs/with_load_more/with_load_more'
 
@@ -132,7 +131,6 @@ const UserProfile = {
     Timeline,
     FollowerList,
     FriendList,
-    ModerationTools,
     FollowCard,
     Conversation
   }
-- 
cgit v1.2.3-70-g09d2


From 2ab00387fe8c335fe554249cd354eadfdb79d57b Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 26 Apr 2019 03:33:25 -0400
Subject: clean up + add btn-group css class

---
 src/App.scss                                       | 25 +++++++++++++++++++
 .../moderation_tools/moderation_tools.vue          |  9 +------
 src/components/user_card/user_card.vue             | 29 ++++++++--------------
 3 files changed, 36 insertions(+), 27 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/App.scss b/src/App.scss
index e4c764bf..1299e05d 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -283,6 +283,31 @@ i[class*=icon-] {
   color: var(--icon, $fallback--icon)
 }
 
+.btn-block {
+  display: block;
+  width: 100%;
+}
+
+.btn-group {
+  position: relative;
+  display: inline-flex;
+  vertical-align: middle;
+
+  button {
+    position: relative;
+    flex: 1 1 auto;
+
+    &:not(:last-child) {
+      border-top-right-radius: 0;
+      border-bottom-right-radius: 0;
+    }
+
+    &:not(:first-child) {
+      border-top-left-radius: 0;
+      border-bottom-left-radius: 0;
+    }
+  }
+}
 
 .container {
   display: flex;
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index 785fe7ba..80f6858e 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -61,7 +61,7 @@
         </span>
       </div>
     </div>
-    <button slot="reference" class="btn btn-default moderation-toggle-btn" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
+    <button slot="reference" class="btn btn-default btn-block" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
       {{ $t('user_card.admin_menu.moderation') }}
     </button>
   </Popper>
@@ -107,11 +107,4 @@
   }
 }
 
-.moderation-toggle-btn {
-  &#{&} {
-    margin: 0;
-    width: 100%;
-  }
-}
-
 </style>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 2f2f9e5f..2d3cf28f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -46,7 +46,7 @@
         </div>
       </div>
       <div v-if="loggedIn && isOtherUser" class="user-interactions">
-        <div>
+        <div class="btn-group">
           <button @click="unfollowUser" class="btn btn-default pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
             <template v-if="followRequestInProgress">
               {{ $t('user_card.follow_progress') }}
@@ -66,9 +66,6 @@
               {{ $t('user_card.follow') }}
             </template>
           </button>
-        </div>
-
-        <div>
           <ProgressButton class="btn btn-default" :click="subscribeUser" v-if="!user.subscribed">
             {{ $t('user_card.subscribe') }}
           </ProgressButton>
@@ -78,19 +75,19 @@
         </div>
 
         <div>
-          <button @click="unmuteUser" class="btn btn-default pressed" v-if="user.muted">
+          <button @click="unmuteUser" class="btn btn-default btn-block pressed" v-if="user.muted">
             {{ $t('user_card.muted') }}
           </button>
-          <button @click="muteUser" class="btn btn-default" v-else>
+          <button @click="muteUser" class="btn btn-default btn-block" v-else>
             {{ $t('user_card.mute') }}
           </button>
         </div>
 
         <div>
-          <button @click="unblockUser" class="btn btn-default pressed" v-if="user.statusnet_blocking">
+          <button @click="unblockUser" class="btn btn-default btn-block pressed" v-if="user.statusnet_blocking">
             {{ $t('user_card.blocked') }}
           </button>
-          <button @click="blockUser" class="btn btn-default" v-else>
+          <button @click="blockUser" class="btn btn-default btn-block" v-else>
             {{ $t('user_card.block') }}
           </button>
         </div>
@@ -365,21 +362,15 @@
       flex: 1 0 0;
       margin: 0 .75em .6em 0;
       white-space: nowrap;
-
-      > button {
-        margin: 0;
-        width: 100%;
-      }
     }
 
-    .remote-button {
-      height: 28px;
+    button {
       margin: 0;
-    }
 
-    button.pressed {
-      border-bottom-color: rgba(255, 255, 255, 0.2);
-      border-top-color: rgba(0, 0, 0, 0.2);
+      &.pressed {
+        border-bottom-color: rgba(255, 255, 255, 0.2);
+        border-top-color: rgba(0, 0, 0, 0.2);
+      }
     }
   }
 }
-- 
cgit v1.2.3-70-g09d2


From 38ba5fe028e09a4a64ef7f4f5d4366b0781b13f8 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 26 Apr 2019 03:43:21 -0400
Subject: change subscribe button to icon button

---
 src/components/user_card/user_card.vue | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 2d3cf28f..013b142d 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -66,11 +66,11 @@
               {{ $t('user_card.follow') }}
             </template>
           </button>
-          <ProgressButton class="btn btn-default" :click="subscribeUser" v-if="!user.subscribed">
-            {{ $t('user_card.subscribe') }}
+          <ProgressButton class="btn btn-default" :click="subscribeUser" :title="$t('user_card.subscribe')" v-if="!user.subscribed">
+            <i class="icon-bell-off" />
           </ProgressButton>
-          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" v-else>
-            {{ $t('user_card.subscribed') }}
+          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" :title="$t('user_card.subscribed')" v-else>
+            <i class="icon-bell-alt" />
           </ProgressButton>
         </div>
 
-- 
cgit v1.2.3-70-g09d2


From 0f4cccd115f514df07725d1d2bfabfe589befff6 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Sat, 4 May 2019 13:23:57 -0400
Subject: improve ui

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

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 013b142d..03c79b49 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -93,7 +93,7 @@
         </div>
 
         <div>
-          <button @click="reportUser">
+          <button @click="reportUser" class="btn btn-default btn-block">
             {{ $t('user_card.report') }}
           </button>
         </div>
-- 
cgit v1.2.3-70-g09d2


From 4f26299bd54efd64ee1e7a8e4f0ccbf364df491c Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Sun, 19 May 2019 09:21:48 -0400
Subject: update copy

---
 src/components/user_card/user_card.vue | 2 +-
 src/i18n/en.json                       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 03c79b49..d73ae716 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -69,7 +69,7 @@
           <ProgressButton class="btn btn-default" :click="subscribeUser" :title="$t('user_card.subscribe')" v-if="!user.subscribed">
             <i class="icon-bell-off" />
           </ProgressButton>
-          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" :title="$t('user_card.subscribed')" v-else>
+          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" :title="$t('user_card.unsubscribe')" v-else>
             <i class="icon-bell-alt" />
           </ProgressButton>
         </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 03455cce..49989f78 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -530,7 +530,7 @@
     "report": "Report",
     "statuses": "Statuses",
     "subscribe": "Subscribe",
-    "subscribed": "Subscribed",
+    "unsubscribe": "Unsubscribe",
     "unblock": "Unblock",
     "unblock_progress": "Unblocking...",
     "block_progress": "Blocking...",
-- 
cgit v1.2.3-70-g09d2


From 1237d0d2b879f4e6859e4ba3d9426c26dd0e5648 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Sun, 19 May 2019 14:33:25 -0400
Subject: use normal bell for unsubscribed state

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

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index d73ae716..9fac0186 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -67,7 +67,7 @@
             </template>
           </button>
           <ProgressButton class="btn btn-default" :click="subscribeUser" :title="$t('user_card.subscribe')" v-if="!user.subscribed">
-            <i class="icon-bell-off" />
+            <i class="icon-bell-alt" />
           </ProgressButton>
           <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" :title="$t('user_card.unsubscribe')" v-else>
             <i class="icon-bell-alt" />
-- 
cgit v1.2.3-70-g09d2


From 9712e324e5d6dd4bae5b61a76a28d902545f029f Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Mon, 20 May 2019 11:36:44 -0400
Subject: hide subscribe button unless following

---
 src/components/user_card/user_card.vue | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 9fac0186..70d5a30d 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -46,16 +46,8 @@
         </div>
       </div>
       <div v-if="loggedIn && isOtherUser" class="user-interactions">
-        <div class="btn-group">
-          <button @click="unfollowUser" class="btn btn-default pressed" :disabled="followRequestInProgress" :title="$t('user_card.follow_unfollow')" v-if="user.following">
-            <template v-if="followRequestInProgress">
-              {{ $t('user_card.follow_progress') }}
-            </template>
-            <template v-else>
-              {{ $t('user_card.following') }}
-            </template>
-          </button>
-          <button @click="followUser" class="btn btn-default" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''" v-else>
+        <div v-if="!user.following">
+          <button @click="followUser" class="btn btn-default btn-block" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''">
             <template v-if="followRequestInProgress">
               {{ $t('user_card.follow_progress') }}
             </template>
@@ -66,6 +58,16 @@
               {{ $t('user_card.follow') }}
             </template>
           </button>
+        </div>
+        <div v-else-if="followRequestInProgress">
+          <button @click="unfollowUser" class="btn btn-default btn-block pressed" disabled :title="$t('user_card.follow_unfollow')">
+            {{ $t('user_card.follow_progress') }}
+          </button>
+        </div>
+        <div class="btn-group" v-else>
+          <button @click="unfollowUser" class="btn btn-default pressed" :title="$t('user_card.follow_unfollow')">
+            {{ $t('user_card.following') }}
+          </button>
           <ProgressButton class="btn btn-default" :click="subscribeUser" :title="$t('user_card.subscribe')" v-if="!user.subscribed">
             <i class="icon-bell-alt" />
           </ProgressButton>
-- 
cgit v1.2.3-70-g09d2


From b2dbf01a728592758b72966550410171ea9ac74e Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 10 Jul 2019 20:59:10 -0400
Subject: eslint —fix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../moderation_tools/moderation_tools.vue          | 235 ++++++++-----
 src/components/progress_button/progress_button.vue |   5 +-
 src/components/user_card/user_card.vue             | 376 ++++++++++++++-------
 3 files changed, 424 insertions(+), 192 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index 80f6858e..f1ab67a6 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -1,85 +1,166 @@
 <template>
-<div>
-  <Popper
-    trigger="click"
-    @hide='showDropDown = false'
-    append-to-body
-    :options="{
-      placement: 'bottom-end',
-      modifiers: {
-        arrow: { enabled: true },
-        offset: { offset: '0, 5px' },
-      }
-    }">
-    <div class="popper-wrapper">
-      <div class="dropdown-menu">
-        <span v-if='user.is_local'>
-          <button class="dropdown-item" @click='toggleRight("admin")'>
-            {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
+  <div>
+    <Popper
+      trigger="click"
+      append-to-body
+      :options="{
+        placement: 'bottom-end',
+        modifiers: {
+          arrow: { enabled: true },
+          offset: { offset: '0, 5px' },
+        }
+      }"
+      @hide="showDropDown = false"
+    >
+      <div class="popper-wrapper">
+        <div class="dropdown-menu">
+          <span v-if="user.is_local">
+            <button
+              class="dropdown-item"
+              @click="toggleRight(&quot;admin&quot;)"
+            >
+              {{ $t(!!user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin') }}
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleRight(&quot;moderator&quot;)"
+            >
+              {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
+            </button>
+            <div
+              role="separator"
+              class="dropdown-divider"
+            />
+          </span>
+          <button
+            class="dropdown-item"
+            @click="toggleActivationStatus()"
+          >
+            {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
           </button>
-          <button class="dropdown-item" @click='toggleRight("moderator")'>
-            {{ $t(!!user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator') }}
+          <button
+            class="dropdown-item"
+            @click="deleteUserDialog(true)"
+          >
+            {{ $t('user_card.admin_menu.delete_account') }}
           </button>
-          <div role="separator" class="dropdown-divider"></div>
-        </span>
-        <button class="dropdown-item" @click='toggleActivationStatus()'>
-          {{ $t(!!user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account') }}
-        </button>
-        <button class="dropdown-item" @click='deleteUserDialog(true)'>
-          {{ $t('user_card.admin_menu.delete_account') }}
-        </button>
-        <div role="separator" class="dropdown-divider" v-if='hasTagPolicy'></div>
-        <span v-if='hasTagPolicy'>
-          <button class="dropdown-item" @click='toggleTag(tags.FORCE_NSFW)'>
-            {{ $t('user_card.admin_menu.force_nsfw') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.STRIP_MEDIA)'>
-            {{ $t('user_card.admin_menu.strip_media') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.FORCE_UNLISTED)'>
-            {{ $t('user_card.admin_menu.force_unlisted') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"></span>
-          </button>
-          <button class="dropdown-item" @click='toggleTag(tags.SANDBOX)'>
-            {{ $t('user_card.admin_menu.sandbox') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)'>
-            {{ $t('user_card.admin_menu.disable_remote_subscription') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)'>
-            {{ $t('user_card.admin_menu.disable_any_subscription') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"></span>
-          </button>
-          <button class="dropdown-item" v-if='user.is_local' @click='toggleTag(tags.QUARANTINE)'>
-            {{ $t('user_card.admin_menu.quarantine') }}
-            <span class="menu-checkbox" v-bind:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"></span>
-          </button>
-        </span>
+          <div
+            v-if="hasTagPolicy"
+            role="separator"
+            class="dropdown-divider"
+          />
+          <span v-if="hasTagPolicy">
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.FORCE_NSFW)"
+            >
+              {{ $t('user_card.admin_menu.force_nsfw') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.STRIP_MEDIA)"
+            >
+              {{ $t('user_card.admin_menu.strip_media') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.FORCE_UNLISTED)"
+            >
+              {{ $t('user_card.admin_menu.force_unlisted') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"
+              />
+            </button>
+            <button
+              class="dropdown-item"
+              @click="toggleTag(tags.SANDBOX)"
+            >
+              {{ $t('user_card.admin_menu.sandbox') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)"
+            >
+              {{ $t('user_card.admin_menu.disable_remote_subscription') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)"
+            >
+              {{ $t('user_card.admin_menu.disable_any_subscription') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"
+              />
+            </button>
+            <button
+              v-if="user.is_local"
+              class="dropdown-item"
+              @click="toggleTag(tags.QUARANTINE)"
+            >
+              {{ $t('user_card.admin_menu.quarantine') }}
+              <span
+                class="menu-checkbox"
+                :class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"
+              />
+            </button>
+          </span>
+        </div>
       </div>
-    </div>
-    <button slot="reference" class="btn btn-default btn-block" v-bind:class="{ pressed: showDropDown }" @click='toggleMenu'>
-      {{ $t('user_card.admin_menu.moderation') }}
-    </button>
-  </Popper>
-  <portal to="modal">
-    <DialogModal v-if="showDeleteUserDialog" :onCancel='deleteUserDialog.bind(this, false)'>
-      <template slot="header">{{ $t('user_card.admin_menu.delete_user') }}</template>
-      <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
-      <template slot="footer">
-        <button class="btn btn-default" @click='deleteUserDialog(false)'>
-          {{ $t('general.cancel') }}
-        </button>
-        <button class="btn btn-default danger" @click='deleteUser()'>
+      <button
+        slot="reference"
+        class="btn btn-default btn-block"
+        :class="{ pressed: showDropDown }"
+        @click="toggleMenu"
+      >
+        {{ $t('user_card.admin_menu.moderation') }}
+      </button>
+    </Popper>
+    <portal to="modal">
+      <DialogModal
+        v-if="showDeleteUserDialog"
+        :on-cancel="deleteUserDialog.bind(this, false)"
+      >
+        <template slot="header">
           {{ $t('user_card.admin_menu.delete_user') }}
-        </button>
-      </template>
-    </DialogModal>
-  </portal>
-</div>
+        </template>
+        <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
+        <template slot="footer">
+          <button
+            class="btn btn-default"
+            @click="deleteUserDialog(false)"
+          >
+            {{ $t('general.cancel') }}
+          </button>
+          <button
+            class="btn btn-default danger"
+            @click="deleteUser()"
+          >
+            {{ $t('user_card.admin_menu.delete_user') }}
+          </button>
+        </template>
+      </DialogModal>
+    </portal>
+  </div>
 </template>
 
 <script src="./moderation_tools.js"></script>
diff --git a/src/components/progress_button/progress_button.vue b/src/components/progress_button/progress_button.vue
index 53481b0d..283a51af 100644
--- a/src/components/progress_button/progress_button.vue
+++ b/src/components/progress_button/progress_button.vue
@@ -1,5 +1,8 @@
 <template>
-  <button :disabled="progress || disabled" @click="onClick">
+  <button
+    :disabled="progress || disabled"
+    @click="onClick"
+  >
     <template v-if="progress && $slots.progress">
       <slot name="progress" />
     </template>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 70d5a30d..f0ee6cae 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -1,131 +1,279 @@
 <template>
-<div class="user-card" :class="classes" :style="style">
-  <div class="panel-heading">
-    <div class='user-info'>
-      <div class='container'>
-        <router-link :to="userProfileLink(user)">
-          <UserAvatar :betterShadow="betterShadow" :user="user"/>
-        </router-link>
-        <div class="user-summary">
-          <div class="top-line">
-            <div :title="user.name" class='user-name' v-if="user.name_html" v-html="user.name_html"></div>
-            <div :title="user.name" class='user-name' v-else>{{user.name}}</div>
-            <router-link :to="{ name: 'user-settings' }" v-if="!isOtherUser">
-              <i class="button-icon icon-wrench usersettings" :title="$t('tool_tip.user_settings')"></i>
-            </router-link>
-            <a :href="user.statusnet_profile_url" target="_blank" v-if="isOtherUser && !user.is_local">
-              <i class="icon-link-ext usersettings"></i>
-            </a>
+  <div
+    class="user-card"
+    :class="classes"
+    :style="style"
+  >
+    <div class="panel-heading">
+      <div class="user-info">
+        <div class="container">
+          <router-link :to="userProfileLink(user)">
+            <UserAvatar
+              :better-shadow="betterShadow"
+              :user="user"
+            />
+          </router-link>
+          <div class="user-summary">
+            <div class="top-line">
+              <!-- eslint-disable vue/no-v-html -->
+              <div
+                v-if="user.name_html"
+                :title="user.name"
+                class="user-name"
+                v-html="user.name_html"
+              />
+              <!-- eslint-enabled vue/no-v-html -->
+              <div
+                v-else
+                :title="user.name"
+                class="user-name"
+              >
+                {{ user.name }}
+              </div>
+              <router-link
+                v-if="!isOtherUser"
+                :to="{ name: 'user-settings' }"
+              >
+                <i
+                  class="button-icon icon-wrench usersettings"
+                  :title="$t('tool_tip.user_settings')"
+                />
+              </router-link>
+              <a
+                v-if="isOtherUser && !user.is_local"
+                :href="user.statusnet_profile_url"
+                target="_blank"
+              >
+                <i class="icon-link-ext usersettings" />
+              </a>
+            </div>
+
+            <div class="bottom-line">
+              <router-link
+                class="user-screen-name"
+                :to="userProfileLink(user)"
+              >
+                @{{ user.screen_name }}
+              </router-link>
+              <span
+                v-if="!hideBio && !!visibleRole"
+                class="alert staff"
+              >{{ visibleRole }}</span>
+              <span v-if="user.locked"><i class="icon icon-lock" /></span>
+              <span
+                v-if="!hideUserStatsLocal && !hideBio"
+                class="dailyAvg"
+              >{{ dailyAvg }} {{ $t('user_card.per_day') }}</span>
+            </div>
           </div>
-
-          <div class="bottom-line">
-            <router-link class="user-screen-name" :to="userProfileLink(user)">@{{user.screen_name}}</router-link>
-            <span class="alert staff" v-if="!hideBio && !!visibleRole">{{visibleRole}}</span>
-            <span v-if="user.locked"><i class="icon icon-lock"></i></span>
-            <span v-if="!hideUserStatsLocal && !hideBio" class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
-          </div>
-        </div>
-      </div>
-      <div class="user-meta">
-        <div v-if="user.follows_you && loggedIn && isOtherUser" class="following">
-          {{ $t('user_card.follows_you') }}
         </div>
-        <div class="highlighter" v-if="isOtherUser && (loggedIn || !switcher)">
-          <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
-          <input class="userHighlightText" type="text" :id="'userHighlightColorTx'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
-          <input class="userHighlightCl" type="color" :id="'userHighlightColor'+user.id" v-if="userHighlightType !== 'disabled'" v-model="userHighlightColor"/>
-          <label for="style-switcher" class='userHighlightSel select'>
-            <select class="userHighlightSel" :id="'userHighlightSel'+user.id" v-model="userHighlightType">
-              <option value="disabled">No highlight</option>
-              <option value="solid">Solid bg</option>
-              <option value="striped">Striped bg</option>
-              <option value="side">Side stripe</option>
-            </select>
-            <i class="icon-down-open"/>
-          </label>
+        <div class="user-meta">
+          <div
+            v-if="user.follows_you && loggedIn && isOtherUser"
+            class="following"
+          >
+            {{ $t('user_card.follows_you') }}
+          </div>
+          <div
+            v-if="isOtherUser && (loggedIn || !switcher)"
+            class="highlighter"
+          >
+            <!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
+            <input
+              v-if="userHighlightType !== 'disabled'"
+              :id="'userHighlightColorTx'+user.id"
+              v-model="userHighlightColor"
+              class="userHighlightText"
+              type="text"
+            >
+            <input
+              v-if="userHighlightType !== 'disabled'"
+              :id="'userHighlightColor'+user.id"
+              v-model="userHighlightColor"
+              class="userHighlightCl"
+              type="color"
+            >
+            <label
+              for="style-switcher"
+              class="userHighlightSel select"
+            >
+              <select
+                :id="'userHighlightSel'+user.id"
+                v-model="userHighlightType"
+                class="userHighlightSel"
+              >
+                <option value="disabled">No highlight</option>
+                <option value="solid">Solid bg</option>
+                <option value="striped">Striped bg</option>
+                <option value="side">Side stripe</option>
+              </select>
+              <i class="icon-down-open" />
+            </label>
+          </div>
         </div>
-      </div>
-      <div v-if="loggedIn && isOtherUser" class="user-interactions">
-        <div v-if="!user.following">
-          <button @click="followUser" class="btn btn-default btn-block" :disabled="followRequestInProgress" :title="followRequestSent ? $t('user_card.follow_again') : ''">
-            <template v-if="followRequestInProgress">
+        <div
+          v-if="loggedIn && isOtherUser"
+          class="user-interactions"
+        >
+          <div v-if="!user.following">
+            <button
+              class="btn btn-default btn-block"
+              :disabled="followRequestInProgress"
+              :title="followRequestSent ? $t('user_card.follow_again') : ''"
+              @click="followUser"
+            >
+              <template v-if="followRequestInProgress">
+                {{ $t('user_card.follow_progress') }}
+              </template>
+              <template v-else-if="followRequestSent">
+                {{ $t('user_card.follow_sent') }}
+              </template>
+              <template v-else>
+                {{ $t('user_card.follow') }}
+              </template>
+            </button>
+          </div>
+          <div v-else-if="followRequestInProgress">
+            <button
+              class="btn btn-default btn-block pressed"
+              disabled
+              :title="$t('user_card.follow_unfollow')"
+              @click="unfollowUser"
+            >
               {{ $t('user_card.follow_progress') }}
-            </template>
-            <template v-else-if="followRequestSent">
-              {{ $t('user_card.follow_sent') }}
-            </template>
-            <template v-else>
-              {{ $t('user_card.follow') }}
-            </template>
-          </button>
-        </div>
-        <div v-else-if="followRequestInProgress">
-          <button @click="unfollowUser" class="btn btn-default btn-block pressed" disabled :title="$t('user_card.follow_unfollow')">
-            {{ $t('user_card.follow_progress') }}
-          </button>
-        </div>
-        <div class="btn-group" v-else>
-          <button @click="unfollowUser" class="btn btn-default pressed" :title="$t('user_card.follow_unfollow')">
-            {{ $t('user_card.following') }}
-          </button>
-          <ProgressButton class="btn btn-default" :click="subscribeUser" :title="$t('user_card.subscribe')" v-if="!user.subscribed">
-            <i class="icon-bell-alt" />
-          </ProgressButton>
-          <ProgressButton class="btn btn-default pressed" :click="unsubscribeUser" :title="$t('user_card.unsubscribe')" v-else>
-            <i class="icon-bell-alt" />
-          </ProgressButton>
-        </div>
+            </button>
+          </div>
+          <div
+            v-else
+            class="btn-group"
+          >
+            <button
+              class="btn btn-default pressed"
+              :title="$t('user_card.follow_unfollow')"
+              @click="unfollowUser"
+            >
+              {{ $t('user_card.following') }}
+            </button>
+            <ProgressButton
+              v-if="!user.subscribed"
+              class="btn btn-default"
+              :click="subscribeUser"
+              :title="$t('user_card.subscribe')"
+            >
+              <i class="icon-bell-alt" />
+            </ProgressButton>
+            <ProgressButton
+              v-else
+              class="btn btn-default pressed"
+              :click="unsubscribeUser"
+              :title="$t('user_card.unsubscribe')"
+            >
+              <i class="icon-bell-alt" />
+            </ProgressButton>
+          </div>
 
-        <div>
-          <button @click="unmuteUser" class="btn btn-default btn-block pressed" v-if="user.muted">
-            {{ $t('user_card.muted') }}
-          </button>
-          <button @click="muteUser" class="btn btn-default btn-block" v-else>
-            {{ $t('user_card.mute') }}
-          </button>
-        </div>
+          <div>
+            <button
+              v-if="user.muted"
+              class="btn btn-default btn-block pressed"
+              @click="unmuteUser"
+            >
+              {{ $t('user_card.muted') }}
+            </button>
+            <button
+              v-else
+              class="btn btn-default btn-block"
+              @click="muteUser"
+            >
+              {{ $t('user_card.mute') }}
+            </button>
+          </div>
 
-        <div>
-          <button @click="unblockUser" class="btn btn-default btn-block pressed" v-if="user.statusnet_blocking">
-            {{ $t('user_card.blocked') }}
-          </button>
-          <button @click="blockUser" class="btn btn-default btn-block" v-else>
-            {{ $t('user_card.block') }}
-          </button>
-        </div>
+          <div>
+            <button
+              v-if="user.statusnet_blocking"
+              class="btn btn-default btn-block pressed"
+              @click="unblockUser"
+            >
+              {{ $t('user_card.blocked') }}
+            </button>
+            <button
+              v-else
+              class="btn btn-default btn-block"
+              @click="blockUser"
+            >
+              {{ $t('user_card.block') }}
+            </button>
+          </div>
 
-        <div>
-          <button @click="reportUser" class="btn btn-default btn-block">
-            {{ $t('user_card.report') }}
-          </button>
-        </div>
+          <div>
+            <button
+              class="btn btn-default btn-block"
+              @click="reportUser"
+            >
+              {{ $t('user_card.report') }}
+            </button>
+          </div>
 
-        <ModerationTools :user='user' v-if='loggedIn.role === "admin"' />
-      </div>
-      <div class="user-interactions" v-if="!loggedIn && user.is_local">
-        <RemoteFollow :user="user" />
+          <ModerationTools
+            v-if="loggedIn.role === &quot;admin&quot;"
+            :user="user"
+          />
+        </div>
+        <div
+          v-if="!loggedIn && user.is_local"
+          class="user-interactions"
+        >
+          <RemoteFollow :user="user" />
+        </div>
       </div>
     </div>
-  </div>
-  <div class="panel-body" v-if="!hideBio">
-    <div v-if="!hideUserStatsLocal && switcher" class="user-counts">
-      <div class="user-count" v-on:click.prevent="setProfileView('statuses')">
-        <h5>{{ $t('user_card.statuses') }}</h5>
-        <span>{{user.statuses_count}} <br></span>
-      </div>
-      <div class="user-count" v-on:click.prevent="setProfileView('friends')">
-        <h5>{{ $t('user_card.followees') }}</h5>
-        <span>{{user.friends_count}}</span>
-      </div>
-      <div class="user-count" v-on:click.prevent="setProfileView('followers')">
-        <h5>{{ $t('user_card.followers') }}</h5>
-        <span>{{user.followers_count}}</span>
+    <div
+      v-if="!hideBio"
+      class="panel-body"
+    >
+      <div
+        v-if="!hideUserStatsLocal && switcher"
+        class="user-counts"
+      >
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('statuses')"
+        >
+          <h5>{{ $t('user_card.statuses') }}</h5>
+          <span>{{ user.statuses_count }} <br></span>
+        </div>
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('friends')"
+        >
+          <h5>{{ $t('user_card.followees') }}</h5>
+          <span>{{ user.friends_count }}</span>
+        </div>
+        <div
+          class="user-count"
+          @click.prevent="setProfileView('followers')"
+        >
+          <h5>{{ $t('user_card.followers') }}</h5>
+          <span>{{ user.followers_count }}</span>
+        </div>
       </div>
+      <!-- eslint-disable vue/no-v-html -->
+      <p
+        v-if="!hideBio && user.description_html"
+        class="user-card-bio"
+        @click.prevent="linkClicked"
+        v-html="user.description_html"
+      />
+      <!-- eslint-enabled vue/no-v-html -->
+      <p
+        v-else-if="!hideBio"
+        class="user-card-bio"
+      >
+        {{ user.description }}
+      </p>
     </div>
-    <p @click.prevent="linkClicked" v-if="!hideBio && user.description_html" class="user-card-bio" v-html="user.description_html"></p>
-    <p v-else-if="!hideBio" class="user-card-bio">{{ user.description }}</p>
   </div>
-</div>
 </template>
 
 <script src="./user_card.js"></script>
-- 
cgit v1.2.3-70-g09d2


From 57c5d269b8fa747a7f377090a8fb5507937f9ceb Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 11 Jul 2019 12:52:05 -0400
Subject: add bell-ringing icon

---
 src/components/user_card/user_card.vue |   2 +-
 static/font/config.json                |  20 ++++++++++++++------
 static/font/css/fontello-codes.css     |   2 +-
 static/font/css/fontello-embedded.css  |  14 +++++++-------
 static/font/css/fontello-ie7-codes.css |   2 +-
 static/font/css/fontello-ie7.css       |   2 +-
 static/font/css/fontello.css           |  16 ++++++++--------
 static/font/demo.html                  |  12 ++++++------
 static/font/font/fontello.eot          | Bin 19060 -> 19060 bytes
 static/font/font/fontello.svg          |   2 +-
 static/font/font/fontello.ttf          | Bin 18892 -> 18892 bytes
 static/font/font/fontello.woff         | Bin 11452 -> 11596 bytes
 static/font/font/fontello.woff2        | Bin 9724 -> 9856 bytes
 13 files changed, 40 insertions(+), 32 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f0ee6cae..1ce13f50 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -168,7 +168,7 @@
               :click="unsubscribeUser"
               :title="$t('user_card.unsubscribe')"
             >
-              <i class="icon-bell-alt" />
+              <i class="icon-bell-ringing-o" />
             </ProgressButton>
           </div>
 
diff --git a/static/font/config.json b/static/font/config.json
index baa2c763..15cedcdb 100755
--- a/static/font/config.json
+++ b/static/font/config.json
@@ -150,12 +150,6 @@
       "code": 61669,
       "src": "fontawesome"
     },
-    {
-      "uid": "cd21cbfb28ad4d903cede582157f65dc",
-      "css": "bell",
-      "code": 59408,
-      "src": "fontawesome"
-    },
     {
       "uid": "ccc2329632396dc096bb638d4b46fb98",
       "css": "mail-alt",
@@ -277,6 +271,20 @@
       "search": [
         "ellipsis"
       ]
+    },
+    {
+      "uid": "0bef873af785ead27781fdf98b3ae740",
+      "css": "bell-ringing-o",
+      "code": 59408,
+      "src": "custom_icons",
+      "selected": true,
+      "svg": {
+        "path": "M497.8 0C468.3 0 444.4 23.9 444.4 53.3 444.4 61.1 446.1 68.3 448.9 75 301.7 96.7 213.3 213.3 213.3 320 213.3 588.3 117.8 712.8 35.6 782.2 35.6 821.1 67.8 853.3 106.7 853.3H355.6C355.6 931.7 419.4 995.6 497.8 995.6S640 931.7 640 853.3H888.9C927.8 853.3 960 821.1 960 782.2 877.8 712.8 782.2 588.3 782.2 320 782.2 213.3 693.9 96.7 546.7 75 549.4 68.3 551.1 61.1 551.1 53.3 551.1 23.9 527.2 0 497.8 0ZM189.4 44.8C108.4 118.6 70.5 215.1 71.1 320.2L142.2 319.8C141.7 231.2 170.4 158.3 237.3 97.4L189.4 44.8ZM806.2 44.8L758.3 97.4C825.2 158.3 853.9 231.2 853.3 319.8L924.4 320.2C925.1 215.1 887.2 118.6 806.2 44.8ZM408.9 844.4C413.9 844.4 417.8 848.3 417.8 853.3 417.8 897.2 453.9 933.3 497.8 933.3 502.8 933.3 506.7 937.2 506.7 942.2S502.8 951.1 497.8 951.1C443.9 951.1 400 907.2 400 853.3 400 848.3 403.9 844.4 408.9 844.4Z",
+        "width": 1000
+      },
+      "search": [
+        "bell-ringing-o"
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/static/font/css/fontello-codes.css b/static/font/css/fontello-codes.css
index 5f84df34..273fce35 100755
--- a/static/font/css/fontello-codes.css
+++ b/static/font/css/fontello-codes.css
@@ -15,7 +15,7 @@
 .icon-right-open:before { content: '\e80d'; } /* '' */
 .icon-left-open:before { content: '\e80e'; } /* '' */
 .icon-up-open:before { content: '\e80f'; } /* '' */
-.icon-bell:before { content: '\e810'; } /* '' */
+.icon-bell-ringing-o:before { content: '\e810'; } /* '' */
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
diff --git a/static/font/css/fontello-embedded.css b/static/font/css/fontello-embedded.css
index 11f93ba7..44b26e90 100755
--- a/static/font/css/fontello-embedded.css
+++ b/static/font/css/fontello-embedded.css
@@ -1,15 +1,15 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?73032098');
-  src: url('../font/fontello.eot?73032098#iefix') format('embedded-opentype'),
-       url('../font/fontello.svg?73032098#fontello') format('svg');
+  src: url('../font/fontello.eot?36125818');
+  src: url('../font/fontello.eot?36125818#iefix') format('embedded-opentype'),
+       url('../font/fontello.svg?36125818#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
 @font-face {
   font-family: 'fontello';
-  src: url('data:application/octet-stream;base64,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') format('woff'),
-       url('data:application/octet-stream;base64,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') format('truetype');
+  src: url('data:application/octet-stream;base64,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') format('woff'),
+       url('data:application/octet-stream;base64,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') format('truetype');
 }
 /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
 /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
@@ -17,7 +17,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?73032098#fontello') format('svg');
+    src: url('../font/fontello.svg?36125818#fontello') format('svg');
   }
 }
 */
@@ -68,7 +68,7 @@
 .icon-right-open:before { content: '\e80d'; } /* '' */
 .icon-left-open:before { content: '\e80e'; } /* '' */
 .icon-up-open:before { content: '\e80f'; } /* '' */
-.icon-bell:before { content: '\e810'; } /* '' */
+.icon-bell-ringing-o:before { content: '\e810'; } /* '' */
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
diff --git a/static/font/css/fontello-ie7-codes.css b/static/font/css/fontello-ie7-codes.css
index 3fe390d8..5df45a1d 100755
--- a/static/font/css/fontello-ie7-codes.css
+++ b/static/font/css/fontello-ie7-codes.css
@@ -15,7 +15,7 @@
 .icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
 .icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
 .icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }
-.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
+.icon-bell-ringing-o { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
 .icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
diff --git a/static/font/css/fontello-ie7.css b/static/font/css/fontello-ie7.css
index 77c23c0e..f700ae78 100755
--- a/static/font/css/fontello-ie7.css
+++ b/static/font/css/fontello-ie7.css
@@ -26,7 +26,7 @@
 .icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
 .icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
 .icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }
-.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
+.icon-bell-ringing-o { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe810;&nbsp;'); }
 .icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe811;&nbsp;'); }
 .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe812;&nbsp;'); }
 .icon-brush { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe813;&nbsp;'); }
diff --git a/static/font/css/fontello.css b/static/font/css/fontello.css
index c1076a7a..6c14be64 100755
--- a/static/font/css/fontello.css
+++ b/static/font/css/fontello.css
@@ -1,11 +1,11 @@
 @font-face {
   font-family: 'fontello';
-  src: url('../font/fontello.eot?59217338');
-  src: url('../font/fontello.eot?59217338#iefix') format('embedded-opentype'),
-       url('../font/fontello.woff2?59217338') format('woff2'),
-       url('../font/fontello.woff?59217338') format('woff'),
-       url('../font/fontello.ttf?59217338') format('truetype'),
-       url('../font/fontello.svg?59217338#fontello') format('svg');
+  src: url('../font/fontello.eot?91349539');
+  src: url('../font/fontello.eot?91349539#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff2?91349539') format('woff2'),
+       url('../font/fontello.woff?91349539') format('woff'),
+       url('../font/fontello.ttf?91349539') format('truetype'),
+       url('../font/fontello.svg?91349539#fontello') format('svg');
   font-weight: normal;
   font-style: normal;
 }
@@ -15,7 +15,7 @@
 @media screen and (-webkit-min-device-pixel-ratio:0) {
   @font-face {
     font-family: 'fontello';
-    src: url('../font/fontello.svg?59217338#fontello') format('svg');
+    src: url('../font/fontello.svg?91349539#fontello') format('svg');
   }
 }
 */
@@ -71,7 +71,7 @@
 .icon-right-open:before { content: '\e80d'; } /* '' */
 .icon-left-open:before { content: '\e80e'; } /* '' */
 .icon-up-open:before { content: '\e80f'; } /* '' */
-.icon-bell:before { content: '\e810'; } /* '' */
+.icon-bell-ringing-o:before { content: '\e810'; } /* '' */
 .icon-lock:before { content: '\e811'; } /* '' */
 .icon-globe:before { content: '\e812'; } /* '' */
 .icon-brush:before { content: '\e813'; } /* '' */
diff --git a/static/font/demo.html b/static/font/demo.html
index 6090aaad..61dfae76 100755
--- a/static/font/demo.html
+++ b/static/font/demo.html
@@ -229,11 +229,11 @@ body {
 }
 @font-face {
       font-family: 'fontello';
-      src: url('./font/fontello.eot?60985121');
-      src: url('./font/fontello.eot?60985121#iefix') format('embedded-opentype'),
-           url('./font/fontello.woff?60985121') format('woff'),
-           url('./font/fontello.ttf?60985121') format('truetype'),
-           url('./font/fontello.svg?60985121#fontello') format('svg');
+      src: url('./font/fontello.eot?82370835');
+      src: url('./font/fontello.eot?82370835#iefix') format('embedded-opentype'),
+           url('./font/fontello.woff?82370835') format('woff'),
+           url('./font/fontello.ttf?82370835') format('truetype'),
+           url('./font/fontello.svg?82370835#fontello') format('svg');
       font-weight: normal;
       font-style: normal;
     }
@@ -322,7 +322,7 @@ body {
         <div class="the-icons span3" title="Code: 0xe80f"><i class="demo-icon icon-up-open">&#xe80f;</i> <span class="i-name">icon-up-open</span><span class="i-code">0xe80f</span></div>
       </div>
       <div class="row">
-        <div class="the-icons span3" title="Code: 0xe810"><i class="demo-icon icon-bell">&#xe810;</i> <span class="i-name">icon-bell</span><span class="i-code">0xe810</span></div>
+        <div class="the-icons span3" title="Code: 0xe810"><i class="demo-icon icon-bell-ringing-o">&#xe810;</i> <span class="i-name">icon-bell-ringing-o</span><span class="i-code">0xe810</span></div>
         <div class="the-icons span3" title="Code: 0xe811"><i class="demo-icon icon-lock">&#xe811;</i> <span class="i-name">icon-lock</span><span class="i-code">0xe811</span></div>
         <div class="the-icons span3" title="Code: 0xe812"><i class="demo-icon icon-globe">&#xe812;</i> <span class="i-name">icon-globe</span><span class="i-code">0xe812</span></div>
         <div class="the-icons span3" title="Code: 0xe813"><i class="demo-icon icon-brush">&#xe813;</i> <span class="i-name">icon-brush</span><span class="i-code">0xe813</span></div>
diff --git a/static/font/font/fontello.eot b/static/font/font/fontello.eot
index 8151bcb9..ca8d57f6 100755
Binary files a/static/font/font/fontello.eot and b/static/font/font/fontello.eot differ
diff --git a/static/font/font/fontello.svg b/static/font/font/fontello.svg
index 028f0498..7849638e 100755
--- a/static/font/font/fontello.svg
+++ b/static/font/font/fontello.svg
@@ -38,7 +38,7 @@
 
 <glyph glyph-name="up-open" unicode="&#xe80f;" d="M939 114l-92-92q-11-10-26-10t-25 10l-296 297-296-297q-11-10-25-10t-25 10l-93 92q-11 11-11 26t11 25l414 414q11 10 25 10t25-10l414-414q11-11 11-25t-11-26z" horiz-adv-x="1000" />
 
-<glyph glyph-name="bell" unicode="&#xe810;" d="M509-89q0 8-9 8-33 0-57 24t-23 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m-372 160h726q-149 168-149 465 0 28-13 58t-39 58-67 45-95 17-95-17-67-45-39-58-13-58q0-297-149-465z m827 0q0-29-21-50t-50-21h-250q0-59-42-101t-101-42-101 42-42 101h-250q-29 0-50 21t-21 50q28 24 51 49t47 67 42 89 27 115 11 145q0 84 66 157t171 89q-5 10-5 21 0 23 16 38t38 16 38-16 16-38q0-11-5-21 106-16 171-89t66-157q0-78 11-145t28-115 41-89 48-67 50-49z" horiz-adv-x="1000" />
+<glyph glyph-name="bell-ringing-o" unicode="&#xe810;" d="M498 857c-30 0-54-24-54-53 0-8 2-15 5-22-147-22-236-138-236-245 0-268-95-393-177-462 0-39 32-71 71-71h249c0-79 63-143 142-143s142 64 142 143h249c39 0 71 32 71 71-82 69-178 194-178 462 0 107-88 223-235 245 2 7 4 14 4 22 0 29-24 53-53 53z m-309-45c-81-74-118-170-118-275l71 0c0 89 28 162 95 223l-48 52z m617 0l-48-52c67-61 96-134 95-223l71 0c1 105-37 201-118 275z m-397-799c5 0 9-4 9-9 0-44 36-80 80-80 5 0 9-4 9-9s-4-9-9-9c-54 0-98 44-98 98 0 5 4 9 9 9z" horiz-adv-x="1000" />
 
 <glyph glyph-name="lock" unicode="&#xe811;" d="M179 428h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
 
diff --git a/static/font/font/fontello.ttf b/static/font/font/fontello.ttf
index d51d8bfa..e0fd784f 100755
Binary files a/static/font/font/fontello.ttf and b/static/font/font/fontello.ttf differ
diff --git a/static/font/font/fontello.woff b/static/font/font/fontello.woff
index 4046e91b..286c7d4d 100755
Binary files a/static/font/font/fontello.woff and b/static/font/font/fontello.woff differ
diff --git a/static/font/font/fontello.woff2 b/static/font/font/fontello.woff2
index f5bd2c11..5e5a3a2c 100755
Binary files a/static/font/font/fontello.woff2 and b/static/font/font/fontello.woff2 differ
-- 
cgit v1.2.3-70-g09d2


From 78594f61d40b5011e0dea97d74142fbbcbf393f9 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 12 Jul 2019 15:10:30 -0400
Subject: add a todo comment

---
 src/components/user_card/user_card.vue | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 1ce13f50..fe804e02 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -518,6 +518,7 @@
       margin: 0;
 
       &.pressed {
+        // TODO: This should be themed.
         border-bottom-color: rgba(255, 255, 255, 0.2);
         border-top-color: rgba(0, 0, 0, 0.2);
       }
-- 
cgit v1.2.3-70-g09d2


From ff90d864ccccd33e9d2cfb7ef64afa2486c537a0 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 12 Jul 2019 15:11:54 -0400
Subject: fix wrong eslint comments

---
 src/components/attachment/attachment.vue | 2 +-
 src/components/user_card/user_card.vue   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 108dc36e..ec326c45 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -100,7 +100,7 @@
         <!-- eslint-disable vue/no-v-html -->
         <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
         <div v-html="attachment.oembed.oembedHTML" />
-        <!-- eslint-enabled vue/no-v-html -->
+        <!-- eslint-enable vue/no-v-html -->
       </div>
     </div>
   </div>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index fe804e02..f987fbbb 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -22,7 +22,7 @@
                 class="user-name"
                 v-html="user.name_html"
               />
-              <!-- eslint-enabled vue/no-v-html -->
+              <!-- eslint-enable vue/no-v-html -->
               <div
                 v-else
                 :title="user.name"
@@ -265,7 +265,7 @@
         @click.prevent="linkClicked"
         v-html="user.description_html"
       />
-      <!-- eslint-enabled vue/no-v-html -->
+      <!-- eslint-enable vue/no-v-html -->
       <p
         v-else-if="!hideBio"
         class="user-card-bio"
-- 
cgit v1.2.3-70-g09d2


From c4789a348fe2bc10ed253f5dafca6547855569ed Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 11 Jul 2019 11:01:12 -0400
Subject: migrate popper css

---
 src/components/extra_buttons/extra_buttons.vue     |   4 +-
 .../moderation_tools/moderation_tools.vue          |   4 +-
 src/components/popper/popper.scss                  | 147 ++++++++++++---------
 src/components/user_card/user_card.vue             |   1 +
 4 files changed, 91 insertions(+), 65 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index 73f3d936..23c1adb6 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -2,10 +2,12 @@
   <v-popover
     v-if="enabled"
     trigger="click"
+    placement="top"
     class="extra-button-popover"
+    :offset="5"
     :container="false"
   >
-    <div class="popper-wrapper" slot="popover">
+    <div slot="popover">
       <div class="dropdown-menu">
         <button
           v-if="!status.pinned && canPin"
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index 4990a151..d97ca3aa 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -4,10 +4,12 @@
       trigger="click"
       class="moderation-tools-popover"
       :container="false"
+      placement="bottom-end"
+      :offset="5"
       @show="showDropDown = true"
       @hide="showDropDown = false"
     >
-      <div class="popper-wrapper" slot="popover">
+      <div slot="popover">
         <div class="dropdown-menu">
           <span v-if="user.is_local">
             <button
diff --git a/src/components/popper/popper.scss b/src/components/popper/popper.scss
index cfc5c8e7..279b01be 100644
--- a/src/components/popper/popper.scss
+++ b/src/components/popper/popper.scss
@@ -1,71 +1,99 @@
 @import '../../_variables.scss';
 
-.popper-wrapper {
+.tooltip.popover {
   z-index: 8;
-}
 
-.popper-wrapper .popper__arrow {
-  width: 0;
-  height: 0;
-  border-style: solid;
-  position: absolute;
-  margin: 5px;
-}
+  .popover-inner {
+    box-shadow: 1px 1px 4px rgba(0,0,0,.6);
+    box-shadow: var(--panelShadow);
+    border-radius: $fallback--btnRadius;
+    border-radius: var(--btnRadius, $fallback--btnRadius);
+    background-color: $fallback--bg;
+    background-color: var(--bg, $fallback--bg);
+  }
 
-.popper-wrapper[x-placement^="top"] {
-  margin-bottom: 5px;
-}
+  .popover-arrow {
+    width: 0;
+    height: 0;
+    border-style: solid;
+    position: absolute;
+    margin: 5px;
+    border-color: $fallback--bg;
+    border-color: var(--bg, $fallback--bg);
+    z-index: 1;
+  }
 
-.popper-wrapper[x-placement^="top"] .popper__arrow {
-  border-width: 5px 5px 0 5px;
-  border-color: $fallback--bg transparent transparent transparent;
-  border-color: var(--bg, $fallback--bg) transparent transparent transparent;
-  bottom: -5px;
-  left: calc(50% - 5px);
-  margin-top: 0;
-  margin-bottom: 0;
-}
+  &[x-placement^="top"] {
+    margin-bottom: 5px;
+
+    .popover-arrow {
+      border-width: 5px 5px 0 5px;
+      border-left-color: transparent !important;
+      border-right-color: transparent !important;
+      border-bottom-color: transparent !important;
+      bottom: -5px;
+      left: calc(50% - 5px);
+      margin-top: 0;
+      margin-bottom: 0;
+    }
+  }
 
-.popper-wrapper[x-placement^="bottom"] {
-  margin-top: 5px;
-}
+  &[x-placement^="bottom"] {
+    margin-top: 5px;
+
+    .popover-arrow {
+      border-width: 0 5px 5px 5px;
+      border-left-color: transparent !important;
+      border-right-color: transparent !important;
+      border-top-color: transparent !important;
+      top: -5px;
+      left: calc(50% - 5px);
+      margin-top: 0;
+      margin-bottom: 0;
+    }
+  }
 
-.popper-wrapper[x-placement^="bottom"] .popper__arrow {
-  border-width: 0 5px 5px 5px;
-  border-color: transparent transparent $fallback--bg transparent;
-  border-color: transparent transparent var(--bg, $fallback--bg) transparent;
-  top: -5px;
-  left: calc(50% - 5px);
-  margin-top: 0;
-  margin-bottom: 0;
-}
+  &[x-placement^="right"] {
+    margin-left: 5px;
+
+    .popover-arrow {
+      border-width: 5px 5px 5px 0;
+      border-left-color: transparent !important;
+      border-top-color: transparent !important;
+      border-bottom-color: transparent !important;
+      left: -5px;
+      top: calc(50% - 5px);
+      margin-left: 0;
+      margin-right: 0;
+    }
+  }
 
-.popper-wrapper[x-placement^="right"] {
-  margin-left: 5px;
-}
+  &[x-placement^="left"] {
+    margin-right: 5px;
 
-.popper-wrapper[x-placement^="right"] .popper__arrow {
-  border-width: 5px 5px 5px 0;
-  border-color: transparent $fallback--bg transparent transparent;
-  border-color: transparent var(--bg, $fallback--bg) transparent transparent;
-  left: -5px;
-  top: calc(50% - 5px);
-  margin-left: 0;
-  margin-right: 0;
-}
+    .popover-arrow {
+      border-width: 5px 0 5px 5px;
+      border-top-color: transparent !important;
+      border-right-color: transparent !important;
+      border-bottom-color: transparent !important;
+      right: -5px;
+      top: calc(50% - 5px);
+      margin-left: 0;
+      margin-right: 0;
+    }
+  }
 
-.popper-wrapper[x-placement^="left"] {
-  margin-right: 5px;
-}
+  &[aria-hidden='true'] {
+    visibility: hidden;
+    opacity: 0;
+    transition: opacity .15s, visibility .15s;
+  }
 
-.popper-wrapper[x-placement^="left"] .popper__arrow {
-  border-width: 5px 0 5px 5px;
-  border-color: transparent transparent transparent $fallback--bg;
-  border-color: transparent transparent transparent var(--bg, $fallback--bg);
-  right: -5px;
-  top: calc(50% - 5px);
-  margin-left: 0;
-  margin-right: 0;
+  &[aria-hidden='false'] {
+    visibility: visible;
+    opacity: 1;
+    transition: opacity .15s;
+  }
 }
 
 .dropdown-menu {
@@ -76,13 +104,6 @@
   list-style: none;
   max-width: 100vw;
   z-index: 10;
-  box-shadow: 1px 1px 4px rgba(0,0,0,.6);
-  box-shadow: var(--panelShadow);
-  border: none;
-  border-radius: $fallback--btnRadius;
-  border-radius: var(--btnRadius, $fallback--btnRadius);
-  background-color: $fallback--bg;
-  background-color: var(--bg, $fallback--bg);
 
   .dropdown-divider {
     height: 0;
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f987fbbb..ef3a5144 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -503,6 +503,7 @@
     }
   }
   .user-interactions {
+    position: relative;
     display: flex;
     flex-flow: row wrap;
     justify-content: space-between;
-- 
cgit v1.2.3-70-g09d2


From e3ac71968b549e90e90db976da1571fddbbb6472 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 11 Jul 2019 11:49:18 -0400
Subject: fix moderation menu partially hidden by usercard boundary

---
 src/components/user_card/user_card.vue | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index ef3a5144..9e142480 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -283,7 +283,6 @@
 
 .user-card {
   background-size: cover;
-  overflow: hidden;
 
   .panel-heading {
     padding: .5em 0;
@@ -298,6 +297,8 @@
     word-wrap: break-word;
     background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
     background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%);
+    border-bottom-right-radius: inherit;
+    border-bottom-left-radius: inherit;
   }
 
   p {
-- 
cgit v1.2.3-70-g09d2


From 7c2982064e6faf60c95e909e7722d6110310055a Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Mon, 22 Jul 2019 16:58:20 -0400
Subject: enlarge avatar in profile page

---
 src/components/user_card/user_card.js  | 14 ++++++++++++++
 src/components/user_card/user_card.vue | 19 ++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index e019ebbd..a3c962fb 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -5,6 +5,7 @@ import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+import { isEqual } from 'lodash'
 
 export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered' ],
@@ -100,6 +101,11 @@ export default {
       const validRole = rights.admin || rights.moderator
       const roleTitle = rights.admin ? 'admin' : 'moderator'
       return validRole && roleTitle
+    },
+    isActiveRoute () {
+      const profileRoute = this.userProfileLink(this.user)
+      const currentRoute = this.$router.currentRoute
+      return profileRoute.name === currentRoute.name && isEqual(profileRoute.params, currentRoute.params)
     }
   },
   components: {
@@ -162,6 +168,14 @@ export default {
     },
     reportUser () {
       this.$store.dispatch('openUserReportingModal', this.user.id)
+    },
+    enlargeAvatar () {
+      const attachment = {
+        url: this.user.profile_image_url_original,
+        mimetype: 'image'
+      }
+      this.$store.dispatch('setMedia', [attachment])
+      this.$store.dispatch('setCurrent', attachment)
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 9e142480..3c0bf0d4 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -7,7 +7,20 @@
     <div class="panel-heading">
       <div class="user-info">
         <div class="container">
-          <router-link :to="userProfileLink(user)">
+          <a
+            v-if="isActiveRoute"
+            class="user-info-avatar-link"
+            @click="enlargeAvatar"
+          >
+            <UserAvatar
+              :better-shadow="betterShadow"
+              :user="user"
+            />
+          </a>
+          <router-link
+            v-else
+            :to="userProfileLink(user)"
+          >
             <UserAvatar
               :better-shadow="betterShadow"
               :user="user"
@@ -372,6 +385,10 @@
     }
   }
 
+  &-avatar-link {
+    cursor: pointer;
+  }
+
   .usersettings {
     color: $fallback--lightText;
     color: var(--lightText, $fallback--lightText);
-- 
cgit v1.2.3-70-g09d2


From b2bd128f059de44a0ec27591dbc0052f494887a1 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Jul 2019 15:14:44 -0400
Subject: allow zooming avatar in profile panel header

---
 src/components/user_card/user_card.js        | 9 ++-------
 src/components/user_card/user_card.vue       | 4 ++--
 src/components/user_profile/user_profile.vue | 1 +
 3 files changed, 5 insertions(+), 9 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 070af38a..82d3b835 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -5,10 +5,9 @@ import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
-import { isEqual } from 'lodash'
 
 export default {
-  props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered' ],
+  props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar' ],
   data () {
     return {
       followRequestInProgress: false,
@@ -101,10 +100,6 @@ export default {
       const validRole = rights.admin || rights.moderator
       const roleTitle = rights.admin ? 'admin' : 'moderator'
       return validRole && roleTitle
-    },
-    isActiveRoute () {
-      const profileRoute = this.userProfileLink(this.user)
-      return profileRoute.name === this.$route.name && isEqual(profileRoute.params, this.$route.params)
     }
   },
   components: {
@@ -168,7 +163,7 @@ export default {
     reportUser () {
       this.$store.dispatch('openUserReportingModal', this.user.id)
     },
-    enlargeAvatar () {
+    zoomAvatar () {
       const attachment = {
         url: this.user.profile_image_url_original,
         mimetype: 'image'
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 3c0bf0d4..3c200a7f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -8,9 +8,9 @@
       <div class="user-info">
         <div class="container">
           <a
-            v-if="isActiveRoute"
+            v-if="allowZoomingAvatar"
             class="user-info-avatar-link"
-            @click="enlargeAvatar"
+            @click="zoomAvatar"
           >
             <UserAvatar
               :better-shadow="betterShadow"
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index e862440e..cffa28f1 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -8,6 +8,7 @@
         :user="user"
         :switcher="true"
         :selected="timeline.viewing"
+        :allow-zooming-avatar="true"
         rounded="top"
       />
       <tab-switcher
-- 
cgit v1.2.3-70-g09d2


From be7a508d89d8ea4b78abeba73625d25d22726270 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 25 Jul 2019 15:49:02 -0400
Subject: add zoom-in indication to avatar

---
 src/components/user_card/user_card.vue | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 3c200a7f..fc18e240 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -16,6 +16,9 @@
               :better-shadow="betterShadow"
               :user="user"
             />
+            <div class="user-info-avatar-link-overlay">
+              <i class="button-icon icon-zoom-in" />
+            </div>
           </a>
           <router-link
             v-else
@@ -364,6 +367,7 @@
   .container {
     padding: 16px 0 6px;
     display: flex;
+    align-items: flex-start;
     max-height: 56px;
 
     .avatar {
@@ -386,7 +390,32 @@
   }
 
   &-avatar-link {
+    position: relative;
     cursor: pointer;
+
+    &-overlay {
+      position: absolute;
+      left: 0;
+      top: 0;
+      right: 0;
+      bottom: 0;
+      background-color: rgba(0, 0, 0, 0.3);
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      border-radius: $fallback--avatarRadius;
+      border-radius: var(--avatarRadius, $fallback--avatarRadius);
+      opacity: 0;
+      transition: opacity .2s ease;
+
+      i {
+        color: #FFF;
+      }
+    }
+
+    &:hover &-overlay {
+      opacity: 1;
+    }
   }
 
   .usersettings {
-- 
cgit v1.2.3-70-g09d2


From 424d4ab57e13a8a271a16e063ce70af98759f8f9 Mon Sep 17 00:00:00 2001
From: rinpatch <rinpatch@sdf.org>
Date: Thu, 5 Sep 2019 11:16:11 +0300
Subject: Utilize `user.requested` to display follow request status on user
 card

Closes #635
---
 src/components/user_card/user_card.js               |  4 +---
 src/components/user_card/user_card.vue              |  4 ++--
 src/services/follow_manipulate/follow_manipulate.js | 11 ++++-------
 3 files changed, 7 insertions(+), 12 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 82d3b835..e3bd7697 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -11,7 +11,6 @@ export default {
   data () {
     return {
       followRequestInProgress: false,
-      followRequestSent: false,
       hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined'
         ? this.$store.state.instance.hideUserStats
         : this.$store.state.config.hideUserStats,
@@ -112,9 +111,8 @@ export default {
     followUser () {
       const store = this.$store
       this.followRequestInProgress = true
-      requestFollow(this.user, store).then(({ sent }) => {
+      requestFollow(this.user, store).then(() => {
         this.followRequestInProgress = false
-        this.followRequestSent = sent
       })
     },
     unfollowUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index fc18e240..0b83cf16 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -135,13 +135,13 @@
             <button
               class="btn btn-default btn-block"
               :disabled="followRequestInProgress"
-              :title="followRequestSent ? $t('user_card.follow_again') : ''"
+              :title="user.requested ? $t('user_card.follow_again') : ''"
               @click="followUser"
             >
               <template v-if="followRequestInProgress">
                 {{ $t('user_card.follow_progress') }}
               </template>
-              <template v-else-if="followRequestSent">
+              <template v-else-if="user.requested">
                 {{ $t('user_card.follow_sent') }}
               </template>
               <template v-else>
diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js
index 529fdb9b..d82ce593 100644
--- a/src/services/follow_manipulate/follow_manipulate.js
+++ b/src/services/follow_manipulate/follow_manipulate.js
@@ -9,10 +9,7 @@ const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => {
   if (!following && !(locked && sent) && attempt <= 3) {
     // If we BE reports that we still not following that user - retry,
     // increment attempts by one
-    return fetchUser(++attempt, user, store)
-  } else {
-    // If we run out of attempts, just return whatever status is.
-    return sent
+    fetchUser(++attempt, user, store)
   }
 })
 
@@ -23,7 +20,7 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => {
 
       if (updated.following || (user.locked && user.requested)) {
         // If we get result immediately or the account is locked, just stop.
-        resolve({ sent: updated.requested })
+        resolve()
         return
       }
 
@@ -35,8 +32,8 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => {
       // Recursive Promise, it will call itself up to 3 times.
 
       return fetchUser(1, user, store)
-        .then((sent) => {
-          resolve({ sent })
+        .then(() => {
+          resolve()
         })
     })
 })
-- 
cgit v1.2.3-70-g09d2


From d2fe79782119c061173c1b07753f634f0766bae9 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 15 Sep 2019 02:14:40 +0300
Subject: update status/user card to use same gradient mask fading effect
 instead of background hack

---
 src/components/status/status.vue       | 16 ++++++++++------
 src/components/user_card/user_card.js  | 11 +----------
 src/components/user_card/user_card.vue | 30 ++++++++++++++++++++++++++----
 3 files changed, 37 insertions(+), 20 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 771615f3..93f37a49 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -665,6 +665,15 @@ $status-margin: 0.75em;
     height: 220px;
     overflow-x: hidden;
     overflow-y: hidden;
+    z-index: 1;
+    .status-content {
+      height: 100%;
+      mask: linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
+            linear-gradient(to top, white, white);
+      // Autoprefixed seem to ignore this one, and also syntax is different
+      -webkit-mask-composite: xor;
+      mask-composite: exclude;
+    }
   }
 
   .tall-status-hider {
@@ -676,12 +685,7 @@ $status-margin: 0.75em;
     width: 100%;
     text-align: center;
     line-height: 110px;
-    background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
-    background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%);
-    &_focused {
-      background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--lightBg 80%);
-      background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--lightBg, $fallback--lightBg) 80%);
-    }
+    z-index: 2;
   }
 
   .status-unhider, .cw-status-hider {
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 82d3b835..e41a3180 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -38,19 +38,10 @@ export default {
         const rgb = (typeof color === 'string') ? hex2rgb(color) : color
         const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
 
-        const gradient = [
-          [tintColor, this.hideBio ? '60%' : ''],
-          this.hideBio ? [
-            color, '100%'
-          ] : [
-            tintColor, ''
-          ]
-        ].map(_ => _.join(' ')).join(', ')
-
         return {
           backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`,
           backgroundImage: [
-            `linear-gradient(to bottom, ${gradient})`,
+            `linear-gradient(to bottom, ${tintColor}, ${tintColor})`,
             `url(${this.user.cover_photo})`
           ].join(', ')
         }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index fc18e240..c2626260 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -2,8 +2,9 @@
   <div
     class="user-card"
     :class="classes"
-    :style="style"
   >
+    <div :class="{ 'hide-bio': hideBio }" :style="style" class="background-image">
+    </div>
     <div class="panel-heading">
       <div class="user-info">
         <div class="container">
@@ -298,7 +299,7 @@
 @import '../../_variables.scss';
 
 .user-card {
-  background-size: cover;
+  position: relative;
 
   .panel-heading {
     padding: .5em 0;
@@ -307,14 +308,35 @@
     background: transparent;
     flex-direction: column;
     align-items: stretch;
+    // create new stacking context
+    position: relative;
   }
 
   .panel-body {
     word-wrap: break-word;
-    background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
-    background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%);
     border-bottom-right-radius: inherit;
     border-bottom-left-radius: inherit;
+    // create new stacking context
+    position: relative;
+  }
+
+  .background-image {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    mask: linear-gradient(to top, white, transparent) bottom no-repeat,
+          linear-gradient(to top, white, white);
+    // Autoprefixed seem to ignore this one, and also syntax is different
+    -webkit-mask-composite: xor;
+    mask-composite: exclude;
+    background-size: cover;
+    mask-size: 100% 60%;
+
+    &.hide-bio {
+      mask-size: 100% 40px;
+    }
   }
 
   p {
-- 
cgit v1.2.3-70-g09d2


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: 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(+)

(limited to 'src/components/user_card/user_card.vue')

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",
-- 
cgit v1.2.3-70-g09d2


From 8721fb57fc3ee169ba401ce498280b8d7257297d Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Sat, 21 Sep 2019 16:24:47 +0300
Subject: added support hide\show reblogs from a specific user

---
 src/components/user_card/user_card.js                 | 15 +++++++++++++--
 src/components/user_card/user_card.vue                | 16 ++++++++++++++++
 src/i18n/en.json                                      |  2 ++
 src/modules/users.js                                  | 19 +++++++++++++++++++
 src/services/api/api.service.js                       |  5 ++++-
 .../backend_interactor_service.js                     |  4 ++--
 .../entity_normalizer/entity_normalizer.service.js    |  1 +
 src/services/follow_manipulate/follow_manipulate.js   |  2 +-
 8 files changed, 58 insertions(+), 6 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index e3bd7697..03f15d8e 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -7,7 +7,9 @@ import { requestFollow, requestUnfollow } from '../../services/follow_manipulate
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
 export default {
-  props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar' ],
+  props: [
+    'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar'
+  ],
   data () {
     return {
       followRequestInProgress: false,
@@ -108,6 +110,12 @@ export default {
     ProgressButton
   },
   methods: {
+    showReblogs () {
+      this.$store.dispatch('showReblogs', this.user.id)
+    },
+    hideReblogs () {
+      this.$store.dispatch('hideReblogs', this.user.id)
+    },
     followUser () {
       const store = this.$store
       this.followRequestInProgress = true
@@ -156,7 +164,10 @@ export default {
       }
     },
     userProfileLink (user) {
-      return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)
+      return generateProfileLink(
+        user.id, user.screen_name,
+        this.$store.state.instance.restrictedNicknames
+      )
     },
     reportUser () {
       this.$store.dispatch('openUserReportingModal', this.user.id)
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 0b83cf16..029406e7 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -186,6 +186,22 @@
             >
               <i class="icon-bell-ringing-o" />
             </ProgressButton>
+            <button
+              v-if="user.showing_reblogs"
+              class="btn btn-default"
+              :title="$t('user_card.hide_boosts', {user: user.screen_name})"
+              @click="hideReblogs"
+            >
+              <i class="icon-eye" />
+            </button>
+            <button
+              v-if="!user.showing_reblogs"
+              class="btn btn-default pressed"
+              :title="$t('user_card.show_boosts', {user: user.screen_name})"
+              @click="showReblogs"
+            >
+              <i class="icon-eye-off" />
+            </button>
           </div>
 
           <div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index ddde471a..c20f880a 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -543,6 +543,8 @@
     "unmute": "Unmute",
     "unmute_progress": "Unmuting...",
     "mute_progress": "Muting...",
+    "hide_boosts": "Hide boosts from {user}",
+    "show_boosts": "Show boosts from {user}",
     "admin_menu": {
       "moderation": "Moderation",
       "grant_admin": "Grant Admin",
diff --git a/src/modules/users.js b/src/modules/users.js
index 4d02f8d7..6d259dc2 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -60,6 +60,18 @@ const unmuteUser = (store, id) => {
     .then((relationship) => store.commit('updateUserRelationship', [relationship]))
 }
 
+const hideReblogs = (store, userId) => {
+  return store.rootState.api.backendInteractor.followUser({ id: userId, reblogs: false })
+    .then((relationship) => {
+      store.commit('updateUserRelationship', [relationship])
+    })
+}
+
+const showReblogs = (store, userId) => {
+  return store.rootState.api.backendInteractor.followUser({ id: userId, reblogs: true })
+    .then((relationship) => store.commit('updateUserRelationship', [relationship]))
+}
+
 export const mutations = {
   setMuted (state, { user: { id }, muted }) {
     const user = state.usersObject[id]
@@ -135,6 +147,7 @@ export const mutations = {
         user.muted = relationship.muting
         user.statusnet_blocking = relationship.blocking
         user.subscribed = relationship.subscribing
+        user.showing_reblogs = relationship.showing_reblogs
       }
     })
   },
@@ -272,6 +285,12 @@ const users = {
     unmuteUser (store, id) {
       return unmuteUser(store, id)
     },
+    hideReblogs (store, id) {
+      return hideReblogs(store, id)
+    },
+    showReblogs (store, id) {
+      return showReblogs(store, id)
+    },
     muteUsers (store, ids = []) {
       return Promise.all(ids.map(id => muteUser(store, id)))
     },
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 887d7d7a..80e94a50 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -219,9 +219,12 @@ const authHeaders = (accessToken) => {
   }
 }
 
-const followUser = ({ id, credentials }) => {
+const followUser = ({ id, reblogs, credentials }) => {
   let url = MASTODON_FOLLOW_URL(id)
+  const form = new FormData()
+  if (reblogs !== undefined) { form.append('reblogs', reblogs) }
   return fetch(url, {
+    body: form,
     headers: authHeaders(credentials),
     method: 'POST'
   }).then((data) => data.json())
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 3c44a10c..cbf48ee4 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -31,8 +31,8 @@ const backendInteractorService = credentials => {
     return apiService.fetchUserRelationship({ id, credentials })
   }
 
-  const followUser = (id) => {
-    return apiService.followUser({ credentials, id })
+  const followUser = ({ id, reblogs }) => {
+    return apiService.followUser({ credentials, id, reblogs })
   }
 
   const unfollowUser = (id) => {
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 7438cd90..906838fd 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -69,6 +69,7 @@ export const parseUser = (data) => {
         output.following = relationship.following
         output.statusnet_blocking = relationship.blocking
         output.muted = relationship.muting
+        output.showing_reblogs = relationship.showing_reblogs
         output.subscribed = relationship.subscribing
       }
 
diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js
index d82ce593..598cb5f7 100644
--- a/src/services/follow_manipulate/follow_manipulate.js
+++ b/src/services/follow_manipulate/follow_manipulate.js
@@ -14,7 +14,7 @@ const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => {
 })
 
 export const requestFollow = (user, store) => new Promise((resolve, reject) => {
-  store.state.api.backendInteractor.followUser(user.id)
+  store.state.api.backendInteractor.followUser({ id: user.id })
     .then((updated) => {
       store.commit('updateUserRelationship', [updated])
 
-- 
cgit v1.2.3-70-g09d2


From f0b9f5d29ca7bbac21cabad3d5f14328dfbf56dd Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Sun, 22 Sep 2019 14:39:28 +0300
Subject: use `repeats` intead `boosts`

---
 src/components/user_card/user_card.js  | 4 ++--
 src/components/user_card/user_card.vue | 8 ++++----
 src/i18n/en.json                       | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 03f15d8e..8b8ae132 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -110,10 +110,10 @@ export default {
     ProgressButton
   },
   methods: {
-    showReblogs () {
+    showRepeats () {
       this.$store.dispatch('showReblogs', this.user.id)
     },
-    hideReblogs () {
+    hideRepeats () {
       this.$store.dispatch('hideReblogs', this.user.id)
     },
     followUser () {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 029406e7..acef1d72 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -189,16 +189,16 @@
             <button
               v-if="user.showing_reblogs"
               class="btn btn-default"
-              :title="$t('user_card.hide_boosts', {user: user.screen_name})"
-              @click="hideReblogs"
+              :title="$t('user_card.hide_repeats')"
+              @click="hideRepeats"
             >
               <i class="icon-eye" />
             </button>
             <button
               v-if="!user.showing_reblogs"
               class="btn btn-default pressed"
-              :title="$t('user_card.show_boosts', {user: user.screen_name})"
-              @click="showReblogs"
+              :title="$t('user_card.show_repeats')"
+              @click="showRepeats"
             >
               <i class="icon-eye-off" />
             </button>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c20f880a..426a2f6a 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -543,8 +543,8 @@
     "unmute": "Unmute",
     "unmute_progress": "Unmuting...",
     "mute_progress": "Muting...",
-    "hide_boosts": "Hide boosts from {user}",
-    "show_boosts": "Show boosts from {user}",
+    "hide_repeats": "Hide repeats",
+    "show_repeats": "Show repeats",
     "admin_menu": {
       "moderation": "Moderation",
       "grant_admin": "Grant Admin",
-- 
cgit v1.2.3-70-g09d2


From 2f26e8acc5395753f4d649d9a1bfbe356717e9ac Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 25 Sep 2019 20:23:55 +0300
Subject: eslint

---
 src/components/emoji_input/emoji_input.js            | 2 +-
 src/components/emoji_picker/emoji_picker.vue         | 9 ++++++---
 src/components/post_status_form/post_status_form.vue | 6 +++---
 src/components/user_card/user_card.vue               | 7 +++++--
 4 files changed, 15 insertions(+), 9 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index f30cd1e4..a586b819 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -401,7 +401,7 @@ const EmojiInput = {
       this.$emit('input', e.target.value)
     },
     onClickInput (e) {
-      this.showPicker = false;
+      this.showPicker = false
     },
     onClickOutside (e) {
       if (this.disableClickOutside) return
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 6c43dd97..42f20130 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -77,13 +77,16 @@
         </div>
         <div
           class="keep-open"
-          >
+        >
           <input
             :id="labelKey + 'keep-open'"
             v-model="keepOpen"
             type="checkbox"
-            >
-          <label class="keep-open-label" :for="labelKey + 'keep-open'">
+          >
+          <label
+            class="keep-open-label"
+            :for="labelKey + 'keep-open'"
+          >
             <div class="keep-open-label-text">
               {{ $t('emoji.keep_open') }}
             </div>
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 5f9e21ae..4916d988 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -1,7 +1,7 @@
 <template>
-<div
-  class="post-status-form"
-  ref="root"
+  <div
+    ref="root"
+    class="post-status-form"
   >
     <form
       autocomplete="off"
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index c2626260..629d1fd0 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -3,8 +3,11 @@
     class="user-card"
     :class="classes"
   >
-    <div :class="{ 'hide-bio': hideBio }" :style="style" class="background-image">
-    </div>
+    <div
+      :class="{ 'hide-bio': hideBio }"
+      :style="style"
+      class="background-image"
+    />
     <div class="panel-heading">
       <div class="user-info">
         <div class="container">
-- 
cgit v1.2.3-70-g09d2


From 979e170bd6880d0ee85bf0dd8898cf53d91055b5 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 29 Sep 2019 22:33:15 +0300
Subject: created mergedConfig getter to avoid obnoxious checks for undefined
 everywhere

---
 src/components/favorite_button/favorite_button.js  |  8 ++--
 src/components/favorite_button/favorite_button.vue |  4 +-
 .../post_status_form/post_status_form.js           | 25 ++++--------
 src/components/retweet_button/retweet_button.js    |  8 ++--
 src/components/retweet_button/retweet_button.vue   |  4 +-
 src/components/status/status.js                    | 46 +++++++++-------------
 src/components/user_card/user_card.js              | 10 ++---
 src/components/user_card/user_card.vue             |  4 +-
 src/modules/config.js                              | 19 +++++++++
 9 files changed, 64 insertions(+), 64 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/favorite_button/favorite_button.js b/src/components/favorite_button/favorite_button.js
index a24eacbf..5014d84f 100644
--- a/src/components/favorite_button/favorite_button.js
+++ b/src/components/favorite_button/favorite_button.js
@@ -1,10 +1,9 @@
+import { mapGetters } from 'vuex'
+
 const FavoriteButton = {
   props: ['status', 'loggedIn'],
   data () {
     return {
-      hidePostStatsLocal: typeof this.$store.state.config.hidePostStats === 'undefined'
-        ? this.$store.state.instance.hidePostStats
-        : this.$store.state.config.hidePostStats,
       animated: false
     }
   },
@@ -28,7 +27,8 @@ const FavoriteButton = {
         'icon-star': this.status.favorited,
         'animate-spin': this.animated
       }
-    }
+    },
+    ...mapGetters(['mergedConfig'])
   }
 }
 
diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue
index 06ce9983..fbc90f84 100644
--- a/src/components/favorite_button/favorite_button.vue
+++ b/src/components/favorite_button/favorite_button.vue
@@ -6,7 +6,7 @@
       :title="$t('tool_tip.favorite')"
       @click.prevent="favorite()"
     />
-    <span v-if="!hidePostStatsLocal && status.fave_num > 0">{{ status.fave_num }}</span>
+    <span v-if="!mergedConfig.hidePostStats && status.fave_num > 0">{{ status.fave_num }}</span>
   </div>
   <div v-else>
     <i
@@ -14,7 +14,7 @@
       class="button-icon favorite-button"
       :title="$t('tool_tip.favorite')"
     />
-    <span v-if="!hidePostStatsLocal && status.fave_num > 0">{{ status.fave_num }}</span>
+    <span v-if="!mergedConfig.hidePostStats && status.fave_num > 0">{{ status.fave_num }}</span>
   </div>
 </template>
 
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 9b2a9c90..46afc79c 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -7,6 +7,7 @@ import fileTypeService from '../../services/file_type/file_type.service.js'
 import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
 import { reject, map, uniqBy } from 'lodash'
 import suggestor from '../emoji_input/suggestor.js'
+import { mapGetters } from 'vuex'
 
 const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
   let allAttentions = [...attentions]
@@ -50,9 +51,7 @@ const PostStatusForm = {
     const preset = this.$route.query.message
     let statusText = preset || ''
 
-    const scopeCopy = typeof this.$store.state.config.scopeCopy === 'undefined'
-      ? this.$store.state.instance.scopeCopy
-      : this.$store.state.config.scopeCopy
+    const { scopeCopy } = this.$store.getters.mergedConfig
 
     if (this.replyTo) {
       const currentUser = this.$store.state.users.currentUser
@@ -63,9 +62,7 @@ const PostStatusForm = {
       ? this.copyMessageScope
       : this.$store.state.users.currentUser.default_scope
 
-    const contentType = typeof this.$store.state.config.postContentType === 'undefined'
-      ? this.$store.state.instance.postContentType
-      : this.$store.state.config.postContentType
+    const { postContentType: contentType } = this.$store.getters.mergedConfig
 
     return {
       dropFiles: [],
@@ -94,10 +91,7 @@ const PostStatusForm = {
       return this.$store.state.users.currentUser.default_scope
     },
     showAllScopes () {
-      const minimalScopesMode = typeof this.$store.state.config.minimalScopesMode === 'undefined'
-        ? this.$store.state.instance.minimalScopesMode
-        : this.$store.state.config.minimalScopesMode
-      return !minimalScopesMode
+      return this.mergedConfig.minimalScopesMode
     },
     emojiUserSuggestor () {
       return suggestor({
@@ -145,13 +139,7 @@ const PostStatusForm = {
       return this.$store.state.instance.minimalScopesMode
     },
     alwaysShowSubject () {
-      if (typeof this.$store.state.config.alwaysShowSubjectInput !== 'undefined') {
-        return this.$store.state.config.alwaysShowSubjectInput
-      } else if (typeof this.$store.state.instance.alwaysShowSubjectInput !== 'undefined') {
-        return this.$store.state.instance.alwaysShowSubjectInput
-      } else {
-        return true
-      }
+      return this.mergedConfig.alwaysShowSubjectInput
     },
     postFormats () {
       return this.$store.state.instance.postFormats || []
@@ -170,7 +158,8 @@ const PostStatusForm = {
       return this.pollFormVisible &&
         this.newStatus.poll &&
         this.newStatus.poll.error
-    }
+    },
+    ...mapGetters(['mergedConfig'])
   },
   methods: {
     postStatus (newStatus) {
diff --git a/src/components/retweet_button/retweet_button.js b/src/components/retweet_button/retweet_button.js
index fb543a9c..d9a0f92e 100644
--- a/src/components/retweet_button/retweet_button.js
+++ b/src/components/retweet_button/retweet_button.js
@@ -1,10 +1,9 @@
+import { mapGetters } from 'vuex'
+
 const RetweetButton = {
   props: ['status', 'loggedIn', 'visibility'],
   data () {
     return {
-      hidePostStatsLocal: typeof this.$store.state.config.hidePostStats === 'undefined'
-        ? this.$store.state.instance.hidePostStats
-        : this.$store.state.config.hidePostStats,
       animated: false
     }
   },
@@ -28,7 +27,8 @@ const RetweetButton = {
         'retweeted-empty': !this.status.repeated,
         'animate-spin': this.animated
       }
-    }
+    },
+    ...mapGetters(['mergedConfig'])
   }
 }
 
diff --git a/src/components/retweet_button/retweet_button.vue b/src/components/retweet_button/retweet_button.vue
index d58a7f8c..074f7747 100644
--- a/src/components/retweet_button/retweet_button.vue
+++ b/src/components/retweet_button/retweet_button.vue
@@ -7,7 +7,7 @@
         :title="$t('tool_tip.repeat')"
         @click.prevent="retweet()"
       />
-      <span v-if="!hidePostStatsLocal && status.repeat_num > 0">{{ status.repeat_num }}</span>
+      <span v-if="!mergedConfig.hidePostStats && status.repeat_num > 0">{{ status.repeat_num }}</span>
     </template>
     <template v-else>
       <i
@@ -23,7 +23,7 @@
       class="button-icon icon-retweet"
       :title="$t('tool_tip.repeat')"
     />
-    <span v-if="!hidePostStatsLocal && status.repeat_num > 0">{{ status.repeat_num }}</span>
+    <span v-if="!mergedConfig.hidePostStats && status.repeat_num > 0">{{ status.repeat_num }}</span>
   </div>
 </template>
 
diff --git a/src/components/status/status.js b/src/components/status/status.js
index d17ba318..976fd320 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -15,6 +15,7 @@ import fileType from 'src/services/file_type/file_type.service'
 import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
 import { mentionMatchesUrl, extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
 import { filter, find, unescape, uniqBy } from 'lodash'
+import { mapGetters } from 'vuex'
 
 const Status = {
   name: 'Status',
@@ -42,20 +43,16 @@ const Status = {
       showingTall: this.inConversation && this.focused,
       showingLongSubject: false,
       error: null,
-      expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined'
-        ? !this.$store.state.instance.collapseMessageWithSubject
-        : !this.$store.state.config.collapseMessageWithSubject,
+      expandingSubject: this.$store.getters.mergedConfig.collapseMessageWithSubject,
       betterShadow: this.$store.state.interface.browserSupport.cssFilter
     }
   },
   computed: {
     localCollapseSubjectDefault () {
-      return typeof this.$store.state.config.collapseMessageWithSubject === 'undefined'
-        ? this.$store.state.instance.collapseMessageWithSubject
-        : this.$store.state.config.collapseMessageWithSubject
+      return this.mergedConfig.collapseMessageWithSubject
     },
     muteWords () {
-      return this.$store.state.config.muteWords
+      return this.mergedConfig.muteWords
     },
     repeaterClass () {
       const user = this.statusoid.user
@@ -70,18 +67,18 @@ const Status = {
     },
     repeaterStyle () {
       const user = this.statusoid.user
-      const highlight = this.$store.state.config.highlight
+      const highlight = this.mergedConfig.highlight
       return highlightStyle(highlight[user.screen_name])
     },
     userStyle () {
       if (this.noHeading) return
       const user = this.retweet ? (this.statusoid.retweeted_status.user) : this.statusoid.user
-      const highlight = this.$store.state.config.highlight
+      const highlight = this.mergedConfig.highlight
       return highlightStyle(highlight[user.screen_name])
     },
     hideAttachments () {
-      return (this.$store.state.config.hideAttachments && !this.inConversation) ||
-        (this.$store.state.config.hideAttachmentsInConv && this.inConversation)
+      return (this.mergedConfig.hideAttachments && !this.inConversation) ||
+        (this.mergedConfig.hideAttachmentsInConv && this.inConversation)
     },
     userProfileLink () {
       return this.generateUserProfileLink(this.status.user.id, this.status.user.screen_name)
@@ -120,9 +117,7 @@ const Status = {
     },
     muted () { return !this.unmuted && ((!this.inProfile && this.status.user.muted) || (!this.inConversation && this.status.thread_muted) || this.muteWordHits.length > 0) },
     hideFilteredStatuses () {
-      return typeof this.$store.state.config.hideFilteredStatuses === 'undefined'
-        ? this.$store.state.instance.hideFilteredStatuses
-        : this.$store.state.config.hideFilteredStatuses
+      return this.mergedConfig.hideFilteredStatuses
     },
     hideStatus () {
       return (this.hideReply || this.deleted) || (this.muted && this.hideFilteredStatuses)
@@ -163,7 +158,7 @@ const Status = {
       }
     },
     hideReply () {
-      if (this.$store.state.config.replyVisibility === 'all') {
+      if (this.mergedConfig.replyVisibility === 'all') {
         return false
       }
       if (this.inConversation || !this.isReply) {
@@ -175,7 +170,7 @@ const Status = {
       if (this.status.type === 'retweet') {
         return false
       }
-      const checkFollowing = this.$store.state.config.replyVisibility === 'following'
+      const checkFollowing = this.mergedConfig.replyVisibility === 'following'
       for (var i = 0; i < this.status.attentions.length; ++i) {
         if (this.status.user.id === this.status.attentions[i].id) {
           continue
@@ -220,9 +215,7 @@ const Status = {
     replySubject () {
       if (!this.status.summary) return ''
       const decodedSummary = unescape(this.status.summary)
-      const behavior = typeof this.$store.state.config.subjectLineBehavior === 'undefined'
-        ? this.$store.state.instance.subjectLineBehavior
-        : this.$store.state.config.subjectLineBehavior
+      const behavior = this.mergedConfig.subjectLineBehavior
       const startsWithRe = decodedSummary.match(/^re[: ]/i)
       if ((behavior !== 'noop' && startsWithRe) || behavior === 'masto') {
         return decodedSummary
@@ -233,8 +226,8 @@ const Status = {
       }
     },
     attachmentSize () {
-      if ((this.$store.state.config.hideAttachments && !this.inConversation) ||
-        (this.$store.state.config.hideAttachmentsInConv && this.inConversation) ||
+      if ((this.mergedConfig.hideAttachments && !this.inConversation) ||
+        (this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||
         (this.status.attachments.length > this.maxThumbnails)) {
         return 'hide'
       } else if (this.compact) {
@@ -246,7 +239,7 @@ const Status = {
       if (this.attachmentSize === 'hide') {
         return []
       }
-      return this.$store.state.config.playVideosInModal
+      return this.mergedConfig.playVideosInModal
         ? ['image', 'video']
         : ['image']
     },
@@ -261,7 +254,7 @@ const Status = {
       )
     },
     maxThumbnails () {
-      return this.$store.state.config.maxThumbnails
+      return this.mergedConfig.maxThumbnails
     },
     contentHtml () {
       if (!this.status.summary_html) {
@@ -284,10 +277,9 @@ const Status = {
       return this.status.tags.filter(tagObj => tagObj.hasOwnProperty('name')).map(tagObj => tagObj.name).join(' ')
     },
     hidePostStats () {
-      return typeof this.$store.state.config.hidePostStats === 'undefined'
-        ? this.$store.state.instance.hidePostStats
-        : this.$store.state.config.hidePostStats
-    }
+      return this.mergedConfig.hidePostStats
+    },
+    ...mapGetters(['mergedConfig'])
   },
   components: {
     Attachment,
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 9c931c01..12f9f9e8 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -5,15 +5,13 @@ import ModerationTools from '../moderation_tools/moderation_tools.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
+import { mapGetters } from 'vuex'
 
 export default {
   props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar' ],
   data () {
     return {
       followRequestInProgress: false,
-      hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined'
-        ? this.$store.state.instance.hideUserStats
-        : this.$store.state.config.hideUserStats,
       betterShadow: this.$store.state.interface.browserSupport.cssFilter
     }
   },
@@ -73,7 +71,8 @@ export default {
         } else {
           this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: undefined })
         }
-      }
+      },
+      ...mapGetters(['mergedConfig'])
     },
     userHighlightColor: {
       get () {
@@ -90,7 +89,8 @@ export default {
       const validRole = rights.admin || rights.moderator
       const roleTitle = rights.admin ? 'admin' : 'moderator'
       return validRole && roleTitle
-    }
+    },
+    ...mapGetters(['mergedConfig'])
   },
   components: {
     UserAvatar,
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 5b6f66e7..6bcc3aac 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -81,7 +81,7 @@
               >{{ visibleRole }}</span>
               <span v-if="user.locked"><i class="icon icon-lock" /></span>
               <span
-                v-if="!hideUserStatsLocal && !hideBio"
+                v-if="!mergedConfig.hideUserStats && !hideBio"
                 class="dailyAvg"
               >{{ dailyAvg }} {{ $t('user_card.per_day') }}</span>
             </div>
@@ -262,7 +262,7 @@
       class="panel-body"
     >
       <div
-        v-if="!hideUserStatsLocal && switcher"
+        v-if="!mergedConfig.hideUserStats && switcher"
         class="user-counts"
       >
         <div
diff --git a/src/modules/config.js b/src/modules/config.js
index cf04d14f..5245308d 100644
--- a/src/modules/config.js
+++ b/src/modules/config.js
@@ -40,8 +40,27 @@ const defaultState = {
   minimalScopesMode: undefined // instance default
 }
 
+// caching the instance default properties
+export const instanceDefaultProperties = Object.entries(defaultState)
+  .filter(([key, value]) => value === undefined)
+  .map(([key, value]) => key)
+
 const config = {
   state: defaultState,
+  getters: {
+    mergedConfig (state, getters, rootState, rootGetters) {
+      const { instance } = rootState
+      return {
+        ...state,
+        ...instanceDefaultProperties
+          .map(key => [key, state[key] === undefined
+            ? instance[key]
+            : state[key]
+          ])
+          .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
+      }
+    }
+  },
   mutations: {
     setOption (state, { name, value }) {
       set(state, name, value)
-- 
cgit v1.2.3-70-g09d2


From 188b6f56ed2f983d8f0fba4dc8f7327ebbee321d Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Mon, 30 Sep 2019 20:34:51 +0300
Subject: added acccount_actions component

---
 src/components/account_actions/account_actions.js  |  59 +++++++++
 src/components/account_actions/account_actions.vue | 133 ++++++++++++++++++++
 src/components/follow_button/follow_button.js      |  58 +++++++++
 src/components/follow_button/follow_button.vue     |  13 ++
 src/components/user_card/user_card.js              |  48 +-------
 src/components/user_card/user_card.vue             | 135 +--------------------
 6 files changed, 268 insertions(+), 178 deletions(-)
 create mode 100644 src/components/account_actions/account_actions.js
 create mode 100644 src/components/account_actions/account_actions.vue
 create mode 100644 src/components/follow_button/follow_button.js
 create mode 100644 src/components/follow_button/follow_button.vue

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
new file mode 100644
index 00000000..1092a96a
--- /dev/null
+++ b/src/components/account_actions/account_actions.js
@@ -0,0 +1,59 @@
+import FollowButton from '../follow_button/follow_button.vue'
+import ProgressButton from '../progress_button/progress_button.vue'
+
+const AccountActions = {
+  props: [
+    'user'
+  ],
+  data () {
+    return {
+      showDropDown: false
+    }
+  },
+  components: {
+    FollowButton,
+    ProgressButton
+  },
+  computed: {
+    tagsSet () {
+      return new Set(this.user.tags)
+    },
+    hasTagPolicy () {
+      return this.$store.state.instance.tagPolicyAvailable
+    }
+  },
+  methods: {
+    subscribeUser () {
+      return this.$store.dispatch('subscribeUser', this.user.id)
+    },
+    unsubscribeUser () {
+      return this.$store.dispatch('unsubscribeUser', this.user.id)
+    },
+    showRepeats () {
+      this.$store.dispatch('showReblogs', this.user.id)
+    },
+    hideRepeats () {
+      this.$store.dispatch('hideReblogs', this.user.id)
+    },
+    muteUser () {
+      this.$store.dispatch('muteUser', this.user.id)
+    },
+    unmuteUser () {
+      this.$store.dispatch('unmuteUser', this.user.id)
+    },
+    blockUser () {
+      this.$store.dispatch('blockUser', this.user.id)
+    },
+    unblockUser () {
+      this.$store.dispatch('unblockUser', this.user.id)
+    },
+    reportUser () {
+      this.$store.dispatch('openUserReportingModal', this.user.id)
+    },
+    mentionUser () {
+      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
+    }
+  }
+}
+
+export default AccountActions
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
new file mode 100644
index 00000000..ce508b0a
--- /dev/null
+++ b/src/components/account_actions/account_actions.vue
@@ -0,0 +1,133 @@
+<template>
+  <div class="account-actions">
+    <FollowButton :user="user" />
+    <v-popover
+      trigger="click"
+      class="account-tools-popover"
+      :container="false"
+      placement="bottom-end"
+      :offset="5"
+      @show="showDropDown = true"
+      @hide="showDropDown = false"
+    >
+      <div slot="popover">
+        <div class="dropdown-menu">
+          <button
+            class="btn btn-default btn-block dropdown-item"
+            @click="mentionUser"
+          >
+            {{ $t('user_card.mention') }}
+          </button>
+          <template v-if="user.following">
+            <div
+              role="separator"
+              class="dropdown-divider"
+            />
+            <ProgressButton
+              v-if="!user.subscribed"
+              class="btn btn-default dropdown-item"
+              :click="subscribeUser"
+              :title="$t('user_card.subscribe')"
+            >
+              {{ $t('user_card.subscribe') }}
+            </ProgressButton>
+            <ProgressButton
+              v-else
+              class="btn btn-default pressed dropdown-item"
+              :click="unsubscribeUser"
+              :title="$t('user_card.unsubscribe')"
+            >
+              {{ $t('user_card.unsubscribe') }}
+            </ProgressButton>
+
+            <button
+              v-if="user.showing_reblogs"
+              class="btn btn-default dropdown-item"
+              @click="hideRepeats"
+            >
+              {{ $t('user_card.hide_repeats') }}
+            </button>
+            <button
+              v-if="!user.showing_reblogs"
+              class="btn btn-default pressed dropdown-item"
+              @click="showRepeats"
+            >
+              {{ $t('user_card.show_repeats') }}
+            </button>
+          </template>
+          <div
+            role="separator"
+            class="dropdown-divider"
+          />
+          <button
+            v-if="user.muted"
+            class="btn btn-default btn-block pressed dropdown-item"
+            @click="unmuteUser"
+          >
+            {{ $t('user_card.muted') }}
+          </button>
+          <button
+            v-else
+            class="btn btn-default btn-block dropdown-item"
+            @click="muteUser"
+          >
+            {{ $t('user_card.mute') }}
+          </button>
+          <button
+            v-if="user.statusnet_blocking"
+            class="btn btn-default btn-block pressed dropdown-item"
+            @click="unblockUser"
+          >
+            {{ $t('user_card.blocked') }}
+          </button>
+          <button
+            v-else
+            class="btn btn-default btn-block dropdown-item"
+            @click="blockUser"
+          >
+            {{ $t('user_card.block') }}
+          </button>
+          <button
+            class="btn btn-default btn-block dropdown-item"
+            @click="reportUser"
+          >
+            {{ $t('user_card.report') }}
+          </button>
+        </div>
+      </div>
+      <button class="btn btn-default ellipsis-button">
+        <i class="icon-ellipsis" />
+      </button>
+    </v-popover>
+  </div>
+</template>
+
+<script src="./account_actions.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+@import '../popper/popper.scss';
+
+.account-tools-popover {
+  height: 100%;
+  .trigger {
+    display: flex !important;
+    height: 100%;
+  }
+}
+.account-actions {
+  display: flex;
+  flex: 0 0 0 !important;
+  margin: 0 3em 0 0 !important;
+}
+.account-actions .follow-button {
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.account-actions .ellipsis-button {
+  border-top-left-radius: 0px;
+  border-bottom-left-radius: 0px;
+}
+.account-actions .button-icon {
+}
+</style>
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
new file mode 100644
index 00000000..9d2834ab
--- /dev/null
+++ b/src/components/follow_button/follow_button.js
@@ -0,0 +1,58 @@
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
+export default {
+  props: ['user'],
+  data () {
+    return {
+      inProgress: false
+    }
+  },
+  computed: {
+    isPressed () {
+      return this.inProgress || this.user.following
+    },
+    title () {
+      if (this.inProgress || this.user.following) {
+        return 'user_card.follow_unfollow'
+      } else if (this.user.requested) {
+        return 'user_card.follow_again'
+      } else {
+        return ''
+      }
+    },
+    label () {
+      if (this.inProgress) {
+        return 'user_card.follow_progress'
+      } else if (this.user.following) {
+        return 'user_card.following'
+      } else if (this.user.requested) {
+        return 'user_card.follow_sent'
+      } else {
+        return 'user_card.follow'
+      }
+    }
+  },
+  methods: {
+    doClick () {
+      if (this.user.following) {
+        this.unfollowUser()
+      } else {
+        this.followUser()
+      }
+    },
+    followUser () {
+      const store = this.$store
+      this.inProgress = true
+      requestFollow(this.user, store).then(() => {
+        this.inProgress = false
+      })
+    },
+    unfollowUser () {
+      const store = this.$store
+      this.inProgress = true
+      requestUnfollow(this.user, store).then(() => {
+        this.inProgress = false
+        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
+      })
+    }
+  }
+}
diff --git a/src/components/follow_button/follow_button.vue b/src/components/follow_button/follow_button.vue
new file mode 100644
index 00000000..61aa75a0
--- /dev/null
+++ b/src/components/follow_button/follow_button.vue
@@ -0,0 +1,13 @@
+<template>
+  <button
+    class="btn btn-default btn-block follow-button"
+    :class="{ pressed: isPressed }"
+    :disabled="inProgress"
+    :title="$t(title)"
+    @click="doClick"
+  >
+    {{ $t(label) }}
+  </button>
+</template>
+
+<script src="./follow_button.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 015a5762..c09e5654 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -2,8 +2,8 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
 import ProgressButton from '../progress_button/progress_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
+import AccountActions from '../account_actions/account_actions.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
-import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
 export default {
@@ -98,48 +98,10 @@ export default {
     UserAvatar,
     RemoteFollow,
     ModerationTools,
+    AccountActions,
     ProgressButton
   },
   methods: {
-    showRepeats () {
-      this.$store.dispatch('showReblogs', this.user.id)
-    },
-    hideRepeats () {
-      this.$store.dispatch('hideReblogs', this.user.id)
-    },
-    followUser () {
-      const store = this.$store
-      this.followRequestInProgress = true
-      requestFollow(this.user, store).then(() => {
-        this.followRequestInProgress = false
-      })
-    },
-    unfollowUser () {
-      const store = this.$store
-      this.followRequestInProgress = true
-      requestUnfollow(this.user, store).then(() => {
-        this.followRequestInProgress = false
-        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
-      })
-    },
-    blockUser () {
-      this.$store.dispatch('blockUser', this.user.id)
-    },
-    unblockUser () {
-      this.$store.dispatch('unblockUser', this.user.id)
-    },
-    muteUser () {
-      this.$store.dispatch('muteUser', this.user.id)
-    },
-    unmuteUser () {
-      this.$store.dispatch('unmuteUser', this.user.id)
-    },
-    subscribeUser () {
-      return this.$store.dispatch('subscribeUser', this.user.id)
-    },
-    unsubscribeUser () {
-      return this.$store.dispatch('unsubscribeUser', this.user.id)
-    },
     setProfileView (v) {
       if (this.switcher) {
         const store = this.$store
@@ -160,9 +122,6 @@ export default {
         this.$store.state.instance.restrictedNicknames
       )
     },
-    reportUser () {
-      this.$store.dispatch('openUserReportingModal', this.user.id)
-    },
     zoomAvatar () {
       const attachment = {
         url: this.user.profile_image_url_original,
@@ -170,9 +129,6 @@ export default {
       }
       this.$store.dispatch('setMedia', [attachment])
       this.$store.dispatch('setCurrent', attachment)
-    },
-    mentionUser () {
-      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f465467c..abaef85f 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -131,135 +131,12 @@
             </label>
           </div>
         </div>
+
         <div
           v-if="loggedIn && isOtherUser"
           class="user-interactions"
         >
-          <div v-if="!user.following">
-            <button
-              class="btn btn-default btn-block"
-              :disabled="followRequestInProgress"
-              :title="user.requested ? $t('user_card.follow_again') : ''"
-              @click="followUser"
-            >
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else-if="user.requested">
-                {{ $t('user_card.follow_sent') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.follow') }}
-              </template>
-            </button>
-          </div>
-          <div v-else-if="followRequestInProgress">
-            <button
-              class="btn btn-default btn-block pressed"
-              disabled
-              :title="$t('user_card.follow_unfollow')"
-              @click="unfollowUser"
-            >
-              {{ $t('user_card.follow_progress') }}
-            </button>
-          </div>
-          <div
-            v-else
-            class="btn-group"
-          >
-            <button
-              class="btn btn-default pressed"
-              :title="$t('user_card.follow_unfollow')"
-              @click="unfollowUser"
-            >
-              {{ $t('user_card.following') }}
-            </button>
-            <ProgressButton
-              v-if="!user.subscribed"
-              class="btn btn-default"
-              :click="subscribeUser"
-              :title="$t('user_card.subscribe')"
-            >
-              <i class="icon-bell-alt" />
-            </ProgressButton>
-            <ProgressButton
-              v-else
-              class="btn btn-default pressed"
-              :click="unsubscribeUser"
-              :title="$t('user_card.unsubscribe')"
-            >
-              <i class="icon-bell-ringing-o" />
-            </ProgressButton>
-            <button
-              v-if="user.showing_reblogs"
-              class="btn btn-default"
-              :title="$t('user_card.hide_repeats')"
-              @click="hideRepeats"
-            >
-              <i class="icon-eye" />
-            </button>
-            <button
-              v-if="!user.showing_reblogs"
-              class="btn btn-default pressed"
-              :title="$t('user_card.show_repeats')"
-              @click="showRepeats"
-            >
-              <i class="icon-eye-off" />
-            </button>
-          </div>
-
-          <div>
-            <button
-              class="btn btn-default btn-block"
-              @click="mentionUser"
-            >
-              {{ $t('user_card.mention') }}
-            </button>
-          </div>
-
-          <div>
-            <button
-              v-if="user.muted"
-              class="btn btn-default btn-block pressed"
-              @click="unmuteUser"
-            >
-              {{ $t('user_card.muted') }}
-            </button>
-            <button
-              v-else
-              class="btn btn-default btn-block"
-              @click="muteUser"
-            >
-              {{ $t('user_card.mute') }}
-            </button>
-          </div>
-
-          <div>
-            <button
-              v-if="user.statusnet_blocking"
-              class="btn btn-default btn-block pressed"
-              @click="unblockUser"
-            >
-              {{ $t('user_card.blocked') }}
-            </button>
-            <button
-              v-else
-              class="btn btn-default btn-block"
-              @click="blockUser"
-            >
-              {{ $t('user_card.block') }}
-            </button>
-          </div>
-
-          <div>
-            <button
-              class="btn btn-default btn-block"
-              @click="reportUser"
-            >
-              {{ $t('user_card.report') }}
-            </button>
-          </div>
-
+          <AccountActions :user="user" />
           <ModerationTools
             v-if="loggedIn.role === &quot;admin&quot;"
             :user="user"
@@ -603,15 +480,9 @@
     position: relative;
     display: flex;
     flex-flow: row wrap;
-    justify-content: space-between;
+    justify-content: flex-end;
     margin-right: -.75em;
 
-    > * {
-      flex: 1 0 0;
-      margin: 0 .75em .6em 0;
-      white-space: nowrap;
-    }
-
     button {
       margin: 0;
 
-- 
cgit v1.2.3-70-g09d2


From 9c305c5f93b2ffee0a98ff8cc6770df052d4b71e Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Tue, 8 Oct 2019 10:21:40 +0300
Subject: Revert "added acccount_actions component"

This reverts commit 188b6f56ed2f983d8f0fba4dc8f7327ebbee321d.
---
 src/components/account_actions/account_actions.js  |  59 ---------
 src/components/account_actions/account_actions.vue | 133 --------------------
 src/components/follow_button/follow_button.js      |  58 ---------
 src/components/follow_button/follow_button.vue     |  13 --
 src/components/user_card/user_card.js              |  48 +++++++-
 src/components/user_card/user_card.vue             | 135 ++++++++++++++++++++-
 6 files changed, 178 insertions(+), 268 deletions(-)
 delete mode 100644 src/components/account_actions/account_actions.js
 delete mode 100644 src/components/account_actions/account_actions.vue
 delete mode 100644 src/components/follow_button/follow_button.js
 delete mode 100644 src/components/follow_button/follow_button.vue

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
deleted file mode 100644
index 1092a96a..00000000
--- a/src/components/account_actions/account_actions.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import FollowButton from '../follow_button/follow_button.vue'
-import ProgressButton from '../progress_button/progress_button.vue'
-
-const AccountActions = {
-  props: [
-    'user'
-  ],
-  data () {
-    return {
-      showDropDown: false
-    }
-  },
-  components: {
-    FollowButton,
-    ProgressButton
-  },
-  computed: {
-    tagsSet () {
-      return new Set(this.user.tags)
-    },
-    hasTagPolicy () {
-      return this.$store.state.instance.tagPolicyAvailable
-    }
-  },
-  methods: {
-    subscribeUser () {
-      return this.$store.dispatch('subscribeUser', this.user.id)
-    },
-    unsubscribeUser () {
-      return this.$store.dispatch('unsubscribeUser', this.user.id)
-    },
-    showRepeats () {
-      this.$store.dispatch('showReblogs', this.user.id)
-    },
-    hideRepeats () {
-      this.$store.dispatch('hideReblogs', this.user.id)
-    },
-    muteUser () {
-      this.$store.dispatch('muteUser', this.user.id)
-    },
-    unmuteUser () {
-      this.$store.dispatch('unmuteUser', this.user.id)
-    },
-    blockUser () {
-      this.$store.dispatch('blockUser', this.user.id)
-    },
-    unblockUser () {
-      this.$store.dispatch('unblockUser', this.user.id)
-    },
-    reportUser () {
-      this.$store.dispatch('openUserReportingModal', this.user.id)
-    },
-    mentionUser () {
-      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
-    }
-  }
-}
-
-export default AccountActions
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
deleted file mode 100644
index ce508b0a..00000000
--- a/src/components/account_actions/account_actions.vue
+++ /dev/null
@@ -1,133 +0,0 @@
-<template>
-  <div class="account-actions">
-    <FollowButton :user="user" />
-    <v-popover
-      trigger="click"
-      class="account-tools-popover"
-      :container="false"
-      placement="bottom-end"
-      :offset="5"
-      @show="showDropDown = true"
-      @hide="showDropDown = false"
-    >
-      <div slot="popover">
-        <div class="dropdown-menu">
-          <button
-            class="btn btn-default btn-block dropdown-item"
-            @click="mentionUser"
-          >
-            {{ $t('user_card.mention') }}
-          </button>
-          <template v-if="user.following">
-            <div
-              role="separator"
-              class="dropdown-divider"
-            />
-            <ProgressButton
-              v-if="!user.subscribed"
-              class="btn btn-default dropdown-item"
-              :click="subscribeUser"
-              :title="$t('user_card.subscribe')"
-            >
-              {{ $t('user_card.subscribe') }}
-            </ProgressButton>
-            <ProgressButton
-              v-else
-              class="btn btn-default pressed dropdown-item"
-              :click="unsubscribeUser"
-              :title="$t('user_card.unsubscribe')"
-            >
-              {{ $t('user_card.unsubscribe') }}
-            </ProgressButton>
-
-            <button
-              v-if="user.showing_reblogs"
-              class="btn btn-default dropdown-item"
-              @click="hideRepeats"
-            >
-              {{ $t('user_card.hide_repeats') }}
-            </button>
-            <button
-              v-if="!user.showing_reblogs"
-              class="btn btn-default pressed dropdown-item"
-              @click="showRepeats"
-            >
-              {{ $t('user_card.show_repeats') }}
-            </button>
-          </template>
-          <div
-            role="separator"
-            class="dropdown-divider"
-          />
-          <button
-            v-if="user.muted"
-            class="btn btn-default btn-block pressed dropdown-item"
-            @click="unmuteUser"
-          >
-            {{ $t('user_card.muted') }}
-          </button>
-          <button
-            v-else
-            class="btn btn-default btn-block dropdown-item"
-            @click="muteUser"
-          >
-            {{ $t('user_card.mute') }}
-          </button>
-          <button
-            v-if="user.statusnet_blocking"
-            class="btn btn-default btn-block pressed dropdown-item"
-            @click="unblockUser"
-          >
-            {{ $t('user_card.blocked') }}
-          </button>
-          <button
-            v-else
-            class="btn btn-default btn-block dropdown-item"
-            @click="blockUser"
-          >
-            {{ $t('user_card.block') }}
-          </button>
-          <button
-            class="btn btn-default btn-block dropdown-item"
-            @click="reportUser"
-          >
-            {{ $t('user_card.report') }}
-          </button>
-        </div>
-      </div>
-      <button class="btn btn-default ellipsis-button">
-        <i class="icon-ellipsis" />
-      </button>
-    </v-popover>
-  </div>
-</template>
-
-<script src="./account_actions.js"></script>
-
-<style lang="scss">
-@import '../../_variables.scss';
-@import '../popper/popper.scss';
-
-.account-tools-popover {
-  height: 100%;
-  .trigger {
-    display: flex !important;
-    height: 100%;
-  }
-}
-.account-actions {
-  display: flex;
-  flex: 0 0 0 !important;
-  margin: 0 3em 0 0 !important;
-}
-.account-actions .follow-button {
-  border-top-right-radius: 0px;
-  border-bottom-right-radius: 0px;
-}
-.account-actions .ellipsis-button {
-  border-top-left-radius: 0px;
-  border-bottom-left-radius: 0px;
-}
-.account-actions .button-icon {
-}
-</style>
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
deleted file mode 100644
index 9d2834ab..00000000
--- a/src/components/follow_button/follow_button.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
-export default {
-  props: ['user'],
-  data () {
-    return {
-      inProgress: false
-    }
-  },
-  computed: {
-    isPressed () {
-      return this.inProgress || this.user.following
-    },
-    title () {
-      if (this.inProgress || this.user.following) {
-        return 'user_card.follow_unfollow'
-      } else if (this.user.requested) {
-        return 'user_card.follow_again'
-      } else {
-        return ''
-      }
-    },
-    label () {
-      if (this.inProgress) {
-        return 'user_card.follow_progress'
-      } else if (this.user.following) {
-        return 'user_card.following'
-      } else if (this.user.requested) {
-        return 'user_card.follow_sent'
-      } else {
-        return 'user_card.follow'
-      }
-    }
-  },
-  methods: {
-    doClick () {
-      if (this.user.following) {
-        this.unfollowUser()
-      } else {
-        this.followUser()
-      }
-    },
-    followUser () {
-      const store = this.$store
-      this.inProgress = true
-      requestFollow(this.user, store).then(() => {
-        this.inProgress = false
-      })
-    },
-    unfollowUser () {
-      const store = this.$store
-      this.inProgress = true
-      requestUnfollow(this.user, store).then(() => {
-        this.inProgress = false
-        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
-      })
-    }
-  }
-}
diff --git a/src/components/follow_button/follow_button.vue b/src/components/follow_button/follow_button.vue
deleted file mode 100644
index 61aa75a0..00000000
--- a/src/components/follow_button/follow_button.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-<template>
-  <button
-    class="btn btn-default btn-block follow-button"
-    :class="{ pressed: isPressed }"
-    :disabled="inProgress"
-    :title="$t(title)"
-    @click="doClick"
-  >
-    {{ $t(label) }}
-  </button>
-</template>
-
-<script src="./follow_button.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index c09e5654..015a5762 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -2,8 +2,8 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
 import ProgressButton from '../progress_button/progress_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
-import AccountActions from '../account_actions/account_actions.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
 export default {
@@ -98,10 +98,48 @@ export default {
     UserAvatar,
     RemoteFollow,
     ModerationTools,
-    AccountActions,
     ProgressButton
   },
   methods: {
+    showRepeats () {
+      this.$store.dispatch('showReblogs', this.user.id)
+    },
+    hideRepeats () {
+      this.$store.dispatch('hideReblogs', this.user.id)
+    },
+    followUser () {
+      const store = this.$store
+      this.followRequestInProgress = true
+      requestFollow(this.user, store).then(() => {
+        this.followRequestInProgress = false
+      })
+    },
+    unfollowUser () {
+      const store = this.$store
+      this.followRequestInProgress = true
+      requestUnfollow(this.user, store).then(() => {
+        this.followRequestInProgress = false
+        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
+      })
+    },
+    blockUser () {
+      this.$store.dispatch('blockUser', this.user.id)
+    },
+    unblockUser () {
+      this.$store.dispatch('unblockUser', this.user.id)
+    },
+    muteUser () {
+      this.$store.dispatch('muteUser', this.user.id)
+    },
+    unmuteUser () {
+      this.$store.dispatch('unmuteUser', this.user.id)
+    },
+    subscribeUser () {
+      return this.$store.dispatch('subscribeUser', this.user.id)
+    },
+    unsubscribeUser () {
+      return this.$store.dispatch('unsubscribeUser', this.user.id)
+    },
     setProfileView (v) {
       if (this.switcher) {
         const store = this.$store
@@ -122,6 +160,9 @@ export default {
         this.$store.state.instance.restrictedNicknames
       )
     },
+    reportUser () {
+      this.$store.dispatch('openUserReportingModal', this.user.id)
+    },
     zoomAvatar () {
       const attachment = {
         url: this.user.profile_image_url_original,
@@ -129,6 +170,9 @@ export default {
       }
       this.$store.dispatch('setMedia', [attachment])
       this.$store.dispatch('setCurrent', attachment)
+    },
+    mentionUser () {
+      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index abaef85f..f465467c 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -131,12 +131,135 @@
             </label>
           </div>
         </div>
-
         <div
           v-if="loggedIn && isOtherUser"
           class="user-interactions"
         >
-          <AccountActions :user="user" />
+          <div v-if="!user.following">
+            <button
+              class="btn btn-default btn-block"
+              :disabled="followRequestInProgress"
+              :title="user.requested ? $t('user_card.follow_again') : ''"
+              @click="followUser"
+            >
+              <template v-if="followRequestInProgress">
+                {{ $t('user_card.follow_progress') }}
+              </template>
+              <template v-else-if="user.requested">
+                {{ $t('user_card.follow_sent') }}
+              </template>
+              <template v-else>
+                {{ $t('user_card.follow') }}
+              </template>
+            </button>
+          </div>
+          <div v-else-if="followRequestInProgress">
+            <button
+              class="btn btn-default btn-block pressed"
+              disabled
+              :title="$t('user_card.follow_unfollow')"
+              @click="unfollowUser"
+            >
+              {{ $t('user_card.follow_progress') }}
+            </button>
+          </div>
+          <div
+            v-else
+            class="btn-group"
+          >
+            <button
+              class="btn btn-default pressed"
+              :title="$t('user_card.follow_unfollow')"
+              @click="unfollowUser"
+            >
+              {{ $t('user_card.following') }}
+            </button>
+            <ProgressButton
+              v-if="!user.subscribed"
+              class="btn btn-default"
+              :click="subscribeUser"
+              :title="$t('user_card.subscribe')"
+            >
+              <i class="icon-bell-alt" />
+            </ProgressButton>
+            <ProgressButton
+              v-else
+              class="btn btn-default pressed"
+              :click="unsubscribeUser"
+              :title="$t('user_card.unsubscribe')"
+            >
+              <i class="icon-bell-ringing-o" />
+            </ProgressButton>
+            <button
+              v-if="user.showing_reblogs"
+              class="btn btn-default"
+              :title="$t('user_card.hide_repeats')"
+              @click="hideRepeats"
+            >
+              <i class="icon-eye" />
+            </button>
+            <button
+              v-if="!user.showing_reblogs"
+              class="btn btn-default pressed"
+              :title="$t('user_card.show_repeats')"
+              @click="showRepeats"
+            >
+              <i class="icon-eye-off" />
+            </button>
+          </div>
+
+          <div>
+            <button
+              class="btn btn-default btn-block"
+              @click="mentionUser"
+            >
+              {{ $t('user_card.mention') }}
+            </button>
+          </div>
+
+          <div>
+            <button
+              v-if="user.muted"
+              class="btn btn-default btn-block pressed"
+              @click="unmuteUser"
+            >
+              {{ $t('user_card.muted') }}
+            </button>
+            <button
+              v-else
+              class="btn btn-default btn-block"
+              @click="muteUser"
+            >
+              {{ $t('user_card.mute') }}
+            </button>
+          </div>
+
+          <div>
+            <button
+              v-if="user.statusnet_blocking"
+              class="btn btn-default btn-block pressed"
+              @click="unblockUser"
+            >
+              {{ $t('user_card.blocked') }}
+            </button>
+            <button
+              v-else
+              class="btn btn-default btn-block"
+              @click="blockUser"
+            >
+              {{ $t('user_card.block') }}
+            </button>
+          </div>
+
+          <div>
+            <button
+              class="btn btn-default btn-block"
+              @click="reportUser"
+            >
+              {{ $t('user_card.report') }}
+            </button>
+          </div>
+
           <ModerationTools
             v-if="loggedIn.role === &quot;admin&quot;"
             :user="user"
@@ -480,9 +603,15 @@
     position: relative;
     display: flex;
     flex-flow: row wrap;
-    justify-content: flex-end;
+    justify-content: space-between;
     margin-right: -.75em;
 
+    > * {
+      flex: 1 0 0;
+      margin: 0 .75em .6em 0;
+      white-space: nowrap;
+    }
+
     button {
       margin: 0;
 
-- 
cgit v1.2.3-70-g09d2


From a26d55013779d7b41e4a4aa0dc2477a6926116ae Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Tue, 8 Oct 2019 10:21:48 +0300
Subject: updated user_card

---
 src/components/account_actions/account_actions.js  |  45 +++++++
 src/components/account_actions/account_actions.vue |  88 ++++++++++++++
 src/components/follow_button/follow_button.js      |  57 +++++++++
 src/components/follow_button/follow_button.vue     |  13 ++
 src/components/user_card/user_card.js              |  40 +-----
 src/components/user_card/user_card.vue             | 134 ++++-----------------
 src/services/api/api.service.js                    |  13 +-
 7 files changed, 240 insertions(+), 150 deletions(-)
 create mode 100644 src/components/account_actions/account_actions.js
 create mode 100644 src/components/account_actions/account_actions.vue
 create mode 100644 src/components/follow_button/follow_button.js
 create mode 100644 src/components/follow_button/follow_button.vue

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
new file mode 100644
index 00000000..453e1f46
--- /dev/null
+++ b/src/components/account_actions/account_actions.js
@@ -0,0 +1,45 @@
+import ProgressButton from '../progress_button/progress_button.vue'
+
+const AccountActions = {
+  props: [
+    'user'
+  ],
+  data () {
+    return {
+      showDropDown: false
+    }
+  },
+  components: {
+    ProgressButton
+  },
+  computed: {
+    tagsSet () {
+      return new Set(this.user.tags)
+    },
+    hasTagPolicy () {
+      return this.$store.state.instance.tagPolicyAvailable
+    }
+  },
+  methods: {
+    showRepeats () {
+      this.$store.dispatch('showReblogs', this.user.id)
+    },
+    hideRepeats () {
+      this.$store.dispatch('hideReblogs', this.user.id)
+    },
+    blockUser () {
+      this.$store.dispatch('blockUser', this.user.id)
+    },
+    unblockUser () {
+      this.$store.dispatch('unblockUser', this.user.id)
+    },
+    reportUser () {
+      this.$store.dispatch('openUserReportingModal', this.user.id)
+    },
+    mentionUser () {
+      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
+    }
+  }
+}
+
+export default AccountActions
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
new file mode 100644
index 00000000..5786a502
--- /dev/null
+++ b/src/components/account_actions/account_actions.vue
@@ -0,0 +1,88 @@
+<template>
+  <div class="account-actions">
+    <v-popover
+      trigger="click"
+      class="account-tools-popover"
+      :container="false"
+      placement="bottom-end"
+      :offset="5"
+      @show="showDropDown = true"
+      @hide="showDropDown = false"
+    >
+      <div slot="popover">
+        <div class="dropdown-menu">
+          <button
+            class="btn btn-default btn-block dropdown-item"
+            @click="mentionUser"
+          >
+            {{ $t('user_card.mention') }}
+          </button>
+          <template v-if="user.following">
+            <div
+              role="separator"
+              class="dropdown-divider"
+            />
+            <button
+              v-if="user.showing_reblogs"
+              class="btn btn-default dropdown-item"
+              @click="hideRepeats"
+            >
+              {{ $t('user_card.hide_repeats') }}
+            </button>
+            <button
+              v-if="!user.showing_reblogs"
+              class="btn btn-default dropdown-item"
+              @click="showRepeats"
+            >
+              {{ $t('user_card.show_repeats') }}
+            </button>
+          </template>
+          <div
+            role="separator"
+            class="dropdown-divider"
+          />
+          <button
+            v-if="user.statusnet_blocking"
+            class="btn btn-default btn-block dropdown-item"
+            @click="unblockUser"
+          >
+            {{ $t('user_card.blocked') }}
+          </button>
+          <button
+            v-else
+            class="btn btn-default btn-block dropdown-item"
+            @click="blockUser"
+          >
+            {{ $t('user_card.block') }}
+          </button>
+          <button
+            class="btn btn-default btn-block dropdown-item"
+            @click="reportUser"
+          >
+            {{ $t('user_card.report') }}
+          </button>
+        </div>
+      </div>
+      <div class="btn btn-default ellipsis-button">
+        <i class="icon-link-ext trigger-button" />
+      </div>
+    </v-popover>
+  </div>
+</template>
+
+<script src="./account_actions.js"></script>
+
+<style lang="scss">
+@import '../../_variables.scss';
+@import '../popper/popper.scss';
+
+.account-actions button.dropdown-item {
+  margin-left: 0;
+}
+.account-actions .trigger-button {
+  color: $fallback--lightText;
+  color: var(--lightText, $fallback--lightText);
+  opacity: .8;
+}
+
+</style>
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
new file mode 100644
index 00000000..708d15a2
--- /dev/null
+++ b/src/components/follow_button/follow_button.js
@@ -0,0 +1,57 @@
+import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
+export default {
+  props: ['user'],
+  data () {
+    return {
+      inProgress: false
+    }
+  },
+  computed: {
+    isPressed () {
+      return this.inProgress || this.user.following
+    },
+    title () {
+      if (this.inProgress || this.user.following) {
+        return this.$t('user_card.follow_unfollow')
+      } else if (this.user.requested) {
+        return this.$t('user_card.follow_again')
+      } else {
+        return this.$t('user_card.follow')
+      }
+    },
+    label () {
+      if (this.inProgress) {
+        return this.$t('user_card.follow_progress')
+      } else if (this.user.following) {
+        return this.$t('user_card.following')
+      } else if (this.user.requested) {
+        return this.$t('user_card.follow_sent')
+      } else {
+        return this.$t('user_card.follow')
+      }
+    }
+  },
+  methods: {
+    onClick () {
+      if (this.user.following) {
+        this.unfollow()
+      } else {
+        this.follow()
+      }
+    },
+    follow () {
+      this.inProgress = true
+      requestFollow(this.user, this.$store).then(() => {
+        this.inProgress = false
+      })
+    },
+    unfollow () {
+      const store = this.$store
+      this.inProgress = true
+      requestUnfollow(this.user, store).then(() => {
+        this.inProgress = false
+        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
+      })
+    }
+  }
+}
diff --git a/src/components/follow_button/follow_button.vue b/src/components/follow_button/follow_button.vue
new file mode 100644
index 00000000..f0cbb94b
--- /dev/null
+++ b/src/components/follow_button/follow_button.vue
@@ -0,0 +1,13 @@
+<template>
+  <button
+    class="btn btn-default follow-button"
+    :class="{ pressed: isPressed }"
+    :disabled="inProgress"
+    :title="title"
+    @click="onClick"
+  >
+    {{ label }}
+  </button>
+</template>
+
+<script src="./follow_button.js"></script>
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 015a5762..0107cfa6 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,9 +1,10 @@
 import UserAvatar from '../user_avatar/user_avatar.vue'
 import RemoteFollow from '../remote_follow/remote_follow.vue'
 import ProgressButton from '../progress_button/progress_button.vue'
+import FollowButton from '../follow_button/follow_button.vue'
 import ModerationTools from '../moderation_tools/moderation_tools.vue'
+import AccountActions from '../account_actions/account_actions.vue'
 import { hex2rgb } from '../../services/color_convert/color_convert.js'
-import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
 
 export default {
@@ -98,36 +99,11 @@ export default {
     UserAvatar,
     RemoteFollow,
     ModerationTools,
-    ProgressButton
+    AccountActions,
+    ProgressButton,
+    FollowButton
   },
   methods: {
-    showRepeats () {
-      this.$store.dispatch('showReblogs', this.user.id)
-    },
-    hideRepeats () {
-      this.$store.dispatch('hideReblogs', this.user.id)
-    },
-    followUser () {
-      const store = this.$store
-      this.followRequestInProgress = true
-      requestFollow(this.user, store).then(() => {
-        this.followRequestInProgress = false
-      })
-    },
-    unfollowUser () {
-      const store = this.$store
-      this.followRequestInProgress = true
-      requestUnfollow(this.user, store).then(() => {
-        this.followRequestInProgress = false
-        store.commit('removeStatus', { timeline: 'friends', userId: this.user.id })
-      })
-    },
-    blockUser () {
-      this.$store.dispatch('blockUser', this.user.id)
-    },
-    unblockUser () {
-      this.$store.dispatch('unblockUser', this.user.id)
-    },
     muteUser () {
       this.$store.dispatch('muteUser', this.user.id)
     },
@@ -160,9 +136,6 @@ export default {
         this.$store.state.instance.restrictedNicknames
       )
     },
-    reportUser () {
-      this.$store.dispatch('openUserReportingModal', this.user.id)
-    },
     zoomAvatar () {
       const attachment = {
         url: this.user.profile_image_url_original,
@@ -170,9 +143,6 @@ export default {
       }
       this.$store.dispatch('setMedia', [attachment])
       this.$store.dispatch('setCurrent', attachment)
-    },
-    mentionUser () {
-      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index f465467c..119079b2 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -59,6 +59,10 @@
                   :title="$t('tool_tip.user_settings')"
                 />
               </router-link>
+              <AccountActions
+                v-if="loggedIn && isOtherUser"
+                :user="user"
+              />
               <a
                 v-if="isOtherUser && !user.is_local"
                 :href="user.statusnet_profile_url"
@@ -135,88 +139,27 @@
           v-if="loggedIn && isOtherUser"
           class="user-interactions"
         >
-          <div v-if="!user.following">
-            <button
-              class="btn btn-default btn-block"
-              :disabled="followRequestInProgress"
-              :title="user.requested ? $t('user_card.follow_again') : ''"
-              @click="followUser"
-            >
-              <template v-if="followRequestInProgress">
-                {{ $t('user_card.follow_progress') }}
-              </template>
-              <template v-else-if="user.requested">
-                {{ $t('user_card.follow_sent') }}
-              </template>
-              <template v-else>
-                {{ $t('user_card.follow') }}
-              </template>
-            </button>
-          </div>
-          <div v-else-if="followRequestInProgress">
-            <button
-              class="btn btn-default btn-block pressed"
-              disabled
-              :title="$t('user_card.follow_unfollow')"
-              @click="unfollowUser"
-            >
-              {{ $t('user_card.follow_progress') }}
-            </button>
-          </div>
-          <div
-            v-else
-            class="btn-group"
-          >
-            <button
-              class="btn btn-default pressed"
-              :title="$t('user_card.follow_unfollow')"
-              @click="unfollowUser"
-            >
-              {{ $t('user_card.following') }}
-            </button>
-            <ProgressButton
-              v-if="!user.subscribed"
-              class="btn btn-default"
-              :click="subscribeUser"
-              :title="$t('user_card.subscribe')"
-            >
-              <i class="icon-bell-alt" />
-            </ProgressButton>
-            <ProgressButton
-              v-else
-              class="btn btn-default pressed"
-              :click="unsubscribeUser"
-              :title="$t('user_card.unsubscribe')"
-            >
-              <i class="icon-bell-ringing-o" />
-            </ProgressButton>
-            <button
-              v-if="user.showing_reblogs"
-              class="btn btn-default"
-              :title="$t('user_card.hide_repeats')"
-              @click="hideRepeats"
-            >
-              <i class="icon-eye" />
-            </button>
-            <button
-              v-if="!user.showing_reblogs"
-              class="btn btn-default pressed"
-              :title="$t('user_card.show_repeats')"
-              @click="showRepeats"
-            >
-              <i class="icon-eye-off" />
-            </button>
-          </div>
-
-          <div>
-            <button
-              class="btn btn-default btn-block"
-              @click="mentionUser"
-            >
-              {{ $t('user_card.mention') }}
-            </button>
+          <div class="btn-group">
+            <FollowButton :user="user" />
+            <template v-if="user.following">
+              <ProgressButton
+                v-if="!user.subscribed"
+                class="btn btn-default"
+                :click="subscribeUser"
+                :title="$t('user_card.subscribe')"
+              >
+                <i class="icon-bell-alt" />
+              </ProgressButton>
+              <ProgressButton
+                v-else
+                class="btn btn-default pressed"
+                :click="unsubscribeUser"
+                :title="$t('user_card.unsubscribe')"
+              >
+                <i class="icon-bell-ringing-o" />
+              </ProgressButton>
+            </template>
           </div>
-
           <div>
             <button
               v-if="user.muted"
@@ -233,33 +176,6 @@
               {{ $t('user_card.mute') }}
             </button>
           </div>
-
-          <div>
-            <button
-              v-if="user.statusnet_blocking"
-              class="btn btn-default btn-block pressed"
-              @click="unblockUser"
-            >
-              {{ $t('user_card.blocked') }}
-            </button>
-            <button
-              v-else
-              class="btn btn-default btn-block"
-              @click="blockUser"
-            >
-              {{ $t('user_card.block') }}
-            </button>
-          </div>
-
-          <div>
-            <button
-              class="btn btn-default btn-block"
-              @click="reportUser"
-            >
-              {{ $t('user_card.report') }}
-            </button>
-          </div>
-
           <ModerationTools
             v-if="loggedIn.role === &quot;admin&quot;"
             :user="user"
@@ -603,11 +519,9 @@
     position: relative;
     display: flex;
     flex-flow: row wrap;
-    justify-content: space-between;
     margin-right: -.75em;
 
     > * {
-      flex: 1 0 0;
       margin: 0 .75em .6em 0;
       white-space: nowrap;
     }
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 80e94a50..61cd4f16 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -219,13 +219,16 @@ const authHeaders = (accessToken) => {
   }
 }
 
-const followUser = ({ id, reblogs, credentials }) => {
+const followUser = ({ id, credentials, ...options }) => {
   let url = MASTODON_FOLLOW_URL(id)
-  const form = new FormData()
-  if (reblogs !== undefined) { form.append('reblogs', reblogs) }
+  const form = {}
+  if (options.reblogs !== undefined) { form['reblogs'] = options.reblogs }
   return fetch(url, {
-    body: form,
-    headers: authHeaders(credentials),
+    body: JSON.stringify(form),
+    headers: {
+      ...authHeaders(credentials),
+      'Content-Type': 'application/json'
+    },
     method: 'POST'
   }).then((data) => data.json())
 }
-- 
cgit v1.2.3-70-g09d2


From e3f6001b3ee197caa4723e0b877b73eddf823bda Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Wed, 9 Oct 2019 09:04:18 +0300
Subject: update css

---
 src/components/account_actions/account_actions.vue | 10 +++++++++-
 src/components/user_card/user_card.vue             |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index c7641b8a..f99707cc 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -46,7 +46,7 @@
             class="btn btn-default btn-block dropdown-item"
             @click="unblockUser"
           >
-            {{ $t('user_card.blocked') }}
+            {{ $t('user_card.unblock') }}
           </button>
           <button
             v-else
@@ -75,6 +75,9 @@
 <style lang="scss">
 @import '../../_variables.scss';
 @import '../popper/popper.scss';
+.account-actions {
+  margin: 0 .8em;
+}
 
 .account-actions button.dropdown-item {
   margin-left: 0;
@@ -83,6 +86,11 @@
   color: $fallback--lightText;
   color: var(--lightText, $fallback--lightText);
   opacity: .8;
+  cursor: pointer;
+  &:hover {
+    color: $fallback--text;
+    color: var(--text, $fallback--text);
+  }
 }
 
 </style>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 119079b2..aa071a73 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -524,6 +524,7 @@
     > * {
       margin: 0 .75em .6em 0;
       white-space: nowrap;
+      min-width: 95px;
     }
 
     button {
-- 
cgit v1.2.3-70-g09d2


From b497882e0e15a0118a6e12ffaa84330942ee28f2 Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Fri, 11 Oct 2019 14:07:34 +0300
Subject: fix position account actions

---
 src/components/account_actions/account_actions.vue |  3 ++
 src/components/user_card/user_card.vue             | 40 ++++++++++++++++------
 2 files changed, 32 insertions(+), 11 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index 5633d01e..818e75bc 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -91,4 +91,7 @@
   }
 }
 
+.account-actions .open {
+  min-width: 130px;
+}
 </style>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index aa071a73..199404fd 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -59,17 +59,22 @@
                   :title="$t('tool_tip.user_settings')"
                 />
               </router-link>
-              <AccountActions
-                v-if="loggedIn && isOtherUser"
-                :user="user"
-              />
-              <a
-                v-if="isOtherUser && !user.is_local"
-                :href="user.statusnet_profile_url"
-                target="_blank"
+              <div
+                v-if="isOtherUser"
+                class="card-actions"
               >
-                <i class="icon-link-ext usersettings" />
-              </a>
+                <AccountActions
+                  v-if="loggedIn"
+                  :user="user"
+                />
+                <a
+                  v-if="!user.is_local"
+                  :href="user.statusnet_profile_url"
+                  target="_blank"
+                >
+                  <i class="icon-link-ext usersettings" />
+                </a>
+              </div>
             </div>
 
             <div class="bottom-line">
@@ -273,7 +278,7 @@
     mask: linear-gradient(to top, white, transparent) bottom no-repeat,
           linear-gradient(to top, white, white);
     // Autoprefixed seem to ignore this one, and also syntax is different
-    -webkit-mask-composite: xor;
+                                                 -webkit-mask-composite: xor;
     mask-composite: exclude;
     background-size: cover;
     mask-size: 100% 60%;
@@ -410,6 +415,19 @@
 
     .top-line {
       display: flex;
+      .card-actions {
+        position: relative;
+        display: flex;
+        width: 60px;
+        .account-actions {
+          position: absolute;
+          left: 0;
+        }
+        a {
+          position: absolute;
+          right: 0;
+        }
+      }
     }
   }
 
-- 
cgit v1.2.3-70-g09d2


From b8d8d02384e03ce8d5d38220527f798a9c0f3b30 Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Fri, 11 Oct 2019 16:41:59 +0300
Subject: revert lint autofix

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

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 199404fd..743fd667 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -278,7 +278,7 @@
     mask: linear-gradient(to top, white, transparent) bottom no-repeat,
           linear-gradient(to top, white, white);
     // Autoprefixed seem to ignore this one, and also syntax is different
-                                                 -webkit-mask-composite: xor;
+    -webkit-mask-composite: xor;
     mask-composite: exclude;
     background-size: cover;
     mask-size: 100% 60%;
-- 
cgit v1.2.3-70-g09d2


From d53e7e3125572075fc3f512fa0343a6ed98e5c12 Mon Sep 17 00:00:00 2001
From: Maksim Pechnikov <parallel588@gmail.com>
Date: Fri, 11 Oct 2019 16:52:26 +0300
Subject: fix orders of a buttons

---
 src/components/account_actions/account_actions.vue |  4 ---
 src/components/user_card/user_card.vue             | 39 ++++++----------------
 2 files changed, 10 insertions(+), 33 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index 818e75bc..046cba93 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -90,8 +90,4 @@
     color: var(--text, $fallback--text);
   }
 }
-
-.account-actions .open {
-  min-width: 130px;
-}
 </style>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 743fd667..f5cba09a 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -59,24 +59,18 @@
                   :title="$t('tool_tip.user_settings')"
                 />
               </router-link>
-              <div
-                v-if="isOtherUser"
-                class="card-actions"
+              <a
+                v-if="isOtherUser && !user.is_local"
+                :href="user.statusnet_profile_url"
+                target="_blank"
               >
-                <AccountActions
-                  v-if="loggedIn"
-                  :user="user"
-                />
-                <a
-                  v-if="!user.is_local"
-                  :href="user.statusnet_profile_url"
-                  target="_blank"
-                >
-                  <i class="icon-link-ext usersettings" />
-                </a>
-              </div>
+                <i class="icon-link-ext usersettings" />
+              </a>
+              <AccountActions
+                v-if="isOtherUser && loggedIn"
+                :user="user"
+              />
             </div>
-
             <div class="bottom-line">
               <router-link
                 class="user-screen-name"
@@ -415,19 +409,6 @@
 
     .top-line {
       display: flex;
-      .card-actions {
-        position: relative;
-        display: flex;
-        width: 60px;
-        .account-actions {
-          position: absolute;
-          left: 0;
-        }
-        a {
-          position: absolute;
-          right: 0;
-        }
-      }
     }
   }
 
-- 
cgit v1.2.3-70-g09d2


From 1d2ddaf2d06281e6769a1ca8f265ff8e620eb90e Mon Sep 17 00:00:00 2001
From: DYM <re@dym.sh>
Date: Wed, 30 Oct 2019 03:15:57 +0000
Subject: profile-banner rounding css, fixes #690

---
 src/components/user_card/user_card.vue | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 2755d89b..6f3c958e 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -276,6 +276,8 @@
     mask-composite: exclude;
     background-size: cover;
     mask-size: 100% 60%;
+    border-top-left-radius: calc(var(--panelRadius) - 1px);
+    border-top-right-radius: calc(var(--panelRadius) - 1px);
 
     &.hide-bio {
       mask-size: 100% 40px;
-- 
cgit v1.2.3-70-g09d2


From 949f47063b0114cd72630d3862df96429835f925 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 12 Nov 2019 10:40:36 -0500
Subject: show N/A when count is hidden

---
 src/components/user_card/user_card.js  | 6 ++++++
 src/components/user_card/user_card.vue | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index cc8a1ed6..a9278200 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -93,6 +93,12 @@ export default {
       const roleTitle = rights.admin ? 'admin' : 'moderator'
       return validRole && roleTitle
     },
+    hideFollowsCount () {
+      return this.isOtherUser && this.user.hide_follows_count
+    },
+    hideFollowersCount () {
+      return this.isOtherUser && this.user.hide_followers_count
+    },
     ...mapGetters(['mergedConfig'])
   },
   components: {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 6f3c958e..e54d30d4 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -208,14 +208,14 @@
           @click.prevent="setProfileView('friends')"
         >
           <h5>{{ $t('user_card.followees') }}</h5>
-          <span>{{ user.friends_count }}</span>
+          <span>{{ hideFollowsCount ? 'N/A' : user.friends_count }}</span>
         </div>
         <div
           class="user-count"
           @click.prevent="setProfileView('followers')"
         >
           <h5>{{ $t('user_card.followers') }}</h5>
-          <span>{{ user.followers_count }}</span>
+          <span>{{ hideFollowersCount ? 'N/A' : user.followers_count }}</span>
         </div>
       </div>
       <!-- eslint-disable vue/no-v-html -->
-- 
cgit v1.2.3-70-g09d2


From 85685d64788193f3f40ce14d3066c48c4523dde0 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 12 Nov 2019 10:47:49 -0500
Subject: add a translation

---
 src/components/user_card/user_card.vue | 4 ++--
 src/i18n/en.json                       | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index e54d30d4..421a1236 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -208,14 +208,14 @@
           @click.prevent="setProfileView('friends')"
         >
           <h5>{{ $t('user_card.followees') }}</h5>
-          <span>{{ hideFollowsCount ? 'N/A' : user.friends_count }}</span>
+          <span>{{ hideFollowsCount ? $t('user_card.na') : user.friends_count }}</span>
         </div>
         <div
           class="user-count"
           @click.prevent="setProfileView('followers')"
         >
           <h5>{{ $t('user_card.followers') }}</h5>
-          <span>{{ hideFollowersCount ? 'N/A' : user.followers_count }}</span>
+          <span>{{ hideFollowersCount ? $t('user_card.na') : user.followers_count }}</span>
         </div>
       </div>
       <!-- eslint-disable vue/no-v-html -->
diff --git a/src/i18n/en.json b/src/i18n/en.json
index ead333c1..b9519617 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -574,6 +574,7 @@
     "mention": "Mention",
     "mute": "Mute",
     "muted": "Muted",
+    "na": "N/A",
     "per_day": "per day",
     "remote_follow": "Remote follow",
     "report": "Report",
-- 
cgit v1.2.3-70-g09d2


From 58839ecef895bbf7cf5fd94ed048a0736ee951fe Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 12 Nov 2019 13:31:30 -0500
Subject: change N/A to Hidden

---
 src/components/user_card/user_card.vue | 4 ++--
 src/i18n/en.json                       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 421a1236..96acf610 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -208,14 +208,14 @@
           @click.prevent="setProfileView('friends')"
         >
           <h5>{{ $t('user_card.followees') }}</h5>
-          <span>{{ hideFollowsCount ? $t('user_card.na') : user.friends_count }}</span>
+          <span>{{ hideFollowsCount ? $t('user_card.hidden') : user.friends_count }}</span>
         </div>
         <div
           class="user-count"
           @click.prevent="setProfileView('followers')"
         >
           <h5>{{ $t('user_card.followers') }}</h5>
-          <span>{{ hideFollowersCount ? $t('user_card.na') : user.followers_count }}</span>
+          <span>{{ hideFollowersCount ? $t('user_card.hidden') : user.followers_count }}</span>
         </div>
       </div>
       <!-- eslint-disable vue/no-v-html -->
diff --git a/src/i18n/en.json b/src/i18n/en.json
index b9519617..ad3e671d 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -569,12 +569,12 @@
     "followers": "Followers",
     "following": "Following!",
     "follows_you": "Follows you!",
+    "hidden": "Hidden",
     "its_you": "It's you!",
     "media": "Media",
     "mention": "Mention",
     "mute": "Mute",
     "muted": "Muted",
-    "na": "N/A",
     "per_day": "per day",
     "remote_follow": "Remote follow",
     "report": "Report",
-- 
cgit v1.2.3-70-g09d2


From 7ebf3602d5d9a8630ffbe239bfe4431655046821 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 26 Nov 2019 19:57:27 -0500
Subject: move mention button right next to mute button

---
 src/components/account_actions/account_actions.js  |  3 ---
 src/components/account_actions/account_actions.vue | 18 ++++--------------
 src/components/user_card/user_card.js              |  3 +++
 src/components/user_card/user_card.vue             |  8 ++++++++
 4 files changed, 15 insertions(+), 17 deletions(-)

(limited to 'src/components/user_card/user_card.vue')

diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
index 204d506a..d2153680 100644
--- a/src/components/account_actions/account_actions.js
+++ b/src/components/account_actions/account_actions.js
@@ -25,9 +25,6 @@ const AccountActions = {
     },
     reportUser () {
       this.$store.dispatch('openUserReportingModal', this.user.id)
-    },
-    mentionUser () {
-      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index 046cba93..d3235be1 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -9,17 +9,7 @@
     >
       <div slot="popover">
         <div class="dropdown-menu">
-          <button
-            class="btn btn-default btn-block dropdown-item"
-            @click="mentionUser"
-          >
-            {{ $t('user_card.mention') }}
-          </button>
           <template v-if="user.following">
-            <div
-              role="separator"
-              class="dropdown-divider"
-            />
             <button
               v-if="user.showing_reblogs"
               class="btn btn-default dropdown-item"
@@ -34,11 +24,11 @@
             >
               {{ $t('user_card.show_repeats') }}
             </button>
+            <div
+              role="separator"
+              class="dropdown-divider"
+            />
           </template>
-          <div
-            role="separator"
-            class="dropdown-divider"
-          />
           <button
             v-if="user.statusnet_blocking"
             class="btn btn-default btn-block dropdown-item"
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index a9278200..2f649910 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -149,6 +149,9 @@ export default {
       }
       this.$store.dispatch('setMedia', [attachment])
       this.$store.dispatch('setCurrent', attachment)
+    },
+    mentionUser () {
+      this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })
     }
   }
 }
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 96acf610..93d55fff 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -175,6 +175,14 @@
               {{ $t('user_card.mute') }}
             </button>
           </div>
+          <div>
+            <button
+              class="btn btn-default btn-block"
+              @click="mentionUser"
+            >
+              {{ $t('user_card.mention') }}
+            </button>
+          </div>
           <ModerationTools
             v-if="loggedIn.role === &quot;admin&quot;"
             :user="user"
-- 
cgit v1.2.3-70-g09d2

