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 { get } from 'lodash'
import { get, set } from 'lodash'
import Select from 'src/components/select/select.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 { 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(
faFile,
@ -95,11 +100,8 @@ export default {
const selectedComponentVariantsAll = computed(() => {
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(() => {
return Object.keys({ normal: null, ...(selectedComponent.value.states || {}) })
})
@ -137,8 +139,8 @@ export default {
if (!!selectedComponent.value.variants?.normal || selectedVariant.value !== 'normal') {
selectors.push(selectedComponent.value.variants[selectedVariant.value])
}
if (selectedStates.size > 0) {
selectedStates.forEach(state => {
if (selectedState.size > 0) {
selectedState.forEach(state => {
const original = selectedComponent.value.states[state]
selectors.push(simulatePseudoSelectors(original))
})
@ -151,104 +153,119 @@ export default {
return scoped.join('\n')
})
// Rules stuff
const selectedComponentRulesList = reactive([])
const selectedComponentRulesObject = computed(() => {
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
// Rules stuff aka meat and potatoes
const editorFriendlyFallbackStructure = computed(() => {
const root = {}
componentKeys.forEach((componentKey) => {
const componentValue = componentsMap.get(componentKey)
const { defaultRules } = componentValue
defaultRules.forEach((rule) => {
const { parent: rParent } = rule
const parent = rParent ?? rule
const hasChildren = !!rParent
const child = hasChildren ? rule : null
const {
component: pComponent,
variant: pVariant = 'normal',
state: pState = [] // no relation to Intel CPUs whatsoever
} = parent
const pPath = `${pComponent}.${pVariant}.${normalizeStates(pState)}`
let output = get(root, pPath)
if (!output) {
set(root, pPath, {})
output = get(root, pPath)
}
)
return result
})
// Edited rule
const editedRuleFallback = computed(() => {
const component = selectedComponentName.value
const variant = selectedVariant.value
const states = ['normal', ...selectedStates.keys()].join(':')
return selectedComponentRulesObject.value[component]?.[variant]?.[states]
})
if (hasChildren) {
output._children = output._children ?? {}
const {
component: cComponent,
variant: cVariant = 'normal',
state: cState = [],
directives
} = child
const editedSubrulesFallback = computed(() => {
const parentComponent = selectedComponentName.value
const subrules = {}
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]
subrules[component][variant] = {} || subrules[component][variant]
subrules[component][variant][state.join(':')] = sr
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) => {
return !!selectedComponent.value.validInnerComponents?.find(x => x === subComponent)
}
const editedTextColor = computed(() => get(
editedSubrulesFallback.value,
'Text.normal.normal.directives.textColor',
null
))
const editedLinkColor = computed(() => get(
editedSubrulesFallback.value,
'Link.normal.normal.directives.linkColor',
null
))
const editedIconColor = computed(() => get(
editedSubrulesFallback.value,
'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 getPath = (component, directive) => {
const pathSuffix = component ? `._children.${component}.normal.normal` : ''
const path = `${selectedComponentName.value}.${selectedVariant.value}.${normalizeStates([...selectedState])}${pathSuffix}.directives.${directive}`
return path
}
const isElementPresent = (component, directive, defaultValue = '') => computed({
get () {
return get(allEditedRules, getPath(component, directive)) != null
},
set (value) {
if (value) {
set(allEditedRules, getPath(component, directive), defaultValue)
} else {
set(allEditedRules, getPath(component, directive), null)
}
}
})
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 = () => {
selectedVariant.value = 'normal'
selectedStates.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)
selectedState.clear()
previewRules.splice(0, previewRules.length)
previewRules.push(...init({
@ -289,24 +306,27 @@ export default {
selectedComponentKey,
selectedComponentVariantsAll,
selectedComponentStates,
selectedComponentRulesObject,
selectedVariant,
selectedStates,
selectedState,
updateSelectedStates (state, v) {
if (v) {
selectedStates.add(state)
selectedState.add(state)
} else {
selectedStates.delete(state)
selectedState.delete(state)
}
},
editedRuleFallback,
editedSubrulesFallback,
editedBackground,
editedBackgroundColor,
editedOpacity,
editedTextColor,
editedLinkColor,
editedIconColor,
editedShadow,
isBackgroundColorPresent,
isOpacityPresent,
isTextColorPresent,
isLinkColorPresent,
isIconColorPresent,
isShadowPresent,
previewCss,
previewClass,
editorHintStyle,

View file

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