Merge branch 'fixes-roundup4' into 'develop'

Fixes roundup 4

See merge request pleroma/pleroma-fe!2040
This commit is contained in:
HJ 2025-02-20 10:16:20 +00:00
commit b0af90a629
49 changed files with 341 additions and 299 deletions

View file

@ -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

View file

View file

@ -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",

View file

@ -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;
}

View file

@ -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',

View file

@ -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"
>

View file

@ -2,6 +2,7 @@ export default {
name: 'ButtonUnstyled',
selector: '.button-unstyled',
notEditable: true,
transparent: true,
states: {
toggled: '.toggled',
disabled: ':disabled',

View file

@ -95,6 +95,4 @@
</template>
<script src="./chat.js"></script>
<style lang="scss">
@import "./chat";
</style>
<style src="./chat.scss" lang="scss" />

View file

@ -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" />

View file

@ -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" />

View file

@ -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" />

View file

@ -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;

View file

@ -22,6 +22,7 @@ const ConfirmModal = {
type: String
}
},
emits: ['cancelled', 'accepted'],
computed: {
},
methods: {

View file

@ -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>

View file

@ -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;
}
}
}

View file

@ -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" />

View file

@ -117,9 +117,6 @@ const MentionLink = {
this.highlightType
]
},
useAtIcon () {
return this.mergedConfig.useAtIcon
},
isRemote () {
return this.userName !== this.userNameFull
},

View file

@ -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

View file

@ -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

View file

@ -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"/>

View file

@ -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;

View file

@ -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 ||

View file

@ -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>

View file

@ -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: {

View file

@ -2,6 +2,7 @@ export default {
name: 'RichContent',
selector: '.RichContent',
notEditable: true,
transparent: true,
validInnerComponents: [
'Text',
'FunText',

View file

@ -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: {

View file

@ -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,

View file

@ -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>

View file

@ -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"
@ -362,14 +365,6 @@
{{ $t('settings.mention_link_use_tooltip') }}
</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') }}

View file

@ -65,7 +65,7 @@ export default {
'getClass',
'getComponent',
'doAction',
'close'
'outerClose'
],
components: {
StatusBookmarkFolderMenu,

View file

@ -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;
}

View file

@ -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>

View file

@ -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,

View file

@ -1,4 +1,4 @@
@import "../../mixins";
@use "../../mixins";
.StatusActionButtons {
.quick-action-buttons {

View file

@ -86,7 +86,7 @@
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:close="close"
:outerClose="close"
:do-action="doAction"
/>
<button

View file

@ -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({

View file

@ -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);
}
}

View file

@ -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" />

View file

@ -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,

View file

@ -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

View file

@ -57,7 +57,6 @@ const defaultState = {
embeddedToS: true,
collapseMessageWithSubject: false,
greentext: false,
useAtIcon: false,
mentionLinkDisplay: 'short',
mentionLinkShowTooltip: true,
mentionLinkShowAvatar: false,

View file

@ -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) {

View file

@ -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,32 +90,28 @@ 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`)
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'))
adoptStyleSheets([eagerStyles, lazyStyles])
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 decode theme cache:', e)
console.error('Failed to load theme cache:', e)
return false
}
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'))
adoptStyleSheets([eagerStyles, lazyStyles])
return true
} else {
console.warn('Engine checksum doesn\'t match, cache not usable, clearing')
localStorage.removeItem('pleroma-fe-theme-cache')
}
}
export const applyTheme = (
@ -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) => {

View file

@ -1,2 +0,0 @@
export const sampleRules = [
]

View file

@ -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 => {

View file

@ -12,6 +12,9 @@ export const usePostStatusStore = defineStore('postStatus', {
},
closePostStatusModal () {
this.modalActivated = false
},
resetPostStatusModal () {
this.params = null
}
}
})

View file

@ -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
}

View file

@ -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)
})
})
})

View file

@ -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"