Spaces:
Paused
Paused
| <script lang="ts"> | |
| import { t } from "$lib/i18n/translations"; | |
| import { downloadFile } from "$lib/download"; | |
| import { createDialog } from "$lib/state/dialogs"; | |
| import { validateSettings } from "$lib/settings/validate"; | |
| import { storedSettings, updateSetting, loadFromString } from "$lib/state/settings"; | |
| import ActionButton from "$components/buttons/ActionButton.svelte"; | |
| import ResetSettingsButton from "$components/settings/ResetSettingsButton.svelte"; | |
| import IconFileExport from "@tabler/icons-svelte/IconFileExport.svelte"; | |
| import IconFileImport from "@tabler/icons-svelte/IconFileImport.svelte"; | |
| const updateSettings = (reader: FileReader) => { | |
| try { | |
| const data = reader.result?.toString(); | |
| if (!data) throw $t("error.import.no_data"); | |
| const loadedSettings = loadFromString(data); | |
| if (!validateSettings(loadedSettings)) | |
| throw $t("error.import.invalid"); | |
| createDialog({ | |
| id: "import-confirm", | |
| type: "small", | |
| icon: "warn-red", | |
| title: $t("dialog.safety.title"), | |
| bodyText: $t("dialog.import.body"), | |
| buttons: [ | |
| { | |
| text: $t("button.cancel"), | |
| main: false, | |
| action: () => {}, | |
| }, | |
| { | |
| text: $t("button.import"), | |
| color: "red", | |
| main: true, | |
| timeout: 5000, | |
| action: () => updateSetting(loadFromString(data)), | |
| }, | |
| ], | |
| }); | |
| } catch (e) { | |
| let message = $t("error.import.no_data"); | |
| if (e instanceof Error) { | |
| console.error("settings import error:", e); | |
| message = $t("error.import.unknown", { value: e.message }); | |
| } else if (typeof e === "string") { | |
| message = e; | |
| } | |
| createDialog({ | |
| id: "settings-import-error", | |
| type: "small", | |
| meowbalt: "error", | |
| bodyText: message, | |
| buttons: [ | |
| { | |
| text: $t("button.gotit"), | |
| main: true, | |
| action: () => {}, | |
| }, | |
| ], | |
| }); | |
| } | |
| }; | |
| 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 = () => updateSettings(reader); | |
| if (target.files?.length === 1) { | |
| reader.readAsText(target.files[0]); | |
| } | |
| }; | |
| pseudoinput.click(); | |
| }; | |
| const exportSettings = async () => { | |
| return await downloadFile({ | |
| file: new File( | |
| [JSON.stringify($storedSettings, null, 4)], | |
| "settings.json", { type: "application/json" } | |
| ), | |
| }); | |
| }; | |
| </script> | |
| <div class="button-row" id="settings-data-transfer"> | |
| <ActionButton id="import-settings" click={importSettings}> | |
| <IconFileImport /> | |
| {$t("button.import")} | |
| </ActionButton> | |
| {#if $storedSettings.schemaVersion} | |
| <ActionButton id="export-settings" click={exportSettings}> | |
| <IconFileExport /> | |
| {$t("button.export")} | |
| </ActionButton> | |
| {/if} | |
| {#if $storedSettings.schemaVersion} | |
| <ResetSettingsButton /> | |
| {/if} | |
| </div> | |
| <style> | |
| .button-row { | |
| display: flex; | |
| gap: var(--padding); | |
| flex-wrap: wrap; | |
| } | |
| </style> | |