diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue new file mode 100644 index 00000000..9914d54a --- /dev/null +++ b/src/components/export_import/export_import.vue @@ -0,0 +1,75 @@ + + + diff --git a/src/components/style_switcher/preview.vue b/src/components/style_switcher/preview.vue new file mode 100644 index 00000000..09a136e9 --- /dev/null +++ b/src/components/style_switcher/preview.vue @@ -0,0 +1,78 @@ + diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index adcbee25..50cd1e6f 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -8,6 +8,8 @@ import ShadowControl from '../shadow_control/shadow_control.vue' import FontControl from '../font_control/font_control.vue' import ContrastRatio from '../contrast_ratio/contrast_ratio.vue' import TabSwitcher from '../tab_switcher/tab_switcher.jsx' +import Preview from './preview.vue' +import ExportImport from '../export_import/export_import.vue' // List of color values used in v1 const v1OnlyNames = [ @@ -26,7 +28,6 @@ export default { return { availableStyles: [], selected: this.$store.state.config.theme, - invalidThemeImported: false, previewShadows: {}, previewColors: {}, @@ -293,20 +294,11 @@ export default { }, themeValid () { return !this.shadowsInvalid && !this.colorsInvalid && !this.radiiInvalid - } - }, - components: { - ColorInput, - OpacityInput, - RangeInput, - ContrastRatio, - ShadowControl, - FontControl, - TabSwitcher - }, - methods: { - exportCurrentTheme () { + }, + exportedTheme () { const saveEverything = !this.keepFonts && !this.keepShadows && !this.keepColors && !this.keepOpacity && !this.keepRoundness + + // TODO change into delete-less version. const theme = { shadows: this.shadowsLocal, fonts: this.fontsLocal, @@ -331,57 +323,24 @@ export default { delete theme.radii } - const stringified = JSON.stringify({ + return { // To separate from other random JSON files and possible future theme formats _pleroma_theme_version: 2, theme - }, 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') - e.setAttribute('download', 'pleroma_theme.json') - e.setAttribute('href', 'data:application/json;base64,' + window.btoa(stringified)) - e.style.display = 'none' - - document.body.appendChild(e) - e.click() - document.body.removeChild(e) - }, - - importTheme () { - this.invalidThemeImported = false - const filePicker = document.createElement('input') - filePicker.setAttribute('type', 'file') - filePicker.setAttribute('accept', '.json') - - filePicker.addEventListener('change', event => { - if (event.target.files[0]) { - // eslint-disable-next-line no-undef - const reader = new FileReader() - reader.onload = ({target}) => { - try { - const parsed = JSON.parse(target.result) - if (parsed._pleroma_theme_version === 1) { - this.normalizeLocalState(parsed, 1) - } else if (parsed._pleroma_theme_version === 2) { - this.normalizeLocalState(parsed.theme, 2) - } else { - // A theme from the future, spooky - this.invalidThemeImported = true - } - } catch (e) { - // This will happen both if there is a JSON syntax error or the theme is missing components - this.invalidThemeImported = true - } - } - reader.readAsText(event.target.files[0]) - } - }) - - document.body.appendChild(filePicker) - filePicker.click() - document.body.removeChild(filePicker) - }, - + } + } + }, + components: { + ColorInput, + OpacityInput, + RangeInput, + ContrastRatio, + ShadowControl, + FontControl, + TabSwitcher, + Preview, + ExportImport + }, + methods: { setCustomTheme () { this.$store.dispatch('setOption', { name: 'customTheme', @@ -394,7 +353,17 @@ export default { } }) }, - + onImport (parsed) { + if (parsed._pleroma_theme_version === 1) { + this.normalizeLocalState(parsed, 1) + } else if (parsed._pleroma_theme_version === 2) { + this.normalizeLocalState(parsed.theme, 2) + } + }, + importValidator (parsed) { + const version = parsed._pleroma_theme_version + return version >= 1 || version <= 2 + }, clearAll () { const state = this.$store.state.config.customTheme const version = state.colors ? 2 : 'l1' diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index 9de60f7b..730bfef0 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -18,11 +18,14 @@ -
- - -

{{ $t('settings.invalid_theme_imported') }}

-
+
@@ -58,82 +61,7 @@
-
-
-
- {{$t('settings.style.preview.header')}} - - 99 - -
- - {{$t('settings.style.preview.header_faint')}} - - - {{$t('settings.style.preview.error')}} - - -
-
-
-
- ( ͡° ͜ʖ ͡°) -
-
-

- {{$t('settings.style.preview.content')}} -

- - - - {{$t('settings.style.preview.mono')}} - - - {{$t('settings.style.preview.link')}} - - - -
- - - - -
-
-
- -
-
- :^) -
- -
-
- - - {{$t('settings.style.preview.error')}} - - - -
- - - - - -
-
-
+
@@ -235,6 +163,7 @@ +

{{$t('settings.radii_help')}}

@@ -249,6 +178,7 @@
+
@@ -294,6 +224,7 @@

{{$t('settings.style.shadows.filter_hint.spread_zero')}}

+

{{$t('settings.style.fonts.help')}}

diff --git a/src/modules/config.js b/src/modules/config.js index fb9b3ca6..45ac8f65 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -1,5 +1,5 @@ import { set, delete as del } from 'vue' -import { setPreset, setColors } from '../services/style_setter/style_setter.js' +import { setPreset, applyTheme } from '../services/style_setter/style_setter.js' const browserLocale = (window.navigator.language || 'en').split('-')[0] @@ -57,7 +57,7 @@ const config = { setPreset(value, commit) break case 'customTheme': - setColors(value, commit) + applyTheme(value, commit) } } }