commit: 692ee06477bab63f67ca22ba23fdfd1a56f8e4b3
parent 2c9547f5ff75e0e0cf9cdf413fc25f08b98835f6
Author: Henry Jameson <me@hjkos.com>
Date: Tue, 14 Jan 2025 22:02:30 +0200
small cleanup
Diffstat:
4 files changed, 256 insertions(+), 271 deletions(-)
diff --git a/src/components/status_action_buttons/action_button.js b/src/components/status_action_buttons/action_button.js
@@ -1,4 +1,5 @@
import StatusBookmarkFolderMenu from 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue'
+import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
import Popover from 'src/components/popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -67,11 +68,11 @@ export default {
],
components: {
StatusBookmarkFolderMenu,
+ EmojiPicker,
Popover
},
computed: {
buttonClass () {
- if (!this.extra) console.log(this.button.name)
return [
this.button.name + '-button',
{
@@ -93,5 +94,14 @@ export default {
}
]
}
+ },
+ methods: {
+ doActionWrap (button) {
+ if (button.name === 'emoji') {
+ this.$refs.picker.showPicker()
+ } else {
+ this.getComponent(button) === 'button' && this.doAction(button)
+ }
+ }
}
}
diff --git a/src/components/status_action_buttons/action_button.vue b/src/components/status_action_buttons/action_button.vue
@@ -11,7 +11,7 @@
:tabindex="0"
:disabled="buttonClass.disabled"
:href="getComponent(button) == 'a' ? button.link?.(funcArg) || getRemoteInteractionLink : undefined"
- @click.stop="getComponent(button) === 'button' && doAction(button)"
+ @click.stop="doActionWrap(button)"
@click="close"
>
<FALayers>
@@ -80,6 +80,15 @@
<StatusBookmarkFolderMenu v-if="button.name === 'bookmark'" :status="status" />
</template>
</Popover>
+
+ <EmojiPicker
+ ref="picker"
+ v-if="button.name === 'emoji'"
+ :enable-sticker-picker="false"
+ :hide-custom-emoji="hideCustomEmoji"
+ class="emoji-picker-panel"
+ @emoji="addReaction"
+ />
</div>
</template>
diff --git a/src/components/status_action_buttons/buttons_definitions.js b/src/components/status_action_buttons/buttons_definitions.js
@@ -0,0 +1,227 @@
+const PRIVATE_SCOPES = new Set(['private', 'direct'])
+const PUBLIC_SCOPES = new Set(['public', 'unlisted'])
+export const BUTTONS = [{
+ // =========
+ // REPLY
+ // =========
+ name: 'reply',
+ label: 'tool_tip.reply',
+ icon: 'reply',
+ active: ({ replying }) => replying,
+ counter: ({ status }) => status.replies_count,
+ anon: true,
+ anonLink: true,
+ toggleable: true,
+ closeIndicator: 'times',
+ activeIndicator: 'none',
+ action ({ emit }) {
+ emit('toggleReplying')
+ return Promise.resolve()
+ }
+}, {
+ // =========
+ // REPEAT
+ // =========
+ name: 'retweet',
+ label: 'tool_tip.repeat',
+ icon ({ status }) {
+ if (PRIVATE_SCOPES.has(status.visibility)) {
+ return 'lock'
+ }
+ return 'retweet'
+ },
+ animated: true,
+ active: ({ status }) => status.repeated,
+ counter: ({ status }) => status.repeat_num,
+ anonLink: true,
+ interactive: ({ status, loggedIn }) => loggedIn && !PRIVATE_SCOPES.has(status.visibility),
+ toggleable: true,
+ confirm: ({ status, getters }) => !status.repeated && getters.mergedConfig.modalOnRepeat,
+ confirmStrings: {
+ title: 'status.repeat_confirm_title',
+ body: 'status.repeat_confirm',
+ confirm: 'status.repeat_confirm_accept_button',
+ cancel: 'status.repeat_confirm_cancel_button'
+ },
+ action ({ status, dispatch }) {
+ if (!status.repeated) {
+ return dispatch('retweet', { id: status.id })
+ } else {
+ return dispatch('unretweet', { id: status.id })
+ }
+ }
+}, {
+ // =========
+ // FAVORITE
+ // =========
+ name: 'favorite',
+ label: 'tool_tip.favorite',
+ icon: ({ status }) => status.favorited
+ ? ['fas', 'star']
+ : ['far', 'star'],
+ animated: true,
+ active: ({ status }) => status.favorited,
+ counter: ({ status }) => status.fave_num,
+ anonLink: true,
+ toggleable: true,
+ action ({ status, dispatch }) {
+ if (!status.favorited) {
+ return dispatch('favorite', { id: status.id })
+ } else {
+ return dispatch('unfavorite', { id: status.id })
+ }
+ }
+}, {
+ // =========
+ // EMOJI REACTIONS
+ // =========
+ name: 'emoji',
+ label: 'tool_tip.add_reaction',
+ icon: ['far', 'smile-beam'],
+ anonLink: true
+}, {
+ // =========
+ // MUTE
+ // =========
+ name: 'mute',
+ icon: 'eye-slash',
+ label: 'status.mute_ellipsis',
+ if: ({ loggedIn }) => loggedIn,
+ toggleable: true,
+ dropdown: true
+ // action ({ status, dispatch, emit }) {
+ // if (status.thread_muted) {
+ // return dispatch('unmuteConversation', { id: status.id })
+ // } else {
+ // return dispatch('muteConversation', { id: status.id })
+ // }
+ // }
+}, {
+ // =========
+ // PIN STATUS
+ // =========
+ name: 'pin',
+ icon: 'thumbtack',
+ label: ({ status }) => status.pinned
+ ? 'status.unpin'
+ : 'status.pin',
+ if ({ status, loggedIn, currentUser }) {
+ return loggedIn &&
+ status.user.id === currentUser.id &&
+ PUBLIC_SCOPES.has(status.visibility)
+ },
+ action ({ status, dispatch, emit }) {
+ if (status.pinned) {
+ return dispatch('unpinStatus', { id: status.id })
+ } else {
+ return dispatch('pinStatus', { id: status.id })
+ }
+ }
+}, {
+ // =========
+ // BOOKMARK
+ // =========
+ name: 'bookmark',
+ icon: 'bookmark',
+ toggleable: true,
+ active: ({ status }) => status.bookmarked,
+ label: ({ status }) => status.bookmarked
+ ? 'status.unbookmark'
+ : 'status.bookmark',
+ if: ({ loggedIn }) => loggedIn,
+ action ({ status, dispatch, emit }) {
+ if (status.bookmarked) {
+ return dispatch('unbookmark', { id: status.id })
+ } else {
+ return dispatch('bookmark', { id: status.id })
+ }
+ }
+}, {
+ // =========
+ // EDIT
+ // =========
+ name: 'edit',
+ icon: 'pen',
+ label: 'status.edit',
+ if ({ status, loggedIn, currentUser, state }) {
+ return loggedIn &&
+ state.instance.editingAvailable &&
+ status.user.id === currentUser.id
+ },
+ action ({ dispatch, status }) {
+ return dispatch('fetchStatusSource', { id: status.id })
+ .then(data => dispatch('openEditStatusModal', {
+ statusId: status.id,
+ subject: data.spoiler_text,
+ statusText: data.text,
+ statusIsSensitive: status.nsfw,
+ statusPoll: status.poll,
+ statusFiles: [...status.attachments],
+ visibility: status.visibility,
+ statusContentType: data.content_type
+ }))
+ }
+}, {
+ // =========
+ // DELETE
+ // =========
+ name: 'delete',
+ icon: 'times',
+ label: 'status.delete',
+ if ({ status, loggedIn, currentUser }) {
+ return loggedIn && (
+ status.user.id === currentUser.id ||
+ currentUser.privileges.includes('messages_delete')
+ )
+ },
+ confirm: ({ status, getters }) => getters.mergedConfig.modalOnDelete,
+ confirmStrings: {
+ title: 'status.delete_confirm_title',
+ body: 'status.delete_confirm',
+ confirm: 'status.delete_confirm_accept_button',
+ cancel: 'status.delete_confirm_cancel_button'
+ },
+ action ({ dispatch, status }) {
+ return dispatch('deleteStatus', { id: status.id })
+ }
+}, {
+ // =========
+ // SHARE/COPY
+ // =========
+ name: 'share',
+ icon: 'share-alt',
+ label: 'status.copy_link',
+ action ({ state, status, router }) {
+ navigator.clipboard.writeText([
+ state.instance.server,
+ router.resolve({ name: 'conversation', params: { id: status.id } }).href
+ ].join(''))
+ return Promise.resolve()
+ }
+}, {
+ // =========
+ // EXTERNAL
+ // =========
+ name: 'external',
+ icon: 'external-link-alt',
+ label: 'status.external_source',
+ link: ({ status }) => status.external_url
+}, {
+ // =========
+ // REPORT
+ // =========
+ name: 'report',
+ icon: 'flag',
+ label: 'user_card.report',
+ if: ({ loggedIn }) => loggedIn,
+ action ({ dispatch, status }) {
+ dispatch('openUserReportingModal', { userId: status.user.id, statusIds: [status.id] })
+ }
+}].map(button => {
+ return Object.fromEntries(
+ Object.entries(button).map(([k, v]) => [
+ k,
+ (typeof v === 'function' || k === 'name') ? v : () => v
+ ])
+ )
+})
diff --git a/src/components/status_action_buttons/status_action_buttons.js b/src/components/status_action_buttons/status_action_buttons.js
@@ -5,280 +5,16 @@ import ActionButtonContainer from './action_button_container.vue'
import Popover from 'src/components/popover/popover.vue'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
+import { BUTTONS } from './buttons_definitions.vue'
+
import { library } from '@fortawesome/fontawesome-svg-core'
import {
- faPlus,
- faMinus,
- faCheck,
- faTimes,
- faWrench,
-
- faReply,
- faRetweet,
- faStar,
- faSmileBeam,
-
- faEllipsisH,
- faBookmark,
- faEyeSlash,
- faThumbtack,
- faShareAlt,
- faExternalLinkAlt,
- faHistory
+ faEllipsisH
} from '@fortawesome/free-solid-svg-icons'
-import {
- faStar as faStarRegular
-} from '@fortawesome/free-regular-svg-icons'
library.add(
- faPlus,
- faMinus,
- faCheck,
- faTimes,
- faWrench,
-
- faReply,
- faRetweet,
- faStar,
- faStarRegular,
- faSmileBeam,
-
- faEllipsisH,
- faBookmark,
- faEyeSlash,
- faThumbtack,
- faShareAlt,
- faExternalLinkAlt,
- faHistory
+ faEllipsisH
)
-const PRIVATE_SCOPES = new Set(['private', 'direct'])
-const PUBLIC_SCOPES = new Set(['public', 'unlisted'])
-const BUTTONS = [{
- // =========
- // REPLY
- // =========
- name: 'reply',
- label: 'tool_tip.reply',
- icon: 'reply',
- active: ({ replying }) => replying,
- counter: ({ status }) => status.replies_count,
- anon: true,
- anonLink: true,
- toggleable: true,
- closeIndicator: 'times',
- activeIndicator: 'none',
- action ({ emit }) {
- emit('toggleReplying')
- return Promise.resolve()
- }
-}, {
- // =========
- // REPEAT
- // =========
- name: 'retweet',
- label: 'tool_tip.repeat',
- icon ({ status }) {
- if (PRIVATE_SCOPES.has(status.visibility)) {
- return 'lock'
- }
- return 'retweet'
- },
- animated: true,
- active: ({ status }) => status.repeated,
- counter: ({ status }) => status.repeat_num,
- anonLink: true,
- interactive: ({ status, loggedIn }) => loggedIn && !PRIVATE_SCOPES.has(status.visibility),
- toggleable: true,
- confirm: ({ status, getters }) => !status.repeated && getters.mergedConfig.modalOnRepeat,
- confirmStrings: {
- title: 'status.repeat_confirm_title',
- body: 'status.repeat_confirm',
- confirm: 'status.repeat_confirm_accept_button',
- cancel: 'status.repeat_confirm_cancel_button'
- },
- action ({ status, dispatch }) {
- if (!status.repeated) {
- return dispatch('retweet', { id: status.id })
- } else {
- return dispatch('unretweet', { id: status.id })
- }
- }
-}, {
- // =========
- // FAVORITE
- // =========
- name: 'favorite',
- label: 'tool_tip.favorite',
- icon: ({ status }) => status.favorited
- ? ['fas', 'star']
- : ['far', 'star'],
- animated: true,
- active: ({ status }) => status.favorited,
- counter: ({ status }) => status.fave_num,
- anonLink: true,
- toggleable: true,
- action ({ status, dispatch }) {
- if (!status.favorited) {
- return dispatch('favorite', { id: status.id })
- } else {
- return dispatch('unfavorite', { id: status.id })
- }
- }
-}, {
- // =========
- // EMOJI REACTIONS
- // =========
- name: 'emoji',
- label: 'tool_tip.add_reaction',
- icon: ['far', 'smile-beam'],
- anonLink: true,
- popover: 'emoji-picker'
-}, {
- // =========
- // MUTE
- // =========
- name: 'mute',
- icon: 'eye-slash',
- label: 'status.mute_ellipsis',
- if: ({ loggedIn }) => loggedIn,
- toggleable: true,
- dropdown: true
- // action ({ status, dispatch, emit }) {
- // if (status.thread_muted) {
- // return dispatch('unmuteConversation', { id: status.id })
- // } else {
- // return dispatch('muteConversation', { id: status.id })
- // }
- // }
-}, {
- // =========
- // PIN STATUS
- // =========
- name: 'pin',
- icon: 'thumbtack',
- label: ({ status }) => status.pinned
- ? 'status.unpin'
- : 'status.pin',
- if ({ status, loggedIn, currentUser }) {
- return loggedIn &&
- status.user.id === currentUser.id &&
- PUBLIC_SCOPES.has(status.visibility)
- },
- action ({ status, dispatch, emit }) {
- if (status.pinned) {
- return dispatch('unpinStatus', { id: status.id })
- } else {
- return dispatch('pinStatus', { id: status.id })
- }
- }
-}, {
- // =========
- // BOOKMARK
- // =========
- name: 'bookmark',
- icon: 'bookmark',
- toggleable: true,
- active: ({ status }) => status.bookmarked,
- label: ({ status }) => status.bookmarked
- ? 'status.unbookmark'
- : 'status.bookmark',
- if: ({ loggedIn }) => loggedIn,
- action ({ status, dispatch, emit }) {
- if (status.bookmarked) {
- return dispatch('unbookmark', { id: status.id })
- } else {
- return dispatch('bookmark', { id: status.id })
- }
- }
-}, {
- // =========
- // EDIT
- // =========
- name: 'edit',
- icon: 'pen',
- label: 'status.edit',
- if ({ status, loggedIn, currentUser, state }) {
- return loggedIn &&
- state.instance.editingAvailable &&
- status.user.id === currentUser.id
- },
- action ({ dispatch, status }) {
- return dispatch('fetchStatusSource', { id: status.id })
- .then(data => dispatch('openEditStatusModal', {
- statusId: status.id,
- subject: data.spoiler_text,
- statusText: data.text,
- statusIsSensitive: status.nsfw,
- statusPoll: status.poll,
- statusFiles: [...status.attachments],
- visibility: status.visibility,
- statusContentType: data.content_type
- }))
- }
-}, {
- // =========
- // DELETE
- // =========
- name: 'delete',
- icon: 'times',
- label: 'status.delete',
- if ({ status, loggedIn, currentUser }) {
- return loggedIn && (
- status.user.id === currentUser.id ||
- currentUser.privileges.includes('messages_delete')
- )
- },
- confirm: ({ status, getters }) => getters.mergedConfig.modalOnDelete,
- confirmStrings: {
- title: 'status.delete_confirm_title',
- body: 'status.delete_confirm',
- confirm: 'status.delete_confirm_accept_button',
- cancel: 'status.delete_confirm_cancel_button'
- },
- action ({ dispatch, status }) {
- return dispatch('deleteStatus', { id: status.id })
- }
-}, {
- // =========
- // SHARE/COPY
- // =========
- name: 'share',
- icon: 'share-alt',
- label: 'status.copy_link',
- action ({ state, status, router }) {
- navigator.clipboard.writeText([
- state.instance.server,
- router.resolve({ name: 'conversation', params: { id: status.id } }).href
- ].join(''))
- return Promise.resolve()
- }
-}, {
- // =========
- // EXTERNAL
- // =========
- name: 'external',
- icon: 'external-link-alt',
- label: 'status.external_source',
- link: ({ status }) => status.external_url
-}, {
- // =========
- // REPORT
- // =========
- name: 'report',
- icon: 'flag',
- label: 'user_card.report',
- if: ({ loggedIn }) => loggedIn,
- action ({ dispatch, status }) {
- dispatch('openUserReportingModal', { userId: status.user.id, statusIds: [status.id] })
- }
-}].map(button => {
- return Object.fromEntries(
- Object.entries(button).map(([k, v]) => [
- k,
- (typeof v === 'function' || k === 'name') ? v : () => v
- ])
- )
-})
const StatusActionButtons = {
props: ['status', 'replying'],
@@ -320,6 +56,9 @@ const StatusActionButtons = {
currentUser () {
return this.$store.state.users.currentUser
},
+ hideCustomEmoji () {
+ return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable
+ },
funcArg () {
return {
status: this.status,
@@ -345,6 +84,7 @@ const StatusActionButtons = {
methods: {
doAction (button) {
if (button.confirm?.(this.funcArg)) {
+ // TODO move to action_button
this.currentConfirmTitle = this.$t(button.confirmStrings(this.funcArg).title)
this.currentConfirmOkText = this.$t(button.confirmStrings(this.funcArg).confirm)
this.currentConfirmCancelText = this.$t(button.confirmStrings(this.funcArg).cancel)
@@ -366,7 +106,6 @@ const StatusActionButtons = {
.finally(() => setTimeout(() => { this.animationState[button.name] = false }))
},
isPinned (button) {
- console.log(this.pinnedItems, button.name)
return this.pinnedItems.has(button.name)
},
unpin (button) {