implemented import/export for themes

This commit is contained in:
Henry Jameson 2021-03-08 19:53:30 +02:00
parent bd5b62b107
commit dda95543e8
4 changed files with 158 additions and 2 deletions

View file

@ -2,10 +2,52 @@ import Modal from 'src/components/modal/modal.vue'
import PanelLoading from 'src/components/panel_loading/panel_loading.vue' import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue' import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
import getResettableAsyncComponent from 'src/services/resettable_async_component.js' import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
import Popover from '../popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep } from 'lodash'
import {
newImporter,
newExporter
} from 'src/services/export_import/export_import.js'
import {
faTimes,
faFileUpload,
faFileDownload,
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
import {
faWindowMinimize
} from '@fortawesome/free-regular-svg-icons'
library.add(
faTimes,
faWindowMinimize,
faFileUpload,
faFileDownload,
faChevronDown
)
const SettingsModal = { const SettingsModal = {
data () {
return {
dataImporter: newImporter({
validator: this.importValidator,
onImport: this.onImport,
onImportFailure: this.onImportFailure
}),
dataThemeExporter: newExporter({
filename: 'pleromafe_settings.full',
getExportedObject: () => this.generateExport(true)
}),
dataExporter: newExporter({
filename: 'pleromafe_settings',
getExportedObject: () => this.generateExport()
})
}
},
components: { components: {
Modal, Modal,
Popover,
SettingsModalContent: getResettableAsyncComponent( SettingsModalContent: getResettableAsyncComponent(
() => import('./settings_modal_content.vue'), () => import('./settings_modal_content.vue'),
{ {
@ -21,6 +63,44 @@ const SettingsModal = {
}, },
peekModal () { peekModal () {
this.$store.dispatch('togglePeekSettingsModal') this.$store.dispatch('togglePeekSettingsModal')
},
importValidator (data) {
return data._pleroma_settings_version[0] === 1
},
onImportFailure () {
this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_settings_imported', level: 'error' })
},
onImport (data) {
this.$store.dispatch('loadSettings', data)
},
restore () {
console.log(this.dataImporter)
this.dataImporter.importData()
},
backup () {
this.dataExporter.exportData()
},
backupWithTheme () {
this.dataThemeExporter.exportData()
},
generateExport (theme = false) {
const { config } = this.$store.state
let sample = config
if (!theme) {
const ignoreList = new Set([
'customTheme',
'customThemeSource',
'colors'
])
sample = Object.fromEntries(
Object
.entries(sample)
.filter(([key]) => !ignoreList.has(key))
)
}
const clone = cloneDeep(sample)
clone._pleroma_settings_version = [1, 0]
return clone
} }
}, },
computed: { computed: {

View file

@ -32,19 +32,85 @@
<button <button
class="btn button-default" class="btn button-default"
@click="peekModal" @click="peekModal"
:title="$t('general.peek')"
> >
{{ $t('general.peek') }} <FAIcon
:icon="['far', 'window-minimize']"
fixed-width
/>
</button> </button>
<button <button
class="btn button-default" class="btn button-default"
@click="closeModal" @click="closeModal"
:title="$t('general.close')"
> >
{{ $t('general.close') }} <FAIcon
icon="times"
fixed-width
/>
</button> </button>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<SettingsModalContent v-if="modalOpenedOnce" /> <SettingsModalContent v-if="modalOpenedOnce" />
</div> </div>
<div class="panel-footer">
<Popover
class="export"
trigger="click"
placement="top"
:offset="{ y: 5, x: 5 }"
:bound-to="{ x: 'container' }"
remove-padding
>
<button
slot="trigger"
class="btn button-default"
:title="$t('general.close')"
>
<span>{{ $t("settings.backup_restore") }}</span>
<FAIcon
icon="chevron-down"
/>
</button>
<div
slot="content"
slot-scope="{close}"
>
<div class="dropdown-menu">
<button
class="button-default dropdown-item dropdown-item-icon"
@click.prevent="backup"
@click="close"
>
<FAIcon
icon="file-download"
fixed-width
/><span>{{ $t("settings.backup_settings") }}</span>
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click.prevent="backupWithTheme"
@click="close"
>
<FAIcon
icon="file-download"
fixed-width
/><span>{{ $t("settings.backup_settings_theme") }}</span>
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click.prevent="restore"
@click="close"
>
<FAIcon
icon="file-upload"
fixed-width
/><span>{{ $t("settings.restore_settings") }}</span>
</button>
</div>
</div>
</Popover>
</div>
</div> </div>
</Modal> </Modal>
</template> </template>

View file

@ -357,6 +357,7 @@
"interface": "Interface", "interface": "Interface",
"interfaceLanguage": "Interface language", "interfaceLanguage": "Interface language",
"invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.", "invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.",
"invalid_settings_imported": "The selected file is not a supported Pleroma settings backup. No changes were made.",
"limited_availability": "Unavailable in your browser", "limited_availability": "Unavailable in your browser",
"links": "Links", "links": "Links",
"lock_account_description": "Restrict your account to approved followers only", "lock_account_description": "Restrict your account to approved followers only",
@ -364,6 +365,10 @@
"loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")", "loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
"mutes_tab": "Mutes", "mutes_tab": "Mutes",
"play_videos_in_modal": "Play videos in a popup frame", "play_videos_in_modal": "Play videos in a popup frame",
"backup_restore": "Settings backup",
"backup_settings": "Backup settings to file",
"backup_settings_theme": "Backup settings and theme to file",
"restore_settings": "Restore settings from file",
"profile_fields": { "profile_fields": {
"label": "Profile metadata", "label": "Profile metadata",
"add_field": "Add Field", "add_field": "Add Field",

View file

@ -110,6 +110,11 @@ const config = {
} }
}, },
actions: { actions: {
loadSettings ({ dispatch }, data) {
Object.keys(this.state.config).forEach(
name => dispatch('setOption', { name, value: data[name] })
)
},
setHighlight ({ commit, dispatch }, { user, color, type }) { setHighlight ({ commit, dispatch }, { user, color, type }) {
commit('setHighlight', { user, color, type }) commit('setHighlight', { user, color, type })
}, },