Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
14 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/status_action_buttons/action_button.scss b/src/components/status_action_buttons/action_button.scss
index 25d7b71d46..e1e5ef3a69 100644
--- a/src/components/status_action_buttons/action_button.scss
+++ b/src/components/status_action_buttons/action_button.scss
@@ -1,132 +1,140 @@
@use "../../mixins";
/* stylelint-disable declaration-no-important */
.quick-action {
justify-content: space-between;
display: flex;
align-items: baseline;
align-items: center;
border: 2px solid transparent;
.action-counter {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
+ &.-counter {
+ justify-self: start;
+ }
+
+ &.-more-actions {
+ justify-self: end;
+ }
+
.action-button-inner,
.extra-button {
padding: 0.5em;
z-index: 1;
}
.separator {
display: block;
align-self: stretch;
width: 1px;
background-color: var(--icon);
opacity: 0.75;
margin: 0.5em 0;
}
.action-button-inner {
display: grid;
gap: 0.125em;
grid-template-columns: max-content;
grid-auto-flow: column;
grid-auto-columns: max-content;
align-items: center;
@include mixins.unfocused-style {
.focus-marker {
visibility: hidden;
}
.active-marker {
visibility: visible;
}
}
@include mixins.focused-style {
.focus-marker {
visibility: visible;
}
.active-marker {
visibility: hidden;
}
}
}
&.-pin {
border: 2px dashed var(--icon);
border-radius: var(--roundness);
grid-template-columns: minmax(max-content, 1fr) auto;
.action-button-inner {
opacity: 0.8;
padding-right: 0;
pointer-events: none;
}
.chevron-icon,
.extra-button,
.separator {
display: none;
}
}
&.-with-extra {
.action-button-inner,
.extra-button {
padding-left: 0.25em;
padding-right: 0.25em;
}
}
}
.action-button {
display: grid;
grid-auto-flow: column;
align-items: center;
padding: 0;
.action-button-inner {
&:hover,
&.-active {
&.reply-button:not(.disabled) {
.svg-inline--fa {
color: var(--cBlue);
}
}
&.retweet-button:not(.disabled) {
.svg-inline--fa {
color: var(--cGreen);
}
}
&.favorite-button:not(.disabled) {
.svg-inline--fa {
color: var(--cOrange);
}
}
}
}
&.-extra {
.action-counter {
justify-self: end;
margin-left: 1em;
}
.chevron-icon {
justify-self: end;
}
.extra-button {
justify-self: end;
justify-content: end;
}
}
}
diff --git a/src/components/status_action_buttons/status_action_buttons.js b/src/components/status_action_buttons/status_action_buttons.js
index ffa9936758..34ff211cb5 100644
--- a/src/components/status_action_buttons/status_action_buttons.js
+++ b/src/components/status_action_buttons/status_action_buttons.js
@@ -1,184 +1,192 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import Popover from 'src/components/popover/popover.vue'
import ActionButtonContainer from './action_button_container.vue'
import { BUTTONS } from './buttons_definitions.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUsersStore } from 'src/stores/users.js'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
library.add(faEllipsisH)
const StatusActionButtons = {
props: {
status: {
type: Object,
required: true,
},
replying: {
type: Boolean,
default: false,
},
fixedPinned: {
type: Boolean,
default: false,
},
pinned: {
type: Set,
},
useDefaultButtons: {
type: Boolean,
default: false,
},
hideLabels: {
type: Boolean,
default: false,
},
inChatView: {
type: Boolean,
default: false,
},
},
emits: ['toggleReplying', 'onSuccess', 'onError'],
data() {
return {
showPin: false,
showingConfirmDialog: false,
currentConfirmTitle: '',
currentConfirmOkText: '',
currentConfirmCancelText: '',
currentConfirmAction: () => {
/* no-op */
},
randomSeed: genRandomSeed(),
emojiPickerShown: false,
}
},
components: {
Popover,
ConfirmModal: defineAsyncComponent(
() => import('src/components/confirm_modal/confirm_modal.vue'),
),
ActionButtonContainer,
},
computed: {
...mapState(useSyncConfigStore, {
userPinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedStatusActions),
}),
pinnedItems() {
if (this.fixedPinned) {
return this.pinned
} else {
return this.userPinnedItems
}
},
buttons() {
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))
},
currentUser() {
return useUsersStore().currentUser
},
funcArg() {
return {
status: this.status,
replying: this.replying,
emojiPickerShown: this.emojiPickerShown,
emit: this.$emit,
router: this.$router,
currentUser: this.currentUser,
loggedIn: !!this.currentUser,
chatView: !!this.inChatView,
}
},
},
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,
)
this.currentConfirmBody = this.$t(
button.confirmStrings(this.funcArg).body,
)
this.currentConfirmAction = () => {
this.showingConfirmDialog = false
this.doActionReal(button)
}
this.showingConfirmDialog = true
} else {
this.doActionReal(button)
}
},
+ quickButtonClass(button) {
+ return {
+ '-pin': this.showPin,
+ '-toggle': button.dropdown?.(),
+ '-with-extra': button.name === 'bookmark',
+ '-counter': button.counter,
+ }
+ },
doActionReal(button) {
const promise = button.action?.(this.funcArg) ?? Promise.resolve()
promise
.then(() => this.$emit('onSuccess'))
.catch((err) => this.$emit('onError', err))
},
onExtraClose() {
this.showPin = false
},
onEmojiPickerShown(state) {
this.emojiPickerShown = state
},
isPinned(button) {
return this.pinnedItems.has(button.name)
},
unpin(button) {
useSyncConfigStore().removeCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useSyncConfigStore().pushSyncConfig()
},
pin(button) {
useSyncConfigStore().addCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useSyncConfigStore().pushSyncConfig()
},
getComponent(button) {
if (!useUsersStore().currentUser && button.anonLink) {
return 'a'
} else if (button.action == null && button.link != null) {
return 'a'
} else {
return 'button'
}
},
getClass(button) {
return {
[button.name + '-button']: true,
disabled: button.interactive
? !button.interactive(this.funcArg)
: false,
'-pin-edit': this.showPin,
'-dropdown': button.dropdown?.(),
'-active': button.active?.(this.funcArg),
}
},
},
}
export default StatusActionButtons
diff --git a/src/components/status_action_buttons/status_action_buttons.scss b/src/components/status_action_buttons/status_action_buttons.scss
index 756f640001..7ed4a42fe4 100644
--- a/src/components/status_action_buttons/status_action_buttons.scss
+++ b/src/components/status_action_buttons/status_action_buttons.scss
@@ -1,28 +1,30 @@
@use "../../mixins";
.StatusActionButtons {
.quick-action-buttons {
display: grid;
margin-left: -0.5em;
- grid-template-columns: repeat(auto-fill, minmax(3.75em, 10%));
+ grid-template-columns: repeat(auto-fit, minmax(3.75em, 10%));
grid-auto-flow: row dense;
grid-auto-rows: 1fr;
+ justify-content: space-between;
+ justify-items: center;
gap: 0.5em 0.1em;
}
.pin-action-button {
display: flex;
z-index: 1;
padding: 0.5em;
margin: 0;
}
}
// popover
.extra-action-buttons {
.extra-action {
margin: 0;
padding-top: 0;
padding-bottom: 0;
padding-right: 0;
}
}
diff --git a/src/components/status_action_buttons/status_action_buttons.vue b/src/components/status_action_buttons/status_action_buttons.vue
index 2426b200d5..4cf996ce2c 100644
--- a/src/components/status_action_buttons/status_action_buttons.vue
+++ b/src/components/status_action_buttons/status_action_buttons.vue
@@ -1,141 +1,141 @@
<template>
<div class="StatusActionButtons">
<span
class="quick-action-buttons"
:class="{ '-pin': showPin }"
role="toolbar"
:aria-label="$t('status.status_actions')"
>
<span
v-for="button in quickButtons"
:key="button.name"
class="quick-action"
role="presentation"
- :class="{ '-pin': showPin, '-toggle': button.dropdown?.(), '-with-extra': button.name === 'bookmark' }"
+ :class="quickButtonClass(button)"
>
<ActionButtonContainer
:class="{ '-pin': showPin }"
:button="button"
:status="status"
:extra="false"
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:close="() => { /* no-op */ }"
:do-action="doAction"
:default-button-style="useDefaultButtons"
:hide-label="hideLabels"
@emoji-picker-shown="onEmojiPickerShown"
/>
<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)"
>
<FAIcon
v-if="showPin && currentUser"
fixed-width
icon="thumbtack"
/>
</button>
</span>
<Popover
trigger="click"
:title="$t('status.more_actions')"
:normal-button="useDefaultButtons"
- class="quick-action"
+ class="quick-action -more-actions"
placement="bottom"
:offset="{ y: 5 }"
remove-padding
@close="onExtraClose"
>
<template #trigger>
<FAIcon
class="action-button-inner"
icon="ellipsis-h"
/>
</template>
<template #content="{close, resize}">
<div
:id="`popup-menu-${randomSeed}`"
class="dropdown-menu extra-action-buttons"
role="menu"
>
<div
v-for="button in extraButtons"
:key="button.name"
class="menu-item dropdown-item extra-action -icon"
:disabled="getClass(button).disabled"
:class="{ disabled: getClass(button).disabled }"
>
<ActionButtonContainer
:button="button"
:status="status"
:extra="true"
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:outer-close="close"
:do-action="doAction"
:default-button-style="useDefaultButtons"
:hide-label="hideLabels"
/>
<button
v-if="showPin && currentUser"
type="button"
class="button-unstyled pin-action-button extra-button"
:title="$t('general.pin')"
:aria-pressed="false"
@click.stop.prevent="pin(button)"
>
<FAIcon
v-if="showPin && currentUser"
fixed-width
class="fa-scale-110"
transform="rotate-45"
icon="thumbtack"
/>
</button>
</div>
<div
v-if="currentUser"
class="menu-item dropdown-item extra-action -icon"
>
<button
class="main-button"
:tabindex="0"
@click.stop="() => { resize(); showPin = !showPin }"
>
<FAIcon
class="fa-scale-110"
fixed-width
icon="wrench"
/><span>{{ $t('nav.edit_pinned') }}</span>
</button>
</div>
</div>
</template>
</Popover>
</span>
<teleport to="#modal">
<ConfirmModal
v-if="showingConfirmDialog"
:title="currentConfirmTitle"
:confirm-text="currentConfirmOkText"
:cancel-text="currentConfirmCancelText"
@accepted="currentConfirmAction"
@cancelled="showingConfirmDialog = false"
>
{{ currentConfirmBody }}
</ConfirmModal>
</teleport>
</div>
</template>
<script src="./status_action_buttons.js"></script>
<style lang="scss" src="./status_action_buttons.scss"></style>

File Metadata

Mime Type
text/x-diff
Expires
Thu, Oct 29, 6:48 AM (14 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1797663
Default Alt Text
(14 KB)

Event Timeline