diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue index 20c6f569..ae00487f 100644 --- a/src/components/export_import/export_import.vue +++ b/src/components/export_import/export_import.vue @@ -42,7 +42,7 @@ export default { }, methods: { exportData () { - const stringified = JSON.stringify(this.exportObject) // Pretty-print and indent with 2 spaces + const stringified = JSON.stringify(this.exportObject, null, 2) // Pretty-print and indent with 2 spaces // Create an invisible link with a data url and simulate a click const e = document.createElement('a') diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index 1e512407..b450dc8e 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -1,6 +1,7 @@ import { rgb2hex, hex2rgb, getContrastRatio, alphaBlend } from '../../services/color_convert/color_convert.js' import { set, delete as del } from 'vue' -import { generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js' +import { merge } from 'lodash' +import { generateCompat, generateColors, generateShadows, generateRadii, generateFonts, composePreset, getThemes } from '../../services/style_setter/style_setter.js' import ColorInput from '../color_input/color_input.vue' import RangeInput from '../range_input/range_input.vue' import OpacityInput from '../opacity_input/opacity_input.vue' @@ -123,6 +124,15 @@ export default { selectedVersion () { return Array.isArray(this.selected) ? 1 : 2 }, + currentCompat () { + return generateCompat({ + shadows: this.shadowsLocal, + fonts: this.fontsLocal, + opacity: this.currentOpacity, + colors: this.currentColors, + radii: this.currentRadii + }) + }, currentColors () { return { bg: this.bgColorLocal, @@ -332,7 +342,7 @@ export default { return { // To separate from other random JSON files and possible future theme formats - _pleroma_theme_version: 2, theme + _pleroma_theme_version: 2, theme: merge(theme, this.currentCompat) } } }, @@ -364,7 +374,7 @@ export default { onImport (parsed) { if (parsed._pleroma_theme_version === 1) { this.normalizeLocalState(parsed, 1) - } else if (parsed._pleroma_theme_version === 2) { + } else if (parsed._pleroma_theme_version >= 2) { this.normalizeLocalState(parsed.theme, 2) } }, @@ -414,6 +424,7 @@ export default { /** * This applies stored theme data onto form. Supports three versions of data: + * v3 (version = 3) - same as 2 but with some incompatible changes * v2 (version = 2) - newer version of themes. * v1 (version = 1) - older version of themes (import from file) * v1l (version = l1) - older version of theme (load from local storage) @@ -421,12 +432,21 @@ export default { * @param {Object} input - input data * @param {Number} version - version of data. 0 means try to guess based on data. "l1" means v1, locastorage type */ - normalizeLocalState (input, version = 0) { - const colors = input.colors || input + normalizeLocalState (originalInput, version = 0) { + let input + if (typeof originalInput.v3compat !== undefined) { + version = 3 + input = merge(originalInput, originalInput.v3compat) + } else { + input = originalInput + } + + const compat = input.v3compat const radii = input.radii || input const opacity = input.opacity const shadows = input.shadows || {} const fonts = input.fonts || {} + const colors = input.colors || input if (version === 0) { if (input.version) version = input.version @@ -530,6 +550,7 @@ export default { currentColors () { try { this.previewColors = generateColors({ + v3compat: this.currentCompat, opacity: this.currentOpacity, colors: this.currentColors }) @@ -542,8 +563,9 @@ export default { currentOpacity () { try { this.previewColors = generateColors({ + v3compat: this.currentCompat, opacity: this.currentOpacity, - colors: this.currentColors + colors: this.currentColors, }) } catch (e) { console.warn(e) diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index 8bbdc7b7..2ecd275a 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -2,7 +2,7 @@
-
- +
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 1e4bc59e..19a06587 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -148,6 +148,26 @@ const getCssColor = (input, a) => { return rgb2rgba({ ...rgb, a }) } +// Generates a "patch" for theme to make it compatible with v2 +export const generateCompat = (input) => { + const { colors } = input + const v3compat = { + colors: {} + } + const v2colorsPatch = {} + + // # Link became optional in v3 + if (typeof colors.link === 'undefined') { + v2colorsPatch.link = colors.accent + v3compat.colors.link = null + } + + return { + v3compat, + colors: v2colorsPatch + } +} + const generateColors = (input) => { const colors = {} const opacity = Object.assign({ @@ -164,7 +184,10 @@ const generateColors = (input) => { const inputColors = input.colors || input const compat = input.v3compat || {} - const compatColors = compat.colors || {} + const compatColors = Object.entries(compat.colors || {}).reduce((acc, [key, value]) => { + const newVal = value === null ? undefined : value + return { ...acc, [key]: newVal } + }, {}) const col = Object.entries({ ...inputColors, ...compatColors }).reduce((acc, [k, v]) => { if (typeof v === 'object') { @@ -210,7 +233,7 @@ const generateColors = (input) => { colors.topBarText = col.topBarText || getTextColor(colors.topBar, colors.fgText) colors.topBarLink = col.topBarLink || getTextColor(colors.topBar, colors.fgLink) - colors.faintLink = col.faintLink || Object.assign({}, col.link) + colors.faintLink = col.faintLink || Object.assign({}, col.link || col.accent) colors.linkBg = alphaBlend(colors.link, 0.4, colors.bg) colors.icon = mixrgb(colors.bg, colors.text)