more work + dropdown items overhaul
This commit is contained in:
parent
eb7406c663
commit
96fd7f91c4
9 changed files with 340 additions and 227 deletions
|
|
@ -113,11 +113,11 @@ const BUTTONS = [{
|
|||
counter: ({ status }) => status.fave_num,
|
||||
anonLink: true,
|
||||
toggleable: true,
|
||||
action ({ status, store }) {
|
||||
action ({ status, dispatch }) {
|
||||
if (!status.favorited) {
|
||||
return store.dispatch('favorite', { id: status.id })
|
||||
return dispatch('favorite', { id: status.id })
|
||||
} else {
|
||||
return store.dispatch('unfavorite', { id: status.id })
|
||||
return dispatch('unfavorite', { id: status.id })
|
||||
}
|
||||
}
|
||||
}, {
|
||||
|
|
@ -125,7 +125,7 @@ const BUTTONS = [{
|
|||
// EMOJI REACTIONS
|
||||
// =========
|
||||
name: 'emoji',
|
||||
label: 'tool_lip.add_reaction',
|
||||
label: 'tool_tip.add_reaction',
|
||||
icon: ['far', 'smile-beam'],
|
||||
anonLink: true,
|
||||
popover: 'emoji-picker'
|
||||
|
|
@ -279,6 +279,7 @@ const StatusActionButtons = {
|
|||
emits: ['toggleReplying'],
|
||||
data () {
|
||||
return {
|
||||
showPin: true,
|
||||
showingConfirmDialog: false,
|
||||
currentConfirmTitle: '',
|
||||
currentConfirmOkText: '',
|
||||
|
|
@ -304,6 +305,9 @@ const StatusActionButtons = {
|
|||
extraButtons () {
|
||||
return this.buttons.filter(x => !this.pinnedItems.has(x.name))
|
||||
},
|
||||
currentUser () {
|
||||
return this.$store.state.users.currentUser
|
||||
},
|
||||
funcArg () {
|
||||
return {
|
||||
status: this.status,
|
||||
|
|
@ -313,8 +317,8 @@ const StatusActionButtons = {
|
|||
state: this.$store.state,
|
||||
getters: this.$store.getters,
|
||||
router: this.$router,
|
||||
currentUser: this.$store.state.users.currentUser,
|
||||
loggedIn: !!this.$store.state.users.currentUser
|
||||
currentUser: this.currentUser,
|
||||
loggedIn: !!this.currentUser
|
||||
}
|
||||
},
|
||||
triggerAttrs () {
|
||||
|
|
@ -336,6 +340,18 @@ const StatusActionButtons = {
|
|||
.then(() => this.$emit('onSuccess'))
|
||||
.catch(err => this.$emit('onError', err.error.error))
|
||||
},
|
||||
isPinned (button) {
|
||||
console.log(this.pinnedItems, button.name)
|
||||
return this.pinnedItems.has(button.name)
|
||||
},
|
||||
unpin (button) {
|
||||
this.$store.commit('removeCollectionPreference', { path: 'collections.pinnedStatusActions', value: button.name })
|
||||
this.$store.dispatch('pushServerSideStorage')
|
||||
},
|
||||
pin (button) {
|
||||
this.$store.commit('addCollectionPreference', { path: 'collections.pinnedStatusActions', value: button.name })
|
||||
this.$store.dispatch('pushServerSideStorage')
|
||||
},
|
||||
component (button) {
|
||||
if (!this.$store.state.users.currentUser && button.anonLink) {
|
||||
return 'a'
|
||||
|
|
@ -348,6 +364,8 @@ const StatusActionButtons = {
|
|||
getClass (button) {
|
||||
return {
|
||||
[button.name + '-button']: true,
|
||||
'-pin-edit': this.showPin,
|
||||
'-dropdown': button.dropdown?.(),
|
||||
'-active': button.active?.(this.funcArg),
|
||||
'-interactive': !!this.$store.state.users.currentUser
|
||||
}
|
||||
|
|
|
|||
112
src/components/status_action_buttons/status_action_buttons.scss
Normal file
112
src/components/status_action_buttons/status_action_buttons.scss
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
@import "../../mixins";
|
||||
|
||||
.StatusActionButtons {
|
||||
.quick-action-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
grid-gap: 1em;
|
||||
margin-top: var(--status-margin);
|
||||
|
||||
.quick-action {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
|
||||
.action-button {
|
||||
display: grid;
|
||||
grid-template-columns: max-content auto;
|
||||
grid-gap: 1em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.-pin {
|
||||
margin: calc(-2px - 0.25em);
|
||||
padding: 0.25em;
|
||||
border: 2px dashed var(--icon);
|
||||
border-radius: var(--roundness);
|
||||
}
|
||||
|
||||
&.-pin,
|
||||
&.-dropdown {
|
||||
grid-template-columns: 1fr max-content;
|
||||
}
|
||||
|
||||
.reply-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cBlue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.retweet-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cGreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cOrange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> button,
|
||||
> a {
|
||||
padding: 0.5em;
|
||||
margin: -0.5em;
|
||||
|
||||
@include unfocused-style {
|
||||
.focus-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@include focused-style {
|
||||
.focus-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// popover
|
||||
.extra-action-buttons {
|
||||
.extra-action {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: auto;
|
||||
grid-gap: 1em;
|
||||
|
||||
.pin-action-button {
|
||||
margin: 0;
|
||||
padding: var(--__horizontal-gap) var(--__horizontal-gap);
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
height: 1em;
|
||||
width: 1px;
|
||||
border-left: 1px solid var(--icon);
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,13 @@
|
|||
<span class="quick-action-buttons">
|
||||
<span
|
||||
class="quick-action"
|
||||
:class="{ '-pin': showPin, '-toggle': button.dropdown?.() }"
|
||||
v-for="button in quickButtons"
|
||||
:key="button.name"
|
||||
>
|
||||
<component
|
||||
:is="component(button)"
|
||||
class="button-unstyled"
|
||||
class="button-unstyled action-button"
|
||||
:class="getClass(button)"
|
||||
role="button"
|
||||
:tabindex="0"
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
@click.stop="component(button) === 'button' && doAction(button)"
|
||||
:href="component(button) == 'a' ? button.link?.(funcArg) || getRemoteInteractionLink : undefined"
|
||||
>
|
||||
<FALayers class="fa-old-padding">
|
||||
<FALayers>
|
||||
<FAIcon
|
||||
class="fa-scale-110"
|
||||
:icon="button.icon(funcArg)"
|
||||
|
|
@ -42,13 +43,28 @@
|
|||
/>
|
||||
</template>
|
||||
</FALayers>
|
||||
<span
|
||||
class="action-counter"
|
||||
v-if="button.counter?.(funcArg) > 0"
|
||||
>
|
||||
{{ button.counter?.(funcArg) }}
|
||||
</span>
|
||||
</component>
|
||||
<span
|
||||
class="action-counter"
|
||||
v-if="button.counter?.(funcArg) > 0"
|
||||
<button
|
||||
v-if="showPin && currentUser"
|
||||
type="button"
|
||||
class="button-unstyled pin-action-button"
|
||||
:title="$t('general.unpin')"
|
||||
:aria-pressed="true"
|
||||
@click.stop.prevent="unpin(button)"
|
||||
>
|
||||
{{ button.counter?.(funcArg) }}
|
||||
</span>
|
||||
<FAIcon
|
||||
v-if="showPin && currentUser"
|
||||
fixed-width
|
||||
class="fa-scale-110"
|
||||
icon="thumbtack"
|
||||
/>
|
||||
</button>
|
||||
</span>
|
||||
<Popover
|
||||
trigger="click"
|
||||
|
|
@ -56,44 +72,61 @@
|
|||
:tabindex="0"
|
||||
placement="top"
|
||||
:offset="{ y: 5 }"
|
||||
:bound-to="{ x: 'container2' }"
|
||||
:bound-to="{ x: 'container' }"
|
||||
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>
|
||||
<FAIcon
|
||||
class="fa-scale-110 "
|
||||
icon="ellipsis-h"
|
||||
/>
|
||||
</template>
|
||||
<template #content="{close}">
|
||||
<div
|
||||
:id="`popup-menu-${randomSeed}`"
|
||||
class="dropdown-menu"
|
||||
class="dropdown-menu extra-action-buttons"
|
||||
role="menu"
|
||||
>
|
||||
<component
|
||||
<div
|
||||
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"
|
||||
class="menu-item dropdown-item extra-action dropdown-item-icon"
|
||||
>
|
||||
<FAIcon
|
||||
class="fa-scale-110"
|
||||
:icon="button.icon(funcArg)"
|
||||
/><span>{{ $t(button.label(funcArg)) }}</span>
|
||||
</component>
|
||||
<component
|
||||
:is="component(button)"
|
||||
class="main-button"
|
||||
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"
|
||||
fixed-width
|
||||
:icon="button.icon(funcArg)"
|
||||
/><span>{{ $t(button.label(funcArg)) }}</span>
|
||||
</component>
|
||||
<button
|
||||
v-if="showPin && currentUser"
|
||||
type="button"
|
||||
class="button-unstyled pin-action-button"
|
||||
:title="$t('general.pin' )"
|
||||
:aria-pressed="false"
|
||||
@click.stop.prevent="pin(button)"
|
||||
>
|
||||
<FAIcon
|
||||
v-if="showPin && currentUser"
|
||||
fixed-width
|
||||
class="fa-scale-110 veryfaint"
|
||||
transform="rotate-45"
|
||||
icon="thumbtack"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popover>
|
||||
|
|
@ -116,78 +149,4 @@
|
|||
|
||||
<script src="./status_action_buttons.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../mixins";
|
||||
|
||||
.StatusActionButtons {
|
||||
.quick-action-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: 1fr;
|
||||
grid-gap: 1em;
|
||||
margin-top: var(--status-margin);
|
||||
|
||||
.quick-action {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-gap: 0.5em;
|
||||
max-width: 4em;
|
||||
|
||||
.reply-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cBlue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.retweet-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cGreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-button {
|
||||
&:hover,
|
||||
&.-active {
|
||||
.svg-inline--fa {
|
||||
color: var(--cOrange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> button,
|
||||
> a {
|
||||
padding: 0.5em;
|
||||
margin: -0.5em;
|
||||
}
|
||||
|
||||
@include unfocused-style {
|
||||
.focus-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
@include focused-style {
|
||||
.focus-marker {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.active-marker {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss" src="./status_action_buttons.scss"></style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue