aboutsummaryrefslogtreecommitdiff
path: root/web/ui.js
blob: 6e8d877dcc7cb509fe9f14acb010803eafdb0fad (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
95
96
97
98
99
100
101
102
import {LitElement, html} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js';

class BumbleControls extends LitElement {
    constructor() {
        super();
        this.bumbleLoaded = false;
        this.connected = false;
    }

    render() {
        return html`
            <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
            <dialog id="settings-dialog" @close=${this.onSettingsDialogClose} style="font-family:sans-serif">
                <p>WebSocket URL for HCI transport</p>
                <form>
                    <input id="settings-hci-url-input" type="text" size="50"></input>
                    <button value="cancel" formmethod="dialog">Cancel</button>
                    <button @click=${this.saveSettings}>Save</button>
                </form>
            </dialog>
            <button @click=${this.openSettingsDialog} class="mdc-icon-button material-icons"><div class="mdc-icon-button__ripple"></div>settings</button>
            <button @click=${this.connectBluetooth} ?disabled=${!this.canConnect()} class="mdc-icon-button material-icons"><div class="mdc-icon-button__ripple"></div>bluetooth</button>
            <button @click=${this.stop} ?disabled=${!this.connected} class="mdc-icon-button material-icons"><div class="mdc-icon-button__ripple"></div>stop</button>
        `
    }

    get settingsHciUrlInput() {
        return this.renderRoot.querySelector('#settings-hci-url-input');
    }

    get settingsDialog() {
        return this.renderRoot.querySelector('#settings-dialog');
    }

    canConnect() {
        return this.bumbleLoaded && !this.connected && this.getHciUrl();
    }

    getHciUrl() {
        // Look for a URL parameter setting first.
        const params = (new URL(document.location)).searchParams;
        let hciWsUrl = params.get("hci");
        if (hciWsUrl) {
          return hciWsUrl;
        }

        // Try to load the setting from storage.
        hciWsUrl = localStorage.getItem("hciWsUrl");
        if (hciWsUrl) {
          return hciWsUrl;
        }

        // Finally, default to nothing.
        return null;
    }

    openSettingsDialog() {
        const hciUrl = this.getHciUrl();
        if (hciUrl) {
            this.settingsHciUrlInput.value = hciUrl;
        } else {
          // Start with default, assuming port 7681.
          this.settingsHciUrlInput.value = "ws://localhost:7681/v1/websocket/bt"
        }
        this.settingsDialog.showModal();
    }

    onSettingsDialogClose() {
        if (this.settingsDialog.returnValue === "cancel") {
            return;
        }
        if (this.settingsHciUrlInput.value) {
            localStorage.setItem("hciWsUrl", this.settingsHciUrlInput.value);
        } else {
            localStorage.removeItem("hciWsUrl");
        }

        this.requestUpdate();
    }

    saveSettings(event) {
        event.preventDefault();
        this.settingsDialog.close(this.settingsHciUrlInput.value);
    }

    async connectBluetooth() {
        this.connected = await this.connector(this.getHciUrl());
        this.requestUpdate();
    }

    async stop() {
        await this.stopper();
        this.connected = false;
        this.requestUpdate();
    }

    onBumbleLoaded() {
        this.bumbleLoaded = true;
        this.requestUpdate();
    }
}
customElements.define('bumble-controls', BumbleControls);