commit: 313eb8f4cd1d7df910ca7862fdb472b8c9e90277
parent ca5c24452e9b6ac917e6920b73805d78d97fc503
Author: Henry Jameson <me@hjkos.com>
Date: Tue, 19 Nov 2024 03:18:52 +0200
bundling theme now works and so are bundled style's palettes
Diffstat:
9 files changed, 290 insertions(+), 225 deletions(-)
diff --git a/src/components/button.style.js b/src/components/button.style.js
@@ -90,6 +90,13 @@ export default {
}
},
{
+ state: ['toggled', 'disabled'],
+ directives: {
+ background: '$blend(--inheritedBackground 0.25 --parent)',
+ shadow: ['--buttonPressedBevel']
+ }
+ },
+ {
state: ['disabled'],
directives: {
background: '$blend(--inheritedBackground 0.25 --parent)',
diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js
@@ -36,6 +36,7 @@ const AppearanceTab = {
return {
availableStyles: [],
bundledPalettes: [],
+ compilationCache: {},
fileImporter: newImporter({
accept: '.json, .piss',
validator: this.importValidator,
@@ -84,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`]
@@ -102,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' })
@@ -166,11 +176,15 @@ 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 {
@@ -307,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)
@@ -323,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: [],
@@ -345,6 +371,10 @@ const AppearanceTab = {
})
}
+ if (!this.compilationCache[key]) {
+ this.compilationCache[key] = theme3
+ }
+
return getScopedVersion(
getCssRules(theme3.eager),
'#theme-preview-' + key
diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue
@@ -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">
@@ -39,19 +39,31 @@
</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">
diff --git a/src/modules/config.js b/src/modules/config.js
@@ -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
diff --git a/src/modules/interface.js b/src/modules/interface.js
@@ -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 && await 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
+ 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)
- // Themes v2 editor support
- commit('setInstanceOption', { name: 'themeData', value: themeDataUsed })
+ 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)
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
@@ -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
})
diff --git a/static/styles/Redmond DX.json b/static/styles/Redmond DX.json
@@ -1,127 +0,0 @@
-@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: #a177ee;
- text: #602040;
- link: #086866;
- accent: #9DF7C8;
- cRed: #ff0088;
- cBlue: #20c8e9;
- cGreen: #0fd27d;
- cOrange: #ECE646;
-}
-
-Root {
- --gradientColor: color | $brightness(--fg, 20);
- --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
-}
diff --git a/static/styles/Redmond DX.piss b/static/styles/Redmond DX.piss
@@ -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
+}
diff --git a/static/styles/index.json b/static/styles/index.json
@@ -1,3 +1,3 @@
{
- "Redmond DX": "/static/styles/Redmond DX.json"
+ "RedmondDX": "/static/styles/Redmond DX.piss"
}