forked from AkkomaGang/akkoma-fe
Merge branch 'feature/theme-export-import' into 'develop'
Theme import & export Closes #119 See merge request pleroma/pleroma-fe!290
This commit is contained in:
commit
9982376f9a
7 changed files with 92 additions and 28 deletions
|
@ -63,6 +63,8 @@ button{
|
||||||
box-shadow: 0px 0px 2px black;
|
box-shadow: 0px 0px 2px black;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
min-width: 10em;
|
||||||
|
min-height: 2em;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
|
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
|
||||||
|
|
|
@ -34,11 +34,6 @@
|
||||||
@import '../../_variables.scss';
|
@import '../../_variables.scss';
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
.btn {
|
|
||||||
min-height: 28px;
|
|
||||||
width: 10em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,10 +107,6 @@
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
|
||||||
button {
|
|
||||||
width: 10em;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0.35em;
|
margin: 0.35em;
|
||||||
padding: 0.35em;
|
padding: 0.35em;
|
||||||
|
|
|
@ -113,8 +113,6 @@
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
min-height: 28px;
|
|
||||||
width: 10em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setting-list {
|
.setting-list {
|
||||||
|
|
|
@ -5,6 +5,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
availableStyles: [],
|
availableStyles: [],
|
||||||
selected: this.$store.state.config.theme,
|
selected: this.$store.state.config.theme,
|
||||||
|
invalidThemeImported: false,
|
||||||
bgColorLocal: '',
|
bgColorLocal: '',
|
||||||
btnColorLocal: '',
|
btnColorLocal: '',
|
||||||
textColorLocal: '',
|
textColorLocal: '',
|
||||||
|
@ -32,25 +33,61 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.bgColorLocal = rgbstr2hex(this.$store.state.config.colors.bg)
|
this.normalizeLocalState(this.$store.state.config.colors, this.$store.state.config.radii)
|
||||||
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
|
|
||||||
},
|
},
|
||||||
methods: {
|
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 () {
|
setCustomTheme () {
|
||||||
if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) {
|
if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) {
|
||||||
// reset to picked themes
|
// reset to picked themes
|
||||||
|
@ -95,6 +132,26 @@ export default {
|
||||||
attachmentRadius: this.attachmentRadiusLocal
|
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: {
|
watch: {
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
<i class="icon-down-open"/>
|
<i class="icon-down-open"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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">
|
<div class="color-container">
|
||||||
<p>{{$t('settings.theme_help')}}</p>
|
<p>{{$t('settings.theme_help')}}</p>
|
||||||
<div class="color-item">
|
<div class="color-item">
|
||||||
|
@ -134,6 +139,11 @@
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.import-warning {
|
||||||
|
color: $fallback--cRed;
|
||||||
|
color: var(--cRed, $fallback--cRed);
|
||||||
|
}
|
||||||
|
|
||||||
.radius-container,
|
.radius-container,
|
||||||
.color-container {
|
.color-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -48,6 +48,9 @@ const de = {
|
||||||
settings: 'Einstellungen',
|
settings: 'Einstellungen',
|
||||||
theme: 'Farbschema',
|
theme: 'Farbschema',
|
||||||
presets: 'Voreinstellungen',
|
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',
|
theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen',
|
||||||
radii_help: 'Kantenrundung (in Pixel) der Oberfläche anpassen',
|
radii_help: 'Kantenrundung (in Pixel) der Oberfläche anpassen',
|
||||||
background: 'Hintergrund',
|
background: 'Hintergrund',
|
||||||
|
@ -288,7 +291,10 @@ const en = {
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
theme: 'Theme',
|
theme: 'Theme',
|
||||||
presets: 'Presets',
|
presets: 'Presets',
|
||||||
|
export_theme: 'Export current theme',
|
||||||
|
import_theme: 'Load saved theme',
|
||||||
theme_help: 'Use hex color codes (#rrggbb) to customize your color 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)',
|
radii_help: 'Set up interface edge rounding (in pixels)',
|
||||||
background: 'Background',
|
background: 'Background',
|
||||||
foreground: 'Foreground',
|
foreground: 'Foreground',
|
||||||
|
|
Loading…
Reference in a new issue