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 { init, navigate } from '../router'; 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'; export default class ModalService { private static instance: ModalService; private stateId: string | null = null; private processId: string | null = null; private constructor() {} private paired_addresses: string[] = []; // 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); } async injectModal(members: any[]) { const container = document.querySelector('#containerId'); if (container) { let html = await fetch('/src/components/modal/confirmation-modal.html').then((res) => res.text()); html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0])); html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1])); container.innerHTML += html; // Dynamically load the header JS const script = document.createElement('script'); script.src = '/src/components/modal/confirmation-modal.ts'; script.type = 'module'; document.head.appendChild(script); } } 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(); } // this is kind of too specific for pairing though public async openPairingConfirmationModal(roleDefinition: Record, processId: string, stateId: string) { // pairing specifics let members; if (roleDefinition['owner']) { const owner = roleDefinition['owner']; members = owner.members; } else { throw new Error('No "owner" role'); } // pairing specifics if (members.length != 1) { throw new Error('Must have exactly 1 member'); } // We take all the addresses except our own const service = await Services.getInstance(); const localAddress = await service.getDeviceAddress(); for (const member of members) { for (const address of member['sp_addresses']) { if (address !== localAddress) { this.paired_addresses.push(address); } } } this.processId = processId; this.stateId = stateId; await this.injectModal(members); const modal = document.getElementById('modal'); if (modal) modal.style.display = 'flex'; // const newScript = document.createElement('script'); // newScript.setAttribute('type', 'module'); // newScript.textContent = confirmationModalScript; // document.head.appendChild(newScript).parentNode?.removeChild(newScript); // Add correct text // Close modal when clicking outside of it window.onclick = (event) => { const modal = document.getElementById('modal'); if (event.target === modal) { this.closeConfirmationModal(); } }; } confirmLogin() { console.log('=============> Confirm Login'); } async closeLoginModal() { const modal = document.getElementById('login-modal'); if (modal) modal.style.display = 'none'; } async confirmPairing() { const service = await Services.getInstance(); const modal = document.getElementById('modal'); if (modal) modal.style.display = 'none'; // We send the prd update if (this.stateId && this.processId) { try { const createPrdUpdateReturn = service.createPrdUpdate(this.processId, this.stateId); await service.handleApiReturn(createPrdUpdateReturn); } catch (e) { throw e; } } else { throw new Error('No currentPcdCommitment'); } // We send confirmation that we validate the change try { const approveChangeReturn = service.approveChange(this.processId!, this.stateId!); await service.handleApiReturn(approveChangeReturn); } catch (e) { throw e; } // try { // service.pairDevice(this.paired_addresses); // } catch (e) { // throw e; // } this.paired_addresses = []; this.processId = null; this.stateId = null; const newDevice = service.dumpDeviceFromMemory(); console.log(newDevice); await service.saveDeviceInDatabase(newDevice); navigate('process'); } async closeConfirmationModal() { const service = await Services.getInstance(); await service.unpairDevice(); const modal = document.getElementById('modal'); if (modal) modal.style.display = 'none'; } }