Adding rules now works

This commit is contained in:
Henry Jameson 2024-09-27 16:24:33 +03:00
parent fb40694e8e
commit 415180e8fa
2 changed files with 131 additions and 111 deletions

View file

@ -1,5 +1,5 @@
import { ref, reactive, computed, watch } from 'vue' import { ref, reactive, computed, watch } from 'vue'
import { get } from 'lodash' import { get, set } from 'lodash'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
@ -17,7 +17,12 @@ import { getCssRules } from 'src/services/theme_data/css_utils.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faFloppyDisk, faFolderOpen, faFile } from '@fortawesome/free-solid-svg-icons' import { faFloppyDisk, faFolderOpen, faFile } from '@fortawesome/free-solid-svg-icons'
const toValue = (x) => JSON.parse(JSON.stringify(x === undefined ? '"lol"' : x)) // helper for debugging
// eslint-disable-next-line no-unused-vars
const toValue = (x) => JSON.parse(JSON.stringify(x === undefined ? 'null' : x))
// helper to make states comparable
const normalizeStates = (states) => ['normal', ...(states?.filter(x => x !== 'normal') || [])].join(':')
library.add( library.add(
faFile, faFile,
@ -95,11 +100,8 @@ export default {
const selectedComponentVariantsAll = computed(() => { const selectedComponentVariantsAll = computed(() => {
return Object.keys({ normal: null, ...(selectedComponent.value.variants || {}) }) return Object.keys({ normal: null, ...(selectedComponent.value.variants || {}) })
}) })
// const selectedComponentVariants = computed(() => {
// return selectedComponentVariantsAll.value.filter(x => x !== 'normal')
// })
const selectedStates = reactive(new Set()) const selectedState = reactive(new Set())
const selectedComponentStatesAll = computed(() => { const selectedComponentStatesAll = computed(() => {
return Object.keys({ normal: null, ...(selectedComponent.value.states || {}) }) return Object.keys({ normal: null, ...(selectedComponent.value.states || {}) })
}) })
@ -137,8 +139,8 @@ export default {
if (!!selectedComponent.value.variants?.normal || selectedVariant.value !== 'normal') { if (!!selectedComponent.value.variants?.normal || selectedVariant.value !== 'normal') {
selectors.push(selectedComponent.value.variants[selectedVariant.value]) selectors.push(selectedComponent.value.variants[selectedVariant.value])
} }
if (selectedStates.size > 0) { if (selectedState.size > 0) {
selectedStates.forEach(state => { selectedState.forEach(state => {
const original = selectedComponent.value.states[state] const original = selectedComponent.value.states[state]
selectors.push(simulatePseudoSelectors(original)) selectors.push(simulatePseudoSelectors(original))
}) })
@ -151,104 +153,119 @@ export default {
return scoped.join('\n') return scoped.join('\n')
}) })
// Rules stuff // Rules stuff aka meat and potatoes
const selectedComponentRulesList = reactive([]) const editorFriendlyFallbackStructure = computed(() => {
const selectedComponentRulesObject = computed(() => { const root = {}
const result = {}
selectedComponentRulesList.forEach(
(rule) => {
const component = rule.component
const { variant = 'normal', state = [] } = rule
result[component] = result[component] || {}
result[component][variant] = result[component][variant] || {}
result[component][variant][state.join(':')] = rule
}
)
return result
})
// Edited rule componentKeys.forEach((componentKey) => {
const editedRuleFallback = computed(() => { const componentValue = componentsMap.get(componentKey)
const component = selectedComponentName.value const { defaultRules } = componentValue
const variant = selectedVariant.value defaultRules.forEach((rule) => {
const states = ['normal', ...selectedStates.keys()].join(':') const { parent: rParent } = rule
return selectedComponentRulesObject.value[component]?.[variant]?.[states] const parent = rParent ?? rule
}) const hasChildren = !!rParent
const child = hasChildren ? rule : null
const editedSubrulesFallback = computed(() => { const {
const parentComponent = selectedComponentName.value component: pComponent,
variant: pVariant = 'normal',
state: pState = [] // no relation to Intel CPUs whatsoever
} = parent
const subrules = {} const pPath = `${pComponent}.${pVariant}.${normalizeStates(pState)}`
selectedComponentRulesList.forEach(sr => {
console.log('SR', toValue(sr))
if (!sr.parent) return
if (sr.parent.component === parentComponent) {
const component = sr.component
const { variant = 'normal', state = [] } = sr
subrules[component] = {} || subrules[component] let output = get(root, pPath)
subrules[component][variant] = {} || subrules[component][variant] if (!output) {
subrules[component][variant][state.join(':')] = sr set(root, pPath, {})
} output = get(root, pPath)
}
if (hasChildren) {
output._children = output._children ?? {}
const {
component: cComponent,
variant: cVariant = 'normal',
state: cState = [],
directives
} = child
const cPath = `${cComponent}.${cVariant}.${normalizeStates(cState)}`
set(output._children, cPath, directives)
}
})
}) })
return subrules return root
}) })
// All rules that are made by editor
const allEditedRules = reactive({})
const componentHas = (subComponent) => { const componentHas = (subComponent) => {
return !!selectedComponent.value.validInnerComponents?.find(x => x === subComponent) return !!selectedComponent.value.validInnerComponents?.find(x => x === subComponent)
} }
const editedTextColor = computed(() => get( const getPath = (component, directive) => {
editedSubrulesFallback.value, const pathSuffix = component ? `._children.${component}.normal.normal` : ''
'Text.normal.normal.directives.textColor', const path = `${selectedComponentName.value}.${selectedVariant.value}.${normalizeStates([...selectedState])}${pathSuffix}.directives.${directive}`
null return path
)) }
const isElementPresent = (component, directive, defaultValue = '') => computed({
const editedLinkColor = computed(() => get( get () {
editedSubrulesFallback.value, return get(allEditedRules, getPath(component, directive)) != null
'Link.normal.normal.directives.linkColor', },
null set (value) {
)) if (value) {
set(allEditedRules, getPath(component, directive), defaultValue)
const editedIconColor = computed(() => get( } else {
editedSubrulesFallback.value, set(allEditedRules, getPath(component, directive), null)
'Icon.normal.normal.directives.iconColor', }
null }
))
const editedBackground = computed(() => get(
editedRuleFallback.value,
'directives.background',
null
))
const editedOpacity = computed(() => get(
editedSubrulesFallback.value,
'Link.normal.normal.directives.linkColor',
null
))
const editedShadow = computed(() => {
return editedRuleFallback.value?.directives.shadow
}) })
const getEditedElement = (component, directive) => computed({
get () {
let usedRule
const fallback = editorFriendlyFallbackStructure
const real = allEditedRules
const path = getPath(component, directive)
usedRule = get(real, path) // get real
if (!usedRule) {
console.log('FALLBACK')
usedRule = get(fallback, path)
} else {
console.log('REAL')
}
console.log('GET', path, toValue(usedRule))
return usedRule
},
set (value) {
console.log(1, toValue(allEditedRules))
set(allEditedRules, getPath(component, directive))
console.log(2, toValue(allEditedRules))
}
})
const editedBackgroundColor = getEditedElement(null, 'background')
const editedOpacity = getEditedElement(null, 'opacity')
const editedTextColor = getEditedElement('Text', 'color')
const editedLinkColor = getEditedElement('Link', 'color')
const editedIconColor = getEditedElement('Icon', 'color')
const editedShadow = getEditedElement(null, 'shadow')
const isBackgroundColorPresent = isElementPresent(null, 'background', '#FFFFFF')
const isOpacityPresent = isElementPresent(null, 'opacity', 1)
const isTextColorPresent = isElementPresent('Text', 'color', '#000000')
const isLinkColorPresent = isElementPresent('Link', 'color', '#000080')
const isIconColorPresent = isElementPresent('Icon', 'color', '#909090')
const isShadowPresent = isElementPresent(null, 'shadow', [{ x: 0, y: 0, blur: 0, color: '#000000' }])
const updateSelectedComponent = () => { const updateSelectedComponent = () => {
selectedVariant.value = 'normal' selectedVariant.value = 'normal'
selectedStates.clear() selectedState.clear()
const processedRulesList = selectedComponent.value.defaultRules.map(r => {
const rule = {
component: selectedComponentName.value,
variant: 'normal',
...r,
state: ['normal', ...(r.state || []).filter(x => x !== 'normal')]
}
return rule
})
selectedComponentRulesList.splice(0, selectedComponentRulesList.length)
selectedComponentRulesList.push(...processedRulesList)
previewRules.splice(0, previewRules.length) previewRules.splice(0, previewRules.length)
previewRules.push(...init({ previewRules.push(...init({
@ -289,24 +306,27 @@ export default {
selectedComponentKey, selectedComponentKey,
selectedComponentVariantsAll, selectedComponentVariantsAll,
selectedComponentStates, selectedComponentStates,
selectedComponentRulesObject,
selectedVariant, selectedVariant,
selectedStates, selectedState,
updateSelectedStates (state, v) { updateSelectedStates (state, v) {
if (v) { if (v) {
selectedStates.add(state) selectedState.add(state)
} else { } else {
selectedStates.delete(state) selectedState.delete(state)
} }
}, },
editedRuleFallback, editedBackgroundColor,
editedSubrulesFallback,
editedBackground,
editedOpacity, editedOpacity,
editedTextColor, editedTextColor,
editedLinkColor, editedLinkColor,
editedIconColor, editedIconColor,
editedShadow, editedShadow,
isBackgroundColorPresent,
isOpacityPresent,
isTextColorPresent,
isLinkColorPresent,
isIconColorPresent,
isShadowPresent,
previewCss, previewCss,
previewClass, previewClass,
editorHintStyle, editorHintStyle,

View file

@ -100,7 +100,7 @@
class="state-selector-list" class="state-selector-list"
> >
<li <li
v-for="state in selectedComponentStates" v-for="state in selectedStates"
:key="'component-variant-' + state" :key="'component-variant-' + state"
> >
<Checkbox <Checkbox
@ -139,13 +139,13 @@
key="main" key="main"
> >
<ColorInput <ColorInput
v-model="editedBackground" v-model="editedBackgroundColor"
:disabled="!editedBackgroundPresent" :disabled="!isBackgroundColorPresent"
:label="$t('settings.style.themes3.editor.background')" :label="$t('settings.style.themes3.editor.background')"
/> />
<Popover trigger="hover"> <Popover trigger="hover">
<template #trigger> <template #trigger>
<Checkbox v-model="editedBackgroundPresent" /> <Checkbox v-model="isBackgroundColorPresent" />
</template> </template>
<template #content> <template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
@ -153,12 +153,12 @@
</Popover> </Popover>
<OpacityInput <OpacityInput
v-model="editedOpacity" v-model="editedOpacity"
:disabled="!editedOpacityPresent" :disabled="!isOpacityPresent"
:label="$t('settings.style.themes3.editor.opacity')" :label="$t('settings.style.themes3.editor.opacity')"
/> />
<Popover trigger="hover"> <Popover trigger="hover">
<template #trigger> <template #trigger>
<Checkbox v-model="editedOpacityPresent" /> <Checkbox v-model="isOpacityPresent" />
</template> </template>
<template #content> <template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
@ -167,7 +167,7 @@
<ColorInput <ColorInput
v-model="editedTextColor" v-model="editedTextColor"
:label="$t('settings.style.themes3.editor.text_color')" :label="$t('settings.style.themes3.editor.text_color')"
:disabled="!editedTextPresent" :disabled="!isTextColorPresent"
v-if="componentHas('Text')" v-if="componentHas('Text')"
/> />
<Popover <Popover
@ -175,7 +175,7 @@
v-if="componentHas('Text')" v-if="componentHas('Text')"
> >
<template #trigger> <template #trigger>
<Checkbox v-model="editedTextPresent" /> <Checkbox v-model="isTextColorPresent" />
</template> </template>
<template #content> <template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
@ -184,7 +184,7 @@
<ColorInput <ColorInput
v-model="editedLinkColor" v-model="editedLinkColor"
:label="$t('settings.style.themes3.editor.link_color')" :label="$t('settings.style.themes3.editor.link_color')"
:disabled="!editedLinkPresent" :disabled="!isLinkColorPresent"
v-if="componentHas('Link')" v-if="componentHas('Link')"
/> />
<Popover <Popover
@ -192,7 +192,7 @@
v-if="componentHas('Link')" v-if="componentHas('Link')"
> >
<template #trigger> <template #trigger>
<Checkbox v-model="editedLinkPresent" /> <Checkbox v-model="isLinkColorPresent" />
</template> </template>
<template #content> <template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
@ -201,7 +201,7 @@
<ColorInput <ColorInput
v-model="editedIconColor" v-model="editedIconColor"
:label="$t('settings.style.themes3.editor.icon_color')" :label="$t('settings.style.themes3.editor.icon_color')"
:disabled="!editedOpacityPresent" :disabled="!isIconColorPresent"
v-if="componentHas('Icon')" v-if="componentHas('Icon')"
/> />
<Popover <Popover
@ -209,7 +209,7 @@
v-if="componentHas('Icon')" v-if="componentHas('Icon')"
> >
<template #trigger> <template #trigger>
<Checkbox v-model="editedIconPresent" /> <Checkbox v-model="isIconColorPresent" />
</template> </template>
<template #content> <template #content>
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
@ -223,15 +223,15 @@
> >
<Checkbox <Checkbox
class="style-control" class="style-control"
v-model="editedOpacityPresent" v-model="isShadowPresent"
> >
{{ $t('settings.style.themes3.editor.include_in_rule') }} {{ $t('settings.style.themes3.editor.include_in_rule') }}
</checkbox> </checkbox>
<ShadowControl <ShadowControl
v-model="editedShadow" v-model="editedShadow"
:disabled="isShadowPresent"
:no-preview="true" :no-preview="true"
:separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'" :separate-inset="shadowSelected === 'avatar' || shadowSelected === 'avatarStatus'"
:fallback="currentShadowFallback"
/> />
</div> </div>
</tab-switcher> </tab-switcher>