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: f4d29b5d5ec741991a5228c478f2dc4a7e24f2d1
parent 21b17f333dd9e24b51d14f63795e27216c970385
Author: Henry Jameson <me@hjkos.com>
Date:   Fri, 18 Oct 2024 13:43:33 +0300

use draft logic for virtualDirective to catch errors

Diffstat:

Msrc/components/select/select_motion.vue2+-
Msrc/components/settings_modal/tabs/style_tab/style_tab.js69++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/components/settings_modal/tabs/style_tab/style_tab.vue10+++++-----
Msrc/services/theme_data/iss_deserializer.js18+++++++++++-------
Msrc/services/theme_data/iss_serializer.js7++++++-
Msrc/services/theme_data/theme_data_3.service.js4++--
6 files changed, 73 insertions(+), 37 deletions(-)

diff --git a/src/components/select/select_motion.vue b/src/components/select/select_motion.vue @@ -4,7 +4,7 @@ > <button class="btn button-default" - :disabled="disabled || shadowsAreNull" + :disabled="disabled" @click="add" > <FAIcon diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -21,7 +21,7 @@ import { getScopedVersion } from 'src/services/theme_data/css_utils.js' import { serializeShadow, serialize } from 'src/services/theme_data/iss_serializer.js' -import { parseShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js' +import { deserializeShadow, deserialize } from 'src/services/theme_data/iss_deserializer.js' import { rgb2hex, hex2rgb, @@ -371,7 +371,11 @@ export default { return shadow } if (typeof shadow === 'string') { - return parseShadow(shadow) + try { + return deserializeShadow(shadow) + } catch (e) { + console.warn(e) + } } return null }) @@ -580,6 +584,7 @@ export default { const selectedVirtualDirectiveId = ref(0) exports.selectedVirtualDirectiveId = selectedVirtualDirectiveId + const selectedVirtualDirective = computed({ get () { return virtualDirectives[selectedVirtualDirectiveId.value] @@ -589,6 +594,7 @@ export default { } }) exports.selectedVirtualDirective = selectedVirtualDirective + exports.selectedVirtualDirectiveValType = computed({ get () { return virtualDirectives[selectedVirtualDirectiveId.value].valType @@ -607,35 +613,56 @@ export default { } } }) - exports.selectedVirtualDirectiveParsed = computed({ - get () { - switch (selectedVirtualDirective.value.valType) { + + const draftVirtualDirectiveValid = ref(true) + const draftVirtualDirective = ref({}) + exports.draftVirtualDirective = draftVirtualDirective + + watch( + selectedVirtualDirective, + (directive) => { + switch (directive.valType) { case 'shadow': { - const directiveValue = selectedVirtualDirective.value.value - if (Array.isArray(directiveValue)) { - return normalizeShadows(directiveValue) + if (Array.isArray(directive.value)) { + draftVirtualDirective.value = normalizeShadows(directive.value) } else { - const splitShadow = directiveValue.split(/,/g).map(x => x.trim()) - return normalizeShadows(splitShadow) + const splitShadow = directive.value.split(/,/g).map(x => x.trim()) + draftVirtualDirective.value = normalizeShadows(splitShadow) } + break } case 'color': - return selectedVirtualDirective.value.value + draftVirtualDirective.value = directive.value + break default: - return selectedVirtualDirective.value.value + draftVirtualDirective.value = directive.value + break } }, - set (value) { - switch (selectedVirtualDirective.value.valType) { - case 'shadow': { - virtualDirectives[selectedVirtualDirectiveId.value].value = value.map(x => serializeShadow(x)).join(', ') - break + { immediate: true } + ) + + watch( + draftVirtualDirective, + (directive) => { + try { + switch (selectedVirtualDirective.value.valType) { + case 'shadow': { + virtualDirectives[selectedVirtualDirectiveId.value].value = + directive.map(x => serializeShadow(x)).join(', ') + break + } + default: + virtualDirectives[selectedVirtualDirectiveId.value].value = directive } - default: - virtualDirectives[selectedVirtualDirectiveId.value].value = value + draftVirtualDirectiveValid.value = true + } catch (e) { + console.error('Invalid virtual directive value', e) + draftVirtualDirectiveValid.value = false } - } - }) + }, + { immediate: true } + ) exports.getNewVirtualDirective = () => ({ name: 'newDirective', diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.vue b/src/components/settings_modal/tabs/style_tab/style_tab.vue @@ -285,7 +285,7 @@ :disabled="!isShadowPresent" :no-preview="true" :compact="true" - :separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'" + :compute-color="computeColor" @subShadowSelected="onSubShadow" /> </div> @@ -408,14 +408,14 @@ </div> <ShadowControl v-if="selectedVirtualDirectiveValType === 'shadow'" - v-model="selectedVirtualDirectiveParsed" - :computeColor="computeColor" + v-model="draftVirtualDirective" + :compute-color="computeColor" :compact="true" /> <ColorInput v-if="selectedVirtualDirectiveValType === 'color'" - v-model="selectedVirtualDirectiveParsed" - :fallback="computeColor(selectedVirtualDirectiveParsed)" + v-model="draftVirtualDirective" + :fallback="computeColor(draftVirtualDirective)" :label="$t('settings.style.themes3.editor.variables.virtual_color')" /> </div> diff --git a/src/services/theme_data/iss_deserializer.js b/src/services/theme_data/iss_deserializer.js @@ -1,10 +1,11 @@ import { flattenDeep } from 'lodash' -export const parseShadow = string => { - const modes = ['_full', 'inset', 'x', 'y', 'blur', 'spread', 'color', 'alpha'] +export const deserializeShadow = string => { + const modes = ['_full', 'inset', 'x', 'y', 'blur', 'spread', 'color', 'alpha', 'name'] const regexPrep = [ // inset keyword (optional) - '^(?:(inset)\\s+)?', + '^', + '(?:(inset)\\s+)?', // x '(?:(-?[0-9]+(?:\\.[0-9]+)?)\\s+)', // y @@ -16,7 +17,10 @@ export const parseShadow = string => { // either hex, variable or function '(#[0-9a-f]{6}|--[a-z\\-_]+|\\$[a-z\\-()_]+)', // opacity (optional) - '(?:\\s+\\/\\s+([0-9]+(?:\\.[0-9]+)?)\\s*)?$' + '(?:\\s+\\/\\s+([0-9]+(?:\\.[0-9]+)?)\\s*)?', + // name + '(?:\\s+#(\\w+)\\s*)?', + '$' ].join('') const regex = new RegExp(regexPrep, 'gis') // global, (stable) indices, single-string const result = regex.exec(string) @@ -28,7 +32,7 @@ export const parseShadow = string => { } } else { const numeric = new Set(['x', 'y', 'blur', 'spread', 'alpha']) - const { x, y, blur, spread, alpha, inset, color } = Object.fromEntries(modes.map((mode, i) => { + const { x, y, blur, spread, alpha, inset, color, name } = Object.fromEntries(modes.map((mode, i) => { if (numeric.has(mode)) { const number = Number(result[i]) if (Number.isNaN(number)) { @@ -43,7 +47,7 @@ export const parseShadow = string => { } }).filter(([k, v]) => v !== false).slice(1)) - return { x, y, blur, spread, color, alpha, inset } + return { x, y, blur, spread, color, alpha, inset, name } } } // this works nearly the same as HTML tree converter @@ -150,7 +154,7 @@ export const deserialize = (input) => { if (realValue === 'none') { realValue = [] } else { - realValue = value.split(',').map(v => parseShadow(v.trim())) + realValue = value.split(',').map(v => deserializeShadow(v.trim())) } } if (!Number.isNaN(Number(value))) { realValue = Number(value) diff --git a/src/services/theme_data/iss_serializer.js b/src/services/theme_data/iss_serializer.js @@ -1,8 +1,13 @@ import { unroll } from './iss_utils.js' +import { deserializeShadow } from './iss_deserializer.js' export const serializeShadow = (s, throwOnInvalid) => { if (typeof s === 'object') { - return `${s.inset ? 'inset ' : ''}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}` + const inset = s.inset ? 'inset ' : '' + const name = s.name ? ` #${s.name} ` : '' + const result = `${inset}${s.x} ${s.y} ${s.blur} ${s.spread} ${s.color} / ${s.alpha}${name}` + deserializeShadow(result) // Verify that output is valid and parseable + return result } else { return s } diff --git a/src/services/theme_data/theme_data_3.service.js b/src/services/theme_data/theme_data_3.service.js @@ -22,7 +22,7 @@ import { normalizeCombination, findRules } from './iss_utils.js' -import { parseShadow } from './iss_deserializer.js' +import { deserializeShadow } from './iss_deserializer.js' // Ensuring the order of components const components = { @@ -48,7 +48,7 @@ const findShadow = (shadows, { dynamicVars, staticVars }) => { const variableSlot = shadow.substring(2) return findShadow(staticVars[variableSlot], { dynamicVars, staticVars }) } else { - targetShadow = parseShadow(shadow) + targetShadow = deserializeShadow(shadow) } } else { targetShadow = shadow