diff --git a/components/account/AccountHeader.vue b/components/account/AccountHeader.vue index 167ed2b6..df7f330b 100644 --- a/components/account/AccountHeader.vue +++ b/components/account/AccountHeader.vue @@ -20,6 +20,7 @@ const relationship = $(useRelationship(account)) const namedFields = ref<mastodon.v1.AccountField[]>([]) const iconFields = ref<mastodon.v1.AccountField[]>([]) +const isEditingPersonalNote = ref<boolean>(false) const hasHeader = $computed(() => !account.header.endsWith('/original/missing.png')) function getFieldIconTitle(fieldName: string) { @@ -80,6 +81,19 @@ watchEffect(() => { iconFields.value = icons }) +async function editNote(event: Event) { + if (!event.target || !('value' in event.target) || !relationship) + return + + const newNote = event.target?.value as string + + if (relationship.note?.trim() === newNote.trim()) + return + + const newNoteApiResult = await client.v1.accounts.createNote(account.id, { comment: newNote }) + relationship.note = newNoteApiResult.note +} + const isSelf = $(useSelfAccount(() => account)) const isNotifiedOnPost = $computed(() => !!relationship?.notifying) </script> @@ -107,7 +121,11 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying) </NuxtLink> <AccountFollowButton :account="account" :command="command" /> <span inset-ie-0 flex gap-2 items-center> - <AccountMoreButton :account="account" :command="command" /> + <AccountMoreButton + :account="account" :command="command" + @add-note="isEditingPersonalNote = true" + @remove-note="isEditingPersonalNote = false" + /> <CommonTooltip v-if="!isSelf && relationship?.following" :content="getNotificationIconTitle()"> <button :aria-pressed="isNotifiedOnPost" @@ -145,6 +163,25 @@ const isNotifiedOnPost = $computed(() => !!relationship?.notifying) <AccountHandle :account="account" /> </div> </div> + <label + v-if="relationship?.note?.length !== 0 || isEditingPersonalNote" + space-y-2 + pb-4 + block + border="b base" + > + <div flex flex-row space-x-2 flex-v-center> + <div i-ri-edit-2-line /> + <p font-medium> + {{ $t('account.profile_personal_note') }} + </p> + </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" /> </div> diff --git a/components/account/AccountMoreButton.vue b/components/account/AccountMoreButton.vue index 9545e8ee..47ddeabc 100644 --- a/components/account/AccountMoreButton.vue +++ b/components/account/AccountMoreButton.vue @@ -5,6 +5,11 @@ const { account } = defineProps<{ account: mastodon.v1.Account command?: boolean }>() +const emit = defineEmits<{ + (evt: 'addNote'): void + (evt: 'removeNote'): void +}>() + let relationship = $(useRelationship(account)) const isSelf = $(useSelfAccount(() => account)) @@ -63,6 +68,19 @@ async function toggleReblogs() { const showingReblogs = !relationship?.showingReblogs relationship = await client.v1.accounts.follow(account.id, { reblogs: showingReblogs }) } + +async function addUserNote() { + emit('addNote') +} + +async function removeUserNote() { + if (!relationship!.note || relationship!.note.length === 0) + return + + const newNote = await client.v1.accounts.createNote(account.id, { comment: '' }) + relationship!.note = newNote.note + emit('removeNote') +} </script> <template> @@ -112,6 +130,21 @@ async function toggleReblogs() { @click="toggleReblogs()" /> + <CommonDropdownItem + v-if="!relationship?.note || relationship?.note?.length === 0" + :text="$t('menu.add_personal_note', [`@${account.acct}`])" + icon="i-ri-edit-2-line" + :command="command" + @click="addUserNote()" + /> + <CommonDropdownItem + v-else + :text="$t('menu.remove_personal_note', [`@${account.acct}`])" + icon="i-ri-edit-2-line" + :command="command" + @click="removeUserNote()" + /> + <CommonDropdownItem v-if="!relationship?.muting" :text="$t('menu.mute_account', [`@${account.acct}`])" diff --git a/locales/en.json b/locales/en.json index cb89f2b2..116476d6 100644 --- a/locales/en.json +++ b/locales/en.json @@ -34,6 +34,7 @@ "posts": "Posts", "posts_count": "{0} Posts|{0} Post|{0} Posts", "profile_description": "{0}'s profile header", + "profile_personal_note": "Personal Note", "profile_unavailable": "Profile unavailable", "request_follow": "Request to follow", "unblock": "Unblock", @@ -225,6 +226,7 @@ "sequence_then": "then" }, "menu": { + "add_personal_note": "Add personal note to {0}", "block_account": "Block {0}", "block_domain": "Block domain {0}", "copy_link_to_post": "Copy link to this post", @@ -239,6 +241,7 @@ "mute_conversation": "Mute this post", "open_in_original_site": "Open in original site", "pin_on_profile": "Pin on profile", + "remove_personal_note": "Remove personal note from {0}", "share_post": "Share this post", "show_favourited_and_boosted_by": "Show who favorited and boosted", "show_reblogs": "Show boosts from {0}",