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';
}
}