From ca4d5950d08aec6fe016b56f7125f7328c1e19a1 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Sat, 16 Nov 2019 03:12:16 +0900
Subject: Display user profile fields

---
 src/components/user_profile/user_profile.vue | 50 ++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

(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 14082e83..f979eff4 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -11,6 +11,44 @@
         :allow-zooming-avatar="true"
         rounded="top"
       />
+      <div
+        v-if="user.fields_html && user.fields_html.length > 0"
+        class="user-profile-fields"
+      >
+        <dl
+          v-for="(field, index) in user.fields_html"
+          :key="index"
+        >
+          <!-- eslint-disable vue/no-v-html -->
+          <dt
+            class="user-profile-field-name"
+            @click.prevent="linkClicked"
+            v-html="field.name"
+          />
+          <dd
+            class="user-profile-field-value"
+            @click.prevent="linkClicked"
+            v-html="field.value"
+          />
+          <!-- eslint-enable vue/no-v-html -->
+        </dl>
+      </div>
+      <div
+        v-else-if="user.fields && user.fields.length > 0"
+        class="user-card-fields"
+      >
+        <dl
+          v-for="(field, index) in user.fields"
+          :key="index"
+        >
+          <dt class="user-card-field-name">
+            {{ field.name }}
+          </dt>
+          <dd class="user-card-field-value">
+            {{ field.value }}
+          </dd>
+        </dl>
+      </div>
       <tab-switcher
         :active-tab="tab"
         :render-only-focused="true"
@@ -113,6 +151,18 @@
   flex: 2;
   flex-basis: 500px;
 
+  .user-profile-fields {
+    dl {
+      margin: 1em 1.5em;
+
+      dt, dd {
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        overflow: hidden;
+      }
+    }
+  }
+
   .userlist-placeholder {
     display: flex;
     justify-content: center;
-- 
cgit v1.2.3-70-g09d2


From 2bc549a66a0e189698e38c029cf8d0bfb19d0351 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Mon, 18 Nov 2019 00:27:14 +0900
Subject: Fix emoji size

---
 src/components/user_profile/user_profile.vue | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(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 f979eff4..d5aa514e 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -152,6 +152,18 @@
   flex-basis: 500px;
 
   .user-profile-fields {
+    img {
+      object-fit: contain;
+      vertical-align: middle;
+      max-width: 100%;
+      max-height: 400px;
+
+      &.emoji {
+        width: 32px;
+        height: 32px;
+      }
+    }
+
     dl {
       margin: 1em 1.5em;
 
-- 
cgit v1.2.3-70-g09d2


From 004827a7f17a0bc349baf1257aa5debe3c6f6060 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Mon, 18 Nov 2019 02:16:37 +0900
Subject: Change profile fields design to horizontal

---
 src/components/user_profile/user_profile.vue | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

(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 d5aa514e..fdff0385 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -159,15 +159,31 @@
       max-height: 400px;
 
       &.emoji {
-        width: 32px;
-        height: 32px;
+        width: 18px;
+        height: 18px;
       }
     }
 
     dl {
+      display: flex;
       margin: 1em 1.5em;
 
+      dt {
+        flex: 0 0 auto;
+        font-weight: 500;
+        color: var(--lightText);
+        width: 30%;
+        min-width: 120px;
+      }
+
+      dd {
+        flex: 1 1 auto;
+        color: var(--text);
+        margin-left: 10px;
+      }
+
       dt, dd {
+        line-height: 18px;
         text-overflow: ellipsis;
         white-space: nowrap;
         overflow: hidden;
-- 
cgit v1.2.3-70-g09d2


From 87940ead8a9bedd312f10635462933a02e0ffb1c Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Wed, 20 Nov 2019 18:59:37 +0900
Subject: Change css selectors to classname from elementname

---
 src/components/user_profile/user_profile.vue | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(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 fdff0385..c1337411 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -18,6 +18,7 @@
         <dl
           v-for="(field, index) in user.fields_html"
           :key="index"
+          class="user-profile-field"
         >
           <!-- eslint-disable vue/no-v-html -->
           <dt
@@ -164,11 +165,11 @@
       }
     }
 
-    dl {
+    .user-profile-field {
       display: flex;
       margin: 1em 1.5em;
 
-      dt {
+      .user-profile-field-name {
         flex: 0 0 auto;
         font-weight: 500;
         color: var(--lightText);
@@ -176,13 +177,13 @@
         min-width: 120px;
       }
 
-      dd {
+      .user-profile-field-value {
         flex: 1 1 auto;
         color: var(--text);
         margin-left: 10px;
       }
 
-      dt, dd {
+      .user-profile-field-name, .user-profile-field-value {
         line-height: 18px;
         text-overflow: ellipsis;
         white-space: nowrap;
-- 
cgit v1.2.3-70-g09d2


From d2e334daa3891d42f77dd10283f0ea2dd23f08bc Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Wed, 20 Nov 2019 19:18:19 +0900
Subject: Add tooltip

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

(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 c1337411..20a64409 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -22,11 +22,13 @@
         >
           <!-- eslint-disable vue/no-v-html -->
           <dt
+            :title="user.fields[index].name"
             class="user-profile-field-name"
             @click.prevent="linkClicked"
             v-html="field.name"
           />
           <dd
+            :title="user.fields[index].value"
             class="user-profile-field-value"
             @click.prevent="linkClicked"
             v-html="field.value"
-- 
cgit v1.2.3-70-g09d2


From a15baa8962a14dd8d0d3f72695be8b677a78b606 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Wed, 20 Nov 2019 19:22:20 +0900
Subject: Use fields_html only

---
 src/components/user_profile/user_profile.vue | 16 ----------------
 1 file changed, 16 deletions(-)

(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 20a64409..0268e5da 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -36,22 +36,6 @@
           <!-- eslint-enable vue/no-v-html -->
         </dl>
       </div>
-      <div
-        v-else-if="user.fields && user.fields.length > 0"
-        class="user-card-fields"
-      >
-        <dl
-          v-for="(field, index) in user.fields"
-          :key="index"
-        >
-          <dt class="user-card-field-name">
-            {{ field.name }}
-          </dt>
-          <dd class="user-card-field-value">
-            {{ field.value }}
-          </dd>
-        </dl>
-      </div>
       <tab-switcher
         :active-tab="tab"
         :render-only-focused="true"
-- 
cgit v1.2.3-70-g09d2


From bfdf7c876c015beb2748cf709d27b9f66df3fe61 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Wed, 20 Nov 2019 19:25:11 +0900
Subject: Change field name to right justify

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

(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 0268e5da..5bffba3a 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -158,6 +158,7 @@
       .user-profile-field-name {
         flex: 0 0 auto;
         font-weight: 500;
+        text-align: right;
         color: var(--lightText);
         width: 30%;
         min-width: 120px;
-- 
cgit v1.2.3-70-g09d2


From 064b59812c715d60526727d42c124375a2bc89d5 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Wed, 19 Feb 2020 21:00:39 +0900
Subject: Change to use tags removed fields instead of raw fields

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

(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 5bffba3a..54f2d4b3 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -22,13 +22,13 @@
         >
           <!-- eslint-disable vue/no-v-html -->
           <dt
-            :title="user.fields[index].name"
+            :title="user.fields_text[index].name"
             class="user-profile-field-name"
             @click.prevent="linkClicked"
             v-html="field.name"
           />
           <dd
-            :title="user.fields[index].value"
+            :title="user.fields_text[index].value"
             class="user-profile-field-value"
             @click.prevent="linkClicked"
             v-html="field.value"
-- 
cgit v1.2.3-70-g09d2


From 6bb75a3a6d8452a3e1b88085fe87cf27386f222c Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Tue, 21 Apr 2020 23:27:51 +0300
Subject: make relationships separate from users

---
 src/boot/after_store.js                            |  3 ++
 src/components/account_actions/account_actions.js  |  2 +-
 src/components/account_actions/account_actions.vue |  8 ++---
 src/components/basic_user_card/basic_user_card.vue |  2 +-
 src/components/block_card/block_card.js            |  5 ++-
 src/components/follow_button/follow_button.js      | 14 ++++----
 src/components/follow_card/follow_card.js          |  3 ++
 src/components/follow_card/follow_card.vue         |  5 +--
 src/components/mute_card/mute_card.js              |  9 ++++--
 src/components/notification/notification.js        |  2 +-
 src/components/notification/notification.vue       |  2 +-
 src/components/side_drawer/side_drawer.vue         |  2 +-
 src/components/status/status.js                    | 15 +++++++--
 src/components/status/status.vue                   |  2 +-
 src/components/user_card/user_card.js              |  8 ++++-
 src/components/user_card/user_card.vue             | 15 +++++----
 src/components/user_panel/user_panel.vue           |  2 +-
 src/components/user_profile/user_profile.vue       |  2 +-
 src/components/user_settings/user_settings.js      |  8 ++---
 src/modules/users.js                               | 37 ++++++++--------------
 src/services/api/api.service.js                    |  4 ++-
 .../entity_normalizer/entity_normalizer.service.js | 25 +++++++++------
 .../follow_manipulate/follow_manipulate.js         | 15 +++++----
 .../notifications_fetcher.service.js               |  1 -
 .../timeline_fetcher/timeline_fetcher.service.js   |  2 ++
 25 files changed, 112 insertions(+), 81 deletions(-)

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

diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index d70e1058..1522d4f0 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -304,6 +304,9 @@ const afterStoreSetup = async ({ store, i18n }) => {
     getNodeInfo({ store })
   ])
 
+  // Start fetching things that don't need to block the UI
+  store.dispatch('fetchMutes')
+
   const router = new VueRouter({
     mode: 'history',
     routes: routes(store),
diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
index 5d7ecf7e..0826c275 100644
--- a/src/components/account_actions/account_actions.js
+++ b/src/components/account_actions/account_actions.js
@@ -3,7 +3,7 @@ import Popover from '../popover/popover.vue'
 
 const AccountActions = {
   props: [
-    'user'
+    'user', 'relationship'
   ],
   data () {
     return { }
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index 483783cf..744b77d5 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -9,16 +9,16 @@
         class="account-tools-popover"
       >
         <div class="dropdown-menu">
-          <template v-if="user.following">
+          <template v-if="relationship.following">
             <button
-              v-if="user.showing_reblogs"
+              v-if="relationship.showing_reblogs"
               class="btn btn-default dropdown-item"
               @click="hideRepeats"
             >
               {{ $t('user_card.hide_repeats') }}
             </button>
             <button
-              v-if="!user.showing_reblogs"
+              v-if="!relationship.showing_reblogs"
               class="btn btn-default dropdown-item"
               @click="showRepeats"
             >
@@ -30,7 +30,7 @@
             />
           </template>
           <button
-            v-if="user.statusnet_blocking"
+            v-if="relationship.blocking"
             class="btn btn-default btn-block dropdown-item"
             @click="unblockUser"
           >
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 8a02174e..b5a11e2b 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -12,7 +12,7 @@
       class="basic-user-card-expanded-content"
     >
       <UserCard
-        :user="user"
+        :userId="user.id"
         :rounded="true"
         :bordered="true"
       />
diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js
index c459ff1b..659c75d8 100644
--- a/src/components/block_card/block_card.js
+++ b/src/components/block_card/block_card.js
@@ -11,8 +11,11 @@ const BlockCard = {
     user () {
       return this.$store.getters.findUser(this.userId)
     },
+    relationship () {
+      return this.$store.state.users.relationships[this.userId] || {}
+    },
     blocked () {
-      return this.user.statusnet_blocking
+      return this.relationship.blocking
     }
   },
   components: {
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
index 12da2645..af7b1fef 100644
--- a/src/components/follow_button/follow_button.js
+++ b/src/components/follow_button/follow_button.js
@@ -1,6 +1,6 @@
 import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate'
 export default {
-  props: ['user', 'labelFollowing', 'buttonClass'],
+  props: ['relationship', 'labelFollowing', 'buttonClass'],
   data () {
     return {
       inProgress: false
@@ -8,12 +8,12 @@ export default {
   },
   computed: {
     isPressed () {
-      return this.inProgress || this.user.following
+      return this.inProgress || this.relationship.following
     },
     title () {
-      if (this.inProgress || this.user.following) {
+      if (this.inProgress || this.relationship.following) {
         return this.$t('user_card.follow_unfollow')
-      } else if (this.user.requested) {
+      } else if (this.relationship.requested) {
         return this.$t('user_card.follow_again')
       } else {
         return this.$t('user_card.follow')
@@ -22,9 +22,9 @@ export default {
     label () {
       if (this.inProgress) {
         return this.$t('user_card.follow_progress')
-      } else if (this.user.following) {
+      } else if (this.relationship.following) {
         return this.labelFollowing || this.$t('user_card.following')
-      } else if (this.user.requested) {
+      } else if (this.relationship.requested) {
         return this.$t('user_card.follow_sent')
       } else {
         return this.$t('user_card.follow')
@@ -33,7 +33,7 @@ export default {
   },
   methods: {
     onClick () {
-      this.user.following ? this.unfollow() : this.follow()
+      this.relationship.following ? this.unfollow() : this.follow()
     },
     follow () {
       this.inProgress = true
diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js
index aefd609e..620ae7fd 100644
--- a/src/components/follow_card/follow_card.js
+++ b/src/components/follow_card/follow_card.js
@@ -18,6 +18,9 @@ const FollowCard = {
     },
     loggedIn () {
       return this.$store.state.users.currentUser
+    },
+    relationship () {
+      return this.$store.state.users.relationships[this.user.id]
     }
   }
 }
diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue
index 81e6e6dc..d789a325 100644
--- a/src/components/follow_card/follow_card.vue
+++ b/src/components/follow_card/follow_card.vue
@@ -2,14 +2,14 @@
   <basic-user-card :user="user">
     <div class="follow-card-content-container">
       <span
-        v-if="!noFollowsYou && user.follows_you"
+        v-if="!noFollowsYou && relationship.followed_by"
         class="faint"
       >
         {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }}
       </span>
       <template v-if="!loggedIn">
         <div
-          v-if="!user.following"
+          v-if="!relationship.following"
           class="follow-card-follow-button"
         >
           <RemoteFollow :user="user" />
@@ -18,6 +18,7 @@
       <template v-else>
         <FollowButton
           :user="user"
+          :relationship="relationship"
           class="follow-card-follow-button"
           :label-following="$t('user_card.follow_unfollow')"
         />
diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
index 65c9cfb5..be528d37 100644
--- a/src/components/mute_card/mute_card.js
+++ b/src/components/mute_card/mute_card.js
@@ -11,8 +11,11 @@ const MuteCard = {
     user () {
       return this.$store.getters.findUser(this.userId)
     },
+    relationship () {
+      return this.$store.state.users.relationships[this.userId]
+    },
     muted () {
-      return this.user.muted
+      return this.relationship.muting
     }
   },
   components: {
@@ -21,13 +24,13 @@ const MuteCard = {
   methods: {
     unmuteUser () {
       this.progress = true
-      this.$store.dispatch('unmuteUser', this.user.id).then(() => {
+      this.$store.dispatch('unmuteUser', this.userId).then(() => {
         this.progress = false
       })
     },
     muteUser () {
       this.progress = true
-      this.$store.dispatch('muteUser', this.user.id).then(() => {
+      this.$store.dispatch('muteUser', this.userId).then(() => {
         this.progress = false
       })
     }
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index e7bd769e..09554f54 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -56,7 +56,7 @@ const Notification = {
       return this.generateUserProfileLink(this.targetUser)
     },
     needMute () {
-      return this.user.muted
+      return (this.$store.state.users.relationships[this.user.id] || {}).muting
     }
   }
 }
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index 411c0271..24d9fe90 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -40,7 +40,7 @@
       <div class="notification-right">
         <UserCard
           v-if="userExpanded"
-          :user="getUser(notification)"
+          :user-id="getUser(notification).id"
           :rounded="true"
           :bordered="true"
         />
diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue
index df1d22a4..a9dbbeec 100644
--- a/src/components/side_drawer/side_drawer.vue
+++ b/src/components/side_drawer/side_drawer.vue
@@ -19,7 +19,7 @@
       >
         <UserCard
           v-if="currentUser"
-          :user="currentUser"
+          :userId="currentUser.id"
           :hide-bio="true"
         />
         <div
diff --git a/src/components/status/status.js b/src/components/status/status.js
index fc5956ec..a73e3ae2 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -118,7 +118,13 @@ const Status = {
 
       return hits
     },
-    muted () { return !this.unmuted && ((!(this.inProfile && this.status.user.id === this.profileUserId) && this.status.user.muted) || (!this.inConversation && this.status.thread_muted) || this.muteWordHits.length > 0) },
+    muted () {
+      const relationship = this.$store.state.users.relationships[this.status.user.id] || {}
+      return !this.unmuted && (
+        (!(this.inProfile && this.status.user.id === this.profileUserId) && relationship.muting) ||
+        (!this.inConversation && this.status.thread_muted) ||
+        this.muteWordHits.length > 0)
+    },
     hideFilteredStatuses () {
       return this.mergedConfig.hideFilteredStatuses
     },
@@ -178,8 +184,11 @@ const Status = {
         if (this.status.user.id === this.status.attentions[i].id) {
           continue
         }
-        const taggedUser = this.$store.getters.findUser(this.status.attentions[i].id)
-        if (checkFollowing && taggedUser && taggedUser.following) {
+        // There's zero guarantee of this working. If we happen to have that user and their
+        // relationship in store then it will work, but there's kinda little chance of having
+        // them for people you're not following.
+        const relationship = this.$store.state.users.relationships[this.status.attentions[i].id]
+        if (checkFollowing && relationship && relationship.following) {
           return false
         }
         if (this.status.attentions[i].id === this.currentUser.id) {
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index ca295640..a04b501a 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -94,7 +94,7 @@
         <div class="status-body">
           <UserCard
             v-if="userExpanded"
-            :user="status.user"
+            :userId="status.user.id"
             :rounded="true"
             :bordered="true"
             class="status-usercard"
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 1cdbd3fa..fb3cfebc 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -9,7 +9,7 @@ import { mapGetters } from 'vuex'
 
 export default {
   props: [
-    'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar'
+    'userId', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar'
   ],
   data () {
     return {
@@ -21,6 +21,12 @@ export default {
     this.$store.dispatch('fetchUserRelationship', this.user.id)
   },
   computed: {
+    user () {
+      return this.$store.getters.findUser(this.userId)
+    },
+    relationship () {
+      return this.$store.state.users.relationships[this.userId] || {}
+    },
     classes () {
       return [{
         'user-card-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 4ee040e8..25fdd70e 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -8,7 +8,9 @@
       :style="style"
       class="background-image"
     />
-    <div class="panel-heading">
+    <div
+      class="panel-heading"
+    >
       <div class="user-info">
         <div class="container">
           <a
@@ -69,6 +71,7 @@
               <AccountActions
                 v-if="isOtherUser && loggedIn"
                 :user="user"
+                :relationship="relationship"
               />
             </div>
             <div class="bottom-line">
@@ -92,7 +95,7 @@
         </div>
         <div class="user-meta">
           <div
-            v-if="user.follows_you && loggedIn && isOtherUser"
+            v-if="relationship.followed_by && loggedIn && isOtherUser"
             class="following"
           >
             {{ $t('user_card.follows_you') }}
@@ -139,10 +142,10 @@
           class="user-interactions"
         >
           <div class="btn-group">
-            <FollowButton :user="user" />
-            <template v-if="user.following">
+            <FollowButton :relationship="relationship" />
+            <template v-if="relationship.following">
               <ProgressButton
-                v-if="!user.subscribed"
+                v-if="!relationship.subscribing"
                 class="btn btn-default"
                 :click="subscribeUser"
                 :title="$t('user_card.subscribe')"
@@ -161,7 +164,7 @@
           </div>
           <div>
             <button
-              v-if="user.muted"
+              v-if="relationship.muting"
               class="btn btn-default btn-block toggled"
               @click="unmuteUser"
             >
diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index e9f08015..ea4e2e9f 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -6,7 +6,7 @@
       class="panel panel-default signed-in"
     >
       <UserCard
-        :user="user"
+        :userId="user.id"
         :hide-bio="true"
         rounded="top"
       />
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 14082e83..7855c839 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -5,7 +5,7 @@
       class="user-profile panel panel-default"
     >
       <UserCard
-        :user="user"
+        :userId="user.id"
         :switcher="true"
         :selected="timeline.viewing"
         :allow-zooming-avatar="true"
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index eca6f9b1..adfab8fa 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -351,14 +351,14 @@ const UserSettings = {
     },
     filterUnblockedUsers (userIds) {
       return reject(userIds, (userId) => {
-        const user = this.$store.getters.findUser(userId)
-        return !user || user.statusnet_blocking || user.id === this.$store.state.users.currentUser.id
+        const relationship = this.$store.state.users.relationships[userId] || {}
+        return relationship.blocking || userId === this.$store.state.users.currentUser.id
       })
     },
     filterUnMutedUsers (userIds) {
       return reject(userIds, (userId) => {
-        const user = this.$store.getters.findUser(userId)
-        return !user || user.muted || user.id === this.$store.state.users.currentUser.id
+        const relationship = this.$store.state.users.relationships[userId] || {}
+        return relationship.muting || userId === this.$store.state.users.currentUser.id
       })
     },
     queryUserIds (query) {
diff --git a/src/modules/users.js b/src/modules/users.js
index df133be0..7e73ab18 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -146,26 +146,19 @@ export const mutations = {
     }
   },
   addNewUsers (state, users) {
-    each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
+    each(users, (user) => {
+      // console.log(user)
+      if (user.relationship) {
+        set(state.relationships, user.relationship.id, user.relationship)
+      }
+      mergeOrAdd(state.users, state.usersObject, user)
+    })
   },
   updateUserRelationship (state, relationships) {
     relationships.forEach((relationship) => {
-      const user = state.usersObject[relationship.id]
-      if (user) {
-        user.follows_you = relationship.followed_by
-        user.following = relationship.following
-        user.muted = relationship.muting
-        user.statusnet_blocking = relationship.blocking
-        user.subscribed = relationship.subscribing
-        user.showing_reblogs = relationship.showing_reblogs
-      }
+      set(state.relationships, relationship.id, relationship)
     })
   },
-  updateBlocks (state, blockedUsers) {
-    // Reset statusnet_blocking of all fetched users
-    each(state.users, (user) => { user.statusnet_blocking = false })
-    each(blockedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
-  },
   saveBlockIds (state, blockIds) {
     state.currentUser.blockIds = blockIds
   },
@@ -174,11 +167,6 @@ export const mutations = {
       state.currentUser.blockIds.push(blockId)
     }
   },
-  updateMutes (state, mutedUsers) {
-    // Reset muted of all fetched users
-    each(state.users, (user) => { user.muted = false })
-    each(mutedUsers, (user) => mergeOrAdd(state.users, state.usersObject, user))
-  },
   saveMuteIds (state, muteIds) {
     state.currentUser.muteIds = muteIds
   },
@@ -254,7 +242,8 @@ export const defaultState = {
   users: [],
   usersObject: {},
   signUpPending: false,
-  signUpErrors: []
+  signUpErrors: [],
+  relationships: {}
 }
 
 const users = {
@@ -279,7 +268,7 @@ const users = {
       return store.rootState.api.backendInteractor.fetchBlocks()
         .then((blocks) => {
           store.commit('saveBlockIds', map(blocks, 'id'))
-          store.commit('updateBlocks', blocks)
+          store.commit('addNewUsers', blocks)
           return blocks
         })
     },
@@ -298,8 +287,8 @@ const users = {
     fetchMutes (store) {
       return store.rootState.api.backendInteractor.fetchMutes()
         .then((mutes) => {
-          store.commit('updateMutes', mutes)
           store.commit('saveMuteIds', map(mutes, 'id'))
+          store.commit('addNewUsers', mutes)
           return mutes
         })
     },
@@ -416,7 +405,7 @@ const users = {
     },
     addNewNotifications (store, { notifications }) {
       const users = map(notifications, 'from_profile')
-      const targetUsers = map(notifications, 'target')
+      const targetUsers = map(notifications, 'target').filter(_ => _)
       const notificationIds = notifications.map(_ => _.id)
       store.commit('addNewUsers', users)
       store.commit('addNewUsers', targetUsers)
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 7db1d094..ee6bf151 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -496,7 +496,8 @@ const fetchTimeline = ({
   userId = false,
   tag = false,
   withMuted = false,
-  withMove = false
+  withMove = false,
+  withRelationships = false
 }) => {
   const timelineUrls = {
     public: MASTODON_PUBLIC_TIMELINE,
@@ -542,6 +543,7 @@ const fetchTimeline = ({
 
   params.push(['count', 20])
   params.push(['with_muted', withMuted])
+  params.push(['with_relationships', withRelationships])
 
   const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
   url += `?${queryString}`
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 84169a7b..97f9f2ae 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -73,7 +73,7 @@ export const parseUser = (data) => {
       output.background_image = data.pleroma.background_image
       output.token = data.pleroma.chat_token
 
-      if (relationship) {
+      if (relationship && !relationship) {
         output.follows_you = relationship.followed_by
         output.requested = relationship.requested
         output.following = relationship.following
@@ -82,6 +82,9 @@ export const parseUser = (data) => {
         output.showing_reblogs = relationship.showing_reblogs
         output.subscribed = relationship.subscribing
       }
+      if (relationship) {
+        output.relationship = relationship
+      }
 
       output.allow_following_move = data.pleroma.allow_following_move
 
@@ -137,16 +140,10 @@ export const parseUser = (data) => {
 
     output.statusnet_profile_url = data.statusnet_profile_url
 
-    output.statusnet_blocking = data.statusnet_blocking
-
     output.is_local = data.is_local
     output.role = data.role
     output.show_role = data.show_role
 
-    output.follows_you = data.follows_you
-
-    output.muted = data.muted
-
     if (data.rights) {
       output.rights = {
         moderator: data.rights.delete_others_notice,
@@ -160,10 +157,16 @@ export const parseUser = (data) => {
     output.hide_follows_count = data.hide_follows_count
     output.hide_followers_count = data.hide_followers_count
     output.background_image = data.background_image
-    // on mastoapi this info is contained in a "relationship"
-    output.following = data.following
     // Websocket token
     output.token = data.token
+
+    // Convert relationsip data to expected format
+    output.relationship = {
+      muting: data.muted,
+      blocking: data.statusnet_blocking,
+      followed_by: data.follows_you,
+      following: data.following
+    }
   }
 
   output.created_at = new Date(data.created_at)
@@ -317,6 +320,9 @@ export const parseStatus = (data) => {
     ? String(output.in_reply_to_user_id)
     : null
 
+  if (data.account.pleroma.relationship) {
+    data.account.pleroma.relationship = undefined
+  }
   output.user = parseUser(masto ? data.account : data.user)
 
   output.attentions = ((masto ? data.mentions : data.attentions) || []).map(parseUser)
@@ -342,7 +348,6 @@ export const parseNotification = (data) => {
   }
   const masto = !data.hasOwnProperty('ntype')
   const output = {}
-
   if (masto) {
     output.type = mastoDict[data.type] || data.type
     output.seen = data.pleroma.is_seen
diff --git a/src/services/follow_manipulate/follow_manipulate.js b/src/services/follow_manipulate/follow_manipulate.js
index 29b38a0f..c5d86afa 100644
--- a/src/services/follow_manipulate/follow_manipulate.js
+++ b/src/services/follow_manipulate/follow_manipulate.js
@@ -1,15 +1,18 @@
-const fetchUser = (attempt, user, store) => new Promise((resolve, reject) => {
+const fetchRelationship = (attempt, user, store) => new Promise((resolve, reject) => {
   setTimeout(() => {
-    store.state.api.backendInteractor.fetchUser({ id: user.id })
-      .then((user) => store.commit('addNewUsers', [user]))
-      .then(() => resolve([user.following, user.requested, user.locked, attempt]))
+    store.state.api.backendInteractor.fetchUserRelationship({ id: user.id })
+      .then((relationship) => {
+        store.commit('updateUserRelationship', [relationship])
+        return relationship
+      })
+      .then((relationship) => resolve([relationship.following, relationship.requested, user.locked, attempt]))
       .catch((e) => reject(e))
   }, 500)
 }).then(([following, sent, locked, attempt]) => {
   if (!following && !(locked && sent) && attempt <= 3) {
     // If we BE reports that we still not following that user - retry,
     // increment attempts by one
-    fetchUser(++attempt, user, store)
+    fetchRelationship(++attempt, user, store)
   }
 })
 
@@ -31,7 +34,7 @@ export const requestFollow = (user, store) => new Promise((resolve, reject) => {
       // don't know that yet.
       // Recursive Promise, it will call itself up to 3 times.
 
-      return fetchUser(1, user, store)
+      return fetchRelationship(1, user, store)
         .then(() => {
           resolve()
         })
diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js
index 864e32f8..eb6d84c4 100644
--- a/src/services/notifications_fetcher/notifications_fetcher.service.js
+++ b/src/services/notifications_fetcher/notifications_fetcher.service.js
@@ -48,7 +48,6 @@ const fetchNotifications = ({ store, args, older }) => {
       update({ store, notifications, older })
       return notifications
     }, () => store.dispatch('setNotificationsError', { value: true }))
-    .catch(() => store.dispatch('setNotificationsError', { value: true }))
 }
 
 const startFetching = ({ credentials, store }) => {
diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js
index c6b28ad5..96fafff9 100644
--- a/src/services/timeline_fetcher/timeline_fetcher.service.js
+++ b/src/services/timeline_fetcher/timeline_fetcher.service.js
@@ -31,6 +31,7 @@ const fetchAndUpdate = ({
   const { getters } = store
   const timelineData = rootState.statuses.timelines[camelCase(timeline)]
   const hideMutedPosts = getters.mergedConfig.hideMutedPosts
+  const replyVisibility = getters.mergedConfig.replyVisibility
 
   if (older) {
     args['until'] = until || timelineData.minId
@@ -41,6 +42,7 @@ const fetchAndUpdate = ({
   args['userId'] = userId
   args['tag'] = tag
   args['withMuted'] = !hideMutedPosts
+  args['withRelationships'] = replyVisibility === 'following'
 
   const numStatusesBeforeFetch = timelineData.statuses.length
 
-- 
cgit v1.2.3-70-g09d2


From c476193fd9e5bbb783ad4d3be80839caf180f598 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Thu, 23 Apr 2020 14:44:55 +0300
Subject: minor lint fixes

---
 src/components/user_panel/user_panel.vue     | 2 +-
 src/components/user_profile/user_profile.vue | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index ea4e2e9f..1db4f648 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -6,7 +6,7 @@
       class="panel panel-default signed-in"
     >
       <UserCard
-        :userId="user.id"
+        :user-id="user.id"
         :hide-bio="true"
         rounded="top"
       />
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 7855c839..1871d46c 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -5,7 +5,7 @@
       class="user-profile panel panel-default"
     >
       <UserCard
-        :userId="user.id"
+        :user-id="userId"
         :switcher="true"
         :selected="timeline.viewing"
         :allow-zooming-avatar="true"
-- 
cgit v1.2.3-70-g09d2


From 580fcd3ad9508befbe93658c2ee7a4e8d776db4b Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Wed, 17 Jun 2020 18:26:06 +0300
Subject: restyle the fields

---
 src/components/user_profile/user_profile.vue       | 22 ++++++++++++++++------
 .../entity_normalizer/entity_normalizer.service.js |  4 ++--
 2 files changed, 18 insertions(+), 8 deletions(-)

(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 0c36f2e2..2892a121 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -133,12 +133,14 @@
 <script src="./user_profile.js"></script>
 
 <style lang="scss">
+@import '../../_variables.scss';
 
 .user-profile {
   flex: 2;
   flex-basis: 500px;
 
   .user-profile-fields {
+    margin: 0 0.5em;
     img {
       object-fit: contain;
       vertical-align: middle;
@@ -146,28 +148,28 @@
       max-height: 400px;
 
       &.emoji {
-        width: 18px;
-        height: 18px;
+        width: 24px;
+        height: 24px;
       }
     }
 
     .user-profile-field {
       display: flex;
-      margin: 1em 1.5em;
+      margin: 0.25em auto;
+      max-width: 32em;
 
       .user-profile-field-name {
-        flex: 0 0 auto;
+        flex: 0 1 30%;
         font-weight: 500;
         text-align: right;
         color: var(--lightText);
-        width: 30%;
         min-width: 120px;
       }
 
       .user-profile-field-value {
         flex: 1 1 auto;
         color: var(--text);
-        margin-left: 10px;
+        margin: 0 0 0 0.25em;
       }
 
       .user-profile-field-name, .user-profile-field-value {
@@ -175,6 +177,14 @@
         text-overflow: ellipsis;
         white-space: nowrap;
         overflow: hidden;
+        padding: 0.5em 1.5em;
+        box-sizing: border-box;
+
+        border: var(--border, $fallback--border);
+        border-radius: $fallback--inputRadius;
+        border-radius: var(--inputRadius, $fallback--inputRadius);
+        border-style: solid;
+        border-width: 1px;
       }
     }
   }
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index ff99e944..c30f6f0a 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -58,8 +58,8 @@ export const parseUser = (data) => {
     })
     output.fields_text = data.fields.map(field => {
       return {
-        name: field.name.replace(/<[^>]*>/g, ''),
-        value: field.value.replace(/<[^>]*>/g, '')
+        name: unescape(field.name.replace(/<[^>]*>/g, '')),
+        value: unescape(field.value.replace(/<[^>]*>/g, ''))
       }
     })
 
-- 
cgit v1.2.3-70-g09d2


From 632f62ee0f24fc87d29550b961b9e3b0230e3812 Mon Sep 17 00:00:00 2001
From: Shpuld Shpuldson <shp@cock.li>
Date: Wed, 17 Jun 2020 18:34:24 +0300
Subject: resume the previous emoji size for now

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

(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 2892a121..445f0471 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -148,8 +148,8 @@
       max-height: 400px;
 
       &.emoji {
-        width: 24px;
-        height: 24px;
+        width: 18px;
+        height: 18px;
       }
     }
 
-- 
cgit v1.2.3-70-g09d2


From bb513dd9615759668ae216042a85ca0d8f087fa0 Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Thu, 18 Jun 2020 20:08:00 +0900
Subject: change key-value to look like one

---
 src/components/user_profile/user_profile.vue | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

(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 445f0471..ccd7c794 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -157,6 +157,9 @@
       display: flex;
       margin: 0.25em auto;
       max-width: 32em;
+      border: 1px solid var(--border, $fallback--border);
+      border-radius: $fallback--inputRadius;
+      border-radius: var(--inputRadius, $fallback--inputRadius);
 
       .user-profile-field-name {
         flex: 0 1 30%;
@@ -164,6 +167,7 @@
         text-align: right;
         color: var(--lightText);
         min-width: 120px;
+        border-right: 1px solid var(--border, $fallback--border);
       }
 
       .user-profile-field-value {
@@ -179,12 +183,6 @@
         overflow: hidden;
         padding: 0.5em 1.5em;
         box-sizing: border-box;
-
-        border: var(--border, $fallback--border);
-        border-radius: $fallback--inputRadius;
-        border-radius: var(--inputRadius, $fallback--inputRadius);
-        border-style: solid;
-        border-width: 1px;
       }
     }
   }
-- 
cgit v1.2.3-70-g09d2


From eed58a7b97bc8c6cddfd367c8d49972a96dfd08e Mon Sep 17 00:00:00 2001
From: kPherox <admin@mail.kr-kp.com>
Date: Thu, 18 Jun 2020 20:13:44 +0900
Subject: fix width of long field value

---
 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 ccd7c794..361a3b5c 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -171,7 +171,7 @@
       }
 
       .user-profile-field-value {
-        flex: 1 1 auto;
+        flex: 1 1 70%;
         color: var(--text);
         margin: 0 0 0 0.25em;
       }
-- 
cgit v1.2.3-70-g09d2

