From 098879be3edf95ab06b05a1f64af2a48b718d5c4 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 17 Nov 2024 15:57:32 +0200 Subject: [PATCH 1/4] fix cache being used even if no cache exists --- src/modules/interface.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/interface.js b/src/modules/interface.js index ec885dbab..0af736717 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -344,7 +344,7 @@ const interfaceMod = { } = rootState.config const forceRecompile = forceThemeRecompilation || recompile - if (!forceRecompile && !themeDebug && tryLoadCache()) { + if (!forceRecompile && !themeDebug && await tryLoadCache()) { return commit('setThemeApplied') } From 973e8697bcd20c75c64e9a311b1b4f0966e35465 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 18 Nov 2024 03:53:37 +0200 Subject: [PATCH 2/4] added validation --- .../settings_modal/tabs/appearance_tab.js | 20 ++++++++++++++++--- .../tabs/style_tab/style_tab.js | 6 +++++- src/services/export_import/export_import.js | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index b4b401574..ddd501f23 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -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' @@ -39,6 +40,7 @@ const AppearanceTab = { accept: '.json, .piss', validator: this.importValidator, onImport: this.onImport, + parser: this.importParser, onImportFailure: this.onImportFailure }), palettesKeys: [ @@ -263,21 +265,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) { diff --git a/src/components/settings_modal/tabs/style_tab/style_tab.js b/src/components/settings_modal/tabs/style_tab/style_tab.js index aa83fda2a..dbf778db0 100644 --- a/src/components/settings_modal/tabs/style_tab/style_tab.js +++ b/src/components/settings_modal/tabs/style_tab/style_tab.js @@ -597,7 +597,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') diff --git a/src/services/export_import/export_import.js b/src/services/export_import/export_import.js index 8865061fc..348a9d006 100644 --- a/src/services/export_import/export_import.js +++ b/src/services/export_import/export_import.js @@ -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) From ca5c24452e9b6ac917e6920b73805d78d97fc503 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 19 Nov 2024 01:16:51 +0200 Subject: [PATCH 3/4] palettes/style meta inconsistency --- .../settings_modal/tabs/appearance_tab.js | 14 +- .../settings_modal/tabs/appearance_tab.vue | 2 +- .../tabs/style_tab/style_tab.js | 20 +-- src/i18n/en.json | 4 +- static/styles/Redmond DX.json | 127 ++++++++++++++++++ static/styles/index.json | 3 + 6 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 static/styles/Redmond DX.json create mode 100644 static/styles/index.json diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index ddd501f23..076bb995f 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -172,8 +172,8 @@ const AppearanceTab = { const result = this.mergedConfig.styleCustomData .filter(x => x.component.startsWith('@palette')) .map(x => { + const { variant, directives } = x const { - variant, bg, fg, text, @@ -184,10 +184,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, @@ -240,12 +240,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() }, diff --git a/src/components/settings_modal/tabs/appearance_tab.vue b/src/components/settings_modal/tabs/appearance_tab.vue index 6ec84eb28..32e0a37fa 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -102,7 +102,7 @@ @click="() => setPaletteCustom(p)" > { 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') }) diff --git a/src/i18n/en.json b/src/i18n/en.json index e77e56374..a34e5cf97 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -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", diff --git a/static/styles/Redmond DX.json b/static/styles/Redmond DX.json new file mode 100644 index 000000000..39018aa7e --- /dev/null +++ b/static/styles/Redmond DX.json @@ -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: #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/index.json b/static/styles/index.json new file mode 100644 index 000000000..2f1a3e8ec --- /dev/null +++ b/static/styles/index.json @@ -0,0 +1,3 @@ +{ + "Redmond DX": "/static/styles/Redmond DX.json" +} From 42087a564f0dc4ee84bd42e6ae32fc976ac5cfb2 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 19 Nov 2024 03:18:52 +0200 Subject: [PATCH 4/4] bundling theme now works and so are bundled style's palettes --- src/components/button.style.js | 7 + .../settings_modal/tabs/appearance_tab.js | 64 ++++++-- .../settings_modal/tabs/appearance_tab.vue | 28 +++- src/modules/config.js | 2 + src/modules/interface.js | 153 ++++++++++-------- src/services/style_setter/style_setter.js | 7 +- .../{Redmond DX.json => Redmond DX.piss} | 14 +- static/styles/index.json | 2 +- 8 files changed, 171 insertions(+), 106 deletions(-) rename static/styles/{Redmond DX.json => Redmond DX.piss} (93%) diff --git a/src/components/button.style.js b/src/components/button.style.js index 248da8bbd..747cfd5eb 100644 --- a/src/components/button.style.js +++ b/src/components/button.style.js @@ -89,6 +89,13 @@ export default { shadow: ['--buttonDefaultHoverGlow', '--buttonPressedBevel'] } }, + { + state: ['toggled', 'disabled'], + directives: { + background: '$blend(--inheritedBackground 0.25 --parent)', + shadow: ['--buttonPressedBevel'] + } + }, { state: ['disabled'], directives: { diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index 076bb995f..711b1961b 100644 --- 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 index 32e0a37fa..547b72c07 100644 --- a/src/components/settings_modal/tabs/appearance_tab.vue +++ b/src/components/settings_modal/tabs/appearance_tab.vue @@ -18,7 +18,7 @@ @@ -30,7 +30,7 @@ +