From 29f69de240530048a31319f8a78274ca7d607853 Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Thu, 28 Jun 2018 01:08:06 +0200 Subject: [PATCH 1/6] Add theme export feature --- src/components/style_switcher/style_switcher.js | 17 +++++++++++++++++ .../style_switcher/style_switcher.vue | 3 +++ src/i18n/messages.js | 1 + 3 files changed, 21 insertions(+) diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index 6f4845c4..041d4b17 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -51,6 +51,23 @@ export default { this.attachmentRadiusLocal = this.$store.state.config.radii.attachmentRadius || 5 }, methods: { + exportCurrentTheme () { + const stringified = JSON.stringify({ + colors: this.$store.state.config.colors, + radii: this.$store.state.config.radii + }, 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) + }, + setCustomTheme () { if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) { // reset to picked themes diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index 7acba1dc..c8d955e1 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -8,6 +8,9 @@ +
+ +

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

diff --git a/src/i18n/messages.js b/src/i18n/messages.js index e9d6e176..ee0fcd2a 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -288,6 +288,7 @@ const en = { settings: 'Settings', theme: 'Theme', presets: 'Presets', + export_theme: 'Export current theme', theme_help: 'Use hex color codes (#rrggbb) to customize your color theme.', radii_help: 'Set up interface edge rounding (in pixels)', background: 'Background', From f36984c4a4d1411d4ec4c6aad7f2740fe676a4fa Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Thu, 28 Jun 2018 02:07:50 +0200 Subject: [PATCH 2/6] Refactor theme settings state initialization --- .../style_switcher/style_switcher.js | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index 041d4b17..d5881a31 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -32,23 +32,7 @@ export default { }) }, mounted () { - this.bgColorLocal = rgbstr2hex(this.$store.state.config.colors.bg) - this.btnColorLocal = rgbstr2hex(this.$store.state.config.colors.btn) - this.textColorLocal = rgbstr2hex(this.$store.state.config.colors.fg) - this.linkColorLocal = rgbstr2hex(this.$store.state.config.colors.link) - - this.redColorLocal = rgbstr2hex(this.$store.state.config.colors.cRed) - this.blueColorLocal = rgbstr2hex(this.$store.state.config.colors.cBlue) - this.greenColorLocal = rgbstr2hex(this.$store.state.config.colors.cGreen) - this.orangeColorLocal = rgbstr2hex(this.$store.state.config.colors.cOrange) - - this.btnRadiusLocal = this.$store.state.config.radii.btnRadius || 4 - this.inputRadiusLocal = this.$store.state.config.radii.inputRadius || 4 - this.panelRadiusLocal = this.$store.state.config.radii.panelRadius || 10 - this.avatarRadiusLocal = this.$store.state.config.radii.avatarRadius || 5 - this.avatarAltRadiusLocal = this.$store.state.config.radii.avatarAltRadius || 50 - this.tooltipRadiusLocal = this.$store.state.config.radii.tooltipRadius || 2 - this.attachmentRadiusLocal = this.$store.state.config.radii.attachmentRadius || 5 + this.normalizeLocalState(this.$store.state.config.colors, this.$store.state.config.radii) }, methods: { exportCurrentTheme () { @@ -112,6 +96,26 @@ export default { attachmentRadius: this.attachmentRadiusLocal }}) } + }, + + normalizeLocalState (colors, radii) { + this.bgColorLocal = rgbstr2hex(colors.bg) + this.btnColorLocal = rgbstr2hex(colors.btn) + this.textColorLocal = rgbstr2hex(colors.fg) + this.linkColorLocal = rgbstr2hex(colors.link) + + this.redColorLocal = rgbstr2hex(colors.cRed) + this.blueColorLocal = rgbstr2hex(colors.cBlue) + this.greenColorLocal = rgbstr2hex(colors.cGreen) + this.orangeColorLocal = rgbstr2hex(colors.cOrange) + + this.btnRadiusLocal = radii.btnRadius || 4 + this.inputRadiusLocal = radii.inputRadius || 4 + this.panelRadiusLocal = radii.panelRadius || 10 + this.avatarRadiusLocal = radii.avatarRadius || 5 + this.avatarAltRadiusLocal = radii.avatarAltRadius || 50 + this.tooltipRadiusLocal = radii.tooltipRadius || 2 + this.attachmentRadiusLocal = radii.attachmentRadius || 5 } }, watch: { From d2b79856c61391e56009cdf313e332ee950b9081 Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Thu, 28 Jun 2018 02:59:57 +0200 Subject: [PATCH 3/6] Add theme import feature --- .../style_switcher/style_switcher.js | 22 +++++++++++++++++++ .../style_switcher/style_switcher.vue | 1 + src/i18n/messages.js | 1 + 3 files changed, 24 insertions(+) diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index d5881a31..7ab56ea2 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -52,6 +52,28 @@ export default { document.body.removeChild(e) }, + importTheme () { + 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}) => { + const parsed = JSON.parse(target.result) + this.normalizeLocalState(parsed.colors, parsed.radii) + } + reader.readAsText(event.target.files[0]) + } + }) + + document.body.appendChild(filePicker) + filePicker.click() + document.body.removeChild(filePicker) + }, + setCustomTheme () { if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) { // reset to picked themes diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index c8d955e1..0bc08bd7 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -10,6 +10,7 @@
+

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

diff --git a/src/i18n/messages.js b/src/i18n/messages.js index ee0fcd2a..cc9090c7 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -289,6 +289,7 @@ const en = { theme: 'Theme', presets: 'Presets', export_theme: 'Export current theme', + import_theme: 'Load saved theme', theme_help: 'Use hex color codes (#rrggbb) to customize your color theme.', radii_help: 'Set up interface edge rounding (in pixels)', background: 'Background', From fdc64cfa8aa9f85e4508a27429f339a946613420 Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Thu, 28 Jun 2018 03:10:37 +0200 Subject: [PATCH 4/6] Add German localization for theme import/export --- src/i18n/messages.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i18n/messages.js b/src/i18n/messages.js index cc9090c7..c44c08ac 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -48,6 +48,8 @@ const de = { settings: 'Einstellungen', theme: 'Farbschema', presets: 'Voreinstellungen', + export_theme: 'Aktuelles Theme exportieren', + import_theme: 'Gespeichertes Theme laden', theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen', radii_help: 'Kantenrundung (in Pixel) der Oberfläche anpassen', background: 'Hintergrund', From 8f7919388391742671ef0398e017383d7f0b2bc5 Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Wed, 4 Jul 2018 13:49:20 +0200 Subject: [PATCH 5/6] Unify button styles and use min-width This seemed to be the same across multiple components anyway. Switched to min-width to allow for buttons with longer text, e.g. from other languages. --- src/App.scss | 2 ++ src/components/login_form/login_form.vue | 5 ----- src/components/post_status_form/post_status_form.vue | 4 ---- src/components/settings/settings.vue | 2 -- 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/App.scss b/src/App.scss index f830a33b..402e7432 100644 --- a/src/App.scss +++ b/src/App.scss @@ -63,6 +63,8 @@ button{ box-shadow: 0px 0px 2px black; font-size: 14px; font-family: sans-serif; + min-width: 10em; + min-height: 2em; &:hover { box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3); diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue index b7fed48a..d2bdffcb 100644 --- a/src/components/login_form/login_form.vue +++ b/src/components/login_form/login_form.vue @@ -34,11 +34,6 @@ @import '../../_variables.scss'; .login-form { - .btn { - min-height: 28px; - width: 10em; - } - .error { text-align: center; } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 7aa0e7c4..2dda6a6e 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -124,10 +124,6 @@ padding: 0.5em; height: 32px; - button { - width: 10em; - } - p { margin: 0.35em; padding: 0.35em; diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 6245e758..4786b930 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -83,8 +83,6 @@ .btn { margin-top: 1em; - min-height: 28px; - width: 10em; } } .setting-list { From 2a87e29180641621301a9e04bc2f493e01f4ca33 Mon Sep 17 00:00:00 2001 From: Ole Bertram Date: Wed, 4 Jul 2018 14:25:40 +0200 Subject: [PATCH 6/6] Add validation of the imported theme and the corresponding warning message --- .../style_switcher/style_switcher.js | 18 ++++++++++++++++-- .../style_switcher/style_switcher.vue | 6 ++++++ src/i18n/messages.js | 2 ++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/style_switcher/style_switcher.js b/src/components/style_switcher/style_switcher.js index 7ab56ea2..95c15b49 100644 --- a/src/components/style_switcher/style_switcher.js +++ b/src/components/style_switcher/style_switcher.js @@ -5,6 +5,7 @@ export default { return { availableStyles: [], selected: this.$store.state.config.theme, + invalidThemeImported: false, bgColorLocal: '', btnColorLocal: '', textColorLocal: '', @@ -37,6 +38,8 @@ export default { methods: { exportCurrentTheme () { const stringified = JSON.stringify({ + // To separate from other random JSON files and possible future theme formats + _pleroma_theme_version: 1, colors: this.$store.state.config.colors, radii: this.$store.state.config.radii }, null, 2) // Pretty-print and indent with 2 spaces @@ -53,6 +56,7 @@ export default { }, importTheme () { + this.invalidThemeImported = false const filePicker = document.createElement('input') filePicker.setAttribute('type', 'file') filePicker.setAttribute('accept', '.json') @@ -62,8 +66,18 @@ export default { // eslint-disable-next-line no-undef const reader = new FileReader() reader.onload = ({target}) => { - const parsed = JSON.parse(target.result) - this.normalizeLocalState(parsed.colors, parsed.radii) + try { + const parsed = JSON.parse(target.result) + if (parsed._pleroma_theme_version === 1) { + this.normalizeLocalState(parsed.colors, parsed.radii) + } 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]) } diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index 0bc08bd7..1439763d 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -11,6 +11,7 @@
+

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

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

@@ -135,6 +136,11 @@ margin-right: 1em; } +.import-warning { + color: $fallback--cRed; + color: var(--cRed, $fallback--cRed); +} + .radius-container, .color-container { display: flex; diff --git a/src/i18n/messages.js b/src/i18n/messages.js index c44c08ac..3951651d 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -50,6 +50,7 @@ const de = { presets: 'Voreinstellungen', export_theme: 'Aktuelles Theme exportieren', import_theme: 'Gespeichertes Theme laden', + invalid_theme_imported: 'Die ausgewählte Datei ist kein unterstütztes Pleroma-Theme. Keine Änderungen wurden vorgenommen.', theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen', radii_help: 'Kantenrundung (in Pixel) der Oberfläche anpassen', background: 'Hintergrund', @@ -293,6 +294,7 @@ const en = { export_theme: 'Export current theme', import_theme: 'Load saved theme', theme_help: 'Use hex color codes (#rrggbb) to customize your color theme.', + invalid_theme_imported: 'The selected file is not a supported Pleroma theme. No changes to your theme were made.', radii_help: 'Set up interface edge rounding (in pixels)', background: 'Background', foreground: 'Foreground',