summaryrefslogtreecommitdiff
path: root/client-web/source/preferences/ui.ts
blob: 634d945979591be61f32b791afe6d10865016e50 (plain)
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
import { ebr, ebutton, ediv, elabel, espan, etd, etr, OverlayUi } from "../helper.ts";
import { PREF_DECLS } from "./decl.ts";
import { change_pref, on_pref_changed, PrefDecl, PREFS } from "./mod.ts";

export class PrefUi extends OverlayUi {
    constructor() {
        const rows = Object.entries(PREF_DECLS as Record<string, PrefDecl<unknown>>).filter(e => !e[1].hidden).map(([key_, decl]) => {
            const key = key_ as keyof typeof PREF_DECLS
            const id = `pref-${key}`
            let prim_control: HTMLInputElement | HTMLSelectElement | undefined;
            if (decl.possible_values) {
                const sel = document.createElement("select")
                sel.id = id
                sel.value = JSON.stringify(PREFS[key])
                for (const v of decl.possible_values) {
                    const opt = document.createElement("option")
                    opt.value = opt.textContent = JSON.stringify(v ?? null)
                    sel.append(opt)
                }
                sel.onchange = () => {
                    change_pref(key, JSON.parse(sel.value) ?? undefined)
                }
                on_pref_changed(key, () => sel.value = JSON.stringify(PREFS[key] ?? null))
                prim_control = sel
            } else if (typeof decl.type == "boolean") {
                const checkbox = document.createElement("input")
                checkbox.type = "checkbox"
                checkbox.id = id
                checkbox.checked = PREFS[key] as boolean
                checkbox.onchange = () => {
                    change_pref(key, checkbox.checked)
                }
                on_pref_changed(key, () => checkbox.checked = PREFS[key] as boolean)
                prim_control = checkbox
            } else if (typeof decl.type == "string") {
                const textbox = document.createElement("input")
                textbox.type = "text"
                textbox.id = id
                textbox.value = PREFS[key] as string
                textbox.onchange = () => {
                    change_pref(key, textbox.value)
                }
                on_pref_changed(key, () => textbox.value = PREFS[key] as string)
                prim_control = textbox
            } else if (typeof decl.type == "number") {
                const textbox = document.createElement("input")
                textbox.type = "number"
                textbox.id = id
                textbox.value = PREFS[key] as string
                textbox.onchange = () => {
                    change_pref(key, parseFloat(textbox.value))
                }
                on_pref_changed(key, () => textbox.value = PREFS[key] as string)
                prim_control = textbox
            }

            let use_opt_;
            if (decl.default === undefined || decl.optional) {
                const use_opt = document.createElement("input")
                use_opt.type = "checkbox"
                use_opt.id = id
                use_opt.checked = PREFS[key] !== undefined
                if (prim_control) prim_control.disabled = !use_opt.checked
                use_opt.onchange = () => {
                    if (use_opt.checked) { if (prim_control?.onchange) prim_control.onchange(new Event("change")) }
                    else change_pref(key, undefined)
                }
                on_pref_changed(key, () => {
                    use_opt.checked = PREFS[key] !== undefined
                    if (prim_control) prim_control.disabled = !use_opt.checked
                })
                use_opt_ = use_opt;
            }

            const label = elabel(decl.description ?? `[${key}]`, { id })
            return etr({ class: "pref" }, etd({}, label), etd({}, use_opt_ ?? ""), etd({}, prim_control ?? ""))
        })
        
        const notification_perm = Notification.permission == "granted" ? ediv() : ediv({},
            espan("For keks-meet to send notifications, it needs you to grant permission: "),
            ebutton("Grant", { onclick: () => Notification.requestPermission() }),
        )
        const reset = ediv({},
            espan("Want to clear all settings? Use this:"),
            ebutton("RESET", { onclick: () => { if (confirm("really clear all preferences?")) { localStorage.clear(); window.location.reload() } } }),
        )

        const table = document.createElement("table")
        table.append(...rows)

        super(ediv({ class: "prefs-overlay" }, notification_perm, reset, ebr(), table))
    }

}