File size: 3,917 Bytes
43a06dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<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>