Merge branch 'themes3-grand-finale-maybe' into shigusegubu-themes3
This commit is contained in:
commit
31527054c2
11 changed files with 339 additions and 120 deletions
|
@ -89,6 +89,13 @@ export default {
|
|||
shadow: ['--buttonDefaultHoverGlow', '--buttonPressedBevel']
|
||||
}
|
||||
},
|
||||
{
|
||||
state: ['toggled', 'disabled'],
|
||||
directives: {
|
||||
background: '$blend(--inheritedBackground 0.25 --parent)',
|
||||
shadow: ['--buttonPressedBevel']
|
||||
}
|
||||
},
|
||||
{
|
||||
state: ['disabled'],
|
||||
directives: {
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
getCssRules,
|
||||
getScopedVersion
|
||||
} from 'src/services/theme_data/css_utils.js'
|
||||
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
|
||||
|
||||
import SharedComputedObject from '../helpers/shared_computed_object.js'
|
||||
import ProfileSettingIndicator from '../helpers/profile_setting_indicator.vue'
|
||||
|
@ -35,10 +36,12 @@ const AppearanceTab = {
|
|||
return {
|
||||
availableStyles: [],
|
||||
bundledPalettes: [],
|
||||
compilationCache: {},
|
||||
fileImporter: newImporter({
|
||||
accept: '.json, .piss',
|
||||
validator: this.importValidator,
|
||||
onImport: this.onImport,
|
||||
parser: this.importParser,
|
||||
onImportFailure: this.onImportFailure
|
||||
}),
|
||||
palettesKeys: [
|
||||
|
@ -82,6 +85,8 @@ const AppearanceTab = {
|
|||
PaletteEditor
|
||||
},
|
||||
mounted () {
|
||||
this.$store.dispatch('getThemeData')
|
||||
|
||||
const updateIndex = (resource) => {
|
||||
const capitalizedResource = resource[0].toUpperCase() + resource.slice(1)
|
||||
const currentIndex = this.$store.state.instance[`${resource}sIndex`]
|
||||
|
@ -100,6 +105,13 @@ const AppearanceTab = {
|
|||
})
|
||||
}
|
||||
|
||||
updateIndex('style').then(styles => {
|
||||
styles.forEach(([key, stylePromise]) => stylePromise.then(data => {
|
||||
const meta = data.find(x => x.component === '@meta')
|
||||
this.availableStyles.push({ key, data, name: meta.directives.name, version: 'v3' })
|
||||
}))
|
||||
})
|
||||
|
||||
updateIndex('theme').then(themes => {
|
||||
themes.forEach(([key, themePromise]) => themePromise.then(data => {
|
||||
this.availableStyles.push({ key, data, name: data.name, version: 'v2' })
|
||||
|
@ -164,14 +176,18 @@ const AppearanceTab = {
|
|||
]
|
||||
},
|
||||
stylePalettes () {
|
||||
if (!this.mergedConfig.styleCustomData) return
|
||||
const meta = this.mergedConfig.styleCustomData
|
||||
.find(x => x.component === '@meta')
|
||||
const result = this.mergedConfig.styleCustomData
|
||||
.filter(x => x.component.startsWith('@palette'))
|
||||
const ruleset = this.$store.state.interface.styleDataUsed || []
|
||||
console.log(
|
||||
'ASR',
|
||||
this.$store.state.interface.paletteDataUsed,
|
||||
this.$store.state.interface.styleDataUsed
|
||||
)
|
||||
if (!ruleset && ruleset.length === 0) return
|
||||
const meta = ruleset.find(x => x.component === '@meta')
|
||||
const result = ruleset.filter(x => x.component.startsWith('@palette'))
|
||||
.map(x => {
|
||||
const { variant, directives } = x
|
||||
const {
|
||||
variant,
|
||||
bg,
|
||||
fg,
|
||||
text,
|
||||
|
@ -182,10 +198,10 @@ const AppearanceTab = {
|
|||
cGreen,
|
||||
cOrange,
|
||||
wallpaper
|
||||
} = x
|
||||
} = directives
|
||||
|
||||
const result = {
|
||||
name: `${meta.name}: ${variant}`,
|
||||
name: `${meta.directives.name || this.$t('settings.style.themes3.palette.imported')}: ${variant}`,
|
||||
bg,
|
||||
fg,
|
||||
text,
|
||||
|
@ -238,12 +254,12 @@ const AppearanceTab = {
|
|||
return themeVersion
|
||||
},
|
||||
isCustomThemeUsed () {
|
||||
const { theme } = this.mergedConfig
|
||||
return theme === 'custom'
|
||||
const { customTheme, customThemeSource } = this.mergedConfig
|
||||
return customTheme != null || customThemeSource != null
|
||||
},
|
||||
isCustomStyleUsed (name) {
|
||||
const { style } = this.mergedConfig
|
||||
return style === 'custom'
|
||||
const { styleCustomData } = this.mergedConfig
|
||||
return styleCustomData != null
|
||||
},
|
||||
...SharedComputedObject()
|
||||
},
|
||||
|
@ -263,21 +279,33 @@ const AppearanceTab = {
|
|||
importFile () {
|
||||
this.fileImporter.importData()
|
||||
},
|
||||
importParser (file, filename) {
|
||||
if (filename.endsWith('.json')) {
|
||||
return JSON.parse(file)
|
||||
} else if (filename.endsWith('.piss')) {
|
||||
return deserialize(file)
|
||||
}
|
||||
},
|
||||
onImport (parsed, filename) {
|
||||
if (filename.endsWith('.json')) {
|
||||
this.$store.dispatch('setThemeCustom', parsed.source || parsed.theme)
|
||||
this.$store.dispatch('applyTheme')
|
||||
} else if (filename.endsWith('.piss')) {
|
||||
this.$store.dispatch('setStyleCustom', parsed)
|
||||
}
|
||||
|
||||
// this.loadTheme(parsed, 'file', forceSource)
|
||||
},
|
||||
onImportFailure (result) {
|
||||
console.error('Failure importing theme:', result)
|
||||
this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' })
|
||||
},
|
||||
importValidator (parsed, filename) {
|
||||
if (filename.endsWith('.json')) {
|
||||
const version = parsed._pleroma_theme_version
|
||||
return version >= 1 || version <= 2
|
||||
} else if (filename.endsWith('.piss')) {
|
||||
if (!Array.isArray(parsed)) return false
|
||||
if (parsed.length < 1) return false
|
||||
if (parsed.find(x => x.component === '@meta') == null) return false
|
||||
return true
|
||||
}
|
||||
},
|
||||
isThemeActive (key) {
|
||||
|
@ -293,7 +321,7 @@ const AppearanceTab = {
|
|||
return key === palette
|
||||
},
|
||||
setStyle (name) {
|
||||
this.$store.dispatch('setTheme', name)
|
||||
this.$store.dispatch('setStyle', name)
|
||||
},
|
||||
setTheme (name) {
|
||||
this.$store.dispatch('setTheme', name)
|
||||
|
@ -309,18 +337,30 @@ const AppearanceTab = {
|
|||
resetTheming (name) {
|
||||
this.$store.dispatch('setStyle', 'stock')
|
||||
},
|
||||
previewTheme (key, input) {
|
||||
previewTheme (key, version, input) {
|
||||
let theme3
|
||||
if (input) {
|
||||
const style = normalizeThemeData(input)
|
||||
const theme2 = convertTheme2To3(style)
|
||||
theme3 = init({
|
||||
inputRuleset: theme2,
|
||||
ultimateBackgroundColor: '#000000',
|
||||
liteMode: true,
|
||||
debug: true,
|
||||
onlyNormalState: true
|
||||
})
|
||||
if (this.compilationCache[key]) {
|
||||
theme3 = this.compilationCache[key]
|
||||
} else if (input) {
|
||||
if (version === 'v2') {
|
||||
const style = normalizeThemeData(input)
|
||||
const theme2 = convertTheme2To3(style)
|
||||
theme3 = init({
|
||||
inputRuleset: theme2,
|
||||
ultimateBackgroundColor: '#000000',
|
||||
liteMode: true,
|
||||
debug: true,
|
||||
onlyNormalState: true
|
||||
})
|
||||
} else if (version === 'v3') {
|
||||
theme3 = init({
|
||||
inputRuleset: input,
|
||||
ultimateBackgroundColor: '#000000',
|
||||
liteMode: true,
|
||||
debug: true,
|
||||
onlyNormalState: true
|
||||
})
|
||||
}
|
||||
} else {
|
||||
theme3 = init({
|
||||
inputRuleset: [],
|
||||
|
@ -331,6 +371,10 @@ const AppearanceTab = {
|
|||
})
|
||||
}
|
||||
|
||||
if (!this.compilationCache[key]) {
|
||||
this.compilationCache[key] = theme3
|
||||
}
|
||||
|
||||
return getScopedVersion(
|
||||
getCssRules(theme3.eager),
|
||||
'#theme-preview-' + key
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
||||
<component
|
||||
:is="'style'"
|
||||
v-html="previewTheme('stock')"
|
||||
v-html="previewTheme('stock', 'v3')"
|
||||
/>
|
||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
||||
<preview id="theme-preview-stock" />
|
||||
|
@ -30,7 +30,7 @@
|
|||
<button
|
||||
v-if="isCustomThemeUsed"
|
||||
disabled
|
||||
class="button-default theme-preview"
|
||||
class="button-default theme-preview toggled"
|
||||
>
|
||||
<preview />
|
||||
<h4 class="theme-name">
|
||||
|
@ -38,20 +38,32 @@
|
|||
<span class="alert neutral version">v2</span>
|
||||
</h4>
|
||||
</button>
|
||||
<button
|
||||
v-if="isCustomStyleUsed"
|
||||
disabled
|
||||
class="button-default theme-preview toggled"
|
||||
>
|
||||
<preview />
|
||||
<h4 class="theme-name">
|
||||
{{ $t('settings.style.custom_style_used') }}
|
||||
<span class="alert neutral version">v3</span>
|
||||
</h4>
|
||||
</button>
|
||||
<button
|
||||
v-for="style in availableStyles"
|
||||
:key="style.key"
|
||||
:data-theme-key="style.key"
|
||||
class="button-default theme-preview"
|
||||
:class="{ toggled: isThemeActive(style.key) }"
|
||||
@click="setTheme(style.key)"
|
||||
@click="style.version == 'v2' ? setTheme(style.key) : setStyle(style.key)"
|
||||
>
|
||||
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
|
||||
<component
|
||||
:is="'style'"
|
||||
v-if="style.ready || noIntersectionObserver"
|
||||
v-html="previewTheme(style.key, style.data)"
|
||||
/>
|
||||
<div v-if="style.ready || noIntersectionObserver">
|
||||
<component
|
||||
:is="'style'"
|
||||
v-html="previewTheme(style.key, style.version, style.data)"
|
||||
/>
|
||||
</div>
|
||||
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
|
||||
<preview :id="'theme-preview-' + style.key" />
|
||||
<h4 class="theme-name">
|
||||
|
@ -102,7 +114,7 @@
|
|||
@click="() => setPaletteCustom(p)"
|
||||
>
|
||||
<label>
|
||||
{{ p.name }}
|
||||
{{ p.name ?? $t('settings.style.themes3.palette.user') }}
|
||||
</label>
|
||||
<span
|
||||
v-for="c in palettesKeys"
|
||||
|
|
|
@ -86,7 +86,6 @@ export default {
|
|||
|
||||
exports.isActive = computed(() => {
|
||||
const tabSwitcher = getCurrentInstance().parent.ctx
|
||||
console.log('TABSW', tabSwitcher)
|
||||
return tabSwitcher ? tabSwitcher.isActive('style') : false
|
||||
})
|
||||
|
||||
|
@ -109,10 +108,12 @@ export default {
|
|||
|
||||
const metaRule = computed(() => ({
|
||||
component: '@meta',
|
||||
name: exports.name.value,
|
||||
author: exports.author.value,
|
||||
license: exports.license.value,
|
||||
website: exports.website.value
|
||||
directives: {
|
||||
name: exports.name.value,
|
||||
author: exports.author.value,
|
||||
license: exports.license.value,
|
||||
website: exports.website.value
|
||||
}
|
||||
}))
|
||||
|
||||
// ## Palette stuff
|
||||
|
@ -190,9 +191,9 @@ export default {
|
|||
return {
|
||||
component: '@palette',
|
||||
variant: name,
|
||||
...Object
|
||||
directives: Object
|
||||
.entries(rest)
|
||||
.filter(([k, v]) => v)
|
||||
.filter(([k, v]) => v && k)
|
||||
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {})
|
||||
}
|
||||
})
|
||||
|
@ -203,6 +204,7 @@ export default {
|
|||
return palettes.map(({ name, ...palette }) => {
|
||||
const entries = Object
|
||||
.entries(palette)
|
||||
.filter(([k, v]) => v && k)
|
||||
.map(([slot, data]) => ` ${slot}: ${data};`)
|
||||
.join('\n')
|
||||
|
||||
|
@ -561,7 +563,9 @@ export default {
|
|||
const virtualDirectivesOut = computed(() => {
|
||||
return [
|
||||
'Root {',
|
||||
...virtualDirectives.value.map(vd => ` --${vd.name}: ${vd.valType} | ${vd.value};`),
|
||||
...virtualDirectives.value
|
||||
.filter(vd => vd.name && vd.valType && vd.value)
|
||||
.map(vd => ` --${vd.name}: ${vd.valType} | ${vd.value};`),
|
||||
'}'
|
||||
].join('\n')
|
||||
})
|
||||
|
@ -597,7 +601,11 @@ export default {
|
|||
|
||||
const styleImporter = newImporter({
|
||||
accept: '.piss',
|
||||
parser: (string) => deserialize(string),
|
||||
parser (string) { return deserialize(string) },
|
||||
onImportFailure (result) {
|
||||
console.error('Failure importing style:', result)
|
||||
this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' })
|
||||
},
|
||||
onImport (parsed, filename) {
|
||||
const editorComponents = parsed.filter(x => x.component.startsWith('@'))
|
||||
const rootComponent = parsed.find(x => x.component === 'Root')
|
||||
|
|
|
@ -750,6 +750,7 @@
|
|||
"more_settings": "More settings",
|
||||
"style": {
|
||||
"custom_theme_used": "(Custom theme)",
|
||||
"custom_style_used": "(Custom style)",
|
||||
"stock_theme_used": "(Stock theme)",
|
||||
"themes2_outdated": "Editor for Themes V2 is being phased out and will eventually be replaced with a new one that takes advantage of new Themes V3 engine. It should still work but experience might be degraded and inconsistent.",
|
||||
"appearance_tab_note": "Changes on this tab do not affect the theme used, so exported theme will be different from what seen in the UI",
|
||||
|
@ -775,7 +776,8 @@
|
|||
"v2_unsupported": "Older v2 themes don't support palettes. Switch to v3 theme to make use of palettes",
|
||||
"bundled": "Bundled palettes",
|
||||
"style": "Palettes provided by selected style",
|
||||
"user": "Custom palette"
|
||||
"user": "Custom palette",
|
||||
"imported": "Imported"
|
||||
},
|
||||
"editor": {
|
||||
"title": "Style",
|
||||
|
|
|
@ -48,7 +48,9 @@ export const defaultState = {
|
|||
|
||||
// V3
|
||||
style: null,
|
||||
styleCustomData: null,
|
||||
palette: null,
|
||||
paletteCustomData: null,
|
||||
themeDebug: false, // debug mode that uses computed backgrounds instead of real ones to debug contrast functions
|
||||
forceThemeRecompilation: false, // flag that forces recompilation on boot even if cache exists
|
||||
theme3hacks: { // Hacks, user overrides that are independent of theme used
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import { getResourcesIndex, applyTheme, tryLoadCache } from '../services/style_setter/style_setter.js'
|
||||
import { CURRENT_VERSION, generatePreset } from 'src/services/theme_data/theme_data.service.js'
|
||||
import { convertTheme2To3 } from 'src/services/theme_data/theme2_to_theme3.js'
|
||||
import { deserialize } from '../services/theme_data/iss_deserializer.js'
|
||||
|
||||
const defaultState = {
|
||||
localFonts: null,
|
||||
themeApplied: false,
|
||||
themeVersion: 'v3',
|
||||
styleNameUsed: null,
|
||||
styleDataUsed: null,
|
||||
paletteNameUsed: null,
|
||||
paletteDataUsed: null,
|
||||
themeNameUsed: null,
|
||||
themeDataUsed: null,
|
||||
temporaryChangesTimeoutId: null, // used for temporary options that revert after a timeout
|
||||
temporaryChangesConfirm: () => {}, // used for applying temporary options
|
||||
temporaryChangesRevert: () => {}, // used for reverting temporary options
|
||||
|
@ -242,7 +249,10 @@ const interfaceMod = {
|
|||
},
|
||||
async fetchStylesIndex ({ commit, state }) {
|
||||
try {
|
||||
const value = await getResourcesIndex('/static/styles/index.json')
|
||||
const value = await getResourcesIndex(
|
||||
'/static/styles/index.json',
|
||||
deserialize
|
||||
)
|
||||
commit('setInstanceOption', { name: 'stylesIndex', value })
|
||||
return value
|
||||
} catch (e) {
|
||||
|
@ -310,17 +320,44 @@ const interfaceMod = {
|
|||
commit('setOption', { name: 'customTheme', value: null })
|
||||
commit('setOption', { name: 'customThemeSource', value: null })
|
||||
},
|
||||
async applyTheme (
|
||||
{ dispatch, commit, rootState, state },
|
||||
{ recompile = false } = {}
|
||||
) {
|
||||
// If we're not not forced to recompile try using
|
||||
// cache (tryLoadCache return true if load successful)
|
||||
async getThemeData ({ dispatch, commit, rootState, state }) {
|
||||
console.log('GET THEME DATA CALLED')
|
||||
const getData = async (resource, index, customData, name) => {
|
||||
const capitalizedResource = resource[0].toUpperCase() + resource.slice(1)
|
||||
const result = {}
|
||||
|
||||
if (customData) {
|
||||
result.nameUsed = 'custom' // custom data overrides name
|
||||
result.dataUsed = customData
|
||||
} else {
|
||||
result.nameUsed = name
|
||||
|
||||
if (result.nameUsed === 'stock') {
|
||||
result.dataUsed = null
|
||||
return result
|
||||
}
|
||||
|
||||
let fetchFunc = index[result.nameUsed]
|
||||
// Fallbacks
|
||||
if (!fetchFunc) {
|
||||
const newName = Object.keys(index)[0]
|
||||
fetchFunc = index[newName]
|
||||
console.warn(`${capitalizedResource} with id '${state.styleNameUsed}' not found, trying back to '${newName}'`)
|
||||
if (!fetchFunc) {
|
||||
console.warn(`${capitalizedResource} doesn't have a fallback, defaulting to stock.`)
|
||||
fetchFunc = () => Promise.resolve(null)
|
||||
}
|
||||
}
|
||||
result.dataUsed = await fetchFunc()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const {
|
||||
style: instanceStyleName,
|
||||
palette: instancePaletteName
|
||||
} = rootState.instance
|
||||
|
||||
let {
|
||||
theme: instanceThemeV2Name,
|
||||
themesIndex,
|
||||
|
@ -332,22 +369,15 @@ const interfaceMod = {
|
|||
style: userStyleName,
|
||||
styleCustomData: userStyleCustomData,
|
||||
palette: userPaletteName,
|
||||
paletteCustomData: userPaletteCustomData,
|
||||
forceThemeRecompilation,
|
||||
themeDebug,
|
||||
theme3hacks
|
||||
paletteCustomData: userPaletteCustomData
|
||||
} = rootState.config
|
||||
|
||||
let {
|
||||
theme: userThemeV2Name,
|
||||
customTheme: userThemeV2Snapshot,
|
||||
customThemeSource: userThemeV2Source
|
||||
} = rootState.config
|
||||
|
||||
const forceRecompile = forceThemeRecompilation || recompile
|
||||
if (!forceRecompile && !themeDebug && tryLoadCache()) {
|
||||
return commit('setThemeApplied')
|
||||
}
|
||||
|
||||
let majorVersionUsed
|
||||
|
||||
console.debug(
|
||||
|
@ -408,44 +438,6 @@ const interfaceMod = {
|
|||
|
||||
state.themeVersion = majorVersionUsed
|
||||
|
||||
let styleDataUsed = null
|
||||
let styleNameUsed = null
|
||||
let paletteDataUsed = null
|
||||
// let paletteNameUsed = null
|
||||
// let themeNameUsed = null
|
||||
let themeDataUsed = null
|
||||
|
||||
const getData = async (resource, index, customData, name) => {
|
||||
const capitalizedResource = resource[0].toUpperCase() + resource.slice(1)
|
||||
const result = {}
|
||||
|
||||
if (customData) {
|
||||
result.nameUsed = 'custom' // custom data overrides name
|
||||
result.dataUsed = customData
|
||||
} else {
|
||||
result.nameUsed = name
|
||||
|
||||
if (result.nameUsed === 'stock') {
|
||||
result.dataUsed = null
|
||||
return result
|
||||
}
|
||||
|
||||
let fetchFunc = index[result.nameUsed]
|
||||
// Fallbacks
|
||||
if (!fetchFunc) {
|
||||
const newName = Object.keys(index)[0]
|
||||
fetchFunc = index[newName]
|
||||
console.warn(`${capitalizedResource} with id '${styleNameUsed}' not found, trying back to '${newName}'`)
|
||||
if (!fetchFunc) {
|
||||
console.warn(`${capitalizedResource} doesn't have a fallback, defaulting to stock.`)
|
||||
fetchFunc = () => Promise.resolve(null)
|
||||
}
|
||||
}
|
||||
result.dataUsed = await fetchFunc()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
console.debug('Version used', majorVersionUsed)
|
||||
|
||||
if (majorVersionUsed === 'v3') {
|
||||
|
@ -455,9 +447,9 @@ const interfaceMod = {
|
|||
userPaletteCustomData,
|
||||
userPaletteName || instancePaletteName
|
||||
)
|
||||
// paletteNameUsed = palette.nameUsed
|
||||
paletteDataUsed = palette.dataUsed
|
||||
if (Array.isArray(paletteDataUsed)) {
|
||||
state.paletteNameUsed = palette.nameUsed
|
||||
state.paletteDataUsed = palette.dataUsed
|
||||
if (Array.isArray(state.paletteDataUsed)) {
|
||||
const [
|
||||
name,
|
||||
bg,
|
||||
|
@ -468,10 +460,10 @@ const interfaceMod = {
|
|||
cGreen = '#00FF00',
|
||||
cBlue = '#0000FF',
|
||||
cOrange = '#E3FF00'
|
||||
] = paletteDataUsed
|
||||
paletteDataUsed = { name, bg, fg, text, link, cRed, cBlue, cGreen, cOrange }
|
||||
] = palette.dataUsed
|
||||
state.paletteDataUsed = { name, bg, fg, text, link, cRed, cBlue, cGreen, cOrange }
|
||||
}
|
||||
console.debug('Palette data used', paletteDataUsed)
|
||||
console.debug('Palette data used', palette.dataUsed)
|
||||
|
||||
const style = await getData(
|
||||
'style',
|
||||
|
@ -479,8 +471,14 @@ const interfaceMod = {
|
|||
userStyleCustomData,
|
||||
userStyleName || instanceStyleName
|
||||
)
|
||||
styleNameUsed = style.nameUsed
|
||||
styleDataUsed = style.dataUsed
|
||||
state.styleNameUsed = style.nameUsed
|
||||
state.styleDataUsed = style.dataUsed
|
||||
|
||||
console.log(
|
||||
'GOT THEME DATA',
|
||||
state.styleDataUsed,
|
||||
state.paletteDataUsed
|
||||
)
|
||||
} else {
|
||||
const theme = await getData(
|
||||
'theme',
|
||||
|
@ -489,25 +487,40 @@ const interfaceMod = {
|
|||
userThemeV2Name || instanceThemeV2Name
|
||||
)
|
||||
// themeNameUsed = theme.nameUsed
|
||||
themeDataUsed = theme.dataUsed
|
||||
|
||||
// Themes v2 editor support
|
||||
commit('setInstanceOption', { name: 'themeData', value: themeDataUsed })
|
||||
state.themeDataUsed = theme.dataUsed
|
||||
}
|
||||
},
|
||||
async applyTheme (
|
||||
{ dispatch, commit, rootState, state },
|
||||
{ recompile = false } = {}
|
||||
) {
|
||||
const {
|
||||
forceThemeRecompilation,
|
||||
themeDebug,
|
||||
theme3hacks
|
||||
} = rootState.config
|
||||
// If we're not not forced to recompile try using
|
||||
// cache (tryLoadCache return true if load successful)
|
||||
|
||||
const forceRecompile = forceThemeRecompilation || recompile
|
||||
if (!forceRecompile && !themeDebug && await tryLoadCache()) {
|
||||
return commit('setThemeApplied')
|
||||
}
|
||||
await dispatch('getThemeData')
|
||||
|
||||
// commit('setOption', { name: 'palette', value: paletteNameUsed })
|
||||
// commit('setOption', { name: 'style', value: styleNameUsed })
|
||||
// commit('setOption', { name: 'theme', value: themeNameUsed })
|
||||
|
||||
const paletteIss = (() => {
|
||||
if (!paletteDataUsed) return null
|
||||
if (!state.paletteDataUsed) return null
|
||||
const result = {
|
||||
component: 'Root',
|
||||
directives: {}
|
||||
}
|
||||
|
||||
Object
|
||||
.entries(paletteDataUsed)
|
||||
.entries(state.paletteDataUsed)
|
||||
.filter(([k]) => k !== 'name')
|
||||
.forEach(([k, v]) => {
|
||||
let issRootDirectiveName
|
||||
|
@ -526,7 +539,7 @@ const interfaceMod = {
|
|||
return result
|
||||
})()
|
||||
|
||||
const theme2ruleset = themeDataUsed && convertTheme2To3(normalizeThemeData(themeDataUsed))
|
||||
const theme2ruleset = state.themeDataUsed && convertTheme2To3(normalizeThemeData(state.themeDataUsed))
|
||||
const hacks = []
|
||||
|
||||
Object.entries(theme3hacks).forEach(([key, value]) => {
|
||||
|
@ -593,7 +606,7 @@ const interfaceMod = {
|
|||
|
||||
const rulesetArray = [
|
||||
theme2ruleset,
|
||||
styleDataUsed,
|
||||
state.styleDataUsed,
|
||||
paletteIss,
|
||||
hacks
|
||||
].filter(x => x)
|
||||
|
|
|
@ -46,7 +46,7 @@ export const newImporter = ({
|
|||
const reader = new FileReader()
|
||||
reader.onload = ({ target }) => {
|
||||
try {
|
||||
const parsed = parser(target.result)
|
||||
const parsed = parser(target.result, filename)
|
||||
const validationResult = validator(parsed, filename)
|
||||
if (validationResult === true) {
|
||||
onImport(parsed, filename)
|
||||
|
|
|
@ -226,7 +226,7 @@ export const applyConfig = (input, i18n) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const getResourcesIndex = async (url) => {
|
||||
export const getResourcesIndex = async (url, parser = JSON.parse) => {
|
||||
const cache = 'no-store'
|
||||
|
||||
try {
|
||||
|
@ -243,8 +243,9 @@ export const getResourcesIndex = async (url) => {
|
|||
k,
|
||||
() => window
|
||||
.fetch(v, { cache })
|
||||
.then((data) => data.json())
|
||||
.catch((e) => {
|
||||
.then(data => data.text())
|
||||
.then(text => parser(text))
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
return null
|
||||
})
|
||||
|
|
127
static/styles/Redmond DX.piss
Normal file
127
static/styles/Redmond DX.piss
Normal file
|
@ -0,0 +1,127 @@
|
|||
@meta {
|
||||
name: Redmond DX;
|
||||
author: HJ;
|
||||
license: WTFPL;
|
||||
website: ebin.club;
|
||||
}
|
||||
|
||||
@palette.Modern {
|
||||
bg: #D3CFC7;
|
||||
fg: #092369;
|
||||
text: #000000;
|
||||
link: #0000FF;
|
||||
accent: #A5C9F0;
|
||||
cRed: #FF3000;
|
||||
cBlue: #009EFF;
|
||||
cGreen: #309E00;
|
||||
cOrange: #FFCE00;
|
||||
}
|
||||
|
||||
@palette.Classic {
|
||||
bg: #BFBFBF;
|
||||
fg: #000180;
|
||||
text: #000000;
|
||||
link: #0000FF;
|
||||
accent: #A5C9F0;
|
||||
cRed: #FF0000;
|
||||
cBlue: #2E2ECE;
|
||||
cGreen: #007E00;
|
||||
cOrange: #CE8F5F;
|
||||
}
|
||||
|
||||
@palette.Vapor {
|
||||
bg: #F0ADCD;
|
||||
fg: #bca4ee;
|
||||
text: #602040;
|
||||
link: #064745;
|
||||
accent: #9DF7C8;
|
||||
cRed: #86004a;
|
||||
cBlue: #0e5663;
|
||||
cGreen: #0a8b51;
|
||||
cOrange: #787424;
|
||||
}
|
||||
|
||||
Root {
|
||||
--gradientColor: color | --accent;
|
||||
--inputColor: color | #FFFFFF;
|
||||
--bevelLight: color | $brightness(--bg 50);
|
||||
--bevelDark: color | $brightness(--bg -20);
|
||||
--bevelExtraDark: color | #404040;
|
||||
--buttonDefaultBevel: shadow | $borderSide(--bevelExtraDark bottom-right 1 1), $borderSide(--bevelLight top-left 1 1), $borderSide(--bevelDark bottom-right 1 2);
|
||||
--buttonPressedBevel: shadow | inset 0 0 0 1 #000000 / 1 #Outer , inset 0 0 0 2 --bevelExtraDark / 1 #inner;
|
||||
--defaultInputBevel: shadow | $borderSide(--bevelLight bottom-right 1), $borderSide(--bevelDark top-left 1 1), $borderSide(--bg bottom-right 1 2), $borderSide(--bevelExtraDark top-left 1 2);
|
||||
}
|
||||
|
||||
Button:toggled {
|
||||
background: --bg;
|
||||
shadow: --buttonPressedBevel
|
||||
}
|
||||
|
||||
Button:focused {
|
||||
shadow: --buttonDefaultBevel, 0 0 0 1 #000000 / 1
|
||||
}
|
||||
|
||||
Button:pressed {
|
||||
shadow: --buttonPressedBevel
|
||||
}
|
||||
|
||||
Button:hover {
|
||||
shadow: --buttonDefaultBevel;
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Button {
|
||||
shadow: --buttonDefaultBevel;
|
||||
background: --bg;
|
||||
roundness: 0
|
||||
}
|
||||
|
||||
Button:pressed:hover {
|
||||
shadow: --buttonPressedBevel
|
||||
}
|
||||
|
||||
Input {
|
||||
background: $mod(--bg -80);
|
||||
shadow: --defaultInputBevel;
|
||||
roundness: 0
|
||||
}
|
||||
|
||||
Panel {
|
||||
shadow: --buttonDefaultBevel;
|
||||
roundness: 0
|
||||
}
|
||||
|
||||
PanelHeader {
|
||||
shadow: inset -1100 0 1000 -1000 --gradientColor / 1 #Gradient ;
|
||||
background: --fg
|
||||
}
|
||||
|
||||
Tab:hover {
|
||||
background: --bg;
|
||||
shadow: --buttonDefaultBevel
|
||||
}
|
||||
|
||||
Tab:active {
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Tab:active:hover {
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Tab:active:hover:disabled {
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Tab:hover:disabled {
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Tab:disabled {
|
||||
background: --bg
|
||||
}
|
||||
|
||||
Tab {
|
||||
background: --bg;
|
||||
shadow: --buttonDefaultBevel
|
||||
}
|
3
static/styles/index.json
Normal file
3
static/styles/index.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"RedmondDX": "/static/styles/Redmond DX.piss"
|
||||
}
|
Loading…
Add table
Reference in a new issue