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
| # |
Base altitude |
Cloud cover |
${cloudInputs.join("")}
`;
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);
}
}