From 2e86a4eb4f7fe55626d2e05c7484b1d7cd0c1070 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Mon, 15 Apr 2019 11:08:28 -0400
Subject: fix mess in UserProfile component

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

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

diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index d449eb85..89900f60 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -1,6 +1,6 @@
 <template>
 <div>
-  <div v-if="user.id" class="user-profile panel panel-default">
+  <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">
       <Timeline
-- 
cgit v1.2.3-70-g09d2


From 738a3dc02da7a3633137e8f0831ec8404e1ba85b Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 3 Apr 2019 22:28:08 -0400
Subject: refactor using List component

---
 src/components/user_profile/user_profile.js  | 38 +++++++++++++---------------
 src/components/user_profile/user_profile.vue | 12 +++++++--
 2 files changed, 27 insertions(+), 23 deletions(-)

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

diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index cb465d66..8dbf8dac 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -4,30 +4,25 @@ 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 List from '../list/list.vue'
 import withLoadMore from '../../hocs/with_load_more/with_load_more'
 import withList from '../../hocs/with_list/with_list'
 
-const FollowerList = compose(
-  withLoadMore({
-    fetch: (props, $store) => $store.dispatch('fetchFollowers', props.userId),
-    select: (props, $store) => get($store.getters.findUser(props.userId), 'followerIds', []).map(id => $store.getters.findUser(id)),
-    destory: (props, $store) => $store.dispatch('clearFollowers', props.userId),
-    childPropName: 'entries',
-    additionalPropNames: ['userId']
-  }),
-  withList({ getEntryProps: user => ({ user }) })
-)(FollowCard)
+const FollowerList = withLoadMore({
+  fetch: (props, $store) => $store.dispatch('fetchFollowers', props.userId),
+  select: (props, $store) => get($store.getters.findUser(props.userId), 'followerIds', []).map(id => $store.getters.findUser(id)),
+  destory: (props, $store) => $store.dispatch('clearFollowers', props.userId),
+  childPropName: 'items',
+  additionalPropNames: ['userId']
+})(List)
 
-const FriendList = compose(
-  withLoadMore({
-    fetch: (props, $store) => $store.dispatch('fetchFriends', props.userId),
-    select: (props, $store) => get($store.getters.findUser(props.userId), 'friendIds', []).map(id => $store.getters.findUser(id)),
-    destory: (props, $store) => $store.dispatch('clearFriends', props.userId),
-    childPropName: 'entries',
-    additionalPropNames: ['userId']
-  }),
-  withList({ getEntryProps: user => ({ user }) })
-)(FollowCard)
+const FriendList = withLoadMore({
+  fetch: (props, $store) => $store.dispatch('fetchFriends', props.userId),
+  select: (props, $store) => get($store.getters.findUser(props.userId), 'friendIds', []).map(id => $store.getters.findUser(id)),
+  destory: (props, $store) => $store.dispatch('clearFriends', props.userId),
+  childPropName: 'items',
+  additionalPropNames: ['userId']
+})(List)
 
 const UserProfile = {
   data () {
@@ -134,7 +129,8 @@ const UserProfile = {
     Timeline,
     FollowerList,
     FriendList,
-    ModerationTools
+    ModerationTools,
+    FollowCard
   }
 }
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 89900f60..39f3c381 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -14,10 +14,18 @@
         :user-id="userId"
       />
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
-        <FriendList :userId="userId" />
+        <FriendList :userId="userId">
+          <template slot="item" scope="p">
+            <FollowCard :key="p.item.id" :user="p.item" />
+          </template>
+        </FriendList>
       </div>
       <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
-        <FollowerList :userId="userId" :entryProps="{noFollowsYou: isUs}" />
+        <FollowerList :userId="userId">
+          <template slot="item" scope="p">
+            <FollowCard :key="p.item.id" :user="p.item" :noFollowsYou="isUs" />
+          </template>
+        </FollowerList>
       </div>
       <Timeline
         :label="$t('user_card.media')"
-- 
cgit v1.2.3-70-g09d2


From 32035217b8e04b0f178409f0f1f49d54296ce80c Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 4 Apr 2019 00:00:21 -0400
Subject: clean up

---
 src/components/list/list.vue                      |  2 +-
 src/components/selectable_list/selectable_list.js | 11 +----------
 src/components/user_profile/user_profile.vue      |  4 ++--
 src/components/user_settings/user_settings.vue    |  8 ++++----
 4 files changed, 8 insertions(+), 17 deletions(-)

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

diff --git a/src/components/list/list.vue b/src/components/list/list.vue
index 1159898d..7d62283a 100644
--- a/src/components/list/list.vue
+++ b/src/components/list/list.vue
@@ -18,7 +18,7 @@ export default {
     },
     getKey: {
       type: Function,
-      default: item => item
+      default: item => item.id
     }
   }
 }
diff --git a/src/components/selectable_list/selectable_list.js b/src/components/selectable_list/selectable_list.js
index 1fdd5a67..7856d725 100644
--- a/src/components/selectable_list/selectable_list.js
+++ b/src/components/selectable_list/selectable_list.js
@@ -6,16 +6,7 @@ const SelectableList = {
     List,
     Checkbox
   },
-  props: {
-    items: {
-      type: Array,
-      default: () => []
-    },
-    getKey: {
-      type: Function,
-      default: item => item
-    }
-  },
+  props: List.props,
   data () {
     return {
       selected: []
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 39f3c381..8d78d2d2 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -16,14 +16,14 @@
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
         <FriendList :userId="userId">
           <template slot="item" scope="p">
-            <FollowCard :key="p.item.id" :user="p.item" />
+            <FollowCard :user="p.item" />
           </template>
         </FriendList>
       </div>
       <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
         <FollowerList :userId="userId">
           <template slot="item" scope="p">
-            <FollowCard :key="p.item.id" :user="p.item" :noFollowsYou="isUs" />
+            <FollowCard :user="p.item" :noFollowsYou="isUs" />
           </template>
         </FollowerList>
       </div>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 741fbe3f..66ce6cea 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -200,9 +200,9 @@
               <BlockCard slot-scope="row" :userId="row.item"/>
             </Autosuggest>
           </div>
-          <BlockList :refresh="true">
+          <BlockList :refresh="true" :getKey="item => item">
             <template slot="item" scope="p">
-              <BlockCard :key="p.item" :userId="p.item" />
+              <BlockCard :userId="p.item" />
             </template>
             <template slot="empty">{{$t('settings.no_blocks')}}</template>
           </BlockList>
@@ -214,9 +214,9 @@
               <MuteCard slot-scope="row" :userId="row.item"/>
             </Autosuggest>
           </div>
-          <MuteList :refresh="true">
+          <MuteList :refresh="true" :getKey="item => item">
             <template slot="item" scope="p">
-              <MuteCard :key="p.item" :userId="p.item" />
+              <MuteCard :userId="p.item" />
             </template>
             <template slot="empty">{{$t('settings.no_mutes')}}</template>
           </MuteList>
-- 
cgit v1.2.3-70-g09d2


From fe7766bc618f9a994e2c0a9337deb7cce8b162cf Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 4 Apr 2019 12:12:27 -0400
Subject: replace scope attributes by slot-scope

---
 src/components/follow_requests/follow_requests.vue | 2 +-
 src/components/selectable_list/selectable_list.vue | 2 +-
 src/components/user_profile/user_profile.vue       | 4 ++--
 src/components/user_search/user_search.vue         | 2 +-
 src/components/user_settings/user_settings.vue     | 4 ++--
 src/components/who_to_follow/who_to_follow.vue     | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

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

diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue
index 0970713b..8b1e8f94 100644
--- a/src/components/follow_requests/follow_requests.vue
+++ b/src/components/follow_requests/follow_requests.vue
@@ -5,7 +5,7 @@
     </div>
     <div class="panel-body">
       <List :items="requests">
-        <template slot="item" scope="p">
+        <template slot="item" slot-scope="p">
           <FollowRequestCard :user="p.item" />
         </template>
       </List>
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index f3dd5e88..25781d06 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -9,7 +9,7 @@
       </div>
     </div>
     <List :items="items" :getKey="getKey">
-      <template slot="item" scope="p">
+      <template slot="item" slot-scope="p">
         <div class="selectable-list-item-inner" :class="{ 'selectable-list-item-selected-inner': isSelected(p.item) }">
           <div class="selectable-list-checkbox-wrapper">
             <Checkbox :checked="isSelected(p.item)" @change="checked => toggle(checked, p.item)" />
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 8d78d2d2..e67231b6 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -15,14 +15,14 @@
       />
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
         <FriendList :userId="userId">
-          <template slot="item" scope="p">
+          <template slot="item" slot-scope="p">
             <FollowCard :user="p.item" />
           </template>
         </FriendList>
       </div>
       <div :label="$t('user_card.followers')" v-if="followersTabVisible" :disabled="!user.followers_count">
         <FollowerList :userId="userId">
-          <template slot="item" scope="p">
+          <template slot="item" slot-scope="p">
             <FollowCard :user="p.item" :noFollowsYou="isUs" />
           </template>
         </FollowerList>
diff --git a/src/components/user_search/user_search.vue b/src/components/user_search/user_search.vue
index 06bfc35f..12aa4289 100644
--- a/src/components/user_search/user_search.vue
+++ b/src/components/user_search/user_search.vue
@@ -14,7 +14,7 @@
     </div>
     <div v-else class="panel-body">
       <List :items="users">
-        <template slot="item" scope="p">
+        <template slot="item" slot-scope="p">
           <FollowCard :user="p.item" />
         </template>
       </List>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 66ce6cea..e6100ced 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -201,7 +201,7 @@
             </Autosuggest>
           </div>
           <BlockList :refresh="true" :getKey="item => item">
-            <template slot="item" scope="p">
+            <template slot="item" slot-scope="p">
               <BlockCard :userId="p.item" />
             </template>
             <template slot="empty">{{$t('settings.no_blocks')}}</template>
@@ -215,7 +215,7 @@
             </Autosuggest>
           </div>
           <MuteList :refresh="true" :getKey="item => item">
-            <template slot="item" scope="p">
+            <template slot="item" slot-scope="p">
               <MuteCard :userId="p.item" />
             </template>
             <template slot="empty">{{$t('settings.no_mutes')}}</template>
diff --git a/src/components/who_to_follow/who_to_follow.vue b/src/components/who_to_follow/who_to_follow.vue
index 4812dd81..2752d519 100644
--- a/src/components/who_to_follow/who_to_follow.vue
+++ b/src/components/who_to_follow/who_to_follow.vue
@@ -5,7 +5,7 @@
     </div>
     <div class="panel-body">
       <List :items="users">
-        <template slot="item" scope="p">
+        <template slot="item" slot-scope="p">
           <FollowCard :user="p.item" />
         </template>
       </List>
-- 
cgit v1.2.3-70-g09d2


From e67fecff0a5e8c0034b860b8a7a625e35c03b5a3 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 11 Apr 2019 22:15:58 -0400
Subject: code readability

---
 src/components/follow_requests/follow_requests.vue |  4 ++--
 src/components/selectable_list/selectable_list.vue |  8 ++++----
 src/components/user_profile/user_profile.vue       |  8 ++++----
 src/components/user_search/user_search.vue         |  4 ++--
 src/components/user_settings/user_settings.vue     | 16 ++++++++--------
 src/components/who_to_follow/who_to_follow.vue     |  4 ++--
 6 files changed, 22 insertions(+), 22 deletions(-)

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

diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue
index 8b1e8f94..d5e45b9d 100644
--- a/src/components/follow_requests/follow_requests.vue
+++ b/src/components/follow_requests/follow_requests.vue
@@ -5,8 +5,8 @@
     </div>
     <div class="panel-body">
       <List :items="requests">
-        <template slot="item" slot-scope="p">
-          <FollowRequestCard :user="p.item" />
+        <template slot="item" slot-scope="{item}">
+          <FollowRequestCard :user="item" />
         </template>
       </List>
     </div>
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
index 80306594..ba1e5266 100644
--- a/src/components/selectable_list/selectable_list.vue
+++ b/src/components/selectable_list/selectable_list.vue
@@ -9,12 +9,12 @@
       </div>
     </div>
     <List :items="items" :getKey="getKey">
-      <template slot="item" slot-scope="p">
-        <div class="selectable-list-item-inner" :class="{ 'selectable-list-item-selected-inner': isSelected(p.item) }">
+      <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(p.item)" @change="checked => toggle(checked, p.item)" />
+            <Checkbox :checked="isSelected(item)" @change="checked => toggle(checked, item)" />
           </div>
-          <slot name="item" :item="p.item" />
+          <slot name="item" :item="item" />
         </div>
       </template>
       <template slot="empty"><slot name="empty" /></template>
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index e67231b6..71c625b7 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -15,15 +15,15 @@
       />
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
         <FriendList :userId="userId">
-          <template slot="item" slot-scope="p">
-            <FollowCard :user="p.item" />
+          <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="p">
-            <FollowCard :user="p.item" :noFollowsYou="isUs" />
+          <template slot="item" slot-scope="{item}">
+            <FollowCard :user="item" :noFollowsYou="isUs" />
           </template>
         </FollowerList>
       </div>
diff --git a/src/components/user_search/user_search.vue b/src/components/user_search/user_search.vue
index 12aa4289..c0636e43 100644
--- a/src/components/user_search/user_search.vue
+++ b/src/components/user_search/user_search.vue
@@ -14,8 +14,8 @@
     </div>
     <div v-else class="panel-body">
       <List :items="users">
-        <template slot="item" slot-scope="p">
-          <FollowCard :user="p.item" />
+        <template slot="item" slot-scope="{item}">
+          <FollowCard :user="item" />
         </template>
       </List>
     </div>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 0dcae0d7..7e8e45fd 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -201,19 +201,19 @@
             </Autosuggest>
           </div>
           <BlockList :refresh="true" :getKey="identity" class="profile-edit-user-list">
-            <template slot="header" slot-scope="p">
+            <template slot="header" slot-scope="{selected}">
               <div class="profile-edit-bulk-actions">
-                <ProgressButton class="btn btn-default" v-if="p.selected.length > 0" :click="() => blockUsers(p.selected)">
+                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => blockUsers(selected)">
                   {{ $t('user_card.block') }}
                   <template slot="progress">{{ $t('user_card.block_progress') }}</template>
                 </ProgressButton>
-                <ProgressButton class="btn btn-default" v-if="p.selected.length > 0" :click="() => unblockUsers(p.selected)">
+                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => unblockUsers(selected)">
                   {{ $t('user_card.unblock') }}
                   <template slot="progress">{{ $t('user_card.unblock_progress') }}</template>
                 </ProgressButton>
               </div>
             </template>
-            <template slot="item" slot-scope="p"><BlockCard :userId="p.item" /></template>
+            <template slot="item" slot-scope="{item}"><BlockCard :userId="item" /></template>
             <template slot="empty">{{$t('settings.no_blocks')}}</template>
           </BlockList>
         </div>
@@ -225,19 +225,19 @@
             </Autosuggest>
           </div>
           <MuteList :refresh="true" :getKey="identity" class="profile-edit-user-list">
-            <template slot="header" slot-scope="p">
+            <template slot="header" slot-scope="{selected}">
               <div class="profile-edit-bulk-actions">
-                <ProgressButton class="btn btn-default" v-if="p.selected.length > 0" :click="() => muteUsers(p.selected)">
+                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => muteUsers(selected)">
                   {{ $t('user_card.mute') }}
                   <template slot="progress">{{ $t('user_card.mute_progress') }}</template>
                 </ProgressButton>
-                <ProgressButton class="btn btn-default" v-if="p.selected.length > 0" :click="() => unmuteUsers(p.selected)">
+                <ProgressButton class="btn btn-default" v-if="selected.length > 0" :click="() => unmuteUsers(selected)">
                   {{ $t('user_card.unmute') }}
                   <template slot="progress">{{ $t('user_card.unmute_progress') }}</template>
                 </ProgressButton>
               </div>
             </template>
-            <template slot="item" slot-scope="p"><MuteCard :userId="p.item" /></template>
+            <template slot="item" slot-scope="{item}"><MuteCard :userId="item" /></template>
             <template slot="empty">{{$t('settings.no_mutes')}}</template>
           </MuteList>
         </div>
diff --git a/src/components/who_to_follow/who_to_follow.vue b/src/components/who_to_follow/who_to_follow.vue
index 2752d519..412a2fbe 100644
--- a/src/components/who_to_follow/who_to_follow.vue
+++ b/src/components/who_to_follow/who_to_follow.vue
@@ -5,8 +5,8 @@
     </div>
     <div class="panel-body">
       <List :items="users">
-        <template slot="item" slot-scope="p">
-          <FollowCard :user="p.item" />
+        <template slot="item" slot-scope="{item}">
+          <FollowCard :user="item" />
         </template>
       </List>
     </div>
-- 
cgit v1.2.3-70-g09d2


From 2c89d49a3d22ed2813a6a57fb6049341fa8624ba Mon Sep 17 00:00:00 2001
From: dave <starpumadev@gmail.com>
Date: Thu, 4 Apr 2019 15:10:34 -0400
Subject: #468 - show pinned timeline and add pinned label to the status

---
 src/components/conversation/conversation.js        |  3 ++-
 src/components/conversation/conversation.vue       |  1 +
 src/components/status/status.js                    |  3 ++-
 src/components/status/status.vue                   | 17 ++++++++++---
 src/components/timeline/timeline.js                |  3 ++-
 src/components/timeline/timeline.vue               |  3 ++-
 src/components/user_profile/user_profile.js        |  5 ++++
 src/components/user_profile/user_profile.vue       | 29 ++++++++++++++--------
 src/modules/statuses.js                            |  3 ++-
 src/services/api/api.service.js                    | 14 +++++++++++
 .../timeline_fetcher/timeline_fetcher.service.js   |  6 +++++
 11 files changed, 69 insertions(+), 18 deletions(-)

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

diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index ffeb7244..fc239ee9 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -41,7 +41,8 @@ const conversation = {
   props: [
     'statusoid',
     'collapsable',
-    'isPage'
+    'isPage',
+    'pinned'
   ],
   created () {
     if (this.isPage) {
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index d04ff722..40011113 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -13,6 +13,7 @@
       :key="status.id"
       :inlineExpanded="collapsable && isExpanded"
       :statusoid="status"
+      :pinned="pinned"
       :expandable='!isExpanded'
       :focused="focused(status.id)"
       :inConversation="isExpanded"
diff --git a/src/components/status/status.js b/src/components/status/status.js
index a3596b69..f2881742 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -26,7 +26,8 @@ const Status = {
     'replies',
     'isPreview',
     'noHeading',
-    'inlineExpanded'
+    'inlineExpanded',
+    'pinned'
   ],
   data () {
     return {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 0443e758..a5614f59 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -12,6 +12,13 @@
       </div>
     </template>
     <template v-else>
+      <div v-if="pinned" class="status-pin">
+        <i class="fa icon-pin faint"></i>
+        <span class="faint">Pinned</span>
+        <div class="button-icon button-action-icon" v-if="status.pinned && ownStatus" @click.prevent="unpinStatus" title="Unpin">
+          <i class="fa icon-cancel"></i>
+        </div>
+      </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 class="media-body faint">
@@ -55,9 +62,6 @@
                 <div class="button-icon button-action-icon" v-if="!status.pinned && ownStatus" @click.prevent="pinStatus" title="Pin">
                   <i class="fa icon-pin"></i>
                 </div>
-                <div class="button-icon button-action-icon" v-if="status.pinned && ownStatus" @click.prevent="unpinStatus" title="Unpin">
-                  <i class="fa icon-cancel"></i>
-                </div>
                 <div class="button-icon button-action-icon" v-if="expandable && !isPreview" @click.prevent="toggleExpanded" title="Expand">
                   <i class="button-icon icon-plus-squared"></i>
                 </div>
@@ -205,6 +209,13 @@ $status-margin: 0.75em;
   max-width: 100%;
 }
 
+.status-pin {
+  padding: 0.75em 0.75em 0;
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+}
+
 .status-preview {
   position: absolute;
   max-width: 95%;
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 19d9a9ac..953b4a06 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -11,7 +11,8 @@ const Timeline = {
     'userId',
     'tag',
     'embedded',
-    'count'
+    'count',
+    'noLoadMore'
   ],
   data () {
     return {
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index e6a8d458..870fe4f5 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -21,11 +21,12 @@
           class="status-fadein"
           :key="status.id"
           :statusoid="status"
+          :pinned="timelineName === 'pinned'"
           :collapsable="true"
         />
       </div>
     </div>
-    <div :class="classes.footer">
+    <div :class="classes.footer" v-if="!noLoadMore">
       <div v-if="count===0" class="new-status-notification text-center panel-footer faint">
         {{$t('timeline.no_statuses')}}
       </div>
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 4eddb8b1..71a88dcf 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -40,6 +40,9 @@ const UserProfile = {
     timeline () {
       return this.$store.state.statuses.timelines.user
     },
+    pinned () {
+      return this.$store.state.statuses.timelines.pinned
+    },
     favorites () {
       return this.$store.state.statuses.timelines.favorites
     },
@@ -91,6 +94,7 @@ const UserProfile = {
     fetchTimelines () {
       const userId = this.userId
       this.$store.dispatch('startFetchingTimeline', { timeline: 'user', userId })
+      this.$store.dispatch('startFetchingTimeline', { timeline: 'pinned', userId })
       this.$store.dispatch('startFetchingTimeline', { timeline: 'media', userId })
       if (this.isUs) {
         this.$store.dispatch('startFetchingTimeline', { timeline: 'favorites', userId })
@@ -98,6 +102,7 @@ const UserProfile = {
     },
     cleanUp () {
       this.$store.dispatch('stopFetching', 'user')
+      this.$store.dispatch('stopFetching', 'pinned')
       this.$store.dispatch('stopFetching', 'favorites')
       this.$store.dispatch('stopFetching', 'media')
       this.$store.commit('clearTimeline', { timeline: 'user' })
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 71c625b7..caf297c6 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -3,16 +3,25 @@
   <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">
-      <Timeline
-        :label="$t('user_card.statuses')"
-        :disabled="!user.statuses_count"
-        :count="user.statuses_count"
-        :embedded="true"
-        :title="$t('user_profile.timeline_title')"
-        :timeline="timeline"
-        :timeline-name="'user'"
-        :user-id="userId"
-      />
+      <div :label="$t('user_card.statuses')" :disabled="!user.statuses_count">
+        <Timeline
+          :count="user.statuses_count"
+          :embedded="true"
+          :title="$t('user_profile.timeline_title')"
+          :timeline="pinned"
+          :timeline-name="'pinned'"
+          :user-id="userId"
+          :no-load-more="true"
+        />
+        <Timeline
+          :count="user.statuses_count"
+          :embedded="true"
+          :title="$t('user_profile.timeline_title')"
+          :timeline="timeline"
+          :timeline-name="'user'"
+          :user-id="userId"
+        />
+      </div>
       <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
         <FriendList :userId="userId">
           <template slot="item" slot-scope="{item}">
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 176e5f42..94d7f30b 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -47,7 +47,8 @@ export const defaultState = () => ({
     publicAndExternal: emptyTl(),
     friends: emptyTl(),
     tag: emptyTl(),
-    dms: emptyTl()
+    dms: emptyTl(),
+    pinned: emptyTl()
   }
 })
 
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 65cebe78..03137d20 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -506,6 +506,19 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
     .then((data) => data.map(isNotifications ? parseNotification : parseStatus))
 }
 
+const fetchPinnedStatuses = ({ id, credentials }) => {
+  const url = MASTODON_USER_TIMELINE_URL(id) + '?pinned=true'
+  return fetch(url, { headers: authHeaders(credentials) })
+    .then((data) => {
+      if (data.ok) {
+        return data
+      }
+      throw new Error('Error fetching pinned timeline', data)
+    })
+    .then((data) => data.json())
+    .then((data) => data.map(parseStatus))
+}
+
 const verifyCredentials = (user) => {
   return fetch(LOGIN_URL, {
     method: 'POST',
@@ -726,6 +739,7 @@ const reportUser = ({credentials, userId, statusIds, comment, forward}) => {
 const apiService = {
   verifyCredentials,
   fetchTimeline,
+  fetchPinnedStatuses,
   fetchConversation,
   fetchStatus,
   fetchFriends,
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index 8e954cdf..e8d9a2ed 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -16,6 +16,12 @@ const update = ({store, statuses, timeline, showImmediately, userId}) => {
 }
 
 const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false, showImmediately = false, userId = false, tag = false, until}) => {
+  if (timeline === 'pinned') {
+    return apiService.fetchPinnedStatuses({ id: userId, credentials })
+      .then(statuses => {
+        update({ store, statuses, timeline, showImmediately, userId })
+      })
+  }
   const args = { timeline, credentials }
   const rootState = store.rootState || store.state
   const timelineData = rootState.statuses.timelines[camelCase(timeline)]
-- 
cgit v1.2.3-70-g09d2


From cd0a7afa06cafc93510286d35a60e9e40ead36bf Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 24 Apr 2019 13:56:53 -0400
Subject: remove pinned timeline, instead, use simple entity of user object

---
 src/components/timeline/timeline.js                   |  3 +--
 src/components/timeline/timeline.vue                  |  3 +--
 src/components/user_profile/user_profile.js           | 13 +++++++------
 src/components/user_profile/user_profile.vue          | 19 ++++++++++---------
 src/modules/statuses.js                               | 14 ++++++++++----
 src/modules/users.js                                  |  3 +++
 .../backend_interactor_service.js                     |  2 ++
 .../entity_normalizer/entity_normalizer.service.js    |  2 ++
 8 files changed, 36 insertions(+), 23 deletions(-)

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

diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index 953b4a06..19d9a9ac 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -11,8 +11,7 @@ const Timeline = {
     'userId',
     'tag',
     'embedded',
-    'count',
-    'noLoadMore'
+    'count'
   ],
   data () {
     return {
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 870fe4f5..e6a8d458 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -21,12 +21,11 @@
           class="status-fadein"
           :key="status.id"
           :statusoid="status"
-          :pinned="timelineName === 'pinned'"
           :collapsable="true"
         />
       </div>
     </div>
-    <div :class="classes.footer" v-if="!noLoadMore">
+    <div :class="classes.footer">
       <div v-if="count===0" class="new-status-notification text-center panel-footer faint">
         {{$t('timeline.no_statuses')}}
       </div>
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 71a88dcf..0071fa89 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -2,6 +2,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 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'
@@ -40,9 +41,6 @@ const UserProfile = {
     timeline () {
       return this.$store.state.statuses.timelines.user
     },
-    pinned () {
-      return this.$store.state.statuses.timelines.pinned
-    },
     favorites () {
       return this.$store.state.statuses.timelines.favorites
     },
@@ -56,6 +54,9 @@ const UserProfile = {
     user () {
       return this.$store.getters.findUser(this.userId)
     },
+    pinnedStatuses () {
+      return this.user.pinnedStatusIds.map(id => this.$store.state.statuses.allStatusesObject[id])
+    },
     isExternal () {
       return this.$route.name === 'external-user-profile'
     },
@@ -94,15 +95,14 @@ const UserProfile = {
     fetchTimelines () {
       const userId = this.userId
       this.$store.dispatch('startFetchingTimeline', { timeline: 'user', userId })
-      this.$store.dispatch('startFetchingTimeline', { timeline: 'pinned', userId })
       this.$store.dispatch('startFetchingTimeline', { timeline: 'media', userId })
       if (this.isUs) {
         this.$store.dispatch('startFetchingTimeline', { timeline: 'favorites', userId })
       }
+      this.$store.dispatch('fetchPinnedStatuses', userId)
     },
     cleanUp () {
       this.$store.dispatch('stopFetching', 'user')
-      this.$store.dispatch('stopFetching', 'pinned')
       this.$store.dispatch('stopFetching', 'favorites')
       this.$store.dispatch('stopFetching', 'media')
       this.$store.commit('clearTimeline', { timeline: 'user' })
@@ -133,7 +133,8 @@ const UserProfile = {
     FollowerList,
     FriendList,
     ModerationTools,
-    FollowCard
+    FollowCard,
+    Conversation
   }
 }
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index caf297c6..46561e2a 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -4,15 +4,16 @@
     <UserCard :user="user" :switcher="true" :selected="timeline.viewing" rounded="top"/>
     <tab-switcher :renderOnlyFocused="true" ref="tabSwitcher">
       <div :label="$t('user_card.statuses')" :disabled="!user.statuses_count">
-        <Timeline
-          :count="user.statuses_count"
-          :embedded="true"
-          :title="$t('user_profile.timeline_title')"
-          :timeline="pinned"
-          :timeline-name="'pinned'"
-          :user-id="userId"
-          :no-load-more="true"
-        />
+        <div class="timeline">
+          <Conversation
+            v-for="status in pinnedStatuses"
+            class="status-fadein"
+            :key="status.id"
+            :statusoid="status"
+            :pinned="true"
+            :collapsable="true"
+          />
+        </div>
         <Timeline
           :count="user.statuses_count"
           :embedded="true"
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index b93f9cb5..3b3ae9e3 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,4 +1,4 @@
-import { remove, slice, each, findIndex, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash'
+import { remove, slice, each, findIndex, find, maxBy, minBy, merge, first, last, isArray, omitBy, map } from 'lodash'
 import { set } from 'vue'
 import apiService from '../services/api/api.service.js'
 // import parse from '../services/status_parser/status_parser.js'
@@ -47,8 +47,7 @@ export const defaultState = () => ({
     publicAndExternal: emptyTl(),
     friends: emptyTl(),
     tag: emptyTl(),
-    dms: emptyTl(),
-    pinned: emptyTl()
+    dms: emptyTl()
   }
 })
 
@@ -171,7 +170,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
   // This makes sure that user timeline won't get data meant for other
   // user. I.e. opening different user profiles makes request which could
   // return data late after user already viewing different user profile
-  if ((timeline === 'user' || timeline === 'media' || timeline === 'pinned') && timelineObject.userId !== userId) {
+  if ((timeline === 'user' || timeline === 'media') && timelineObject.userId !== userId) {
     return
   }
 
@@ -542,6 +541,13 @@ const statuses = {
       rootState.api.backendInteractor.unfavorite(status.id)
         .then(status => commit('setFavoritedConfirm', { status, user: rootState.users.currentUser }))
     },
+    fetchPinnedStatuses ({ rootState, dispatch, commit }, userId) {
+      rootState.api.backendInteractor.fetchPinnedStatuses(userId)
+        .then(statuses => {
+          dispatch('addNewStatuses', { statuses })
+          commit('savePinnedStatusIds', { userId, statusIds: map(statuses, 'id') })
+        })
+    },
     updatePinned ({ rootState, commit }, status) {
       commit('setPinned', { status })
       if (status.pinned) {
diff --git a/src/modules/users.js b/src/modules/users.js
index adcab233..def2b38c 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -160,6 +160,9 @@ export const mutations = {
   saveMuteIds (state, muteIds) {
     state.currentUser.muteIds = muteIds
   },
+  savePinnedStatusIds (state, { userId, statusIds }) {
+    state.usersObject[userId].pinnedStatusIds = statusIds
+  },
   addMuteId (state, muteId) {
     if (state.currentUser.muteIds.indexOf(muteId) === -1) {
       state.currentUser.muteIds.push(muteId)
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 816e73c1..7a302f57 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -106,6 +106,7 @@ const backendInteractorService = (credentials) => {
   const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
   const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials})
   const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials})
+  const fetchPinnedStatuses = (id) => apiService.fetchPinnedStatuses({ id, credentials })
 
   const getCaptcha = () => apiService.getCaptcha()
   const register = (params) => apiService.register(params)
@@ -154,6 +155,7 @@ const backendInteractorService = (credentials) => {
     fetchBlocks,
     fetchOAuthTokens,
     revokeOAuthToken,
+    fetchPinnedStatuses,
     tagUser,
     untagUser,
     addRight,
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 97e20b99..3636c05b 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -131,6 +131,8 @@ export const parseUser = (data) => {
   output.statuses_count = data.statuses_count
   output.friendIds = []
   output.followerIds = []
+  output.pinnedStatusIds = []
+
   if (data.pleroma) {
     output.follow_request_count = data.pleroma.follow_request_count
   }
-- 
cgit v1.2.3-70-g09d2


From 32be0e15d11c14513ff4fdc984aeaa4a5f462eac Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Fri, 26 Apr 2019 15:46:40 -0400
Subject: use pinned property from status directly

---
 src/components/conversation/conversation.js  | 3 +--
 src/components/conversation/conversation.vue | 1 -
 src/components/status/status.js              | 3 +--
 src/components/status/status.vue             | 2 +-
 src/components/user_profile/user_profile.vue | 1 -
 5 files changed, 3 insertions(+), 7 deletions(-)

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

diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index fc239ee9..ffeb7244 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -41,8 +41,7 @@ const conversation = {
   props: [
     'statusoid',
     'collapsable',
-    'isPage',
-    'pinned'
+    'isPage'
   ],
   created () {
     if (this.isPage) {
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 40011113..d04ff722 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -13,7 +13,6 @@
       :key="status.id"
       :inlineExpanded="collapsable && isExpanded"
       :statusoid="status"
-      :pinned="pinned"
       :expandable='!isExpanded'
       :focused="focused(status.id)"
       :inConversation="isExpanded"
diff --git a/src/components/status/status.js b/src/components/status/status.js
index fa4b426c..09a2a010 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -26,8 +26,7 @@ const Status = {
     'replies',
     'isPreview',
     'noHeading',
-    'inlineExpanded',
-    'pinned'
+    'inlineExpanded'
   ],
   data () {
     return {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 1644f6b0..41662576 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -13,7 +13,7 @@
       </div>
     </template>
     <template v-else>
-      <div v-if="pinned" class="status-pin">
+      <div v-if="statusoid.pinned" class="status-pin">
         <i class="fa icon-pin faint"></i>
         <span class="faint">Pinned</span>
       </div>
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 46561e2a..1e104403 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -10,7 +10,6 @@
             class="status-fadein"
             :key="status.id"
             :statusoid="status"
-            :pinned="true"
             :collapsable="true"
           />
         </div>
-- 
cgit v1.2.3-70-g09d2


From 110c9d3b26e3871c8fc8157458be201ed4316d49 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 30 Apr 2019 08:20:19 -0400
Subject: improve performance by caching pinned status ids into user object

---
 src/components/user_profile/user_profile.js             |  3 ---
 src/components/user_profile/user_profile.vue            | 16 +++++++++-------
 src/modules/statuses.js                                 |  6 +++---
 src/modules/users.js                                    | 17 +++++++++++++++--
 .../entity_normalizer/entity_normalizer.service.js      |  2 ++
 5 files changed, 29 insertions(+), 15 deletions(-)

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

diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 176ec228..8d660780 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -42,9 +42,6 @@ const UserProfile = {
     timeline () {
       return this.$store.state.statuses.timelines.user
     },
-    pinnedStatuses () {
-      return filter(this.timeline.statuses, { pinned: true })
-    },
     favorites () {
       return this.$store.state.statuses.timelines.favorites
     },
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 1e104403..36d75b9e 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -5,13 +5,15 @@
     <tab-switcher :renderOnlyFocused="true" ref="tabSwitcher">
       <div :label="$t('user_card.statuses')" :disabled="!user.statuses_count">
         <div class="timeline">
-          <Conversation
-            v-for="status in pinnedStatuses"
-            class="status-fadein"
-            :key="status.id"
-            :statusoid="status"
-            :collapsable="true"
-          />
+          <template v-for="statusId in user.pinnedStatuseIds">
+            <Conversation
+              v-if="timeline.statusesObject[statusId]"
+              class="status-fadein"
+              :key="statusId"
+              :statusoid="timeline.statusesObject[statusId]"
+              :collapsable="true"
+            />
+          </template>
         </div>
         <Timeline
           :count="user.statuses_count"
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 0650a86b..e6ee5447 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -424,7 +424,7 @@ export const mutations = {
       newStatus.favoritedBy.push(user)
     }
   },
-  setPinned (state, { status }) {
+  setPinned (state, status) {
     const newStatus = state.allStatusesObject[status.id]
     newStatus.pinned = status.pinned
   },
@@ -543,11 +543,11 @@ const statuses = {
     },
     pinStatus ({ rootState, commit }, statusId) {
       return rootState.api.backendInteractor.pinOwnStatus(statusId)
-        .then((status) => commit('setPinned', { status }))
+        .then((status) => commit('setPinned', status))
     },
     unpinStatus ({ rootState, commit }, statusId) {
       rootState.api.backendInteractor.unpinOwnStatus(statusId)
-        .then((status) => commit('setPinned', { status }))
+        .then((status) => commit('setPinned', status))
     },
     retweet ({ rootState, commit }, status) {
       // Optimistic retweeting...
diff --git a/src/modules/users.js b/src/modules/users.js
index adcab233..e72a657c 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -165,6 +165,15 @@ export const mutations = {
       state.currentUser.muteIds.push(muteId)
     }
   },
+  setPinned (state, status) {
+    const user = state.usersObject[status.user.id]
+    const index = user.pinnedStatuseIds.indexOf(status.id)
+    if (status.pinned && index === -1) {
+      user.pinnedStatuseIds.push(status.id)
+    } else if (!status.pinned && index !== -1) {
+      user.pinnedStatuseIds.splice(index, 1)
+    }
+  },
   setUserForStatus (state, status) {
     status.user = state.usersObject[status.user.id]
   },
@@ -318,13 +327,17 @@ const users = {
       store.commit('addNewUsers', users)
       store.commit('addNewUsers', retweetedUsers)
 
-      // Reconnect users to statuses
       each(statuses, (status) => {
+        // Reconnect users to statuses
         store.commit('setUserForStatus', status)
+        // Set pinned statuses to user
+        store.commit('setPinned', status)
       })
-      // Reconnect users to retweets
       each(compact(map(statuses, 'retweeted_status')), (status) => {
+        // Reconnect users to retweets
         store.commit('setUserForStatus', status)
+        // Set pinned retweets to user
+        store.commit('setPinned', status)
       })
     },
     addNewNotifications (store, { notifications }) {
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 5b8ad8a4..e3d1646a 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -131,6 +131,8 @@ export const parseUser = (data) => {
   output.statuses_count = data.statuses_count
   output.friendIds = []
   output.followerIds = []
+  output.pinnedStatuseIds = []
+
   if (data.pleroma) {
     output.follow_request_count = data.pleroma.follow_request_count
   }
-- 
cgit v1.2.3-70-g09d2


From f68653d0dd0b374aa28eca35b424b6c834c701d6 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 30 Apr 2019 11:06:22 -0400
Subject: show pinned state only in the user timeline

---
 src/components/conversation/conversation.js  | 3 ++-
 src/components/conversation/conversation.vue | 1 +
 src/components/status/status.js              | 3 ++-
 src/components/status/status.vue             | 2 +-
 src/components/user_profile/user_profile.vue | 1 +
 5 files changed, 7 insertions(+), 3 deletions(-)

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

diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index ffeb7244..b3074590 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -41,7 +41,8 @@ const conversation = {
   props: [
     'statusoid',
     'collapsable',
-    'isPage'
+    'isPage',
+    'showPinned'
   ],
   created () {
     if (this.isPage) {
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index d04ff722..0b4998c3 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -14,6 +14,7 @@
       :inlineExpanded="collapsable && isExpanded"
       :statusoid="status"
       :expandable='!isExpanded'
+      :showPinned="showPinned"
       :focused="focused(status.id)"
       :inConversation="isExpanded"
       :highlight="getHighlight()"
diff --git a/src/components/status/status.js b/src/components/status/status.js
index a1ffb026..5b3d98c3 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -26,7 +26,8 @@ const Status = {
     'replies',
     'isPreview',
     'noHeading',
-    'inlineExpanded'
+    'inlineExpanded',
+    'showPinned'
   ],
   data () {
     return {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 8575a95e..997c1b31 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -16,7 +16,7 @@
       </div>
     </template>
     <template v-else>
-      <div v-if="statusoid.pinned" class="status-pin">
+      <div v-if="showPinned && statusoid.pinned" class="status-pin">
         <i class="fa icon-pin faint"></i>
         <span class="faint">{{$t('status.pinned')}}</span>
       </div>
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 36d75b9e..48b774ea 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -12,6 +12,7 @@
               :key="statusId"
               :statusoid="timeline.statusesObject[statusId]"
               :collapsable="true"
+              :showPinned="true"
             />
           </template>
         </div>
-- 
cgit v1.2.3-70-g09d2

