commit: 9982376f9a316a5e4224ea44c7392b272f5549d1
parent: 65dfceae59de8c0a8d79168f345d16942695c573
Author: kaniini <nenolod@gmail.com>
Date: Mon, 20 Aug 2018 00:03:35 +0000
Merge branch 'feature/theme-export-import' into 'develop'
Theme import & export
Closes #119
See merge request pleroma/pleroma-fe!290
Diffstat:
7 files changed, 92 insertions(+), 28 deletions(-)
diff --git 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
@@ -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
@@ -107,10 +107,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
@@ -113,8 +113,6 @@
.btn {
margin-top: 1em;
- min-height: 28px;
- width: 10em;
}
}
.setting-list {
diff --git 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: '',
@@ -32,25 +33,61 @@ 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 () {
+ 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
+
+ // 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.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])
+ }
+ })
+
+ document.body.appendChild(filePicker)
+ filePicker.click()
+ document.body.removeChild(filePicker)
+ },
+
setCustomTheme () {
if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) {
// reset to picked themes
@@ -95,6 +132,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: {
diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue
@@ -11,6 +11,11 @@
<i class="icon-down-open"/>
</label>
</div>
+ <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>
<div class="color-item">
@@ -134,6 +139,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
@@ -48,6 +48,9 @@ const de = {
settings: 'Einstellungen',
theme: 'Farbschema',
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',
@@ -288,7 +291,10 @@ const en = {
settings: 'Settings',
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.',
+ 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',