import { CaptureEyeModal, ModalOptions } from './modal.js'; import { AssetModel } from '../asset/asset-model.js'; import { fetchAsset, hasNftProduct, } from '../asset/asset-service.js'; import interactionTracker, { TrackerEvent } from './interaction-tracker.js'; export class ModalManager { private static instance: ModalManager; private modalElement: CaptureEyeModal | null = null; private constructor() { interactionTracker.trackInteraction(TrackerEvent.SCRIPT); } get nid() { return this?.modalElement?.nid ?? ''; } get modalHidden() { return this?.modalElement?.modalHidden ?? true; } static getInstance(): ModalManager { if (!ModalManager.instance) { ModalManager.instance = new ModalManager(); } return ModalManager.instance; } async updateModal(options: ModalOptions, delay = 150): Promise { const existed = this.modalElement !== null; let modal = this.getModal(); modal.modalHidden = true; await new Promise((resolve) => setTimeout(resolve, delay)); const nidChanged = modal.nid !== options.nid; if (existed && nidChanged) { modal.clearModalOptions(); this.removeModal(); modal = this.getModal(); } modal.modalHidden = false; modal.updateModalOptions(options); if (nidChanged) { fetchAsset(options.nid).then((assetData) => { this.updateModalAsset(assetData, true); }); hasNftProduct(options.nid).then((hasNftProduct) => this.updateModalAsset({ hasNftProduct }, false) ); } } removeModal(): void { if (!this.modalElement) return; this.modalElement.modalHidden = true; this.unregisterRootClickListener(); this.modalElement.remove(); this.modalElement = null; } private getModal(): CaptureEyeModal { if (!this.modalElement) { this.modalElement = document.createElement('capture-eye-modal'); this.modalElement.addEventListener('remove-capture-eye-modal', () => { this.removeModal(); }); document.body.appendChild(this.modalElement); this.registerRootClickListener(); return this.modalElement; } return this.modalElement; } private updateModalAsset( assetModel: AssetModel | undefined, setAsLoaded: boolean ) { if (!this.modalElement || !assetModel) return; this.modalElement.updateAsset(assetModel, setAsLoaded); } private registerRootClickListener() { document.body.addEventListener('click', this.handleRootClick); } private unregisterRootClickListener() { document.body.removeEventListener('click', this.handleRootClick); } private handleRootClick = (event: MouseEvent) => { if (this.modalElement && !this.modalElement.contains(event.target as Node)) { this.removeModal(); } }; }