view src/main.ts @ 0:5a77696c6dab

start
author drewp@bigasterisk.com
date Sun, 28 Jan 2024 15:32:18 -0800
parents
children 42a494b8ee1a
line wrap: on
line source

import { LitElement, css, html } from "lit";
import { customElement, state } from "lit/decorators.js";

@customElement("lb-page")
export class LbPage extends LitElement {
  static styles = [
    css`
      :host {
        display: flex;
        flex-direction: column;
        height: 100vh;
      }
      table {
        border-collapse: collapse;
      }
      td,
      th {
        border: 1px solid #aaa;
        text-align: center;
      }
      .color {
        display: inline-block;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        margin: 3px;
        vertical-align: middle;
      }
    `,
  ];
  @state() lights: object[] = [];

  connectedCallback(): void {
    super.connectedCallback();
    const es = new EventSource("api/table");
    es.onmessage = (ev) => {
      this.lights = JSON.parse(ev.data).lights;
    };
  }
  render() {
    return html`
      <h1>Light-bridge</h1>

      <table>
        <tr>
          <th>light</th>
          <th>address</th>
          <th>online</th>
          <th>color request</th>
          <th>color message</th>
          <th>color current</th>
          <th>latency</th>
        </tr>
        ${this.lights.map(
          (d: any) => html`
            <tr>
              <td>${d.light.name}</td>
              <td><code>${d.light.address}</code></td>
              <td>${d.light.online ? "✔" : ""}</td>
              <td>
                <code>${d.light.colorRequest}</code>
                <input type="color" @input=${this.onColorRequest.bind(this, d.light.name)} value="${d.light.colorRequest}" />
              </td>
              <td><code>${JSON.stringify(d.light.colorMessage)}</code></td>
              <td>${d.light.colorCurrent} <span class="color" style="background: ${d.light.colorCurrent}"></span></td>
              <td>${d.light.latencyMs} ms</td>
            </tr>
          `
        )}
      </table>
      <p>
        <a href="metrics">metrics</a> |
        <a href="api/graph">graph</a>
      </p>
      <bigast-loginbar></bigast-loginbar>
    `;
  }
  onColorRequest(lightName: string, ev: InputEvent) {
    const value = (ev.target as HTMLInputElement).value;
    const url = new URL("api/output", location as any);
    url.searchParams.append("light", lightName);
    fetch(url, { method: "PUT", body: value }); // todo: only run one fetch at a time, per light
  }
}