import modalHtml from '../components/login-modal/login-modal.html?raw'; import modalScript from '../components/login-modal/login-modal.js?raw'; import validationModalStyle from '../components/validation-modal/validation-modal.css?raw'; import Services from './service'; import { navigate } from '../router'; // import { init } from '../router'; // Unused import import { addressToEmoji } from '../utils/sp-address.utils'; import { RoleDefinition } from 'pkg/sdk_client'; import { initValidationModal } from '../components/validation-modal/validation-modal'; import { interpolate } from '../utils/html.utils'; interface ConfirmationModalOptions { title: string; content: string; confirmText?: string; cancelText?: string; } export default class ModalService { private static instance: ModalService; private stateId: string | null = null; private processId: string | null = null; private constructor() {} private paired_addresses: string[] = []; private modal: HTMLElement | null = null; // Method to access the singleton instance of Services public static async getInstance(): Promise { if (!ModalService.instance) { ModalService.instance = new ModalService(); } return ModalService.instance; } public openLoginModal(myAddress: string, receiverAddress: string) { const container = document.querySelector('.page-container'); let html = modalHtml; html = html.replace('{{device1}}', myAddress); html = html.replace('{{device2}}', receiverAddress); if (container) container.innerHTML += html; const modal = document.getElementById('login-modal'); if (modal) modal.style.display = 'flex'; const newScript = document.createElement('script'); newScript.setAttribute('type', 'module'); newScript.textContent = modalScript; document.head.appendChild(newScript).parentNode?.removeChild(newScript); } // Removed unused modal injection methods async injectValidationModal(processDiff: any) { const container = document.querySelector('#containerId'); if (container) { let html = await fetch('/src/components/validation-modal/validation-modal.html').then(res => res.text() ); html = interpolate(html, { processId: processDiff.processId }); container.innerHTML += html; // Dynamically load the header JS const script = document.createElement('script'); script.id = 'validation-modal-script'; script.src = '/src/components/validation-modal/validation-modal.ts'; script.type = 'module'; document.head.appendChild(script); const css = document.createElement('style'); css.id = 'validation-modal-css'; css.innerText = validationModalStyle; document.head.appendChild(css); initValidationModal(processDiff); } } async closeValidationModal() { const script = document.querySelector('#validation-modal-script'); const css = document.querySelector('#validation-modal-css'); const component = document.querySelector('#validation-modal'); script?.remove(); css?.remove(); component?.remove(); } public async openPairingConfirmationModal( roleDefinition: Record, processId: string, stateId: string ) { let members; if (roleDefinition['pairing']) { const owner = roleDefinition['pairing']; members = owner.members; } else { throw new Error('No "pairing" role'); } if (members.length != 1) { throw new Error('Must have exactly 1 member'); } console.log('MEMBERS:', members); // We take all the addresses except our own const service = await Services.getInstance(); const localAddress = service.getDeviceAddress(); for (const member of members) { if (member.sp_addresses) { for (const address of member.sp_addresses) { if (address !== localAddress) { this.paired_addresses.push(address); } } } } this.processId = processId; this.stateId = stateId; // Modal injection methods removed - using confirmation modal instead this.modal = document.getElementById('confirmation-modal'); if (this.modal) this.modal.style.display = 'flex'; // Close modal when clicking outside of it window.onclick = event => { if (event.target === this.modal) { this.closeConfirmationModal(); } }; } confirmLogin() { console.log('=============> Confirm Login'); } async closeLoginModal() { if (this.modal) this.modal.style.display = 'none'; } async showConfirmationModal( options: ConfirmationModalOptions, fullscreen: boolean = false ): Promise { // Create modal element const modalElement = document.createElement('div'); modalElement.id = 'confirmation-modal'; modalElement.innerHTML = ` `; // Add modal to document document.body.appendChild(modalElement); // Return promise that resolves with user choice return new Promise(resolve => { const confirmButton = modalElement.querySelector('#confirm-button'); const cancelButton = modalElement.querySelector('#cancel-button'); const modalOverlay = modalElement.querySelector('.modal-overlay'); const cleanup = () => { modalElement.remove(); }; confirmButton?.addEventListener('click', () => { cleanup(); resolve(true); }); cancelButton?.addEventListener('click', () => { cleanup(); resolve(false); }); modalOverlay?.addEventListener('click', e => { if (e.target === modalOverlay) { cleanup(); resolve(false); } }); }); } async closeConfirmationModal() { const service = await Services.getInstance(); await service.unpairDevice(); if (this.modal) this.modal.style.display = 'none'; } }