extraButtons implementation
This commit is contained in:
parent
08f8b975b6
commit
eb7406c663
5 changed files with 182 additions and 51 deletions
|
@ -166,26 +166,24 @@
|
|||
</div>
|
||||
</template>
|
||||
<template #trigger>
|
||||
<span class="button-unstyled popover-trigger">
|
||||
<FALayers class="fa-old-padding-layer">
|
||||
<FAIcon
|
||||
class="fa-scale-110 "
|
||||
icon="ellipsis-h"
|
||||
/>
|
||||
<FAIcon
|
||||
v-show="!expanded"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-8 right-16"
|
||||
icon="plus"
|
||||
/>
|
||||
<FAIcon
|
||||
v-show="expanded"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-8 right-16"
|
||||
icon="times"
|
||||
/>
|
||||
</FALayers>
|
||||
</span>
|
||||
<FALayers class="fa-old-padding-layer">
|
||||
<FAIcon
|
||||
class="fa-scale-110 "
|
||||
icon="ellipsis-h"
|
||||
/>
|
||||
<FAIcon
|
||||
v-show="!expanded"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-8 right-16"
|
||||
icon="plus"
|
||||
/>
|
||||
<FAIcon
|
||||
v-show="expanded"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-8 right-16"
|
||||
icon="times"
|
||||
/>
|
||||
</FALayers>
|
||||
<teleport to="#modal">
|
||||
<ConfirmModal
|
||||
v-if="showingDeleteDialog"
|
||||
|
|
|
@ -264,13 +264,11 @@
|
|||
.status-actions {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-columns: 1fr;
|
||||
grid-auto-flow: column;
|
||||
margin-top: var(--status-margin);
|
||||
|
||||
> * {
|
||||
max-width: 4em;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.muted {
|
||||
|
|
|
@ -1,17 +1,52 @@
|
|||
import ConfirmModal from '../confirm_modal/confirm_modal.vue'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
|
||||
import Popover from 'src/components/popover/popover.vue'
|
||||
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
faRetweet,
|
||||
faPlus,
|
||||
faMinus,
|
||||
faCheck
|
||||
faCheck,
|
||||
faTimes,
|
||||
|
||||
faReply,
|
||||
faRetweet,
|
||||
faStar,
|
||||
faSmileBeam,
|
||||
|
||||
faEllipsisH,
|
||||
faBookmark,
|
||||
faEyeSlash,
|
||||
faThumbtack,
|
||||
faShareAlt,
|
||||
faExternalLinkAlt,
|
||||
faHistory
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faStar as faStarRegular
|
||||
} from '@fortawesome/free-regular-svg-icons'
|
||||
|
||||
library.add(
|
||||
faRetweet,
|
||||
faPlus,
|
||||
faMinus,
|
||||
faCheck
|
||||
faCheck,
|
||||
faTimes,
|
||||
|
||||
faReply,
|
||||
faRetweet,
|
||||
faStar,
|
||||
faStarRegular,
|
||||
faSmileBeam,
|
||||
|
||||
faEllipsisH,
|
||||
faBookmark,
|
||||
faEyeSlash,
|
||||
faThumbtack,
|
||||
faShareAlt,
|
||||
faExternalLinkAlt,
|
||||
faHistory
|
||||
)
|
||||
const PRIVATE_SCOPES = new Set(['private', 'direct'])
|
||||
const PUBLIC_SCOPES = new Set(['public', 'unlisted'])
|
||||
|
@ -27,6 +62,8 @@ const BUTTONS = [{
|
|||
anon: true,
|
||||
anonLink: true,
|
||||
toggleable: true,
|
||||
closeIndicator: 'times',
|
||||
activeIndicator: 'none',
|
||||
action ({ emit }) {
|
||||
emit('toggleReplying')
|
||||
return Promise.resolve()
|
||||
|
@ -230,7 +267,10 @@ const BUTTONS = [{
|
|||
}
|
||||
}].map(button => {
|
||||
return Object.fromEntries(
|
||||
Object.entries(button).map(([k, v]) => [k, typeof v === 'function' ? v : () => v])
|
||||
Object.entries(button).map(([k, v]) => [
|
||||
k,
|
||||
(typeof v === 'function' || k === 'name') ? v : () => v
|
||||
])
|
||||
)
|
||||
})
|
||||
|
||||
|
@ -243,15 +283,26 @@ const StatusActionButtons = {
|
|||
currentConfirmTitle: '',
|
||||
currentConfirmOkText: '',
|
||||
currentConfirmCancelText: '',
|
||||
currentConfirmAction: () => {}
|
||||
currentConfirmAction: () => {},
|
||||
randomSeed: genRandomSeed()
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Popover,
|
||||
ConfirmModal
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedStatusActions)
|
||||
}),
|
||||
buttons () {
|
||||
return BUTTONS.filter(x => x.if(this.funcArg))
|
||||
return BUTTONS.filter(x => x.if ? x.if(this.funcArg) : true)
|
||||
},
|
||||
quickButtons () {
|
||||
return this.buttons.filter(x => this.pinnedItems.has(x.name))
|
||||
},
|
||||
extraButtons () {
|
||||
return this.buttons.filter(x => !this.pinnedItems.has(x.name))
|
||||
},
|
||||
funcArg () {
|
||||
return {
|
||||
|
@ -265,6 +316,15 @@ const StatusActionButtons = {
|
|||
currentUser: this.$store.state.users.currentUser,
|
||||
loggedIn: !!this.$store.state.users.currentUser
|
||||
}
|
||||
},
|
||||
triggerAttrs () {
|
||||
return {
|
||||
title: this.$t('status.more_actions'),
|
||||
id: `popup-trigger-${this.randomSeed}`,
|
||||
'aria-controls': `popup-menu-${this.randomSeed}`,
|
||||
'aria-expanded': this.expanded,
|
||||
'aria-haspopup': 'menu'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -272,7 +332,7 @@ const StatusActionButtons = {
|
|||
this.doActionReal(button)
|
||||
},
|
||||
doActionReal (button) {
|
||||
button.action(this.funcArg(button))
|
||||
button.action(this.funcArg)
|
||||
.then(() => this.$emit('onSuccess'))
|
||||
.catch(err => this.$emit('onError', err.error.error))
|
||||
},
|
||||
|
@ -287,8 +347,8 @@ const StatusActionButtons = {
|
|||
},
|
||||
getClass (button) {
|
||||
return {
|
||||
[button.name() + '-button']: true,
|
||||
'-active': button.active?.(this.funcArg()),
|
||||
[button.name + '-button']: true,
|
||||
'-active': button.active?.(this.funcArg),
|
||||
'-interactive': !!this.$store.state.users.currentUser
|
||||
}
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<span class="quick-action-buttons">
|
||||
<span
|
||||
class="quick-action"
|
||||
v-for="button in buttons"
|
||||
v-for="button in quickButtons"
|
||||
:key="button.name"
|
||||
>
|
||||
<component
|
||||
|
@ -23,16 +23,22 @@
|
|||
/>
|
||||
<template v-if="button.toggleable?.(funcArg) && button.active">
|
||||
<FAIcon
|
||||
v-show="!button.active(funcArg)"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-9 right-17"
|
||||
icon="plus"
|
||||
v-if="button.active(funcArg)"
|
||||
class="active-marker"
|
||||
transform="shrink-6 up-9 right-12"
|
||||
:icon="button.activeIndicator?.(funcArg) || 'check'"
|
||||
/>
|
||||
<FAIcon
|
||||
v-show="button.active(funcArg)"
|
||||
v-if="!button.active(funcArg)"
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-9 right-17"
|
||||
icon="times"
|
||||
transform="shrink-6 up-9 right-12"
|
||||
:icon="button.openIndicator?.(funcArg) || 'plus'"
|
||||
/>
|
||||
<FAIcon
|
||||
v-else
|
||||
class="focus-marker"
|
||||
transform="shrink-6 up-9 right-12"
|
||||
:icon="button.closeIndicator?.(funcArg) || 'minus'"
|
||||
/>
|
||||
</template>
|
||||
</FALayers>
|
||||
|
@ -44,7 +50,55 @@
|
|||
{{ button.counter?.(funcArg) }}
|
||||
</span>
|
||||
</span>
|
||||
<Popover
|
||||
trigger="click"
|
||||
:trigger-attrs="triggerAttrs"
|
||||
:tabindex="0"
|
||||
placement="top"
|
||||
:offset="{ y: 5 }"
|
||||
:bound-to="{ x: 'container2' }"
|
||||
remove-padding
|
||||
@show="onShow"
|
||||
@close="onClose"
|
||||
>
|
||||
<template #trigger>
|
||||
<span class="popover-trigger">
|
||||
<FALayers class="fa-old-padding-layer">
|
||||
<FAIcon
|
||||
class="fa-scale-110 "
|
||||
icon="ellipsis-h"
|
||||
/>
|
||||
</FALayers>
|
||||
</span>
|
||||
</template>
|
||||
<template #content="{close}">
|
||||
<div
|
||||
:id="`popup-menu-${randomSeed}`"
|
||||
class="dropdown-menu"
|
||||
role="menu"
|
||||
>
|
||||
<component
|
||||
v-for="button in extraButtons"
|
||||
:key="button.name"
|
||||
:is="component(button)"
|
||||
class="menu-item dropdown-item dropdown-item-icon"
|
||||
role="menuitem"
|
||||
:class="getClass(button)"
|
||||
:tabindex="0"
|
||||
@click.stop="component(button) === 'button' && doAction(button)"
|
||||
@click="close"
|
||||
:href="component(button) == 'a' ? button.link?.(funcArg) || getRemoteInteractionLink : undefined"
|
||||
>
|
||||
<FAIcon
|
||||
class="fa-scale-110"
|
||||
:icon="button.icon(funcArg)"
|
||||
/><span>{{ $t(button.label(funcArg)) }}</span>
|
||||
</component>
|
||||
</div>
|
||||
</template>
|
||||
</Popover>
|
||||
</span>
|
||||
|
||||
<teleport to="#modal">
|
||||
<confirm-modal
|
||||
v-if="showingConfirmDialog"
|
||||
|
@ -66,11 +120,7 @@
|
|||
@import "../../mixins";
|
||||
|
||||
.StatusActionButtons {
|
||||
width: 100%;
|
||||
|
||||
.quick-action-buttons {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-flow: column;
|
||||
|
@ -121,12 +171,20 @@
|
|||
.focus-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@include focused-style {
|
||||
.focus-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
import { toRaw } from 'vue'
|
||||
import { isEqual, cloneDeep, set, get, clamp, flatten, groupBy, findLastIndex, takeRight, uniqWith } from 'lodash'
|
||||
import {
|
||||
isEqual,
|
||||
cloneDeep,
|
||||
set,
|
||||
get,
|
||||
clamp,
|
||||
flatten,
|
||||
groupBy,
|
||||
findLastIndex,
|
||||
takeRight,
|
||||
uniqWith,
|
||||
merge
|
||||
} from 'lodash'
|
||||
import { CURRENT_UPDATE_COUNTER } from 'src/components/update_notification/update_notification.js'
|
||||
|
||||
export const VERSION = 1
|
||||
|
@ -26,6 +38,7 @@ export const defaultState = {
|
|||
collapseNav: false
|
||||
},
|
||||
collections: {
|
||||
pinnedStatusActions: ['reply', 'retweet', 'favorite', 'emoji'],
|
||||
pinnedNavItems: ['home', 'dms', 'chats']
|
||||
}
|
||||
},
|
||||
|
@ -110,7 +123,11 @@ export const _getRecentData = (cache, live) => {
|
|||
console.debug('Both sources are invalid, start from scratch')
|
||||
result.needUpload = true
|
||||
}
|
||||
return result
|
||||
|
||||
result.recent = merge(defaultState, result.recent)
|
||||
result.stale = merge(defaultState, result.stale)
|
||||
|
||||
return merge(defaultState, result)
|
||||
}
|
||||
|
||||
export const _getAllFlags = (recent, stale) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue