From 1101305ffb72bacd68698bfbe6e961953a9043de Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sat, 20 Aug 2022 13:02:27 -0400
Subject: Add ui for note editing

---
 src/components/user_note/user_note.vue | 88 ++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 src/components/user_note/user_note.vue

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

diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue
new file mode 100644
index 00000000..46db1ca7
--- /dev/null
+++ b/src/components/user_note/user_note.vue
@@ -0,0 +1,88 @@
+<template>
+  <div
+    class="user-note"
+  >
+    <div class="heading">
+      <span>{{ $t('user_card.note') }}</span>
+      <div class="buttons">
+        <button
+          v-show="!editing"
+          class="button-default btn"
+          @click="startEditing"
+        >
+          {{ $t('user_card.edit_note') }}
+        </button>
+        <button
+          v-show="editing"
+          class="button-default btn"
+          @click="finalizeEditing"
+        >
+          {{ $t('user_card.edit_note_apply') }}
+        </button>
+        <button
+          v-show="editing"
+          class="button-default btn"
+          @click="cancelEditing"
+        >
+          {{ $t('user_card.edit_note_cancel') }}
+        </button>
+      </div>
+    </div>
+    <input
+      v-show="editing"
+      class="note-text"
+      type="string"
+      :model="localNote"
+    >
+    <span
+      v-show="!editing"
+      class="note-text"
+      :class="{ '-blank': !relationship.note }"
+    >
+      {{ relationship.note || $t('user_card.note_blank') }}
+    </span>
+  </div>
+</template>
+
+<script src="./user_note.js"></script>
+
+<style lang="scss">
+@import '../../variables';
+
+.user-note {
+  display: flex;
+  flex-direction: column;
+
+  .heading {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 0.75em;
+
+    .btn {
+      min-width: 95px;
+    }
+
+    .buttons {
+      display: flex;
+      flex-direction: row;
+      justify-content: right;
+
+      .btn {
+        margin-left: 0.5em;
+      }
+    }
+  }
+
+  .note-text {
+    line-height: 2;
+    align-self: stretch;
+  }
+
+  .note-text.-blank {
+    font-style: italic;
+    color: var(--faint, $fallback--faint);
+  }
+}
+</style>
-- 
cgit v1.2.3-70-g09d2


From 9f51517ecdee7de0e9288eb94e6ecf70fd161eb3 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sat, 20 Aug 2022 13:18:57 -0400
Subject: Make API requests to edit note

---
 src/components/user_note/user_note.js  | 17 +++++++++++++++--
 src/components/user_note/user_note.vue |  5 +++--
 src/modules/users.js                   |  8 ++++++++
 src/services/api/api.service.js        | 13 +++++++++++++
 4 files changed, 39 insertions(+), 4 deletions(-)

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

diff --git a/src/components/user_note/user_note.js b/src/components/user_note/user_note.js
index 6a479800..dc5b8e71 100644
--- a/src/components/user_note/user_note.js
+++ b/src/components/user_note/user_note.js
@@ -6,7 +6,8 @@ const UserNote = {
   data () {
     return {
       localNote: '',
-      editing: false
+      editing: false,
+      frozen: false
     }
   },
   computed: {
@@ -23,7 +24,19 @@ const UserNote = {
       this.editing = false
     },
     finalizeEditing () {
-      this.editing = false
+      this.frozen = true
+
+      this.$store.dispatch('editUserNote', {
+        id: this.user.id,
+        comment: this.localNote
+      })
+        .then(() => {
+          this.frozen = false
+          this.editing = false
+        })
+        .catch(() => {
+          this.frozen = false
+        })
     }
   }
 }
diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue
index 46db1ca7..a8f3fb10 100644
--- a/src/components/user_note/user_note.vue
+++ b/src/components/user_note/user_note.vue
@@ -15,6 +15,7 @@
         <button
           v-show="editing"
           class="button-default btn"
+          :disabled="frozen"
           @click="finalizeEditing"
         >
           {{ $t('user_card.edit_note_apply') }}
@@ -22,6 +23,7 @@
         <button
           v-show="editing"
           class="button-default btn"
+          :disabled="frozen"
           @click="cancelEditing"
         >
           {{ $t('user_card.edit_note_cancel') }}
@@ -30,9 +32,8 @@
     </div>
     <input
       v-show="editing"
+      v-model="localNote"
       class="note-text"
-      type="string"
-      :model="localNote"
     >
     <span
       v-show="!editing"
diff --git a/src/modules/users.js b/src/modules/users.js
index 10b4603f..053e44b6 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -56,6 +56,11 @@ const removeUserFromFollowers = (store, id) => {
     .then((relationship) => store.commit('updateUserRelationship', [relationship]))
 }
 
+const editUserNote = (store, { id, comment }) => {
+  return store.rootState.api.backendInteractor.editUserNote({ id, comment })
+    .then((relationship) => store.commit('updateUserRelationship', [relationship]))
+}
+
 const muteUser = (store, id) => {
   const predictedRelationship = store.state.relationships[id] || { id }
   predictedRelationship.muting = true
@@ -335,6 +340,9 @@ const users = {
     unblockUsers (store, ids = []) {
       return Promise.all(ids.map(id => unblockUser(store, id)))
     },
+    editUserNote (store, args) {
+      return editUserNote(store, args)
+    },
     fetchMutes (store) {
       return store.rootState.api.backendInteractor.fetchMutes()
         .then((mutes) => {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index df652ae1..7174cc5d 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -70,6 +70,7 @@ const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute`
 const MASTODON_REMOVE_USER_FROM_FOLLOWERS = id => `/api/v1/accounts/${id}/remove_from_followers`
 const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe`
 const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe`
+const MASTODON_USER_NOTE_URL = id => `/api/v1/accounts/${id}/note`
 const MASTODON_BOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/bookmark`
 const MASTODON_UNBOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/unbookmark`
 const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
@@ -321,6 +322,17 @@ const removeUserFromFollowers = ({ id, credentials }) => {
   }).then((data) => data.json())
 }
 
+const editUserNote = ({ id, credentials, comment }) => {
+  return promisedRequest({
+    url: MASTODON_USER_NOTE_URL(id),
+    credentials,
+    payload: {
+      comment
+    },
+    method: 'POST'
+  })
+}
+
 const approveUser = ({ id, credentials }) => {
   const url = MASTODON_APPROVE_USER_URL(id)
   return fetch(url, {
@@ -1667,6 +1679,7 @@ const apiService = {
   blockUser,
   unblockUser,
   removeUserFromFollowers,
+  editUserNote,
   fetchUser,
   fetchUserByName,
   fetchUserRelationship,
-- 
cgit v1.2.3-70-g09d2


From a35fa29a6b12d31f403327225d4b38787fe5a0b6 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 7 Sep 2022 18:36:27 -0400
Subject: Use textarea for note input

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

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

diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue
index a8f3fb10..328e2350 100644
--- a/src/components/user_note/user_note.vue
+++ b/src/components/user_note/user_note.vue
@@ -30,11 +30,11 @@
         </button>
       </div>
     </div>
-    <input
+    <textarea
       v-show="editing"
       v-model="localNote"
       class="note-text"
-    >
+    />
     <span
       v-show="!editing"
       class="note-text"
-- 
cgit v1.2.3-70-g09d2


From 2e2512019230f299c2c9eae18afec3c8218d2697 Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Wed, 7 Sep 2022 18:46:18 -0400
Subject: Make notes editable only on user profile

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

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

diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index 65140d4e..67879307 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -40,7 +40,8 @@ export default {
     'rounded',
     'bordered',
     'avatarAction', // default - open profile, 'zoom' - zoom, function - call function
-    'onClose'
+    'onClose',
+    'hasNoteEditor'
   ],
   data () {
     return {
@@ -130,6 +131,9 @@ export default {
       const privileges = this.loggedIn.privileges
       return this.loggedIn.role === 'admin' || privileges.includes('users_manage_activation_state') || privileges.includes('users_delete') || privileges.includes('users_manage_tags')
     },
+    hasNote () {
+      return this.relationship.note
+    },
     supportsNote () {
       return 'note' in this.relationship
     },
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 88434c59..349c7cb1 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -269,10 +269,10 @@
           <RemoteFollow :user="user" />
         </div>
         <UserNote
-          v-if="loggedIn && isOtherUser && supportsNote"
+          v-if="loggedIn && isOtherUser && (hasNote || (hasNoteEditor && supportsNote))"
           :user="user"
           :relationship="relationship"
-          :editing="isEditingNote"
+          :editable="hasNoteEditor"
         />
       </div>
     </div>
diff --git a/src/components/user_note/user_note.js b/src/components/user_note/user_note.js
index dc5b8e71..830b2e59 100644
--- a/src/components/user_note/user_note.js
+++ b/src/components/user_note/user_note.js
@@ -1,7 +1,8 @@
 const UserNote = {
   props: {
     user: Object,
-    relationship: Object
+    relationship: Object,
+    editable: Boolean
   },
   data () {
     return {
diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue
index 328e2350..4286e017 100644
--- a/src/components/user_note/user_note.vue
+++ b/src/components/user_note/user_note.vue
@@ -6,7 +6,7 @@
       <span>{{ $t('user_card.note') }}</span>
       <div class="buttons">
         <button
-          v-show="!editing"
+          v-show="!editing && editable"
           class="button-default btn"
           @click="startEditing"
         >
@@ -77,7 +77,6 @@
   }
 
   .note-text {
-    line-height: 2;
     align-self: stretch;
   }
 
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index d0da2b5b..d5e8d230 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -10,6 +10,7 @@
         :selected="timeline.viewing"
         avatar-action="zoom"
         rounded="top"
+        :has-note-editor="true"
       />
       <div
         v-if="user.fields_html && user.fields_html.length > 0"
-- 
cgit v1.2.3-70-g09d2

