web/settings: settings import/export

This commit is contained in:
dumbmoron 2024-07-23 18:17:38 +00:00
parent 6e24a8d172
commit f8d06cf18b
No known key found for this signature in database
3 changed files with 76 additions and 1 deletions

View file

@ -0,0 +1,68 @@
<script lang="ts">
import ActionButton from "$components/buttons/ActionButton.svelte";
import IconFileExport from "@tabler/icons-svelte/IconFileExport.svelte";
import IconFileImport from "@tabler/icons-svelte/IconFileImport.svelte";
import settings, { updateSetting, loadFromString } from "$lib/state/settings";
const importSettings = () => {
const pseudoinput = document.createElement('input');
pseudoinput.type = 'file';
pseudoinput.accept = '.json';
pseudoinput.onchange = (e: Event) => {
const target = e.target as HTMLInputElement;
const reader = new FileReader();
reader.onload = function() {
try {
const data = reader.result?.toString();
if (!data) {
throw "data is missing";
}
// TODO: input is not validated at all here, which means
// someone can potentially import a broken config.
// i don't know if we should do something about it
// or just thug it out.
updateSetting(
loadFromString(data)
);
} catch(e) {
alert(e);
}
}
if (target.files?.length === 1) {
reader.readAsText(target.files[0]);
} else alert('file missing');
};
pseudoinput.click();
}
const exportSettings = () => {
const blob = new Blob(
[ JSON.stringify($settings, null, 2) ],
{ type: 'application/json' }
);
const pseudolink = document.createElement('a');
pseudolink.href = URL.createObjectURL(blob);
pseudolink.download = 'settings.json';
pseudolink.click();
}
</script>
<div class="button-row" id="settings-data-transfer">
<ActionButton id="import-settings" click={importSettings}>
<IconFileImport /> import
</ActionButton>
<ActionButton id="export-settings" click={exportSettings}>
<IconFileExport /> export
</ActionButton>
</div>
<style>
.button-row {
display: flex;
gap: var(--padding);
}
</style>

View file

@ -41,6 +41,7 @@ const migrate = (settings: AllPartialSettingsWithSchema): PartialSettings => {
}, settings as AllPartialSettingsWithSchema);
}
const loadFromStorage = () => {
const settings = localStorage.getItem('settings');
if (!settings) {
@ -52,6 +53,10 @@ const loadFromStorage = () => {
return {};
}
return loadFromString(settings);
}
export const loadFromString = (settings: string) => {
const parsed = JSON.parse(settings) as AllPartialSettingsWithSchema;
if (parsed.schemaVersion < defaultSettings.schemaVersion) {
return migrate(parsed);

View file

@ -1,9 +1,10 @@
<script>
<script lang="ts">
import { t } from "$lib/i18n/translations";
import SettingsCategory from "$components/settings/SettingsCategory.svelte";
import SettingsToggle from "$components/buttons/SettingsToggle.svelte";
import ResetSettingsButton from "$components/buttons/ResetSettingsButton.svelte";
import TransferSettings from "$components/settings/TransferSettings.svelte";
</script>
<SettingsCategory sectionId="debug" title={$t("settings.advanced.debug")}>
@ -16,5 +17,6 @@
</SettingsCategory>
<SettingsCategory sectionId="data" title={$t("settings.advanced.data")}>
<TransferSettings />
<ResetSettingsButton />
</SettingsCategory>