logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/
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:

Msrc/components/button.style.js7+++++++
Msrc/components/settings_modal/tabs/appearance_tab.js64+++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/components/settings_modal/tabs/appearance_tab.vue28++++++++++++++++++++--------
Msrc/modules/config.js2++
Msrc/modules/interface.js151+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/services/style_setter/style_setter.js7++++---
Dstatic/styles/Redmond DX.json127-------------------------------------------------------------------------------
Astatic/styles/Redmond DX.piss127+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mstatic/styles/index.json2+-
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" }