Merge branch 'themes3-grand-finale-maybe' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2024-10-05 18:47:28 +03:00
commit f354de14cc
15 changed files with 718 additions and 556 deletions

View file

@ -351,7 +351,12 @@ const afterStoreSetup = async ({ store, i18n }) => {
store.dispatch('setInstanceOption', { name: 'server', value: server }) store.dispatch('setInstanceOption', { name: 'server', value: server })
await setConfig({ store }) await setConfig({ store })
await store.dispatch('applyTheme', { recompile: false }) document.querySelector('#status').textContent = i18n.global.t('splash.theme')
try {
await store.dispatch('applyTheme').catch((e) => { console.error('Error setting theme', e) })
} catch (e) {
return Promise.reject(e)
}
applyConfig(store.state.config) applyConfig(store.state.config)

View file

@ -0,0 +1,115 @@
<template>
<div
class="SelectMotion btn-group"
>
<button
class="btn button-default"
:disabled="disabled || shadowsAreNull"
@click="add"
>
<FAIcon
fixed-width
icon="plus"
/>
</button>
<button
class="btn button-default"
:disabled="disabled || !moveUpValid"
:class="{ disabled: disabled || !moveUpValid }"
@click="moveUp"
>
<FAIcon
fixed-width
icon="chevron-up"
/>
</button>
<button
class="btn button-default"
:disabled="disabled || !moveDnValid"
:class="{ disabled: disabled || !moveDnValid }"
@click="moveDn"
>
<FAIcon
fixed-width
icon="chevron-down"
/>
</button>
<button
class="btn button-default"
:disabled="disabled || !present"
:class="{ disabled: disabled || !present }"
@click="del"
>
<FAIcon
fixed-width
icon="times"
/>
</button>
</div>
</template>
<script setup>
import { computed, defineEmits, defineProps } from 'vue'
const props = defineProps(['modelValue', 'selectedId', 'disabled', 'getAddValue'])
const emit = defineEmits(['update:modelValue', 'update:selectedId'])
const moveUpValid = computed(() => {
return props.selectedId > 0
})
const present = computed(() => props.modelValue[props.selectedId] != null)
const moveUp = () => {
const newModel = [...props.modelValue]
const movable = newModel.splice(props.selectedId, 1)[0]
newModel.splice(props.selectedId - 1, 0, movable)
emit('update:modelValue', newModel)
emit('update:selectedId', props.selectedId - 1)
}
const moveDnValid = computed(() => {
return props.selectedId < props.modelValue.length - 1
})
const moveDn = () => {
const newModel = [...props.modelValue]
const movable = newModel.splice(props.selectedId.value, 1)[0]
newModel.splice(props.selectedId + 1, 0, movable)
emit('update:modelValue', newModel)
emit('update:selectedId', props.selectedId + 1)
}
const add = () => {
const newModel = [...props.modelValue]
newModel.push(props.getAddValue())
console.log(newModel)
emit('update:modelValue', newModel)
emit('update:selectedId', Math.max(newModel.length - 1, 0))
}
const del = () => {
const newModel = [...props.modelValue]
newModel.splice(props.selectedId, 1)
emit('update:modelValue', newModel)
emit('update:selectedId', newModel.length === 0 ? undefined : Math.max(props.selectedId - 1, 0))
}
</script>
<style lang="scss">
.SelectMotion {
flex: 0 0 auto;
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
margin-top: 0.25em;
.button-default {
margin: 0;
padding: 0;
}
}
</style>

View file

@ -34,7 +34,7 @@ const AppearanceTab = {
return { return {
availableStyles: [], availableStyles: [],
availablePalettes: [], availablePalettes: [],
themeImporter: newImporter({ fileImporter: newImporter({
accept: '.json, .piss', accept: '.json, .piss',
validator: this.importValidator, validator: this.importValidator,
onImport: this.onImport, onImport: this.onImport,
@ -179,6 +179,10 @@ const AppearanceTab = {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val }) this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
} }
}, },
customThemeVersion () {
const { themeVersion } = this.$store.state.interface
return themeVersion
},
isCustomThemeUsed () { isCustomThemeUsed () {
const { theme } = this.mergedConfig const { theme } = this.mergedConfig
return theme === 'custom' return theme === 'custom'
@ -202,8 +206,8 @@ const AppearanceTab = {
} }
}) })
}, },
importTheme () { importFile () {
this.themeImporter.importData() this.fileImporter.importData()
}, },
onImport (parsed, filename) { onImport (parsed, filename) {
if (filename.endsWith('.json')) { if (filename.endsWith('.json')) {
@ -234,14 +238,18 @@ const AppearanceTab = {
const { palette } = this.mergedConfig const { palette } = this.mergedConfig
return key === palette return key === palette
}, },
importStyle () { setStyle (name) {
this.$store.dispatch('resetThemeV2')
this.$store.dispatch('setTheme', name)
this.$store.dispatch('applyTheme')
}, },
setTheme (name) { setTheme (name) {
this.$store.dispatch('resetThemeV3')
this.$store.dispatch('setTheme', name) this.$store.dispatch('setTheme', name)
this.$store.dispatch('applyTheme') this.$store.dispatch('applyTheme')
}, },
setPalette (name) { setPalette (name) {
this.$store.dispatch('resetThemeV2')
this.$store.dispatch('setPalette', name) this.$store.dispatch('setPalette', name)
this.$store.dispatch('applyTheme') this.$store.dispatch('applyTheme')
}, },

View file

@ -24,6 +24,10 @@
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
grid-gap: 0.5em; grid-gap: 0.5em;
.unsupported-theme-v2 {
grid-column: 1 / span 2;
}
} }
.palette-entry { .palette-entry {

View file

@ -7,7 +7,7 @@
<h2>{{ $t('settings.theme') }}</h2> <h2>{{ $t('settings.theme') }}</h2>
<button <button
class="btn button-default" class="btn button-default"
@click="importTheme" @click="importFile"
> >
<FAIcon icon="folder-open" /> <FAIcon icon="folder-open" />
{{ $t('settings.style.themes3.editor.load_style') }} {{ $t('settings.style.themes3.editor.load_style') }}
@ -30,7 +30,7 @@
v-html="previewTheme('stock')" v-html="previewTheme('stock')"
/> />
<!-- eslint-enable vue/no-v-text-v-html-on-component --> <!-- eslint-enable vue/no-v-text-v-html-on-component -->
<preview /> <preview id="theme-preview-stock" />
<h4 class="theme-name"> <h4 class="theme-name">
{{ $t('settings.style.stock_theme_used') }} {{ $t('settings.style.stock_theme_used') }}
<span class="alert neutral version">v3</span> <span class="alert neutral version">v3</span>
@ -71,6 +71,7 @@
</ul> </ul>
<h3>{{ $t('settings.style.themes3.palette.label') }}</h3> <h3>{{ $t('settings.style.themes3.palette.label') }}</h3>
<div class="palettes"> <div class="palettes">
<template v-if="customThemeVersion === 'v3'">
<button <button
v-for="p in availablePalettes" v-for="p in availablePalettes"
:key="p.name" :key="p.name"
@ -88,6 +89,12 @@
:style="{ backgroundColor: p[c], border: '1px solid ' + (p[c] ?? 'var(--text)') }" :style="{ backgroundColor: p[c], border: '1px solid ' + (p[c] ?? 'var(--text)') }"
/> />
</button> </button>
</template>
<template v-else-if="customThemeVersion === 'v2'">
<div class="alert neutral theme-notice unsupported-theme-v2">
{{ $t('settings.style.themes3.palette.v2_unsupported') }}
</div>
</template>
</div> </div>
</div> </div>
<div class="alert neutral theme-notice"> <div class="alert neutral theme-notice">

View file

@ -219,9 +219,13 @@ export default {
return selectors.map(x => x.substring(1)).join('') return selectors.map(x => x.substring(1)).join('')
}) })
const previewCss = computed(() => { const previewCss = computed(() => {
const scoped = getCssRules(previewRules) try {
.map(simulatePseudoSelectors) const scoped = getCssRules(previewRules).map(simulatePseudoSelectors)
return scoped.join('\n') return scoped.join('\n')
} catch (e) {
console.error('Invalid ruleset', e)
return null
}
}) })
// ### Rules stuff aka meat and potatoes // ### Rules stuff aka meat and potatoes
@ -415,8 +419,8 @@ export default {
}) })
const updatePreview = () => { const updatePreview = () => {
previewRules.splice(0, previewRules.length) try {
previewRules.push(...init({ const rules = init({
inputRuleset: editorFriendlyToOriginal.value, inputRuleset: editorFriendlyToOriginal.value,
initialStaticVars: { initialStaticVars: {
...palette.value ...palette.value
@ -425,7 +429,12 @@ export default {
rootComponentName: selectedComponentName.value, rootComponentName: selectedComponentName.value,
editMode: true, editMode: true,
debug: true debug: true
}).eager) }).eager
previewRules.splice(0, previewRules.length)
previewRules.push(...rules)
} catch (e) {
console.error('Could not compile preview theme', e)
}
} }
const updateSelectedComponent = () => { const updateSelectedComponent = () => {

View file

@ -51,7 +51,12 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="setting-item component-editor"> <tab-switcher>
<div
key="component"
class="setting-item component-editor"
:label="$t('settings.style.themes3.editor.component_tab')"
>
<div class="component-selector"> <div class="component-selector">
<label for="component-selector"> <label for="component-selector">
{{ $t('settings.style.themes3.editor.component_selector') }} {{ $t('settings.style.themes3.editor.component_selector') }}
@ -125,7 +130,7 @@
:shadow-control="isShadowTabOpen" :shadow-control="isShadowTabOpen"
:preview-class="previewClass" :preview-class="previewClass"
:preview-style="editorHintStyle" :preview-style="editorHintStyle"
:disabled="!editedSubShadow" :disabled="!editedSubShadow && typeof editedShadow !== 'string'"
:shadow="editedSubShadow" :shadow="editedSubShadow"
@update:shadow="({ axis, value }) => updateSubShadow(axis, value)" @update:shadow="({ axis, value }) => updateSubShadow(axis, value)"
/> />
@ -250,7 +255,11 @@
</div> </div>
</tab-switcher> </tab-switcher>
</div> </div>
<div class="setting-item palette-editor"> <div
key="palette"
:label="$t('settings.style.themes3.editor.palette_tab')"
class="setting-item palette-editor"
>
<div class="label"> <div class="label">
<label for="palette-selector"> <label for="palette-selector">
{{ $t('settings.style.themes3.palette.label') }} {{ $t('settings.style.themes3.palette.label') }}
@ -276,6 +285,7 @@
</div> </div>
<PaletteEditor v-model="palette" /> <PaletteEditor v-model="palette" />
</div> </div>
</tab-switcher>
</div> </div>
</template> </template>

View file

@ -1,6 +1,7 @@
import ColorInput from 'src/components/color_input/color_input.vue' import ColorInput from 'src/components/color_input/color_input.vue'
import OpacityInput from 'src/components/opacity_input/opacity_input.vue' import OpacityInput from 'src/components/opacity_input/opacity_input.vue'
import Select from 'src/components/select/select.vue' import Select from 'src/components/select/select.vue'
import SelectMotion from 'src/components/select/select_motion.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import Popover from 'src/components/popover/popover.vue' import Popover from 'src/components/popover/popover.vue'
import ComponentPreview from 'src/components/component_preview/component_preview.vue' import ComponentPreview from 'src/components/component_preview/component_preview.vue'
@ -21,7 +22,9 @@ library.add(
faPlus faPlus
) )
const toModel = (object = {}) => ({ const toModel = (input) => {
if (typeof input === 'object') {
return {
x: 0, x: 0,
y: 0, y: 0,
blur: 0, blur: 0,
@ -29,8 +32,12 @@ const toModel = (object = {}) => ({
inset: false, inset: false,
color: '#000000', color: '#000000',
alpha: 1, alpha: 1,
...object ...input
}) }
} else if (typeof input === 'string') {
return input
}
}
export default { export default {
props: [ props: [
@ -48,21 +55,35 @@ export default {
ColorInput, ColorInput,
OpacityInput, OpacityInput,
Select, Select,
SelectMotion,
Checkbox, Checkbox,
Popover, Popover,
ComponentPreview ComponentPreview
}, },
beforeUpdate () {
this.cValue = (this.modelValue ?? this.fallback ?? []).map(toModel)
},
computed: { computed: {
selected () { selectedType: {
get () {
return typeof this.selected
},
set (newType) {
this.selected = toModel(newType === 'object' ? {} : '')
}
},
selected: {
get () {
const selected = this.cValue[this.selectedId] const selected = this.cValue[this.selectedId]
if (selected) { if (selected && typeof selected === 'object') {
return { ...selected } return { ...selected }
} else if (typeof selected === 'string') {
return selected
} }
return null return null
}, },
set (value) {
this.cValue[this.selectedId] = toModel(value)
this.$emit('update:modelValue', this.cValue)
}
},
present () { present () {
return this.selected != null && !this.usingFallback return this.selected != null && !this.usingFallback
}, },
@ -72,16 +93,11 @@ export default {
currentFallback () { currentFallback () {
return this.fallback?.[this.selectedId] return this.fallback?.[this.selectedId]
}, },
moveUpValid () {
return this.selectedId > 0
},
moveDnValid () {
return this.selectedId < this.cValue.length - 1
},
usingFallback () { usingFallback () {
return this.modelValue == null return this.modelValue == null
}, },
style () { style () {
try {
if (this.separateInset) { if (this.separateInset) {
return { return {
filter: getCssShadowFilter(this.cValue), filter: getCssShadowFilter(this.cValue),
@ -91,42 +107,41 @@ export default {
return { return {
boxShadow: getCssShadow(this.cValue) boxShadow: getCssShadow(this.cValue)
} }
} catch (e) {
return {
border: '1px solid red'
}
}
} }
}, },
watch: { watch: {
modelValue (value) {
if (!value) this.cValue = (this.modelValue ?? this.fallback ?? []).map(toModel)
},
selected (value) { selected (value) {
this.$emit('subShadowSelected', this.selectedId) this.$emit('subShadowSelected', this.selectedId)
} }
}, },
methods: { methods: {
getNewSubshadow () {
return toModel(this.selected)
},
onSelectChange (id) {
this.selectedId = id
},
getSubshadowLabel (shadow, index) {
if (typeof shadow === 'object') {
return shadow?.name ?? this.$t('settings.style.shadows.shadow_id', { value: index })
} else if (typeof shadow === 'string') {
return shadow || this.$t('settings.style.shadows.empty_expression')
}
},
updateProperty: throttle(function (prop, value) { updateProperty: throttle(function (prop, value) {
this.cValue[this.selectedId][prop] = value this.cValue[this.selectedId][prop] = value
if (prop === 'inset' && value === false && this.separateInset) { if (prop === 'inset' && value === false && this.separateInset) {
this.cValue[this.selectedId].spread = 0 this.cValue[this.selectedId].spread = 0
} }
this.$emit('update:modelValue', this.cValue) this.$emit('update:modelValue', this.cValue)
}, 100), }, 100)
add () {
this.cValue.push(toModel(this.selected))
this.selectedId = Math.max(this.cValue.length - 1, 0)
this.$emit('update:modelValue', this.cValue)
},
del () {
this.cValue.splice(this.selectedId, 1)
this.selectedId = this.cValue.length === 0 ? undefined : Math.max(this.selectedId - 1, 0)
this.$emit('update:modelValue', this.cValue)
},
moveUp () {
const movable = this.cValue.splice(this.selectedId, 1)[0]
this.cValue.splice(this.selectedId - 1, 0, movable)
this.selectedId -= 1
this.$emit('update:modelValue', this.cValue)
},
moveDn () {
const movable = this.cValue.splice(this.selectedId, 1)[0]
this.cValue.splice(this.selectedId + 1, 0, movable)
this.selectedId += 1
this.$emit('update:modelValue', this.cValue)
}
} }
} }

View file

@ -4,6 +4,7 @@
justify-content: stretch; justify-content: stretch;
grid-gap: 0.25em; grid-gap: 0.25em;
margin-bottom: 1em; margin-bottom: 1em;
width: 100%;
.shadow-switcher { .shadow-switcher {
order: 1; order: 1;
@ -16,19 +17,6 @@
.shadow-list { .shadow-list {
flex: 1 0 auto; flex: 1 0 auto;
} }
.arrange-buttons {
flex: 0 0 auto;
display: grid;
grid-auto-columns: 1fr;
grid-auto-flow: column;
margin-top: 0.25em;
.button-default {
margin: 0;
padding: 0;
}
}
} }
.shadow-tweak { .shadow-tweak {
@ -37,6 +25,9 @@
min-width: 10em; min-width: 10em;
margin-left: 0.125em; margin-left: 0.125em;
margin-right: 0.125em; margin-right: 0.125em;
display: grid;
grid-template-rows: auto 1fr;
grid-gap: 0.25em;
/* hack */ /* hack */
.input-boolean { .input-boolean {
@ -52,6 +43,11 @@
flex: 1 0 5em; flex: 1 0 5em;
} }
.shadow-expression {
width: 100%;
height: 100%;
}
.id-control { .id-control {
align-items: stretch; align-items: stretch;
@ -100,6 +96,5 @@
} }
.inset-tooltip { .inset-tooltip {
padding: 0.5em;
max-width: 30em; max-width: 30em;
} }

View file

@ -8,7 +8,6 @@
class="shadow-preview" class="shadow-preview"
:shadow-control="true" :shadow-control="true"
:shadow="selected" :shadow="selected"
:preview-style="style"
:disabled="disabled || !present" :disabled="disabled || !present"
@update:shadow="({ axis, value }) => updateProperty(axis, value)" @update:shadow="({ axis, value }) => updateProperty(axis, value)"
/> />
@ -18,7 +17,7 @@
v-model="selectedId" v-model="selectedId"
class="shadow-list" class="shadow-list"
size="10" size="10"
:disabled="shadowsAreNull" :disabled="disabled || shadowsAreNull"
> >
<option <option
v-for="(shadow, index) in cValue" v-for="(shadow, index) in cValue"
@ -26,58 +25,38 @@
:value="index" :value="index"
:class="{ '-active': index === Number(selectedId) }" :class="{ '-active': index === Number(selectedId) }"
> >
{{ shadow?.name ?? $t('settings.style.shadows.shadow_id', { value: index }) }} {{ getSubshadowLabel(shadow, index) }}
</option> </option>
</Select> </Select>
<div <SelectMotion
class="id-control btn-group arrange-buttons" v-model="cValue"
> :selected-id="selectedId"
<button :get-add-value="getNewSubshadow"
class="btn button-default" :disabled="disabled"
:disabled="disabled || shadowsAreNull" @update:selectedId="onSelectChange"
@click="add"
>
<FAIcon
fixed-width
icon="plus"
/> />
</button>
<button
class="btn button-default"
:disabled="disabled || !moveUpValid"
:class="{ disabled: disabled || !moveUpValid }"
@click="moveUp"
>
<FAIcon
fixed-width
icon="chevron-up"
/>
</button>
<button
class="btn button-default"
:disabled="disabled || !moveDnValid"
:class="{ disabled: disabled || !moveDnValid }"
@click="moveDn"
>
<FAIcon
fixed-width
icon="chevron-down"
/>
</button>
<button
class="btn button-default"
:disabled="disabled || !present"
:class="{ disabled: disabled || !present }"
@click="del"
>
<FAIcon
fixed-width
icon="times"
/>
</button>
</div>
</div> </div>
<div class="shadow-tweak"> <div class="shadow-tweak">
<Select
v-model="selectedType"
:disabled="disabled || !present"
>
<option value="object">
{{ $t('settings.style.shadows.raw') }}
</option>
<option value="string">
{{ $t('settings.style.shadows.expression') }}
</option>
</Select>
<template v-if="selectedType === 'string'">
<textarea
v-model="selected"
class="input shadow-expression"
:disabled="disabled || shadowsAreNull"
:class="{disabled: disabled || shadowsAreNull}"
/>
</template>
<template v-else-if="selectedType === 'object'">
<div <div
:class="{ disabled: disabled || !present }" :class="{ disabled: disabled || !present }"
class="name-control style-control" class="name-control style-control"
@ -218,7 +197,7 @@
</div> </div>
</template> </template>
<template #content> <template #content>
<div class="inset-tooltip"> <div class="inset-tooltip tooltip">
<i18n-t <i18n-t
scope="global" scope="global"
keypath="settings.style.shadows.filter_hint.always_drop_shadow" keypath="settings.style.shadows.filter_hint.always_drop_shadow"
@ -247,6 +226,7 @@
</div> </div>
</template> </template>
</Popover> </Popover>
</template>
</div> </div>
</div> </div>
</template> </template>

View file

@ -773,7 +773,8 @@
"cOrange": "Orange color", "cOrange": "Orange color",
"extra1": "Extra 1", "extra1": "Extra 1",
"extra2": "Extra 2", "extra2": "Extra 2",
"extra3": "Extra 3" "extra3": "Extra 3",
"v2_unsupported": "Older v2 themes don't support palettes. Switch to v3 theme to make use of palettes",
}, },
"editor": { "editor": {
"title": "Style", "title": "Style",
@ -964,6 +965,9 @@
"blur": "Blur", "blur": "Blur",
"spread": "Spread", "spread": "Spread",
"inset": "Inset", "inset": "Inset",
"raw": "Plain shadow",
"expression": "Expression (advanced)",
"empty_expression": "Empty expression",
"hintV3": "For shadows you can also use the {0} notation to use other color slot.", "hintV3": "For shadows you can also use the {0} notation to use other color slot.",
"filter_hint": { "filter_hint": {
"always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.", "always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.",

View file

@ -5,6 +5,7 @@ import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
const defaultState = { const defaultState = {
localFonts: null, localFonts: null,
themeApplied: false, themeApplied: false,
themeVersion: 'v3',
temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout
temporaryChangesConfirm: () => {}, // used for applying temporary options temporaryChangesConfirm: () => {}, // used for applying temporary options
temporaryChangesRevert: () => {}, // used for reverting temporary options temporaryChangesRevert: () => {}, // used for reverting temporary options
@ -219,7 +220,8 @@ const interfaceMod = {
return value return value
} catch (e) { } catch (e) {
console.error('Could not fetch palettes index', e) console.error('Could not fetch palettes index', e)
return {} commit('setInstanceOption', { name: 'palettesIndex', value: { _error: e } })
return Promise.resolve({})
} }
}, },
setPalette ({ dispatch, commit }, value) { setPalette ({ dispatch, commit }, value) {
@ -245,6 +247,7 @@ const interfaceMod = {
return value return value
} catch (e) { } catch (e) {
console.error('Could not fetch styles index', e) console.error('Could not fetch styles index', e)
commit('setInstanceOption', { name: 'stylesIndex', value: { _error: e } })
return Promise.resolve({}) return Promise.resolve({})
} }
}, },
@ -271,6 +274,7 @@ const interfaceMod = {
return value return value
} catch (e) { } catch (e) {
console.error('Could not fetch themes index', e) console.error('Could not fetch themes index', e)
commit('setInstanceOption', { name: 'themesIndex', value: { _error: e } })
return Promise.resolve({}) return Promise.resolve({})
} }
}, },
@ -307,7 +311,7 @@ const interfaceMod = {
commit('setOption', { name: 'customThemeSource', value: null }) commit('setOption', { name: 'customThemeSource', value: null })
}, },
async applyTheme ( async applyTheme (
{ dispatch, commit, rootState }, { dispatch, commit, rootState, state },
{ recompile = true } = {} { recompile = true } = {}
) { ) {
// If we're not not forced to recompile try using // If we're not not forced to recompile try using
@ -373,7 +377,19 @@ const interfaceMod = {
userThemeV2Snapshot = null userThemeV2Snapshot = null
majorVersionUsed = 'v3' majorVersionUsed = 'v3'
if (!palettesIndex || !stylesIndex) { } else if (
(userThemeV2Name ||
userThemeV2Snapshot ||
userThemeV2Source ||
instanceThemeV2Name)
) {
majorVersionUsed = 'v2'
} else {
// if all fails fallback to v3
majorVersionUsed = 'v3'
}
if (majorVersionUsed === 'v3') {
const result = await Promise.all([ const result = await Promise.all([
dispatch('fetchPalettesIndex'), dispatch('fetchPalettesIndex'),
dispatch('fetchStylesIndex') dispatch('fetchStylesIndex')
@ -381,23 +397,17 @@ const interfaceMod = {
palettesIndex = result[0] palettesIndex = result[0]
stylesIndex = result[1] stylesIndex = result[1]
} } else {
} else if (
userThemeV2Name ||
userThemeV2Snapshot ||
userThemeV2Source ||
instanceThemeV2Name
) {
majorVersionUsed = 'v2'
// Promise.all just to be uniform with v3 // Promise.all just to be uniform with v3
const result = await Promise.all([ const result = await Promise.all([
dispatch('fetchThemesIndex') dispatch('fetchThemesIndex')
]) ])
themesIndex = result[0] themesIndex = result[0]
} else {
majorVersionUsed = 'v3'
} }
state.themeVersion = majorVersionUsed
let styleDataUsed = null let styleDataUsed = null
let styleNameUsed = null let styleNameUsed = null
let paletteDataUsed = null let paletteDataUsed = null
@ -520,7 +530,7 @@ const interfaceMod = {
return result return result
})() })()
const theme2ruleset = themeDataUsed && convertTheme2To3(normalizeThemeData(themeDataUsed)) const theme2ruleset = themeDataUsed && convertTheme2To3(generatePreset(themeDataUsed).source)
const hacks = [] const hacks = []
Object.entries(theme3hacks).forEach(([key, value]) => { Object.entries(theme3hacks).forEach(([key, value]) => {

View file

@ -144,8 +144,7 @@ export const tryLoadCache = () => {
} }
} }
export const applyTheme = async (input, onFinish = (data) => {}, debug) => { export const applyTheme = (input, onFinish = (data) => {}, debug) => {
console.log('INPUT', input)
const eagerStyles = createStyleSheet(EAGER_STYLE_ID) const eagerStyles = createStyleSheet(EAGER_STYLE_ID)
const lazyStyles = createStyleSheet(LAZY_STYLE_ID) const lazyStyles = createStyleSheet(LAZY_STYLE_ID)

View file

@ -44,8 +44,8 @@ const findShadow = (shadows, { dynamicVars, staticVars }) => {
if (shadow.startsWith('$')) { if (shadow.startsWith('$')) {
targetShadow = process(shadow, shadowFunctions, { findColor, findShadow }, { dynamicVars, staticVars }) targetShadow = process(shadow, shadowFunctions, { findColor, findShadow }, { dynamicVars, staticVars })
} else if (shadow.startsWith('--')) { } else if (shadow.startsWith('--')) {
const [variable] = shadow.split(/,/g).map(str => str.trim()) // discarding modifier since it's not supported // modifiers are completely unsupported here
const variableSlot = variable.substring(2) const variableSlot = shadow.substring(2)
return findShadow(staticVars[variableSlot], { dynamicVars, staticVars }) return findShadow(staticVars[variableSlot], { dynamicVars, staticVars })
} else { } else {
targetShadow = parseShadow(shadow) targetShadow = parseShadow(shadow)
@ -66,6 +66,7 @@ const findColor = (color, { dynamicVars, staticVars }) => {
if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color if (typeof color !== 'string' || (!color.startsWith('--') && !color.startsWith('$'))) return color
let targetColor = null let targetColor = null
if (color.startsWith('--')) { if (color.startsWith('--')) {
// Modifier support is pretty much for v2 themes only
const [variable, modifier] = color.split(/,/g).map(str => str.trim()) const [variable, modifier] = color.split(/,/g).map(str => str.trim())
const variableSlot = variable.substring(2) const variableSlot = variable.substring(2)
if (variableSlot === 'stack') { if (variableSlot === 'stack') {
@ -421,7 +422,7 @@ export const init = ({
break break
} }
case 'shadow': { case 'shadow': {
const shadow = value.split(/,/g).map(s => s.trim()) const shadow = value.split(/,/g).map(s => s.trim()).filter(x => x)
dynamicVars[k] = shadow dynamicVars[k] = shadow
if (combination.component === rootComponentName) { if (combination.component === rootComponentName) {
staticVars[k.substring(2)] = shadow staticVars[k.substring(2)] = shadow

View file

@ -1,6 +1,6 @@
{ {
"pleroma-light": [ "Pleroma Light", "#f2f4f6", "#dbe0e8", "#304055", "#f86f0f", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
"pleroma-dark": [ "Pleroma Dark", "#121a24", "#182230", "#b9b9ba", "#d8a070", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ], "pleroma-dark": [ "Pleroma Dark", "#121a24", "#182230", "#b9b9ba", "#d8a070", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
"pleroma-light": [ "Pleroma Light", "#f2f4f6", "#dbe0e8", "#304055", "#f86f0f", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
"classic-dark": { "classic-dark": {
"name": "Classic Dark", "name": "Classic Dark",
"background": "#161c20", "background": "#161c20",
@ -12,6 +12,7 @@
"cBlue": "#0095ff", "cBlue": "#0095ff",
"cOrange": "#ffa500" "cOrange": "#ffa500"
}, },
"bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
"pleroma-amoled": [ "Pleroma Dark AMOLED", "#000000", "#111111", "#b0b0b1", "#d8a070", "#aa0000", "#0fa00f", "#0095ff", "#d59500"], "pleroma-amoled": [ "Pleroma Dark AMOLED", "#000000", "#111111", "#b0b0b1", "#d8a070", "#aa0000", "#0fa00f", "#0095ff", "#d59500"],
"tomorrow-night": { "tomorrow-night": {
"name": "Tomorrow Night", "name": "Tomorrow Night",
@ -26,7 +27,6 @@
"_cYellow": "#f0c674", "_cYellow": "#f0c674",
"_cPurple": "#b294bb" "_cPurple": "#b294bb"
}, },
"bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
"ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ], "ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ],
"monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ] "monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ]
} }