logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/
commit: b0af90a6292f5e31f4f1910e26522b57e0745303
parent bf2101124df7e2e0764a0370c855bd0684a0c919
Author: HJ <30-hj@users.noreply.git.pleroma.social>
Date:   Thu, 20 Feb 2025 10:16:20 +0000

Merge branch 'fixes-roundup4' into 'develop'

Fixes roundup 4

See merge request pleroma/pleroma-fe!2040

Diffstat:

Mbuild/dev-server.js3++-
Achangelog.d/roundup4.skip0
Mpackage.json1-
Msrc/App.scss13++++++-------
Msrc/components/attachment/attachment.style.js4++--
Msrc/components/attachment/attachment.vue18+++++++++---------
Msrc/components/button_unstyled.style.js1+
Msrc/components/chat/chat.vue4+---
Msrc/components/chat_list_item/chat_list_item.vue4+---
Msrc/components/chat_message/chat_message.vue4+---
Msrc/components/chat_new/chat_new.vue5++---
Msrc/components/checkbox/checkbox.vue6+++---
Msrc/components/confirm_modal/confirm_modal.js1+
Msrc/components/confirm_modal/confirm_modal.vue6+++---
Asrc/components/emoji_reactions/emoji_reactions.scss121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/emoji_reactions/emoji_reactions.vue123+------------------------------------------------------------------------------
Msrc/components/mention_link/mention_link.js3---
Msrc/components/mention_link/mention_link.vue7+------
Msrc/components/mobile_post_status_button/mobile_post_status_button.js2+-
Msrc/components/mrf_transparency_panel/mrf_transparency_panel.vue4+---
Msrc/components/popover/popover.scss6++++--
Msrc/components/post_status_form/post_status_form.js6++++++
Msrc/components/post_status_form/post_status_form.vue30+++++++++++++++++-------------
Msrc/components/post_status_modal/post_status_modal.js2+-
Msrc/components/rich_content/rich_content.style.js1+
Msrc/components/root.style.js21---------------------
Msrc/components/settings_modal/settings_modal.js9+++++----
Msrc/components/settings_modal/settings_modal.vue4++--
Msrc/components/settings_modal/tabs/general_tab.vue27+++++++++++----------------
Msrc/components/status_action_buttons/action_button.js2+-
Msrc/components/status_action_buttons/action_button.scss6+++---
Msrc/components/status_action_buttons/action_button.vue5+++--
Msrc/components/status_action_buttons/buttons_definitions.js7++++---
Msrc/components/status_action_buttons/status_action_buttons.scss2+-
Msrc/components/status_action_buttons/status_action_buttons.vue2+-
Msrc/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js9++++++---
Asrc/components/status_bookmark_folder_menu/status_bookmark_folder_menu.scss9+++++++++
Msrc/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue9++++++---
Msrc/components/user_card/user_card.js2+-
Msrc/modules/default_config_state.js1-
Msrc/modules/instance.js1-
Msrc/panel.scss7+++++--
Msrc/services/style_setter/style_setter.js49++++++++++++++++++++-----------------------------
Dsrc/services/theme_data/pleromafe.t3.js2--
Msrc/services/theme_data/theme_data_3.service.js64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Dsrc/stores/postStatus.js17-----------------
Asrc/stores/post_status.js20++++++++++++++++++++
Mstatic/styles/Redmond DX.iss9+++++++++
Mtest/unit/specs/services/theme_data/theme_data3.spec.js8++++----
Myarn.lock5-----
50 files changed, 357 insertions(+), 315 deletions(-)

diff --git a/build/dev-server.js b/build/dev-server.js @@ -53,7 +53,8 @@ Object.keys(proxyTable).forEach(function (context) { if (typeof options === 'string') { options = { target: options } } - app.use(proxyMiddleware.createProxyMiddleware(context, options)) + options.pathFilter = context + app.use(proxyMiddleware.createProxyMiddleware(options)) }) // handle fallback for HTML5 history API diff --git a/changelog.d/roundup4.skip b/changelog.d/roundup4.skip diff --git a/package.json b/package.json @@ -36,7 +36,6 @@ "hash-sum": "^2.0.0", "js-cookie": "3.0.5", "localforage": "1.10.0", - "pako": "^2.1.0", "parse-link-header": "2.0.0", "phoenix": "1.7.19", "pinia": "^2.0.33", diff --git a/src/App.scss b/src/App.scss @@ -1,6 +1,6 @@ // stylelint-disable rscss/class-format /* stylelint-disable no-descending-specificity */ -@import "./panel"; +@use "panel"; :root { --status-margin: 0.75em; @@ -762,12 +762,6 @@ option { margin-left: 0.7em; margin-top: -1em; } - - &.-neutral { - background-color: var(--badgeNeutral); - color: white; - color: var(--badgeNeutralText, white); - } } .alert { @@ -1100,3 +1094,8 @@ option { } } } + +@property --shadow { + syntax: "*"; + inherits: false; +} diff --git a/src/components/attachment/attachment.style.js b/src/components/attachment/attachment.style.js @@ -4,7 +4,7 @@ export default { notEditable: true, validInnerComponents: [ 'Border', - 'ButtonUnstyled', + 'Button', 'Input' ], defaultRules: [ @@ -14,7 +14,7 @@ export default { } }, { - component: 'ButtonUnstyled', + component: 'Button', parent: { component: 'Attachment' }, directives: { background: '#FFFFFF', diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue @@ -1,7 +1,7 @@ <template> <button v-if="usePlaceholder" - class="Attachment -placeholder button-unstyled" + class="Attachment -placeholder button-default" :class="classNames" @click="openModal" > @@ -23,7 +23,7 @@ > <button v-if="remove" - class="button-unstyled attachment-button" + class="button-default attachment-button" @click.prevent="onRemove" > <FAIcon icon="trash-alt" /> @@ -81,7 +81,7 @@ > <button v-if="type === 'flash' && flashLoaded" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.attachment_stop_flash')" @click.prevent="stopFlash" > @@ -89,7 +89,7 @@ </button> <button v-if="attachment.description && size !== 'small' && !edit && type !== 'unknown'" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.show_attachment_description')" @click.prevent="toggleDescription" > @@ -97,7 +97,7 @@ </button> <button v-if="!useModal && type !== 'unknown'" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.show_attachment_in_modal')" @click.prevent="openModalForce" > @@ -105,7 +105,7 @@ </button> <button v-if="nsfw && hideNsfwLocal" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.hide_attachment')" @click.prevent="toggleHidden" > @@ -113,7 +113,7 @@ </button> <button v-if="shiftUp" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.move_up')" @click.prevent="onShiftUp" > @@ -121,7 +121,7 @@ </button> <button v-if="shiftDn" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.move_down')" @click.prevent="onShiftDn" > @@ -129,7 +129,7 @@ </button> <button v-if="remove" - class="button-unstyled attachment-button" + class="button-default attachment-button" :title="$t('status.remove_attachment')" @click.prevent="onRemove" > diff --git a/src/components/button_unstyled.style.js b/src/components/button_unstyled.style.js @@ -2,6 +2,7 @@ export default { name: 'ButtonUnstyled', selector: '.button-unstyled', notEditable: true, + transparent: true, states: { toggled: '.toggled', disabled: ':disabled', diff --git a/src/components/chat/chat.vue b/src/components/chat/chat.vue @@ -95,6 +95,4 @@ </template> <script src="./chat.js"></script> -<style lang="scss"> -@import "./chat"; -</style> +<style src="./chat.scss" lang="scss" /> diff --git a/src/components/chat_list_item/chat_list_item.vue b/src/components/chat_list_item/chat_list_item.vue @@ -47,6 +47,4 @@ <script src="./chat_list_item.js"></script> -<style lang="scss"> -@import "./chat_list_item"; -</style> +<style src="./chat_list_item.scss" lang="scss" /> diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue @@ -98,7 +98,5 @@ </template> <script src="./chat_message.js"></script> -<style lang="scss"> -@import "./chat_message"; -</style> +<style src="./chat_message.scss" lang="scss" /> diff --git a/src/components/chat_new/chat_new.vue b/src/components/chat_new/chat_new.vue @@ -47,6 +47,5 @@ </template> <script src="./chat_new.js"></script> -<style lang="scss"> -@import "./chat_new"; -</style> + +<style src="./chat_new.scss" lang="scss" /> diff --git a/src/components/checkbox/checkbox.vue b/src/components/checkbox/checkbox.vue @@ -63,8 +63,6 @@ export default { </script> <style lang="scss"> -@import "../../mixins"; - .checkbox { position: relative; display: inline-block; @@ -85,6 +83,8 @@ export default { width: 1.2em; height: 1.2em; box-shadow: none; + + --_shadow: var(--shadow); } &-indicator::before { @@ -96,7 +96,7 @@ export default { width: 1.1em; height: 1.1em; border-radius: var(--roundness); - box-shadow: var(--shadow); + box-shadow: var(--_shadow); background-color: var(--background); vertical-align: top; text-align: center; diff --git a/src/components/confirm_modal/confirm_modal.js b/src/components/confirm_modal/confirm_modal.js @@ -22,6 +22,7 @@ const ConfirmModal = { type: String } }, + emits: ['cancelled', 'accepted'], computed: { }, methods: { diff --git a/src/components/confirm_modal/confirm_modal.vue b/src/components/confirm_modal/confirm_modal.vue @@ -1,8 +1,8 @@ <template> - <dialog-modal + <DialogModal v-body-scroll-lock="true" class="confirm-modal" - :on-cancel="onCancel" + @cancel="onCancel" > <template #header> <span v-text="title" /> @@ -23,7 +23,7 @@ v-text="cancelText" /> </template> - </dialog-modal> + </DialogModal> </template> <script src="./confirm_modal.js"></script> diff --git a/src/components/emoji_reactions/emoji_reactions.scss b/src/components/emoji_reactions/emoji_reactions.scss @@ -0,0 +1,121 @@ +@use "../../mixins"; + +.EmojiReactions { + display: flex; + margin-top: 0.25em; + flex-wrap: wrap; + + --emoji-size: calc(var(--emojiSize, 1.25em) * var(--emojiReactionsScale, 1)); + + .emoji-reaction-container { + display: flex; + align-items: stretch; + margin-top: 0.5em; + margin-right: 0.5em; + + .emoji-reaction-popover { + padding: 0; + + .emoji-reaction-count-button { + margin: 0; + height: 100%; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + box-sizing: border-box; + min-width: 2em; + display: inline-flex; + justify-content: center; + align-items: center; + } + } + } + + .emoji-reaction { + padding-left: 0.5em; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + border-top-right-radius: 0; + border-bottom-right-radius: 0; + margin: 0; + + .reaction-emoji { + width: var(--emoji-size); + height: var(--emoji-size); + margin-right: 0.25em; + line-height: var(--emoji-size); + display: flex; + justify-content: center; + align-items: center; + + --_still_image-label-scale: 0.3; + } + + .reaction-emoji-content { + max-width: 100%; + max-height: 100%; + width: var(--emoji-size); + height: var(--emoji-size); + line-height: inherit; + overflow: hidden; + font-size: calc(var(--emoji-size) * 0.8); + margin: 0; + + img { + object-fit: contain; + } + } + + &:focus { + outline: none; + } + + .svg-inline--fa { + color: var(--text); + } + + &.-picked-reaction { + .svg-inline--fa { + color: var(--accent); + } + } + + @include mixins.unfocused-style { + .focus-marker { + visibility: hidden; + } + + .active-marker { + visibility: visible; + } + } + + @include mixins.focused-style { + .svg-inline--fa { + color: var(--accent); + } + + .focus-marker { + visibility: visible; + } + + .active-marker { + visibility: hidden; + } + } + } + + .emoji-reaction-expand { + padding: 0 0.5em; + margin-right: 0.5em; + margin-top: 0.5em; + display: flex; + align-items: center; + justify-content: center; + + &:hover { + text-decoration: underline; + } + } +} diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue @@ -70,126 +70,5 @@ </template> <script src="./emoji_reactions.js"></script> -<style lang="scss"> -@import "../../mixins"; -.EmojiReactions { - display: flex; - margin-top: 0.25em; - flex-wrap: wrap; - - --emoji-size: calc(var(--emojiSize, 1.25em) * var(--emojiReactionsScale, 1)); - - .emoji-reaction-container { - display: flex; - align-items: stretch; - margin-top: 0.5em; - margin-right: 0.5em; - - .emoji-reaction-popover { - padding: 0; - - .emoji-reaction-count-button { - margin: 0; - height: 100%; - border-top-left-radius: 0; - border-bottom-left-radius: 0; - box-sizing: border-box; - min-width: 2em; - display: inline-flex; - justify-content: center; - align-items: center; - } - } - } - - .emoji-reaction { - padding-left: 0.5em; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - border-top-right-radius: 0; - border-bottom-right-radius: 0; - margin: 0; - - .reaction-emoji { - width: var(--emoji-size); - height: var(--emoji-size); - margin-right: 0.25em; - line-height: var(--emoji-size); - display: flex; - justify-content: center; - align-items: center; - - --_still_image-label-scale: 0.3; - } - - .reaction-emoji-content { - max-width: 100%; - max-height: 100%; - width: var(--emoji-size); - height: var(--emoji-size); - line-height: inherit; - overflow: hidden; - font-size: calc(var(--emoji-size) * 0.8); - margin: 0; - - img { - object-fit: contain; - } - } - - &:focus { - outline: none; - } - - .svg-inline--fa { - color: var(--text); - } - - &.-picked-reaction { - .svg-inline--fa { - color: var(--accent); - } - } - - @include unfocused-style { - .focus-marker { - visibility: hidden; - } - - .active-marker { - visibility: visible; - } - } - - @include focused-style { - .svg-inline--fa { - color: var(--accent); - } - - .focus-marker { - visibility: visible; - } - - .active-marker { - visibility: hidden; - } - } - } - - .emoji-reaction-expand { - padding: 0 0.5em; - margin-right: 0.5em; - margin-top: 0.5em; - display: flex; - align-items: center; - justify-content: center; - - &:hover { - text-decoration: underline; - } - } -} -</style> +<style src="./emoji_reactions.scss" lang="scss" /> diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js @@ -117,9 +117,6 @@ const MentionLink = { this.highlightType ] }, - useAtIcon () { - return this.mergedConfig.useAtIcon - }, isRemote () { return this.userName !== this.userNameFull }, diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue @@ -34,12 +34,7 @@ :user="user" /><span class="shortName" - ><FAIcon - v-if="useAtIcon" - size="sm" - icon="at" - class="at" - />{{ !useAtIcon ? '@' : '' }}<span + >@<span class="userName" v-html="userName" /><span diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.js b/src/components/mobile_post_status_button/mobile_post_status_button.js @@ -3,7 +3,7 @@ import { library } from '@fortawesome/fontawesome-svg-core' import { faPen } from '@fortawesome/free-solid-svg-icons' -import { usePostStatusStore } from 'src/stores/postStatus' +import { usePostStatusStore } from 'src/stores/post_status' library.add( faPen diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.vue b/src/components/mrf_transparency_panel/mrf_transparency_panel.vue @@ -238,6 +238,4 @@ <script src="./mrf_transparency_panel.js"></script> -<style lang="scss"> -@import "./mrf_transparency_panel"; -</style> +<style src="./mrf_transparency_panel.scss" lang="scss"/> diff --git a/src/components/popover/popover.scss b/src/components/popover/popover.scss @@ -7,7 +7,8 @@ position: fixed; min-width: 0; max-width: calc(100vw - 20px); - box-shadow: var(--shadow); + + --_shadow: var(--shadow); } .popover-default { @@ -19,7 +20,7 @@ left: -1px; right: -1px; z-index: -1px; - box-shadow: var(--shadow); + box-shadow: var(--_shadow); pointer-events: none; } @@ -54,6 +55,7 @@ grid-template-columns: 1fr; grid-auto-flow: column; grid-auto-columns: auto; + grid-gap: 0.5em; .popover-wrapper { box-sizing: border-box; diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js @@ -363,6 +363,12 @@ const PostStatusForm = { } }, safeToSaveDraft () { + console.log('safe', ( + this.newStatus.status || + this.newStatus.spoilerText || + this.newStatus.files?.length || + this.newStatus.hasPoll + ) && this.saveable) return ( this.newStatus.status || this.newStatus.spoilerText || diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue @@ -334,22 +334,26 @@ class="dropdown-menu" role="menu" > - <button - v-if="!hideDraft || !disableDraft" + <div class="menu-item dropdown-item" - role="menu" - :disabled="!safeToSaveDraft && saveable" :class="{ disabled: !safeToSaveDraft }" - @click.prevent="saveDraft" - @click="close" > - <template v-if="closeable"> - {{ $t('post_status.save_to_drafts_and_close_button') }} - </template> - <template v-else> - {{ $t('post_status.save_to_drafts_button') }} - </template> - </button> + <button + v-if="!hideDraft || !disableDraft" + class="main-button" + role="menu" + :disabled="!safeToSaveDraft" + @click.prevent="saveDraft" + @click="close" + > + <template v-if="closeable"> + {{ $t('post_status.save_to_drafts_and_close_button') }} + </template> + <template v-else> + {{ $t('post_status.save_to_drafts_button') }} + </template> + </button> + </div> </div> </template> </Popover> diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js @@ -1,7 +1,7 @@ import PostStatusForm from '../post_status_form/post_status_form.vue' import Modal from '../modal/modal.vue' import get from 'lodash/get' -import { usePostStatusStore } from 'src/stores/postStatus' +import { usePostStatusStore } from 'src/stores/post_status' const PostStatusModal = { components: { diff --git a/src/components/rich_content/rich_content.style.js b/src/components/rich_content/rich_content.style.js @@ -2,6 +2,7 @@ export default { name: 'RichContent', selector: '.RichContent', notEditable: true, + transparent: true, validInnerComponents: [ 'Text', 'FunText', diff --git a/src/components/root.style.js b/src/components/root.style.js @@ -2,27 +2,6 @@ export default { name: 'Root', selector: ':root', notEditable: true, - validInnerComponents: [ - // These are purely for --parent--text et such to work - 'Text', - 'Link', - 'Border', - - 'Underlay', - 'Modals', - 'Popover', - 'TopBar', - 'Scrollbar', - 'ScrollbarElement', - 'MobileDrawer', - 'Alert', - 'Button' // mobile post button - ], - validInnerComponentsLite: [ - 'Underlay', - 'Scrollbar', - 'ScrollbarElement' - ], defaultRules: [ { directives: { diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js @@ -7,7 +7,7 @@ import Checkbox from 'src/components/checkbox/checkbox.vue' import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { cloneDeep, isEqual } from 'lodash' -import { mapState as mapPiniaState } from 'pinia' +import { mapState, mapActions } from 'pinia' import { newImporter, newExporter @@ -165,11 +165,12 @@ const SettingsModal = { }, pushAdminDraft () { this.$store.dispatch('pushAdminDraft') - } + }, + ...mapActions(useInterfaceStore, ['temporaryChangesRevert', 'temporaryChangesConfirm']) }, computed: { - ...mapPiniaState(useInterfaceStore, { - temporaryChangesTimeoutId: store => store.layoutType === 'mobile', + ...mapState(useInterfaceStore, { + temporaryChangesTimeoutId: store => store.temporaryChangesTimeoutId, currentSaveStateNotice: store => store.settings.currentSaveStateNotice, modalActivated: store => store.settingsModalState !== 'hidden', modalMode: store => store.settingsModalMode, diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue @@ -162,8 +162,8 @@ :title="$t('settings.confirm_new_setting')" :cancel-text="$t('settings.revert')" :confirm-text="$t('settings.confirm')" - @cancelled="$store.state.interface.temporaryChangesRevert" - @accepted="$store.state.interface.temporaryChangesConfirm" + @cancelled="temporaryChangesRevert" + @accepted="temporaryChangesConfirm" > {{ $t('settings.confirm_new_question') }} </ConfirmModal> diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue @@ -269,14 +269,17 @@ {{ $t('settings.image_compression') }} </BooleanSetting> </li> - <li> - <BooleanSetting - path="alwaysUseJpeg" - expert="1" - > - {{ $t('settings.always_use_jpeg') }} - </BooleanSetting> - </li> + <ul class="setting-list suboptions"> + <li> + <BooleanSetting + path="alwaysUseJpeg" + expert="1" + parent-path="imageCompression" + > + {{ $t('settings.always_use_jpeg') }} + </BooleanSetting> + </li> + </ul> <li> <BooleanSetting path="useContainFit" @@ -363,14 +366,6 @@ </BooleanSetting> </li> <li> - <BooleanSetting - path="useAtIcon" - expert="1" - > - {{ $t('settings.use_at_icon') }} - </BooleanSetting> - </li> - <li> <BooleanSetting path="mentionLinkShowAvatar"> {{ $t('settings.mention_link_show_avatar') }} </BooleanSetting> diff --git a/src/components/status_action_buttons/action_button.js b/src/components/status_action_buttons/action_button.js @@ -65,7 +65,7 @@ export default { 'getClass', 'getComponent', 'doAction', - 'close' + 'outerClose' ], components: { StatusBookmarkFolderMenu, diff --git a/src/components/status_action_buttons/action_button.scss b/src/components/status_action_buttons/action_button.scss @@ -1,4 +1,4 @@ -@import "../../mixins"; +@use "../../mixins"; /* stylelint-disable declaration-no-important */ .quick-action { @@ -52,7 +52,7 @@ grid-auto-columns: max-content; align-items: center; - @include unfocused-style { + @include mixins.unfocused-style { .focus-marker { visibility: hidden; } @@ -62,7 +62,7 @@ } } - @include focused-style { + @include mixins.focused-style { .focus-marker { visibility: visible; } diff --git a/src/components/status_action_buttons/action_button.vue b/src/components/status_action_buttons/action_button.vue @@ -14,7 +14,7 @@ :tabindex="0" :disabled="buttonClass.disabled" :href="getComponent(button) == 'a' ? button.link?.(funcArg) || remoteInteractionLink : undefined" - @click="doActionWrap(button, close)" + @click="doActionWrap(button, outerClose)" > <FALayers> <FAIcon @@ -84,10 +84,11 @@ fixed-width /> </template> - <template #content> + <template #content="{close}"> <StatusBookmarkFolderMenu v-if="button.name === 'bookmark'" :status="status" + :close="() => { close(); outerClose() }" /> </template> </Popover> diff --git a/src/components/status_action_buttons/buttons_definitions.js b/src/components/status_action_buttons/buttons_definitions.js @@ -1,3 +1,4 @@ +import { useEditStatusStore } from 'src/stores/editStatus.js' const PRIVATE_SCOPES = new Set(['private', 'direct']) const PUBLIC_SCOPES = new Set(['public', 'unlisted']) export const BUTTONS = [{ @@ -111,9 +112,9 @@ export const BUTTONS = [{ }, action ({ status, dispatch }) { if (status.pinned) { - return dispatch('unpinStatus', { id: status.id }) + return dispatch('unpinStatus', status.id) } else { - return dispatch('pinStatus', { id: status.id }) + return dispatch('pinStatus', status.id) } } }, { @@ -151,7 +152,7 @@ export const BUTTONS = [{ }, action ({ dispatch, status }) { return dispatch('fetchStatusSource', { id: status.id }) - .then(data => dispatch('openEditStatusModal', { + .then(data => useEditStatusStore().openEditStatusModal({ statusId: status.id, subject: data.spoiler_text, statusText: data.text, diff --git a/src/components/status_action_buttons/status_action_buttons.scss b/src/components/status_action_buttons/status_action_buttons.scss @@ -1,4 +1,4 @@ -@import "../../mixins"; +@use "../../mixins"; .StatusActionButtons { .quick-action-buttons { diff --git a/src/components/status_action_buttons/status_action_buttons.vue b/src/components/status_action_buttons/status_action_buttons.vue @@ -86,7 +86,7 @@ :func-arg="funcArg" :get-class="getClass" :get-component="getComponent" - :close="close" + :outerClose="close" :do-action="doAction" /> <button diff --git a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js @@ -2,19 +2,22 @@ import { library } from '@fortawesome/fontawesome-svg-core' import { faChevronRight, faFolder } from '@fortawesome/free-solid-svg-icons' import { mapState } from 'vuex' -import Popover from '../popover/popover.vue' +import Popover from 'src/components/popover/popover.vue' +import StillImage from 'src/components/still-image/still-image.vue' library.add(faChevronRight, faFolder) const StatusBookmarkFolderMenu = { props: [ - 'status' + 'status', + 'close' ], data () { return {} }, components: { - Popover + Popover, + StillImage }, computed: { ...mapState({ diff --git a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.scss b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.scss @@ -0,0 +1,9 @@ +.bookmark-folder-menu { + --__horizontal-gap: 0.5em; + --_still-image-label-visibility: hidden; + + .emoji { + width: var(--__line-height); + height: var(--__line-height); + } +} diff --git a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue @@ -1,22 +1,25 @@ <template> - <div class="dropdown-menu"> + <div class="dropdown-menu bookmark-folder-menu"> <div v-for="folder in folders" :key="folder.id" - class="menu-item dropdown-item -icon" + class="menu-item dropdown-item -icon-double" > <button class="main-button" @click="toggleFolder(folder.id)" + @click.stop="close" > <span class="input menu-checkbox -radio" :class="{ 'menu-checkbox-checked': status.bookmark_folder_id == folder.id }" /> - {{ folder.name }} + <StillImage :src="folder.emoji_url" class="emoji" /> + {{ ' ' + folder.name }} </button> </div> </div> </template> <script src="./status_bookmark_folder_menu.js"></script> +<stlye src="./status_bookmark_folder_menu.scss" /> diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js @@ -11,7 +11,7 @@ import RichContent from 'src/components/rich_content/rich_content.jsx' import MuteConfirm from '../confirm_modal/mute_confirm.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import { mapGetters } from 'vuex' -import { usePostStatusStore } from 'src/stores/postStatus' +import { usePostStatusStore } from 'src/stores/post_status' import { library } from '@fortawesome/fontawesome-svg-core' import { faBell, diff --git a/src/modules/default_config_state.js b/src/modules/default_config_state.js @@ -129,7 +129,6 @@ export const defaultState = { forcedRoundness: undefined, // instance default navbarColumnStretch: false, greentext: undefined, // instance default - useAtIcon: undefined, // instance default mentionLinkDisplay: undefined, // instance default mentionLinkShowTooltip: undefined, // instance default mentionLinkShowAvatar: undefined, // instance default diff --git a/src/modules/instance.js b/src/modules/instance.js @@ -57,7 +57,6 @@ const defaultState = { embeddedToS: true, collapseMessageWithSubject: false, greentext: false, - useAtIcon: false, mentionLinkDisplay: 'short', mentionLinkShowTooltip: true, mentionLinkShowAvatar: false, diff --git a/src/panel.scss b/src/panel.scss @@ -2,6 +2,7 @@ .panel { --__panel-background: var(--background); --__panel-backdrop-filter: var(--backdrop-filter); + --_shadow: var(--shadow); .tab-switcher .tabs { background: var(--__panel-background); @@ -29,7 +30,7 @@ left: 0; right: 0; z-index: 5; - box-shadow: var(--shadow); + box-shadow: var(--_shadow); pointer-events: none; } } @@ -154,11 +155,13 @@ linear-gradient(to bottom, var(--background), var(--background)), linear-gradient(to bottom, var(--__panel-background), var(--__panel-background)); + --_shadow: var(--shadow); + &::after { background-color: var(--background); z-index: -2; border-radius: var(--roundness) var(--roundness) 0 0; - box-shadow: var(--shadow); + box-shadow: var(--_shadow); } &:not(.-flexible-height) { diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js @@ -2,11 +2,8 @@ import { init, getEngineChecksum } from '../theme_data/theme_data_3.service.js' import { getCssRules } from '../theme_data/css_utils.js' import { defaultState } from 'src/modules/default_config_state.js' import { chunk } from 'lodash' -import pako from 'pako' import localforage from 'localforage' -console.log('CONFIG', defaultState) - // On platforms where this is not supported, it will return undefined // Otherwise it will return an array const supportsAdoptedStyleSheets = !!document.adoptedStyleSheets @@ -93,31 +90,27 @@ export const generateTheme = (inputRuleset, callbacks, debug) => { export const tryLoadCache = async () => { console.info('Trying to load compiled theme data from cache') - const data = await localforage.getItem('pleromafe-theme-cache') - if (!data) return null - let cache + const cache = await localforage.getItem('pleromafe-theme-cache') + if (!cache) return null try { - const inflated = pako.inflate(data) - const decoded = new TextDecoder().decode(inflated) - cache = JSON.parse(decoded) - console.info(`Loaded theme from cache, compressed=${Math.ceil(data.length / 1024)}kiB size=${Math.ceil(inflated.length / 1024)}kiB`) - } catch (e) { - console.error('Failed to decode theme cache:', e) - return false - } - if (cache.engineChecksum === getEngineChecksum()) { - const eagerStyles = createStyleSheet(EAGER_STYLE_ID) - const lazyStyles = createStyleSheet(LAZY_STYLE_ID) + if (cache.engineChecksum === getEngineChecksum()) { + const eagerStyles = createStyleSheet(EAGER_STYLE_ID) + const lazyStyles = createStyleSheet(LAZY_STYLE_ID) - cache.data[0].forEach(rule => eagerStyles.sheet.insertRule(rule, 'index-max')) - cache.data[1].forEach(rule => lazyStyles.sheet.insertRule(rule, 'index-max')) + cache.data[0].forEach(rule => eagerStyles.sheet.insertRule(rule, 'index-max')) + cache.data[1].forEach(rule => lazyStyles.sheet.insertRule(rule, 'index-max')) - adoptStyleSheets([eagerStyles, lazyStyles]) + adoptStyleSheets([eagerStyles, lazyStyles]) - return true - } else { - console.warn('Engine checksum doesn\'t match, cache not usable, clearing') - localStorage.removeItem('pleroma-fe-theme-cache') + console.info(`Loaded theme from cache`) + return true + } else { + console.warn('Engine checksum doesn\'t match, cache not usable, clearing') + localStorage.removeItem('pleroma-fe-theme-cache') + } + } catch (e) { + console.error('Failed to load theme cache:', e) + return false } } @@ -157,15 +150,14 @@ export const applyTheme = ( onEagerFinished () { adoptStyleSheets([eagerStyles]) onEagerFinish() + console.info('Eager part of theme finished, waiting for lazy part to finish to store cache') }, onLazyFinished () { adoptStyleSheets([eagerStyles, lazyStyles]) const cache = { engineChecksum: getEngineChecksum(), data: [eagerStyles.rules, lazyStyles.rules] } onFinish(cache) - const compress = (js) => { - return pako.deflate(JSON.stringify(js)) - } - localforage.setItem('pleromafe-theme-cache', compress(cache)) + localforage.setItem('pleromafe-theme-cache', cache) + console.info('Theme cache stored') } }, debug @@ -214,7 +206,6 @@ const extractStyleConfig = ({ return result } -console.log(defaultState) const defaultStyleConfig = extractStyleConfig(defaultState) export const applyConfig = (input) => { diff --git a/src/services/theme_data/pleromafe.t3.js b/src/services/theme_data/pleromafe.t3.js @@ -1,2 +0,0 @@ -export const sampleRules = [ -] diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js @@ -32,9 +32,12 @@ const components = { Link: null, Icon: null, Border: null, + PanelHeader: null, + Attachment: null, Panel: null, Chat: null, - ChatMessage: null + ChatMessage: null, + Button: null } export const findShadow = (shadows, { dynamicVars, staticVars }) => { @@ -152,6 +155,25 @@ componentsContext.keys().forEach(key => { components[component.name] = component }) +Object.keys(components).forEach(key => { + if (key === 'Root') return + components.Root.validInnerComponents = components.Root.validInnerComponents || [] + components.Root.validInnerComponents.push(key) +}) + +Object.keys(components).forEach(key => { + const component = components[key] + const { validInnerComponents = [] } = component + validInnerComponents.forEach(inner => { + const child = components[inner] + component.possibleChildren = component.possibleChildren || [] + component.possibleChildren.push(child) + child.possibleParents = child.possibleParents || [] + child.possibleParents.push(component) + }) +}) + + const engineChecksum = sum(components) const ruleToSelector = genericRuleToSelector(components) @@ -244,7 +266,21 @@ export const init = ({ } const virtualComponents = new Set(Object.values(components).filter(c => c.virtual).map(c => c.name)) + const transparentComponents = new Set(Object.values(components).filter(c => c.transparent).map(c => c.name)) const nonEditableComponents = new Set(Object.values(components).filter(c => c.notEditable).map(c => c.name)) + const extraCompileComponents = new Set([]) + + Object.values(components).forEach(component => { + const relevantRules = ruleset.filter(r => r.component === component.name) + const backgrounds = relevantRules.map(r => r.directives.background).filter(x => x) + const opacities = relevantRules.map(r => r.directives.opacity).filter(x => x) + if ( + backgrounds.some(x => x.match(/--parent/)) || + opacities.some(x => x != null && x < 1)) + { + extraCompileComponents.add(component.name) + } + }) const processCombination = (combination) => { try { @@ -473,11 +509,21 @@ export const init = ({ let validInnerComponents if (editMode) { const temp = (component.validInnerComponentsLite || component.validInnerComponents || []) - validInnerComponents = temp.filter(c => virtualComponents.has(c) && !nonEditableComponents.has(c)) + validInnerComponents = temp + .filter(c => virtualComponents.has(c) && !nonEditableComponents.has(c)) } else if (liteMode) { validInnerComponents = (component.validInnerComponentsLite || component.validInnerComponents || []) - } else { + } else if (component.name === 'Root') { validInnerComponents = component.validInnerComponents || [] + } else { + validInnerComponents = component + .validInnerComponents + ?.filter( + c => virtualComponents.has(c) + || transparentComponents.has(c) + || extraCompileComponents.has(c) + ) + || [] } // Normalizing states and variants to always include "normal" @@ -491,7 +537,7 @@ export const init = ({ // Optimization: we only really need combinations without "normal" because all states implicitly have it const permutationStateKeys = Object.keys(states).filter(s => s !== 'normal') - const stateCombinations = onlyNormalState + const stateCombinations = (onlyNormalState && !virtualComponents.has(component.name)) ? [ ['normal'] ] @@ -524,6 +570,16 @@ export const init = ({ combination.lazy = true } + if ( + !liteMode && + parent?.component !== 'Root' && + !virtualComponents.has(component.name) && + !transparentComponents.has(component.name) && + extraCompileComponents.has(component.name) + ) { + combination.lazy = true + } + combinations.push(combination) innerComponents.forEach(innerComponent => { diff --git a/src/stores/postStatus.js b/src/stores/postStatus.js @@ -1,17 +0,0 @@ -import { defineStore } from 'pinia' - -export const usePostStatusStore = defineStore('postStatus', { - state: () => ({ - params: null, - modalActivated: false - }), - actions: { - openPostStatusModal (params) { - this.params = params - this.modalActivated = true - }, - closePostStatusModal () { - this.modalActivated = false - } - } -}) diff --git a/src/stores/post_status.js b/src/stores/post_status.js @@ -0,0 +1,20 @@ +import { defineStore } from 'pinia' + +export const usePostStatusStore = defineStore('postStatus', { + state: () => ({ + params: null, + modalActivated: false + }), + actions: { + openPostStatusModal (params) { + this.params = params + this.modalActivated = true + }, + closePostStatusModal () { + this.modalActivated = false + }, + resetPostStatusModal () { + this.params = null + } + } +}) diff --git a/static/styles/Redmond DX.iss b/static/styles/Redmond DX.iss @@ -167,3 +167,12 @@ Tab:hover:active { TopBar Link { textColor: #ffffff } + +MenuItem:hover { + background: --fg +} + +Popover { + shadow: --buttonDefaultBevel, 5 5 0 0 #000000 / 0.2; + roundness: 0 +} diff --git a/test/unit/specs/services/theme_data/theme_data3.spec.js b/test/unit/specs/services/theme_data/theme_data3.spec.js @@ -1,4 +1,3 @@ -// import { topoSort } from 'src/services/theme_data/theme_data.service.js' import { getAllPossibleCombinations } from 'src/services/theme_data/iss_utils.js' @@ -120,6 +119,7 @@ describe('Theme Data 3', () => { opacity: 0.5 } }], + onlyNormalState: true, ultimateBackgroundColor: '#DEADAF' }) @@ -142,9 +142,9 @@ describe('Theme Data 3', () => { */ - expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.r').that.is.closeTo(88.8, 0.01) - expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.g').that.is.closeTo(133.2, 0.01) - expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.b').that.is.closeTo(134, 0.01) + expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.r').that.is.closeTo(111, 0.01) + expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.g').that.is.closeTo(150.5, 0.01) + expect(panelRule).to.have.nested.deep.property('dynamicVars.stacked.b').that.is.closeTo(151.5, 0.01) }) }) }) diff --git a/yarn.lock b/yarn.lock @@ -6614,11 +6614,6 @@ package-json-from-dist@^1.0.0: resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== -pako@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" - integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== - pako@~1.0.2: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"