/** * @fileoverview * File for camera selection UI. * * @author mebjas * * The word "QR Code" is registered trademark of DENSO WAVE INCORPORATED * http://www.denso-wave.com/qrcode/faqpatent-e.html */ import { CameraDevice } from "../../camera/core"; import { BaseUiElementFactory, PublicUiElementIdAndClasses } from "./base"; import { Html5QrcodeScannerStrings } from "../../strings"; /** Class for rendering and handling camera selection UI. */ export class CameraSelectionUi { private readonly selectElement: HTMLSelectElement; private readonly options: Array; private readonly cameras: Array; private constructor(cameras: Array) { this.selectElement = BaseUiElementFactory .createElement( "select", PublicUiElementIdAndClasses.CAMERA_SELECTION_SELECT_ID); this.cameras = cameras; this.options = []; } /*eslint complexity: ["error", 10]*/ private render( parentElement: HTMLElement) { const cameraSelectionContainer = document.createElement("span"); cameraSelectionContainer.style.marginRight = "10px"; const numCameras = this.cameras.length; if (numCameras === 0) { throw new Error("No cameras found"); } if (numCameras === 1) { // If only one camera is found, don't show camera selection. cameraSelectionContainer.style.display = "none"; } else { // Otherwise, show the number of cameras found as well. const selectCameraString = Html5QrcodeScannerStrings.selectCamera(); cameraSelectionContainer.innerText = `${selectCameraString} (${this.cameras.length}) `; } let anonymousCameraId = 1; for (const camera of this.cameras) { const value = camera.id; let name = camera.label == null ? value : camera.label; // If no name is returned by the browser, replace it with custom // camera label with a count. if (!name || name === "") { name = [ Html5QrcodeScannerStrings.anonymousCameraPrefix(), anonymousCameraId++ ].join(" "); } const option = document.createElement("option"); option.value = value; option.innerText = name; this.options.push(option); this.selectElement.appendChild(option); } cameraSelectionContainer.appendChild(this.selectElement); parentElement.appendChild(cameraSelectionContainer); } //#region Public APIs public disable() { this.selectElement.disabled = true; } public isDisabled() { return this.selectElement.disabled === true; } public enable() { this.selectElement.disabled = false; } public getValue(): string { return this.selectElement.value; } public hasValue(value: string): boolean { for (const option of this.options) { if (option.value === value) { return true; } } return false; } public setValue(value: string) { if (!this.hasValue(value)) { throw new Error(`${value} is not present in the camera list.`); } this.selectElement.value = value; } public hasSingleItem() { return this.cameras.length === 1; } public numCameras() { return this.cameras.length; } //#endregion /** Creates instance of {@link CameraSelectionUi} and renders it. */ public static create( parentElement: HTMLElement, cameras: Array): CameraSelectionUi { let cameraSelectUi = new CameraSelectionUi(cameras); cameraSelectUi.render(parentElement); return cameraSelectUi; } }