From dbbbe8aa01c8a7910a56c7e777ea99273e6a3773 Mon Sep 17 00:00:00 2001
From: Tuur Martens <tuurmartens4@gmail.com>
Date: Sat, 22 Apr 2023 12:41:27 +0200
Subject: [PATCH] feat: improve personal notes (#1978)

---
 components/account/AccountHeader.vue | 42 ++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/components/account/AccountHeader.vue b/components/account/AccountHeader.vue
index ffe610b8..b1d63781 100644
--- a/components/account/AccountHeader.vue
+++ b/components/account/AccountHeader.vue
@@ -81,6 +81,8 @@ watchEffect(() => {
   iconFields.value = icons
 })
 
+const personalNoteDraft = ref(relationship?.note ?? '')
+
 async function editNote(event: Event) {
   if (!event.target || !('value' in event.target) || !relationship)
     return
@@ -92,10 +94,13 @@ async function editNote(event: Event) {
 
   const newNoteApiResult = await client.v1.accounts.createNote(account.id, { comment: newNote })
   relationship.note = newNoteApiResult.note
+  personalNoteDraft.value = relationship.note ?? ''
 }
 
 const isSelf = $(useSelfAccount(() => account))
 const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
+
+const personalNoteMaxLength = 2000
 </script>
 
 <template>
@@ -124,7 +129,7 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
               <AccountMoreButton
                 :account="account" :command="command"
                 @add-note="isEditingPersonalNote = true"
-                @remove-note="isEditingPersonalNote = false"
+                @remove-note="() => { isEditingPersonalNote = false; personalNoteDraft = '' }"
               />
               <CommonTooltip v-if="!isSelf && relationship?.following" :content="getNotificationIconTitle()">
                 <button
@@ -175,12 +180,31 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
           <p font-medium>
             {{ $t('account.profile_personal_note') }}
           </p>
+          <p text-secondary text-sm :class="{ 'text-orange': personalNoteDraft.length > (personalNoteMaxLength - 100) }">
+            {{ personalNoteDraft.length }} / {{ personalNoteMaxLength }}
+          </p>
+        </div>
+        <div position-relative>
+          <div
+            input-base
+            min-h-10ex
+            whitespace-pre-wrap
+            opacity-0
+            :class="{ 'trailing-newline': personalNoteDraft.endsWith('\n') }"
+          >
+            {{ personalNoteDraft }}
+          </div>
+          <textarea
+            v-model="personalNoteDraft"
+            input-base
+            position-absolute
+            style="height: 100%"
+            top-0
+            resize-none
+            :maxlength="personalNoteMaxLength"
+            @change="editNote"
+          />
         </div>
-        <textarea
-          input-base
-          :value="relationship?.note ?? ''"
-          @change="editNote"
-        />
       </label>
       <div v-if="account.note" max-h-100 overflow-y-auto>
         <ContentRich text-4 text-base :content="account.note" :emojis="account.emojis" />
@@ -206,3 +230,9 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying)
     </div>
   </div>
 </template>
+
+<style>
+.trailing-newline::after {
+  content: '\a';
+}
+</style>