From 29f69de240530048a31319f8a78274ca7d607853 Mon Sep 17 00:00:00 2001
From: Ole Bertram <git@bertr.am>
Date: Thu, 28 Jun 2018 01:08:06 +0200
Subject: Add theme export feature

---
 src/components/style_switcher/style_switcher.vue | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'src/components/style_switcher/style_switcher.vue')

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 @@
         <i class="icon-down-open"/>
       </label>
     </div>
+    <div>
+      <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
+    </div>
     <div class="color-container">
       <p>{{$t('settings.theme_help')}}</p>
       <div class="color-item">
-- 
cgit v1.2.3-70-g09d2


From d2b79856c61391e56009cdf313e332ee950b9081 Mon Sep 17 00:00:00 2001
From: Ole Bertram <git@bertr.am>
Date: Thu, 28 Jun 2018 02:59:57 +0200
Subject: Add theme import feature

---
 src/components/style_switcher/style_switcher.js  | 22 ++++++++++++++++++++++
 src/components/style_switcher/style_switcher.vue |  1 +
 src/i18n/messages.js                             |  1 +
 3 files changed, 24 insertions(+)

(limited to 'src/components/style_switcher/style_switcher.vue')

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 @@
     </div>
     <div>
       <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
+      <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
     </div>
     <div class="color-container">
       <p>{{$t('settings.theme_help')}}</p>
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',
-- 
cgit v1.2.3-70-g09d2


From 2a87e29180641621301a9e04bc2f493e01f4ca33 Mon Sep 17 00:00:00 2001
From: Ole Bertram <git@bertr.am>
Date: Wed, 4 Jul 2018 14:25:40 +0200
Subject: Add validation of the imported theme and the corresponding warning
 message

---
 src/components/style_switcher/style_switcher.js  | 18 ++++++++++++++++--
 src/components/style_switcher/style_switcher.vue |  6 ++++++
 src/i18n/messages.js                             |  2 ++
 3 files changed, 24 insertions(+), 2 deletions(-)

(limited to 'src/components/style_switcher/style_switcher.vue')

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 @@
     <div>
       <button class="btn" @click="exportCurrentTheme">{{ $t('settings.export_theme') }}</button>
       <button class="btn" @click="importTheme">{{ $t('settings.import_theme') }}</button>
+      <p v-if="invalidThemeImported" class="import-warning">{{ $t('settings.invalid_theme_imported') }}</p>
     </div>
     <div class="color-container">
       <p>{{$t('settings.theme_help')}}</p>
@@ -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',
-- 
cgit v1.2.3-70-g09d2

