{"version":3,"sources":["archive/product/qr-code/product-qr-code-scanner.ts"],"names":["QrScanner","initI18Next","NS","createTranslator","ProductQrCodeScanner","HTMLElement","constructor","super","this","isScanning","t","COMMON_PRODUCT","init","styles","document","createElement","textContent","appendChild","scanButtonText","scanButton","classList","add","addEventListener","async","e","preventDefault","closeScan","lastFoundUrl","await","openScan","innerHTML","videoCont","style","display","closeScanButton","type","spinner","width","height","video","qrScanner","onQrCodeFound","result","data","maxScansPerSecond","highlightScanRegion","highlightCodeOutline","scrollToThis","start","stop","forceReflow","lastFoundTimeout","window","clearTimeout","let","url","URL","relativeUrl","pathname","search","hash","startsWith","match","length","lastFoundDate","Date","setTimeout","getTime","removeChild","remove","location","assign","offsetHeight","scrollIntoView","behavior","connectedCallback","customElements","define"],"mappings":"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","file":"product-qr-code-scanner.js","sourcesContent":["import QrScanner from \"qr-scanner\";\nimport {\n initI18Next,\n NS,\n createTranslator,\n} from \"../../../../components-shared/utils/init-i18next.js\";\n\nexport class ProductQrCodeScanner extends HTMLElement {\n constructor() {\n super();\n }\n\n /* #region Private */\n private videoCont: HTMLDivElement;\n private video: HTMLVideoElement;\n private spinner: HTMLDivElement;\n private qrScanner: QrScanner;\n private isScanning = false;\n private t = createTranslator(NS.COMMON_PRODUCT);\n private lastFoundUrl: string;\n private lastFoundTimeout: number;\n private lastFoundDate: Date;\n\n private init() {\n const styles = document.createElement(\"style\");\n styles.textContent = `\n .video-container {\n overflow: hidden;\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right:0;\n z-index: 1;\n background-color: #1e1e1ee6;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n }\n\n .video-container video {\n width: 100%;\n display: block;\n }\n `;\n\n this.appendChild(styles);\n\n // Scan button\n const scanButtonText = (isScanning: boolean) => this.t(isScanning ? \"closeQrScanner\" : \"openQrScanner\");\n\n const scanButton = document.createElement(\"button\");\n scanButton.textContent = scanButtonText(this.isScanning);\n scanButton.classList.add(\"btn\", \"btn-primary\", \"btn-scanqr\");\n scanButton.addEventListener(\"click\", async (e: MouseEvent) => {\n e.preventDefault();\n\n if (this.isScanning) {\n this.closeScan();\n this.lastFoundUrl = null;\n scanButton.innerHTML = scanButtonText(this.isScanning);\n return;\n }\n\n await this.openScan();\n scanButton.innerHTML = scanButtonText(this.isScanning);\n });\n\n // Video container\n this.videoCont = document.createElement(\"div\");\n this.videoCont.classList.add(\"video-container\");\n this.videoCont.style.display = \"none\";\n this.appendChild(this.videoCont);\n\n const closeScanButton = document.createElement(\"button\");\n closeScanButton.type = \"button\";\n closeScanButton.classList.add(\"btn\", \"btn-scanqr-close\");\n closeScanButton.innerHTML = ``;\n closeScanButton.addEventListener(\"click\", (e: MouseEvent) => {\n e.preventDefault();\n this.closeScan();\n this.videoCont.style.display = \"none\";\n this.lastFoundUrl = null;\n //scanButton.innerHTML = scanButtonText(this.isScanning);\n });\n\n this.videoCont.appendChild(closeScanButton);\n\n this.spinner = document.createElement(\"div\");\n this.spinner.classList.add(\"spinner-border\", \"text-primary\", \"d-none\");\n this.spinner.style.width = \"3rem\";\n this.spinner.style.height = \"3rem\";\n\n this.videoCont.appendChild(this.spinner);\n\n this.appendChild(scanButton);\n\n this.video = document.createElement(\"video\");\n this.videoCont.appendChild(this.video);\n\n // QR Scanner\n this.qrScanner = new QrScanner(\n this.video,\n (result) => {\n this.onQrCodeFound(result.data);\n },\n {\n maxScansPerSecond: 10,\n highlightScanRegion: true,\n highlightCodeOutline: true,\n }\n );\n }\n\n private async openScan() {\n this.videoCont.style.display = \"flex\";\n this.isScanning = true;\n this.scrollToThis();\n await this.qrScanner.start();\n }\n\n private closeScan() {\n this.isScanning = false;\n this.qrScanner.stop();\n\n this.forceReflow();\n\n if (this.lastFoundTimeout) {\n window.clearTimeout(this.lastFoundTimeout);\n }\n }\n\n private onQrCodeFound(data: string) {\n let url: URL;\n try {\n url = new URL(data);\n } catch {\n return;\n }\n\n const relativeUrl = url.pathname + url.search + url.hash;\n\n if (\n !url ||\n !url.pathname.startsWith(\"/sku/\") ||\n (url.pathname.match(/\\//g) || []).length !== 2 ||\n this.lastFoundUrl === relativeUrl\n ) {\n if (this.lastFoundUrl === relativeUrl) {\n this.lastFoundDate = new Date();\n } else {\n this.lastFoundDate = null;\n this.lastFoundUrl = null;\n }\n\n return;\n }\n\n this.lastFoundDate = new Date();\n this.lastFoundUrl = relativeUrl;\n\n if (this.lastFoundTimeout) {\n window.clearTimeout(this.lastFoundTimeout);\n }\n\n this.lastFoundTimeout = window.setTimeout(() => {\n if (new Date().getTime() - this.lastFoundDate.getTime() < 200 && this.lastFoundUrl?.length > 0) {\n this.videoCont.removeChild(this.video);\n this.spinner.classList.remove(\"d-none\");\n this.closeScan();\n window.location.assign(this.lastFoundUrl);\n } else {\n this.lastFoundDate = null;\n this.lastFoundUrl = null;\n }\n }, 1000);\n\n this.forceReflow();\n }\n\n private forceReflow() {\n this.offsetHeight;\n }\n\n private scrollToThis() {\n this.scrollIntoView({ behavior: \"smooth\" });\n }\n /* #endregion */\n\n async connectedCallback() {\n await initI18Next(NS.COMMON_PRODUCT);\n this.init();\n }\n}\n\ncustomElements.define(\"product-qr-code-scanner\", ProductQrCodeScanner);\n"]}