Merge remote-tracking branch 'origin/develop' into 2-10-1-fixes

This commit is contained in:
Henry Jameson 2026-01-08 19:12:32 +02:00
commit dcb7ed1b8c
428 changed files with 55612 additions and 18549 deletions

View file

@ -1,34 +1,31 @@
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 StatusBookmarkFolderMenu from 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faPlus,
faMinus,
faBookmark as faBookmarkRegular,
faStar as faStarRegular,
} from '@fortawesome/free-regular-svg-icons'
import {
faBookmark,
faCheck,
faTimes,
faWrench,
faChevronRight,
faChevronUp,
faExternalLinkAlt,
faEyeSlash,
faHistory,
faMinus,
faPlus,
faReply,
faRetweet,
faStar,
faSmileBeam,
faBookmark,
faEyeSlash,
faThumbtack,
faShareAlt,
faExternalLinkAlt,
faHistory
faSmileBeam,
faStar,
faThumbtack,
faTimes,
faWrench,
} from '@fortawesome/free-solid-svg-icons'
import {
faStar as faStarRegular,
faBookmark as faBookmarkRegular
} from '@fortawesome/free-regular-svg-icons'
library.add(
faPlus,
@ -52,7 +49,7 @@ library.add(
faThumbtack,
faShareAlt,
faExternalLinkAlt,
faHistory
faHistory,
)
export default {
@ -65,66 +62,78 @@ export default {
'getClass',
'getComponent',
'doAction',
'outerClose'
],
emits: [
'interacted'
'outerClose',
],
emits: ['interacted'],
components: {
StatusBookmarkFolderMenu,
EmojiPicker,
Popover
Popover,
},
data: () => ({
animationState: false
animationState: false,
}),
computed: {
buttonClass () {
buttonClass() {
return [
this.button.name + '-button',
{
'-with-extra': this.button.name === 'bookmark',
'-extra': this.extra,
'-quick': !this.extra
}
'-quick': !this.extra,
},
]
},
userIsMuted () {
userIsMuted() {
return this.$store.getters.relationship(this.status.user.id).muting
},
threadIsMuted () {
threadIsMuted() {
return this.status.thread_muted
},
hideCustomEmoji () {
hideCustomEmoji() {
return !this.$store.state.instance.pleromaCustomEmojiReactionsAvailable
},
buttonInnerClass () {
buttonInnerClass() {
return [
this.button.name + '-button',
{
'main-button': this.extra,
'button-unstyled': !this.extra,
'-active': this.button.active?.(this.funcArg),
disabled: this.button.interactive ? !this.button.interactive(this.funcArg) : false
}
disabled: this.button.interactive
? !this.button.interactive(this.funcArg)
: false,
},
]
},
remoteInteractionLink () {
return this.$store.getters.remoteInteractionLink({ statusId: this.status.id })
}
remoteInteractionLink() {
return this.$store.getters.remoteInteractionLink({
statusId: this.status.id,
})
},
},
methods: {
addReaction (event) {
addReaction(event) {
const emoji = event.insertion
const existingReaction = this.status.emoji_reactions.find(r => r.name === emoji)
const existingReaction = this.status.emoji_reactions.find(
(r) => r.name === emoji,
)
if (existingReaction && existingReaction.me) {
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
} else {
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
}
},
doActionWrap (button, close = () => {}) {
if (this.button.interactive ? !this.button.interactive(this.funcArg) : false) return
doActionWrap(
button,
close = () => {
/* no-op */
},
) {
if (
this.button.interactive ? !this.button.interactive(this.funcArg) : false
)
return
this.$emit('interacted')
if (button.name === 'emoji') {
this.$refs.picker.showPicker()
@ -136,6 +145,6 @@ export default {
}, 500)
close()
}
}
}
},
},
}

View file

@ -1,92 +1,90 @@
import ActionButton from './action_button.vue'
import Popover from 'src/components/popover/popover.vue'
import MuteConfirm from 'src/components/confirm_modal/mute_confirm.vue'
import Popover from 'src/components/popover/popover.vue'
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
import ActionButton from './action_button.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUser,
faFolderTree,
faGlobe,
faFolderTree
faUser,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUser,
faGlobe,
faFolderTree
)
library.add(faUser, faGlobe, faFolderTree)
export default {
components: {
ActionButton,
Popover,
MuteConfirm,
UserTimedFilterModal
UserTimedFilterModal,
},
props: ['button', 'status'],
emits: ['interacted'],
mounted () {
mounted() {
if (this.button.name === 'mute') {
this.$store.dispatch('fetchDomainMutes')
}
},
computed: {
buttonClass () {
buttonClass() {
return [
this.button.name + '-button',
{
'-with-extra': this.button.name === 'bookmark',
'-extra': this.extra,
'-quick': !this.extra
}
'-quick': !this.extra,
},
]
},
user () {
user() {
return this.status.user
},
userIsMuted () {
userIsMuted() {
return this.$store.getters.relationship(this.user.id).muting
},
conversationIsMuted () {
conversationIsMuted() {
return this.status.thread_muted
},
domain () {
domain() {
return this.user.fqn.split('@')[1]
},
domainIsMuted () {
return new Set(this.$store.state.users.currentUser.domainMutes).has(this.domain)
}
domainIsMuted() {
return new Set(this.$store.state.users.currentUser.domainMutes).has(
this.domain,
)
},
},
methods: {
unmuteUser () {
unmuteUser() {
return this.$store.dispatch('unmuteUser', this.user.id)
},
unmuteConversation () {
unmuteConversation() {
return this.$store.dispatch('unmuteConversation', { id: this.status.id })
},
unmuteDomain () {
unmuteDomain() {
return this.$store.dispatch('unmuteDomain', this.domain)
},
toggleUserMute () {
toggleUserMute() {
if (this.userIsMuted) {
this.unmuteUser()
} else {
this.$refs.confirmUser.optionallyPrompt()
}
},
toggleConversationMute () {
toggleConversationMute() {
if (this.conversationIsMuted) {
this.unmuteConversation()
} else {
this.$refs.confirmConversation.optionallyPrompt()
}
},
toggleDomainMute () {
toggleDomainMute() {
if (this.domainIsMuted) {
this.unmuteDomain()
} else {
this.$refs.confirmDomain.optionallyPrompt()
}
}
}
},
},
}

View file

@ -4,257 +4,282 @@ import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
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: ({ status }) => status.repeated
? 'tool_tip.unrepeat'
: 'tool_tip.repeat',
icon ({ status, currentUser }) {
if (currentUser.id !== status.user.id && PRIVATE_SCOPES.has(status.visibility)) {
return 'lock'
}
return 'retweet'
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()
},
},
animated: true,
active: ({ status }) => status.repeated,
counter: ({ status }) => status.repeat_num,
anonLink: true,
interactive: ({ status, currentUser }) => !!currentUser && (currentUser.id === status.user.id || !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'
{
// =========
// REPEAT
// =========
name: 'retweet',
label: ({ status }) =>
status.repeated ? 'tool_tip.unrepeat' : 'tool_tip.repeat',
icon({ status, currentUser }) {
if (
currentUser.id !== status.user.id &&
PRIVATE_SCOPES.has(status.visibility)
) {
return 'lock'
}
return 'retweet'
},
animated: true,
active: ({ status }) => status.repeated,
counter: ({ status }) => status.repeat_num,
anonLink: true,
interactive: ({ status, currentUser }) =>
!!currentUser &&
(currentUser.id === status.user.id ||
!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 })
}
},
},
action ({ status, dispatch }) {
if (!status.repeated) {
return dispatch('retweet', { id: status.id })
} else {
return dispatch('unretweet', { id: status.id })
}
}
}, {
// =========
// FAVORITE
// =========
name: 'favorite',
label: ({ status }) => status.favorited
? 'tool_tip.unfavorite'
: '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 }) {
// }
}, {
// =========
// 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)
{
// =========
// FAVORITE
// =========
name: 'favorite',
label: ({ status }) =>
status.favorited ? 'tool_tip.unfavorite' : '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 })
}
},
},
action ({ status, dispatch }) {
if (status.pinned) {
return dispatch('unpinStatus', status.id)
} else {
return dispatch('pinStatus', status.id)
}
}
}, {
// =========
// BOOKMARK
// =========
name: 'bookmark',
icon: ({ status }) => status.bookmarked
? ['fas', 'bookmark']
: ['far', 'bookmark'],
toggleable: true,
active: ({ status }) => status.bookmarked,
label: ({ status }) => status.bookmarked
? 'status.unbookmark'
: 'status.bookmark',
if: ({ loggedIn }) => loggedIn,
action ({ status, dispatch }) {
if (status.bookmarked) {
return dispatch('unbookmark', { id: status.id })
} else {
return dispatch('bookmark', { id: status.id })
}
}
}, {
// =========
// EDIT HISTORY
// =========
name: 'editHistory',
icon: 'history',
label: 'status.status_history',
if ({ status, state }) {
return state.instance.editingAvailable &&
status.edited_at !== null
{
// =========
// EMOJI REACTIONS
// =========
name: 'emoji',
label: 'tool_tip.add_reaction',
icon: ['far', 'smile-beam'],
anonLink: true,
},
action ({ status }) {
const originalStatus = { ...status }
const stripFieldsList = [
'attachments',
'created_at',
'emojis',
'text',
'raw_html',
'nsfw',
'poll',
'summary',
'summary_raw_html'
]
stripFieldsList.forEach(p => delete originalStatus[p])
useStatusHistoryStore().openStatusHistoryModal(originalStatus)
return Promise.resolve()
}
}, {
// =========
// EDIT
// =========
name: 'edit',
icon: 'pen',
label: 'status.edit',
if ({ status, loggedIn, currentUser, state }) {
return loggedIn &&
state.instance.editingAvailable &&
status.user.id === currentUser.id
{
// =========
// MUTE
// =========
name: 'mute',
icon: 'eye-slash',
label: 'status.mute_ellipsis',
if: ({ loggedIn }) => loggedIn,
toggleable: true,
dropdown: true,
// action ({ status, dispatch, emit }) {
// }
},
action ({ dispatch, status }) {
return dispatch('fetchStatusSource', { id: status.id })
.then(data => useEditStatusStore().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')
)
{
// =========
// 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 }) {
if (status.pinned) {
return dispatch('unpinStatus', status.id)
} else {
return dispatch('pinStatus', status.id)
}
},
},
confirm: ({ 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'
{
// =========
// BOOKMARK
// =========
name: 'bookmark',
icon: ({ status }) =>
status.bookmarked ? ['fas', 'bookmark'] : ['far', 'bookmark'],
toggleable: true,
active: ({ status }) => status.bookmarked,
label: ({ status }) =>
status.bookmarked ? 'status.unbookmark' : 'status.bookmark',
if: ({ loggedIn }) => loggedIn,
action({ status, dispatch }) {
if (status.bookmarked) {
return dispatch('unbookmark', { id: status.id })
} else {
return dispatch('bookmark', { id: status.id })
}
},
},
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 ({ status }) {
return useReportsStore().openUserReportingModal({ userId: status.user.id, statusIds: [status.id] })
}
}].map(button => {
{
// =========
// EDIT HISTORY
// =========
name: 'editHistory',
icon: 'history',
label: 'status.status_history',
if({ status, state }) {
return state.instance.editingAvailable && status.edited_at !== null
},
action({ status }) {
const originalStatus = { ...status }
const stripFieldsList = [
'attachments',
'created_at',
'emojis',
'text',
'raw_html',
'nsfw',
'poll',
'summary',
'summary_raw_html',
]
stripFieldsList.forEach((p) => delete originalStatus[p])
useStatusHistoryStore().openStatusHistoryModal(originalStatus)
return Promise.resolve()
},
},
{
// =========
// 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) =>
useEditStatusStore().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: ({ 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({ status }) {
return useReportsStore().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
])
typeof v === 'function' || k === 'name' ? v : () => v,
]),
)
})

View file

@ -1,59 +1,56 @@
import { mapState } from 'pinia'
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
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 { useServerSideStorageStore } from 'src/stores/serverSideStorage'
import ActionButtonContainer from './action_button_container.vue'
import { BUTTONS } from './buttons_definitions.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEllipsisH
} from '@fortawesome/free-solid-svg-icons'
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
library.add(
faEllipsisH
)
library.add(faEllipsisH)
const StatusActionButtons = {
props: ['status', 'replying'],
emits: ['toggleReplying', 'interacted'],
data () {
data() {
return {
showPin: false,
showingConfirmDialog: false,
currentConfirmTitle: '',
currentConfirmOkText: '',
currentConfirmCancelText: '',
currentConfirmAction: () => {},
randomSeed: genRandomSeed()
currentConfirmAction: () => {
/* no-op */
},
randomSeed: genRandomSeed(),
}
},
components: {
Popover,
ConfirmModal,
ActionButtonContainer
ActionButtonContainer,
},
computed: {
...mapState(useServerSideStorageStore, {
pinnedItems: store => new Set(store.prefsStorage.collections.pinnedStatusActions)
pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedStatusActions),
}),
buttons () {
return BUTTONS.filter(x => x.if ? x.if(this.funcArg) : true)
buttons() {
return BUTTONS.filter((x) => (x.if ? x.if(this.funcArg) : true))
},
quickButtons () {
return this.buttons.filter(x => this.pinnedItems.has(x.name))
quickButtons() {
return this.buttons.filter((x) => this.pinnedItems.has(x.name))
},
extraButtons () {
return this.buttons.filter(x => !this.pinnedItems.has(x.name))
extraButtons() {
return this.buttons.filter((x) => !this.pinnedItems.has(x.name))
},
currentUser () {
currentUser() {
return this.$store.state.users.currentUser
},
funcArg () {
funcArg() {
return {
status: this.status,
replying: this.replying,
@ -63,25 +60,33 @@ const StatusActionButtons = {
getters: this.$store.getters,
router: this.$router,
currentUser: this.currentUser,
loggedIn: !!this.currentUser
loggedIn: !!this.currentUser,
}
},
triggerAttrs () {
triggerAttrs() {
return {
title: this.$t('status.more_actions'),
'aria-controls': `popup-menu-${this.randomSeed}`,
'aria-haspopup': 'menu'
'aria-haspopup': 'menu',
}
}
},
},
methods: {
doAction (button) {
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)
this.currentConfirmBody = this.$t(button.confirmStrings(this.funcArg).body)
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,
)
this.currentConfirmBody = this.$t(
button.confirmStrings(this.funcArg).body,
)
this.currentConfirmAction = () => {
this.showingConfirmDialog = false
this.doActionReal(button)
@ -91,26 +96,33 @@ const StatusActionButtons = {
this.doActionReal(button)
}
},
doActionReal (button) {
button.action(this.funcArg)
doActionReal(button) {
button
.action(this.funcArg)
.then(() => this.$emit('onSuccess'))
.catch(err => this.$emit('onError', err.error.error))
.catch((err) => this.$emit('onError', err.error.error))
},
onExtraClose () {
onExtraClose() {
this.showPin = false
},
isPinned (button) {
isPinned(button) {
return this.pinnedItems.has(button.name)
},
unpin (button) {
useServerSideStorageStore().removeCollectionPreference({ path: 'collections.pinnedStatusActions', value: button.name })
unpin(button) {
useServerSideStorageStore().removeCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useServerSideStorageStore().pushServerSideStorage()
},
pin (button) {
useServerSideStorageStore().addCollectionPreference({ path: 'collections.pinnedStatusActions', value: button.name })
pin(button) {
useServerSideStorageStore().addCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useServerSideStorageStore().pushServerSideStorage()
},
getComponent (button) {
getComponent(button) {
if (!this.$store.state.users.currentUser && button.anonLink) {
return 'a'
} else if (button.action == null && button.link != null) {
@ -119,16 +131,18 @@ const StatusActionButtons = {
return 'button'
}
},
getClass (button) {
getClass(button) {
return {
[button.name + '-button']: true,
disabled: button.interactive ? !button.interactive(this.funcArg) : false,
disabled: button.interactive
? !button.interactive(this.funcArg)
: false,
'-pin-edit': this.showPin,
'-dropdown': button.dropdown?.(),
'-active': button.active?.(this.funcArg)
'-active': button.active?.(this.funcArg),
}
}
}
},
},
}
export default StatusActionButtons

View file

@ -15,7 +15,7 @@
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:close="() => {}"
:close="() => { /* no-op */ }"
:do-action="doAction"
@interacted="e => $emit('interacted')"
/>