From a56d2dfeb1c5ddd93c1c23036c0e0f2ca16d273c Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 13 Feb 2019 07:15:08 -0500
Subject: Add blocks tab with test data to user settings page

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

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 948b5c25..be9f27e7 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -162,6 +162,10 @@
             <h2>{{$t('settings.follow_export_processing')}}</h2>
           </div>
         </div>
+        
+        <div :label="$t('settings.blocks_tab')">
+          <block-list />
+        </div>
       </tab-switcher>
     </div>
   </div>
-- 
cgit v1.2.3-70-g09d2


From 8c8a6edc7800bac854ef23f29aa87f5b932cb415 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 13 Feb 2019 21:08:14 -0500
Subject: Remove pagination support from block-list

---
 src/components/user_settings/user_settings.js           | 10 ++++++----
 src/components/user_settings/user_settings.vue          |  2 +-
 src/modules/users.js                                    | 17 ++++++-----------
 .../entity_normalizer/entity_normalizer.service.js      |  2 +-
 4 files changed, 14 insertions(+), 17 deletions(-)

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

diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 621dcd4b..8eade382 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -7,13 +7,15 @@ import StyleSwitcher from '../style_switcher/style_switcher.vue'
 import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
 import BlockCard from '../block_card/block_card.vue'
 import withLoadMore from '../../hocs/with_load_more/with_load_more'
+import withSubscription from '../../hocs/with_subscription/with_subscription'
 import withList from '../../hocs/with_list/with_list'
 
-const BlockList = withList(BlockCard, entry => ({ userId: entry.id }))
-const BlockListWithLoadMore = withLoadMore(
+const BlockList = withList(BlockCard, userId => ({ userId }))
+const BlockListWithSubscription = withSubscription(
   BlockList,
   (props, $store) => $store.dispatch('fetchBlocks'),
-  (props, $store) => get($store.state.users.currentUser, 'blocks', [])
+  (props, $store) => get($store.state.users.currentUser, 'blockIds', []),
+  'entries'
 )
 
 const UserSettings = {
@@ -53,7 +55,7 @@ const UserSettings = {
     StyleSwitcher,
     TabSwitcher,
     ImageCropper,
-    'block-list': BlockListWithLoadMore
+    'block-list': BlockListWithSubscription
   },
   computed: {
     user () {
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index be9f27e7..5cf21815 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -164,7 +164,7 @@
         </div>
         
         <div :label="$t('settings.blocks_tab')">
-          <block-list />
+          <block-list id="123" />
         </div>
       </tab-switcher>
     </div>
diff --git a/src/modules/users.js b/src/modules/users.js
index ce8af68c..1f03b47e 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -1,5 +1,5 @@
 import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
-import { compact, map, each, merge, find } from 'lodash'
+import { compact, map, each, merge, find, union } from 'lodash'
 import { set } from 'vue'
 import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js'
 import oauthApi from '../services/new_api/oauth'
@@ -85,14 +85,9 @@ export const mutations = {
   addNewUsers (state, users) {
     each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
   },
-  addBlocks (state, { blocks, page }) {
+  addBlocks (state, blockIds) {
     const user = state.currentUser
-    each(blocks, block => {
-      if (!find(user.blocks, { id: block.id })) {
-        user.blocks.push(block)
-      }
-    })
-    user.blocksPage = page + 1
+    user.blockIds = union(user.blockIds, blockIds)
   },
   setUserForStatus (state, status) {
     status.user = state.usersObject[status.user.id]
@@ -147,10 +142,10 @@ const users = {
         .then((user) => store.commit('addNewUsers', [user]))
     },
     fetchBlocks (store) {
-      const page = store.state.currentUser.blocksPage || 1
-      return store.rootState.api.backendInteractor.fetchBlocks({ page })
+      return store.rootState.api.backendInteractor.fetchBlocks()
         .then((blocks) => {
-          store.commit('addBlocks', { blocks, page })
+          store.commit('addBlocks', map(blocks, 'id'))
+          store.commit('addNewUsers', blocks)
           return blocks
         })
     },
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 1192b6cc..0e1be61e 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -120,7 +120,7 @@ export const parseUser = (data) => {
   if (data.pleroma) {
     output.follow_request_count = data.pleroma.follow_request_count
   }
-  output.blocks = []
+  output.blockIds = []
 
   return output
 }
-- 
cgit v1.2.3-70-g09d2


From 09315b27804beadb7590f8e908ae9d0eb1d6a992 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 13 Feb 2019 21:21:56 -0500
Subject: Add a prop to force-refresh data to withSubscription hoc

---
 src/components/user_settings/user_settings.vue  |  2 +-
 src/hocs/with_subscription/with_subscription.js | 13 +++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 5cf21815..5bae583c 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -164,7 +164,7 @@
         </div>
         
         <div :label="$t('settings.blocks_tab')">
-          <block-list id="123" />
+          <block-list :refresh="true" />
         </div>
       </tab-switcher>
     </div>
diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js
index 31fc106f..633517e3 100644
--- a/src/hocs/with_subscription/with_subscription.js
+++ b/src/hocs/with_subscription/with_subscription.js
@@ -1,24 +1,25 @@
 import Vue from 'vue'
-import filter from 'lodash/filter'
+import reject from 'lodash/reject'
 import isEmpty from 'lodash/isEmpty'
+import omit from 'lodash/omit'
 import './with_subscription.scss'
 
 const withSubscription = (Component, fetch, select, contentPropName = 'content') => {
   const originalProps = Component.props || []
-  const props = filter(originalProps, v => v !== 'content')
+  const props = reject(originalProps, v => v === 'content')
 
   return Vue.component('withSubscription', {
     render (createElement) {
       const props = {
         props: {
-          ...this.$props,
+          ...omit(this.$props, 'refresh'),
           [contentPropName]: this.fetchedData
         },
         on: this.$listeners
       }
       return (
         <div class="with-subscription">
-          <Component {...props} />
+          {!this.error && !this.loading && <Component {...props} />}
           <div class="with-subscription-footer">
             {this.error && <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>}
             {!this.error && this.loading && <i class="icon-spin3 animate-spin"/>}
@@ -26,7 +27,7 @@ const withSubscription = (Component, fetch, select, contentPropName = 'content')
         </div>
       )
     },
-    props,
+    props: [...props, 'refresh'],
     data () {
       return {
         loading: false,
@@ -39,7 +40,7 @@ const withSubscription = (Component, fetch, select, contentPropName = 'content')
       }
     },
     created () {
-      if (isEmpty(this.fetchedData)) {
+      if (this.refresh || isEmpty(this.fetchedData)) {
         this.fetchData()
       }
     },
-- 
cgit v1.2.3-70-g09d2


From e91a94ff9c4b9559f53a4b001f8972ceca843771 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 13 Feb 2019 22:04:28 -0500
Subject: Add mutes tab

---
 src/components/mute_card/mute_card.js              | 37 ++++++++++++++++++++++
 src/components/mute_card/mute_card.vue             | 24 ++++++++++++++
 src/components/user_settings/user_settings.js      | 13 ++++++--
 src/components/user_settings/user_settings.vue     |  4 +++
 src/i18n/en.json                                   |  1 +
 src/modules/users.js                               | 25 ++++++++++++---
 .../entity_normalizer/entity_normalizer.service.js |  1 +
 7 files changed, 99 insertions(+), 6 deletions(-)
 create mode 100644 src/components/mute_card/mute_card.js
 create mode 100644 src/components/mute_card/mute_card.vue

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

diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
new file mode 100644
index 00000000..5dd0a9e5
--- /dev/null
+++ b/src/components/mute_card/mute_card.js
@@ -0,0 +1,37 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+
+const MuteCard = {
+  props: ['userId'],
+  data () {
+    return {
+      progress: false
+    }
+  },
+  computed: {
+    user () {
+      return this.$store.getters.userById(this.userId)
+    },
+    muted () {
+      return this.user.muted
+    }
+  },
+  components: {
+    BasicUserCard
+  },
+  methods: {
+    unmuteUser () {
+      this.progress = true
+      this.$store.dispatch('unmuteUser', this.user.id).then(() => {
+        this.progress = false
+      })
+    },
+    muteUser () {
+      this.progress = true
+      this.$store.dispatch('muteUser', this.user.id).then(() => {
+        this.progress = false
+      })
+    }
+  }
+}
+
+export default MuteCard
diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue
new file mode 100644
index 00000000..e1bfe20b
--- /dev/null
+++ b/src/components/mute_card/mute_card.vue
@@ -0,0 +1,24 @@
+<template>
+  <basic-user-card :user="user">
+    <template slot="secondary-area">
+      <button class="btn btn-default" @click="unmuteUser" :disabled="progress" v-if="muted">
+        <template v-if="progress">
+          {{ $t('user_card.unmute_progress') }}
+        </template>
+        <template v-else>
+          {{ $t('user_card.unmute') }}
+        </template>
+      </button>
+      <button class="btn btn-default" @click="muteUser" :disabled="progress" v-else>
+        <template v-if="progress">
+          {{ $t('user_card.mute_progress') }}
+        </template>
+        <template v-else>
+          {{ $t('user_card.mute') }}
+        </template>
+      </button>
+    </template>
+  </basic-user-card>
+</template>
+
+<script src="./mute_card.js"></script>
\ No newline at end of file
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 8eade382..8114d5e2 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -6,7 +6,7 @@ import ImageCropper from '../image_cropper/image_cropper.vue'
 import StyleSwitcher from '../style_switcher/style_switcher.vue'
 import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
 import BlockCard from '../block_card/block_card.vue'
-import withLoadMore from '../../hocs/with_load_more/with_load_more'
+import MuteCard from '../mute_card/mute_card.vue'
 import withSubscription from '../../hocs/with_subscription/with_subscription'
 import withList from '../../hocs/with_list/with_list'
 
@@ -18,6 +18,14 @@ const BlockListWithSubscription = withSubscription(
   'entries'
 )
 
+const MuteList = withList(MuteCard, userId => ({ userId }))
+const MuteListWithSubscription = withSubscription(
+  MuteList,
+  (props, $store) => $store.dispatch('fetchMutes'),
+  (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
+  'entries'
+)
+
 const UserSettings = {
   data () {
     return {
@@ -55,7 +63,8 @@ const UserSettings = {
     StyleSwitcher,
     TabSwitcher,
     ImageCropper,
-    'block-list': BlockListWithSubscription
+    'block-list': BlockListWithSubscription,
+    'mute-list': MuteListWithSubscription
   },
   computed: {
     user () {
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 5bae583c..27f3e7cb 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -166,6 +166,10 @@
         <div :label="$t('settings.blocks_tab')">
           <block-list :refresh="true" />
         </div>
+
+        <div :label="$t('settings.mutes_tab')">
+          <mute-list :refresh="true" />
+        </div>
       </tab-switcher>
     </div>
   </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index eeb95f9c..b41b6db9 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -165,6 +165,7 @@
     "lock_account_description": "Restrict your account to approved followers only",
     "loop_video": "Loop videos",
     "loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
+    "mutes_tab": "Mutes",
     "play_videos_in_modal": "Play videos directly in the media viewer",
     "use_contain_fit": "Don't crop the attachment in thumbnails",
     "name": "Name",
diff --git a/src/modules/users.js b/src/modules/users.js
index 1f03b47e..71201a77 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -89,6 +89,10 @@ export const mutations = {
     const user = state.currentUser
     user.blockIds = union(user.blockIds, blockIds)
   },
+  saveMutes (state, ids) {
+    const user = state.currentUser
+    user.muteIds = union(user.muteIds, ids)
+  },
   setUserForStatus (state, status) {
     status.user = state.usersObject[status.user.id]
   },
@@ -157,6 +161,22 @@ const users = {
       return store.rootState.api.backendInteractor.unblockUser(id)
         .then((user) => store.commit('addNewUsers', [user]))
     },
+    fetchMutes (store) {
+      return store.rootState.api.backendInteractor.fetchMutes()
+        .then((mutedUsers) => {
+          each(mutedUsers, (user) => { user.muted = 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]))
+    },
+    unmuteUser (store, id) {
+      return store.state.api.backendInteractor.setUserMute({ id, muted: false })
+        .then((user) => store.commit('addNewUsers', [user]))
+    },
     addFriends ({ rootState, commit }, fetchBy) {
       return new Promise((resolve, reject) => {
         const user = rootState.users.usersObject[fetchBy]
@@ -300,10 +320,7 @@ const users = {
               store.dispatch('startFetching', { timeline: 'friends' })
 
               // Get user mutes and follower info
-              store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
-                each(mutedUsers, (user) => { user.muted = true })
-                store.commit('addNewUsers', mutedUsers)
-              })
+              store.dispatch('fetchMutes')
 
               // Fetch our friends
               store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 0e1be61e..49c83811 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -121,6 +121,7 @@ export const parseUser = (data) => {
     output.follow_request_count = data.pleroma.follow_request_count
   }
   output.blockIds = []
+  output.muteIds = []
 
   return output
 }
-- 
cgit v1.2.3-70-g09d2


From a5162bd636880f53a8a47fbd547971f2aaead381 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 14 Feb 2019 03:16:37 -0500
Subject: Add note for empty state to the lists using slot

---
 src/components/user_settings/user_settings.vue |  8 ++++++--
 src/hocs/with_list/with_list.js                | 11 +++++++++--
 src/hocs/with_list/with_list.scss              |  6 ++++++
 3 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 src/hocs/with_list/with_list.scss

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 27f3e7cb..520a8cbe 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -164,11 +164,15 @@
         </div>
         
         <div :label="$t('settings.blocks_tab')">
-          <block-list :refresh="true" />
+          <block-list :refresh="true">
+            <template slot="empty">No blocks</template>
+          </block-list>
         </div>
 
         <div :label="$t('settings.mutes_tab')">
-          <mute-list :refresh="true" />
+          <mute-list :refresh="true">
+            <template slot="empty">No mutes</template>
+          </mute-list>
         </div>
       </tab-switcher>
     </div>
diff --git a/src/hocs/with_list/with_list.js b/src/hocs/with_list/with_list.js
index e5770cee..896f8fc8 100644
--- a/src/hocs/with_list/with_list.js
+++ b/src/hocs/with_list/with_list.js
@@ -1,5 +1,7 @@
 import Vue from 'vue'
 import map from 'lodash/map'
+import isEmpty from 'lodash/isEmpty'
+import './with_list.scss'
 
 const defaultEntryPropsGetter = entry => ({ entry })
 const defaultKeyGetter = entry => entry.id
@@ -9,6 +11,11 @@ const withList = ({
   getKey = defaultKeyGetter                 // funciton to accept entry and index values and return key prop value
 }) => (ItemComponent) => (
   Vue.component('withList', {
+    props: [
+      'entries',                            // array of entry
+      'entryProps',                         // additional props to be passed into each entry
+      'entryListeners'                      // additional event listeners to be passed into each entry
+    ],
     render (createElement) {
       return (
         <div class="with-list">
@@ -23,10 +30,10 @@ const withList = ({
             }
             return <ItemComponent {...props} />
           })}
+          {isEmpty(this.entries) && this.$slots.empty && <div class="with-list-empty-content faint">{this.$slots.empty}</div>}
         </div>
       )
-    },
-    props: ['entries', 'entryProps', 'entryListeners']
+    }
   })
 )
 
diff --git a/src/hocs/with_list/with_list.scss b/src/hocs/with_list/with_list.scss
new file mode 100644
index 00000000..c6e13d5b
--- /dev/null
+++ b/src/hocs/with_list/with_list.scss
@@ -0,0 +1,6 @@
+.with-list {
+  &-empty-content {
+    text-align: center;
+    padding: 10px;
+  }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 395d21290462525209ee4446746f14f996adf6b2 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 14 Feb 2019 03:19:07 -0500
Subject: Add new strings to i18n

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

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 520a8cbe..e18ca4ee 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -165,13 +165,13 @@
         
         <div :label="$t('settings.blocks_tab')">
           <block-list :refresh="true">
-            <template slot="empty">No blocks</template>
+            <template slot="empty">{{$t('settings.no_blocks')}}</template>
           </block-list>
         </div>
 
         <div :label="$t('settings.mutes_tab')">
           <mute-list :refresh="true">
-            <template slot="empty">No mutes</template>
+            <template slot="empty">{{$t('settings.no_mutes')}}</template>
           </mute-list>
         </div>
       </tab-switcher>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index b41b6db9..93819c2c 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -177,6 +177,8 @@
     "notification_visibility_mentions": "Mentions",
     "notification_visibility_repeats": "Repeats",
     "no_rich_text_description": "Strip rich text formatting from all posts",
+    "no_blocks": "No blocks",
+    "no_mutes": "No mutes",
     "hide_follows_description": "Don't show who I'm following",
     "hide_followers_description": "Don't show who's following me",
     "show_admin_badge": "Show Admin badge in my profile",
-- 
cgit v1.2.3-70-g09d2


From 37eec09b9b63ef494a075776234382a3da25773e Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 20 Feb 2019 12:36:15 -0500
Subject: Comment out the mutes tab

---
 src/components/user_settings/user_settings.vue | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index e18ca4ee..5c272114 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -162,18 +162,18 @@
             <h2>{{$t('settings.follow_export_processing')}}</h2>
           </div>
         </div>
-        
+
         <div :label="$t('settings.blocks_tab')">
           <block-list :refresh="true">
             <template slot="empty">{{$t('settings.no_blocks')}}</template>
           </block-list>
         </div>
 
-        <div :label="$t('settings.mutes_tab')">
+        <!-- <div :label="$t('settings.mutes_tab')">
           <mute-list :refresh="true">
             <template slot="empty">{{$t('settings.no_mutes')}}</template>
           </mute-list>
-        </div>
+        </div> -->
       </tab-switcher>
     </div>
   </div>
-- 
cgit v1.2.3-70-g09d2


From 22851a3a967cc5364a95c71bda48eccc3808bf41 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 21 Feb 2019 20:15:51 -0500
Subject: Remove needless code

---
 src/components/user_settings/user_settings.vue | 6 ------
 1 file changed, 6 deletions(-)

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

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 5c272114..983cbda0 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -168,12 +168,6 @@
             <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>
-- 
cgit v1.2.3-70-g09d2

