From fe84a52dcc0a1cfe5088363edd5116bd0a61f36e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 9 Jan 2025 17:43:48 +0200 Subject: [PATCH] initial work on quick actions --- src/components/status/status.js | 4 +- src/components/status/status.vue | 10 +- .../status_action_buttons.js | 119 ++++++++++------- .../status_action_buttons.vue | 126 +++++++++++++++++- src/i18n/en.json | 1 + 5 files changed, 206 insertions(+), 54 deletions(-) diff --git a/src/components/status/status.js b/src/components/status/status.js index ccecaac7e..903542564 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -16,6 +16,7 @@ import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' import UserLink from '../user_link/user_link.vue' import MentionsLine from 'src/components/mentions_line/mentions_line.vue' import MentionLink from 'src/components/mention_link/mention_link.vue' +import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js' import { muteWordHits } from '../../services/status_parser/status_parser.js' @@ -119,7 +120,8 @@ const Status = { MentionLink, MentionsLine, UserPopover, - UserLink + UserLink, + StatusActionButtons }, props: [ 'statusoid', diff --git a/src/components/status/status.vue b/src/components/status/status.vue index c58178b3c..4e6c3f2d1 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -65,7 +65,6 @@ v-if="retweet" class="left-side repeater-avatar" :show-actor-type-indicator="showActorTypeIndicator" - :better-shadow="betterShadow" :user="statusoid.user" />
@@ -120,7 +119,6 @@ class="post-avatar" :show-actor-type-indicator="showActorTypeIndicator" :compact="compact" - :better-shadow="betterShadow" :user="status.user" /> @@ -537,6 +535,12 @@ :status="status" /> +
diff --git a/src/components/status_action_buttons/status_action_buttons.js b/src/components/status_action_buttons/status_action_buttons.js index 5de69d56d..2a7c70a41 100644 --- a/src/components/status_action_buttons/status_action_buttons.js +++ b/src/components/status_action_buttons/status_action_buttons.js @@ -28,7 +28,8 @@ const BUTTONS = [{ anonLink: true, toggleable: true, action ({ emit }) { - emit('toggle') + emit('toggleReplying') + return Promise.resolve() } }, { // ========= @@ -44,11 +45,16 @@ const BUTTONS = [{ }, animated: true, active: ({ status }) => status.repeated, - counter: ({ status }) => status.replies_count, + counter: ({ status }) => status.repeat_num, anonLink: true, interactive: ({ status }) => !PRIVATE_SCOPES.has(status.visibility), toggleable: true, confirm: ({ status, getters }) => !status.repeated && getters.mergedConfig.modalOnRepeat, + confirmStrings: { + title: 'status.repeat_confirm_title', + confirm: 'status.repeat_confirm_accept_button', + cancel: 'status.repeat_confirm_cancel_button' + }, action ({ status, store }) { if (!status.repeated) { return store.dispatch('retweet', { id: status.id }) @@ -62,10 +68,12 @@ const BUTTONS = [{ // ========= name: 'favorite', label: 'tool_tip.favorite', - icon: 'star', + icon: ({ status }) => status.favorited + ? ['fas', 'star'] + : ['far', 'star'], animated: true, active: ({ status }) => status.favorited, - counter: ({ status }) => status.fave_count, + counter: ({ status }) => status.fave_num, anonLink: true, toggleable: true, action ({ status, store }) { @@ -81,11 +89,9 @@ const BUTTONS = [{ // ========= name: 'emoji', label: 'tool_lip.add_reaction', - icon: 'smile-beam', + icon: ['far', 'smile-beam'], anonLink: true, - action ({ emojiPicker }) { - emojiPicker.show() - } + popover: 'emoji-picker' }, { // ========= // MUTE CONVERSATION, my beloved @@ -141,7 +147,8 @@ const BUTTONS = [{ } else { return dispatch('bookmark', { id: status.id }) } - } + }, + popover: 'bookmark-folders' }, { // ========= // EDIT @@ -180,8 +187,13 @@ const BUTTONS = [{ currentUser.privileges.includes('messages_delete') ) }, + confirmStrings: { + title: 'status.delete_confirm_title', + confirm: 'status.delete_confirm_cancel_button', + cancel: 'status.delete_confirm_accept_button' + }, action ({ dispatch, status }) { - dispatch('deleteStatus', { id: status.id }) + return dispatch('deleteStatus', { id: status.id }) } }, { // ========= @@ -195,6 +207,7 @@ const BUTTONS = [{ state.instance.server, router.resolve({ name: 'conversation', params: { id: status.id } }).href ].join('')) + return Promise.resolve() } }, { // ========= @@ -210,58 +223,74 @@ const BUTTONS = [{ // ========= name: 'report', icon: 'flag', - label: 'status.report', + 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' ? v : () => v]) + ) +}) +console.log(BUTTONS) const StatusActionButtons = { - props: ['status'], + props: ['status', 'replying'], + emits: ['toggleReplying'], + data () { + return { + buttons: BUTTONS, + showingConfirmDialog: false, + currentConfirmTitle: '', + currentConfirmOkText: '', + currentConfirmCancelText: '', + currentConfirmAction: () => {} + } + }, components: { ConfirmModal }, - data () { - return { - } - }, methods: { - retweet () { - if (!this.status.repeated && this.shouldConfirmRepeat) { - this.showConfirmDialog() + doAction (button) { + this.doActionReal(button) + }, + doActionReal (button) { + button.action(this.funcArg(button)) + .then(() => this.$emit('onSuccess')) + .catch(err => this.$emit('onError', err.error.error)) + }, + component (button) { + if (!this.$store.state.users.currentUser && button.anonLink) { + return 'a' + } else if (button.action == null && button.link != null) { + return 'a' } else { - this.doRetweet() + return 'button' } }, - doRetweet () { - if (!this.status.repeated) { - this.$store.dispatch('retweet', { id: this.status.id }) - } else { - this.$store.dispatch('unretweet', { id: this.status.id }) + funcArg () { + return { + status: this.status, + replying: this.replying, + emit: this.$emit, + dispatch: this.$store.dispatch, + state: this.$store.state, + getters: this.$store.getters, + router: this.$router, + currentUser: this.$store.state.users.currentUser, + loggedIn: !!this.$store.state.users.currentUser } - this.animated = true - setTimeout(() => { - this.animated = false - }, 500) - this.hideConfirmDialog() }, - showConfirmDialog () { - this.showingConfirmDialog = true + getClass (button) { + return { + [button.name() + '-button']: true, + '-active': button.active?.(this.funcArg()), + '-interactive': !!this.$store.state.users.currentUser + } }, - hideConfirmDialog () { - this.showingConfirmDialog = false - } - }, - computed: { - mergedConfig () { - return this.$store.getters.mergedConfig - }, - remoteInteractionLink () { + getRemoteInteractionLink () { return this.$store.getters.remoteInteractionLink({ statusId: this.status.id }) - }, - shouldConfirmRepeat () { - return this.mergedConfig.modalOnRepeat } } } diff --git a/src/components/status_action_buttons/status_action_buttons.vue b/src/components/status_action_buttons/status_action_buttons.vue index 83cd1eb73..3950e22db 100644 --- a/src/components/status_action_buttons/status_action_buttons.vue +++ b/src/components/status_action_buttons/status_action_buttons.vue @@ -1,21 +1,135 @@ - + diff --git a/src/i18n/en.json b/src/i18n/en.json index 3d7a674ce..a083e5757 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1410,6 +1410,7 @@ "mentions": "Mentions", "repeat": "Repeat", "reply": "Reply", + "add_reaction": "Add reaction", "favorite": "Favorite", "add_reaction": "Add Reaction", "user_settings": "User Settings",