import { sendToMain } from "../../renderer/sendToMain.js"; import { AbstractStateSubscriberWebComponent } from "../util/AbstractStateSubscriberWebComponent.js"; import { registerElement } from "../../renderer/registerElement.js"; export type CloudsWebComponentState = { clouds: { baseFt: number; coverageEighths: number; }[]; }; export class CloudsWebComponent extends AbstractStateSubscriberWebComponent { private isInitialized = false; private elements!: { base: HTMLInputElement; coverage: HTMLSelectElement; }[]; get state(): CloudsWebComponentState { return { clouds: this.elements.map((element) => ({ baseFt: element.base.valueAsNumber || 0, coverageEighths: element.coverage.selectedIndex || 0, })), }; } private initialize() { this.setAttribute("aria-role", "region"); const cloudInputs: string[] = [0, 1, 2].map((i) => { return `\ ${i + 1} ft `; }); this.innerHTML = `\

 Clouds

${cloudInputs.join("")}
# Base altitude Cloud cover
`; this.elements = [...this.querySelectorAll("tbody tr")].map((row) => ({ base: row.querySelector(`input`) as HTMLInputElement, coverage: row.querySelector(`select`) as HTMLSelectElement, })); } connectedCallback() { if (!this.isInitialized) { this.initialize(); this.isInitialized = true; } this.subscribeToStateUpdates((state) => { this.elements.forEach((element, i) => { const cloud = state.clouds[i]; if (cloud) { element.base.valueAsNumber = Math.round(cloud.height_ft / 100) * 100; // round to nearest 100 ft element.coverage.selectedIndex = Math.round(cloud.density * 8); // 0-1 mapped to 0-8 oktas } else { element.base.valueAsNumber = 0; element.coverage.selectedIndex = 0; } }); this.checkDisable(); }); this.addEventListener("input", this.handleChange); } disconnectedCallback(): void { super.disconnectedCallback(); this.removeEventListener("input", this.handleChange); } private checkDisable(): void { for (const element of this.elements) { element.base.classList.toggle("inactive", element.coverage.selectedIndex === 0); } } private handleChange = () => { this.checkDisable(); for (const element of this.elements) { const step = Number(element.base.step ?? 100); if (element.base.valueAsNumber > 0 && element.base.valueAsNumber < step) { element.base.valueAsNumber = step; } } sendToMain("clouds:set", this.state); }; static registerElement() { registerElement("startgeraet-clouds", CloudsWebComponent); } }