multimodal / videoinput /srcts /avSettingsMenu.ts
jcheng5's picture
Initial checkin
21e6506
class DeviceChangeEvent extends CustomEvent<{ deviceId: string | null }> {
constructor(type: string, detail: { deviceId: string | null }) {
super(type, { detail });
}
}
class AVSettingsMenuElement extends HTMLElement {
constructor() {
super();
this.addEventListener("click", (e) => {
if (e.target instanceof HTMLAnchorElement) {
const a = e.target;
if (a.classList.contains("camera-device-item")) {
this.cameraId = a.dataset.deviceId!;
} else if (a.classList.contains("mic-device-item")) {
this.micId = a.dataset.deviceId!;
}
}
});
}
#setDevices(deviceType: "camera" | "mic", devices: MediaDeviceInfo[]) {
const deviceEls = devices.map((dev) =>
this.#createDeviceElement(dev, `${deviceType}-device-item`)
);
const header = this.querySelector(`.${deviceType}-header`)!;
header.after(...deviceEls);
}
setCameras(cameras: MediaDeviceInfo[]) {
this.#setDevices("camera", cameras);
}
setMics(mics: MediaDeviceInfo[]) {
this.#setDevices("mic", mics);
}
get cameraId(): string | null {
return this.#getSelectedDevice("camera");
}
set cameraId(id: string | null) {
this.#setSelectedDevice("camera", id);
}
get micId(): string | null {
return this.#getSelectedDevice("mic");
}
set micId(id: string | null) {
this.#setSelectedDevice("mic", id);
}
#createDeviceElement(dev: MediaDeviceInfo, className: string): HTMLLIElement {
const li = this.ownerDocument.createElement("li");
const a = li.appendChild(this.ownerDocument.createElement("a"));
a.onclick = (e) => e.preventDefault();
a.href = "#";
a.textContent = dev.label;
a.dataset.deviceId = dev.deviceId!;
a.className = className;
return li;
}
#getSelectedDevice(device: "camera" | "mic"): string | null {
return (
(
this.querySelector(
`a.${device}-device-item.active`
) as HTMLAnchorElement
)?.dataset.deviceId ?? null
);
}
#setSelectedDevice(device: "camera" | "mic", id: string | null) {
this.querySelectorAll(`a.${device}-device-item.active`).forEach((a) =>
a.classList.remove("active")
);
if (id) {
this.querySelector(
`a.${device}-device-item[data-device-id="${id}"]`
)!.classList.add("active");
}
this.dispatchEvent(
new DeviceChangeEvent(`${device}-change`, {
deviceId: id,
})
);
}
}
customElements.define("av-settings-menu", AVSettingsMenuElement);