diff options
Diffstat (limited to 'web/ui.js')
-rw-r--r-- | web/ui.js | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/web/ui.js b/web/ui.js new file mode 100644 index 0000000..6e8d877 --- /dev/null +++ b/web/ui.js @@ -0,0 +1,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); |