commit: bd5b62b1071d6424f82477dca2f0d374f709a596
parent 4baa397ed02f5deab4d5548dd89bbfb07c8a3d80
Author: Henry Jameson <me@hjkos.com>
Date: Mon, 8 Mar 2021 19:42:24 +0200
changed importexport into a service instead of component for simplicity
Diffstat:
4 files changed, 112 insertions(+), 142 deletions(-)
diff --git a/src/components/export_import/export_import.vue b/src/components/export_import/export_import.vue
@@ -1,102 +0,0 @@
-<template>
- <div class="import-export-container">
- <slot name="before" />
- <button
- class="btn button-default"
- @click="exportData"
- >
- {{ exportLabel }}
- </button>
- <button
- class="btn button-default"
- @click="importData"
- >
- {{ importLabel }}
- </button>
- <slot name="afterButtons" />
- <p
- v-if="importFailed"
- class="alert error"
- >
- {{ importFailedText }}
- </p>
- <slot name="afterError" />
- </div>
-</template>
-
-<script>
-export default {
- props: [
- 'exportObject',
- 'importLabel',
- 'exportLabel',
- 'importFailedText',
- 'validator',
- 'onImport',
- 'onImportFailure'
- ],
- data () {
- return {
- importFailed: false
- }
- },
- methods: {
- exportData () {
- 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')
- 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)
- },
- importData () {
- this.importFailed = 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)
- const valid = this.validator(parsed)
- if (valid) {
- this.onImport(parsed)
- } else {
- this.importFailed = true
- // this.onImportFailure(valid)
- }
- } catch (e) {
- // This will happen both if there is a JSON syntax error or the theme is missing components
- this.importFailed = true
- // this.onImportFailure(e)
- }
- }
- reader.readAsText(event.target.files[0])
- }
- })
-
- document.body.appendChild(filePicker)
- filePicker.click()
- document.body.removeChild(filePicker)
- }
- }
-}
-</script>
-
-<style lang="scss">
-.import-export-container {
- display: flex;
- flex-wrap: wrap;
- align-items: baseline;
- justify-content: center;
-}
-</style>
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.js b/src/components/settings_modal/tabs/theme_tab/theme_tab.js
@@ -16,6 +16,10 @@ import {
colors2to3
} from 'src/services/style_setter/style_setter.js'
import {
+ newImporter,
+ newExporter
+} from 'src/services/export_import/export_import.js'
+import {
SLOT_INHERITANCE
} from 'src/services/theme_data/pleromafe.js'
import {
@@ -31,7 +35,6 @@ import ShadowControl from 'src/components/shadow_control/shadow_control.vue'
import FontControl from 'src/components/font_control/font_control.vue'
import ContrastRatio from 'src/components/contrast_ratio/contrast_ratio.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
-import ExportImport from 'src/components/export_import/export_import.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import Preview from './preview.vue'
@@ -67,6 +70,15 @@ const colorConvert = (color) => {
export default {
data () {
return {
+ themeImporter: newImporter({
+ validator: this.importValidator,
+ onImport: this.onImport,
+ onImportFailure: this.onImportFailure
+ }),
+ themeExporter: newExporter({
+ filename: 'pleroma_theme',
+ getExportedObject: () => this.exportedTheme
+ }),
availableStyles: [],
selected: this.$store.getters.mergedConfig.theme,
themeWarning: undefined,
@@ -383,7 +395,6 @@ export default {
FontControl,
TabSwitcher,
Preview,
- ExportImport,
Checkbox
},
methods: {
@@ -528,10 +539,15 @@ export default {
this.previewColors.mod
)
},
+ importTheme () { this.themeImporter.importData() },
+ exportTheme () { this.themeExporter.exportData() },
onImport (parsed, forceSource = false) {
this.tempImportFile = parsed
this.loadTheme(parsed, 'file', forceSource)
},
+ onImportFailure (result) {
+ this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_theme_imported', level: 'error' })
+ },
importValidator (parsed) {
const version = parsed._pleroma_theme_version
return version >= 1 || version <= 2
diff --git a/src/components/settings_modal/tabs/theme_tab/theme_tab.vue b/src/components/settings_modal/tabs/theme_tab/theme_tab.vue
@@ -48,46 +48,45 @@
</template>
</div>
</div>
- <ExportImport
- :export-object="exportedTheme"
- :export-label="$t("settings.export_theme")"
- :import-label="$t("settings.import_theme")"
- :import-failed-text="$t("settings.invalid_theme_imported")"
- :on-import="onImport"
- :validator="importValidator"
- >
- <template slot="before">
- <div class="presets">
- {{ $t('settings.presets') }}
- <label
- for="preset-switcher"
- class="select"
+ <div class="top">
+ <div class="presets">
+ {{ $t('settings.presets') }}
+ <label
+ for="preset-switcher"
+ class="select"
+ >
+ <select
+ id="preset-switcher"
+ v-model="selected"
+ class="preset-switcher"
>
- <select
- id="preset-switcher"
- v-model="selected"
- class="preset-switcher"
+ <option
+ v-for="style in availableStyles"
+ :key="style.name"
+ :value="style"
+ :style="{
+ backgroundColor: style[1] || (style.theme || style.source).colors.bg,
+ color: style[3] || (style.theme || style.source).colors.text
+ }"
>
- <option
- v-for="style in availableStyles"
- :key="style.name"
- :value="style"
- :style="{
- backgroundColor: style[1] || (style.theme || style.source).colors.bg,
- color: style[3] || (style.theme || style.source).colors.text
- }"
- >
- {{ style[0] || style.name }}
- </option>
- </select>
- <FAIcon
- class="select-down-icon"
- icon="chevron-down"
- />
- </label>
- </div>
- </template>
- </ExportImport>
+ {{ style[0] || style.name }}
+ </option>
+ </select>
+ <FAIcon
+ class="select-down-icon"
+ icon="chevron-down"
+ />
+ </label>
+ </div>
+ <div class="export-import">
+ <button class="btn button-default" @click="importTheme">
+ {{ $t("settings.import_theme") }}
+ </button>
+ <button class="btn button-default" @click="exportTheme">
+ {{ $t("settings.export_theme") }}
+ </button>
+ </div>
+ </div>
</div>
<div class="save-load-options">
<span class="keep-option">
diff --git a/src/services/export_import/export_import.js b/src/services/export_import/export_import.js
@@ -0,0 +1,57 @@
+export const newExporter = ({
+ filename = 'data',
+ getExportedObject
+}) => ({
+ exportData () {
+ const stringified = JSON.stringify(getExportedObject(), 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', `${filename}.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)
+ }
+})
+
+export const newImporter = ({
+ onImport,
+ onImportFailure,
+ validator = () => true
+}) => ({
+ importData () {
+ const filePicker = document.createElement('input')
+ filePicker.setAttribute('type', 'file')
+ filePicker.setAttribute('accept', '.json')
+ console.log(1)
+
+ 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)
+ const validationResult = validator(parsed)
+ if (validationResult === true) {
+ onImport(parsed)
+ } else {
+ onImportFailure({ validationResult })
+ }
+ } catch (error) {
+ onImportFailure({ error })
+ }
+ }
+ console.log(2)
+ reader.readAsText(event.target.files[0])
+ }
+ })
+
+ document.body.appendChild(filePicker)
+ filePicker.click()
+ document.body.removeChild(filePicker)
+ }
+})