diff --git a/src/html/confirmation-modal.html b/src/html/confirmation-modal.html index 6face18..9356b8b 100644 --- a/src/html/confirmation-modal.html +++ b/src/html/confirmation-modal.html @@ -13,4 +13,4 @@ Refuse - \ No newline at end of file + diff --git a/src/services/routing.service.ts b/src/services/routing.service.ts index ee074df..6973357 100644 --- a/src/services/routing.service.ts +++ b/src/services/routing.service.ts @@ -76,7 +76,7 @@ export default class Routing { window.onclick = (event) => { const modal = document.getElementById('modal'); if (event.target === modal) { - this.confirmPairing(); + this.closeConfirmationModal(); } } } @@ -109,6 +109,8 @@ export default class Routing { } async closeConfirmationModal() { + const service = await Services.getInstance() + await service.unpairDevice() const modal = document.getElementById('modal') if (modal) modal.style.display = 'none'; } diff --git a/src/services/service.ts b/src/services/service.ts index 1b1a432..4b5fed1 100644 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -13,859 +13,874 @@ import { ApiReturn, CachedMessage, Member } from '../../dist/pkg/sdk_client'; import Routing from './routing.service'; type ProcessesCache = { - [key: string]: any; + [key: string]: any; }; export const U32_MAX = 4294967295; const wsurl = `https://demo.4nkweb.com/ws/`; export default class Services { - private static initializing: Promise | null = null; - private static instance: Services; - private current_process: string | null = null; - private sdkClient: any; - private websocketConnection: WebSocketClient | null = null; - private processes: IProcess[] | null = null; - private notifications: INotification[] | null = null; - private subscriptions: {element: Element; event: string; eventHandler: string;}[] = [] ; - private database: any - // Private constructor to prevent direct instantiation from outside - private constructor() {} + private static initializing: Promise | null = null; + private static instance: Services; + private current_process: string | null = null; + private sdkClient: any; + private websocketConnection: WebSocketClient | null = null; + private processes: IProcess[] | null = null; + private notifications: INotification[] | null = null; + private subscriptions: { element: Element; event: string; eventHandler: string; }[] = []; + private database: any + // Private constructor to prevent direct instantiation from outside + private constructor() { } - // Method to access the singleton instance of Services - public static async getInstance(): Promise { - if (Services.instance) { - return Services.instance; - } - - if (!Services.initializing) { - Services.initializing = (async () => { - const instance = new Services(); - await instance.init(); - return instance; - })(); - } - - console.log('initializing services'); - Services.instance = await Services.initializing; - Services.initializing = null; // Reset for potential future use - return Services.instance; + // Method to access the singleton instance of Services + public static async getInstance(): Promise { + if (Services.instance) { + return Services.instance; } - public async init(): Promise { - this.notifications = this.getNotifications(); - this.sdkClient = await import("../../dist/pkg/sdk_client"); - this.sdkClient.setup(); - await this.addWebsocketConnection(wsurl); - await this.recoverInjectHtml(); + if (!Services.initializing) { + Services.initializing = (async () => { + const instance = new Services(); + await instance.init(); + return instance; + })(); } - public async addWebsocketConnection(url: string): Promise { - // const services = await Services.getInstance(); - if (!this.websocketConnection) { - console.log('Opening new websocket connection'); - const newClient = new WebSocketClient(url, this); - this.websocketConnection = newClient; - } + console.log('initializing services'); + Services.instance = await Services.initializing; + Services.initializing = null; // Reset for potential future use + return Services.instance; + } + + public async init(): Promise { + this.notifications = this.getNotifications(); + this.sdkClient = await import("../../dist/pkg/sdk_client"); + this.sdkClient.setup(); + await this.addWebsocketConnection(wsurl); + await this.recoverInjectHtml(); + } + + public async addWebsocketConnection(url: string): Promise { + // const services = await Services.getInstance(); + if (!this.websocketConnection) { + console.log('Opening new websocket connection'); + const newClient = new WebSocketClient(url, this); + this.websocketConnection = newClient; + } + } + + public async recoverInjectHtml(): Promise { + const container = document.getElementById('containerId'); + + if (!container) { + console.error("No html container"); + return; } - public async recoverInjectHtml(): Promise { - const container = document.getElementById('containerId'); + container.innerHTML = homePage; - if (!container) { - console.error("No html container"); - return; + const newScript = document.createElement('script') + newScript.setAttribute('type', 'module') + newScript.textContent = homeScript; + document.head.appendChild(newScript).parentNode?.removeChild(newScript); + } + + private generateQRCode = async (text: string) => { + console.log("๐Ÿš€ ~ Services ~ generateQRCode= ~ text:", text) + try { + const container = document.getElementById('containerId'); + const currentUrl = window.location.href; + const url = await QRCode.toDataURL(currentUrl + "?sp_address=" + text); + const qrCode = container?.querySelector('.qr-code img'); + qrCode?.setAttribute('src', url) + + //Generate Address CopyBtn + const address = container?.querySelector('.sp-address-btn') + if (address) { + address.textContent = "Copy address"; + } + const copyBtn = document.getElementById('copyBtn'); + if (copyBtn) { + copyBtn.addEventListener('click', () => this.copyToClipboard(currentUrl + "?sp_address=" + text)); + } + } catch (err) { + console.error(err); + } + } + + //Copy Address + public async copyToClipboard(fullAddress: string) { + try { + await navigator.clipboard.writeText(fullAddress); + alert("Adresse copiรฉe dans le presse-papiers !"); + } catch (err) { + console.error("Failed to copy the address: ", err); + } + } + + //Generate emojis list + public generateEmojiList(): string[] { + const emojiRanges = [ + [0x1F600, 0x1F64F], + [0x1F300, 0x1F5FF], + [0x1F680, 0x1F6FF], + [0x1F700, 0x1F77F] + ]; + + const emojiList: string[] = []; + for (const range of emojiRanges) { + const [start, end] = range; + for (let i = start; i <= end && emojiList.length < 256; i++) { + emojiList.push(String.fromCodePoint(i)); + } + if (emojiList.length >= 256) { + break; + } + } + + return emojiList.slice(0, 256); + } + + //Adress to emojis + public addressToEmoji = async (text: string): Promise => { + //Adress to Hash + const encoder = new TextEncoder(); + const data = encoder.encode(text); + const hashBuffer = await crypto.subtle.digest('SHA-256', data); + + const hash = new Uint8Array(hashBuffer); + const bytes = hash.slice(-4); + + //Hash slice to emojis + const emojiList = this.generateEmojiList(); + const emojis = Array.from(bytes).map(byte => emojiList[byte]).join(''); + return emojis; + } + + //Get emojis from other device + public async emojisPairingRequest() { + try { + const container = document.getElementById('containerId'); + + const urlParams: URLSearchParams = new URLSearchParams(window.location.search); + const sp_adress: string | null = urlParams.get('sp_address'); + + if (!sp_adress) { + // console.error("No 'sp_adress' parameter found in the URL."); + return; + } + + const emojis = await this.addressToEmoji(sp_adress); + const emojiDisplay = container?.querySelector('.pairing-request'); + + if (emojiDisplay) { + emojiDisplay.textContent = "(Request from: " + emojis + ")"; + } + } catch (err) { + console.error(err); + } + } + + // Display address emojis and other device emojis + private displayEmojis = async (text: string) => { + console.log("๐Ÿš€ ~ Services ~ adressToEmoji") + try { + const container = document.getElementById('containerId'); + const emojis = await this.addressToEmoji(text); + const emojiDisplay = container?.querySelector('.emoji-display'); + + if (emojiDisplay) { + emojiDisplay.textContent = emojis; + } + + this.emojisPairingRequest(); + + this.initAddressInput(); + + } catch (err) { + console.error(err); + } + } + + // Verify Other address + public initAddressInput() { + const addressInput = document.getElementById('addressInput') as HTMLInputElement; + const emojiDisplay = document.getElementById('emoji-display-2'); + const okButton = document.getElementById('okButton'); + + addressInput.addEventListener('input', async () => { + let address = addressInput.value; + + // Vรฉrifie si l'adresse est une URL + try { + const url = new URL(address); + // Si c'est une URL valide, extraire le paramรจtre sp_address + const urlParams = new URLSearchParams(url.search); + const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaรฎne vide + + if (extractedAddress) { + address = extractedAddress; + addressInput.value = address; // Met ร  jour l'input pour afficher uniquement l'adresse extraite + } + } catch (e) { + // Si ce n'est pas une URL valide, on garde l'adresse originale + console.log("Ce n'est pas une URL valide, on garde l'adresse originale."); } - container.innerHTML = homePage; - - const newScript = document.createElement('script') - newScript.setAttribute('type', 'module') - newScript.textContent = homeScript; - document.head.appendChild(newScript).parentNode?.removeChild(newScript); - } - - private generateQRCode = async (text: string) => { - console.log("๐Ÿš€ ~ Services ~ generateQRCode= ~ text:", text) - try { - const container = document.getElementById('containerId'); - const currentUrl = window.location.href; - const url = await QRCode.toDataURL(currentUrl + "?sp_address=" + text); - const qrCode = container?.querySelector('.qr-code img'); - qrCode?.setAttribute('src', url) - - //Generate Address CopyBtn - const address = container?.querySelector('.sp-address-btn') if (address) { - address.textContent = "Copy address"; - } - const copyBtn = document.getElementById('copyBtn'); - if (copyBtn) { - copyBtn.addEventListener('click', () => this.copyToClipboard(text)); - } - } catch (err) { - console.error(err); - } - } - - //Copy Address - public async copyToClipboard(fullAddress: string) { - try { - await navigator.clipboard.writeText(fullAddress); - alert("Adresse copiรฉe dans le presse-papiers !"); - } catch (err) { - console.error("Failed to copy the address: ", err); - } - } - - //Generate emojis list - public generateEmojiList(): string[] { - const emojiRanges = [ - [0x1F600, 0x1F64F], - [0x1F300, 0x1F5FF], - [0x1F680, 0x1F6FF], - [0x1F700, 0x1F77F] - ]; - - const emojiList: string[] = []; - for (const range of emojiRanges) { - const [start, end] = range; - for (let i = start; i <= end && emojiList.length < 256; i++) { - emojiList.push(String.fromCodePoint(i)); - } - if (emojiList.length >= 256) { - break; - } - } - - return emojiList.slice(0, 256); - } - - //Adress to emojis - public addressToEmoji = async (text: string): Promise => { - //Adress to Hash - const encoder = new TextEncoder(); - const data = encoder.encode(text); - const hashBuffer = await crypto.subtle.digest('SHA-256', data); - - const hash = new Uint8Array(hashBuffer); - const bytes = hash.slice(-4); - - //Hash slice to emojis - const emojiList = this.generateEmojiList(); - const emojis = Array.from(bytes).map(byte => emojiList[byte]).join(''); - return emojis; - } - - //Get emojis from other device - public async emojisPairingRequest () { - try { - const container = document.getElementById('containerId'); - - const urlParams: URLSearchParams = new URLSearchParams(window.location.search); - const sp_adress: string | null = urlParams.get('sp_address'); - - if (!sp_adress) { - // console.error("No 'sp_adress' parameter found in the URL."); - return; - } - - const emojis = await this.addressToEmoji(sp_adress); - const emojiDisplay = container?.querySelector('.pairing-request'); - - if (emojiDisplay) { - emojiDisplay.textContent = "(Request from: " +emojis+")"; - } - } catch (err) { - console.error(err); - } - } - - // Display address emojis and other device emojis - private displayEmojis = async (text: string) => { - console.log("๐Ÿš€ ~ Services ~ adressToEmoji") - try { - const container = document.getElementById('containerId'); - const emojis = await this.addressToEmoji(text); - const emojiDisplay = container?.querySelector('.emoji-display'); - - if (emojiDisplay) { - emojiDisplay.textContent = emojis; - } - - this.emojisPairingRequest(); - - this.initAddressInput(); - - } catch (err) { - console.error(err); - } - } - - // Verify Other address - public initAddressInput() { - const addressInput = document.getElementById('addressInput') as HTMLInputElement; - const emojiDisplay = document.getElementById('emoji-display-2'); - const okButton = document.getElementById('okButton'); - - addressInput.addEventListener('input', async () => { - const address = addressInput.value; - - - if (address) { - const emojis = await this.addressToEmoji(address); - if (emojiDisplay) { - emojiDisplay.innerHTML = emojis; - } - if (okButton) { + const emojis = await this.addressToEmoji(address); + if (emojiDisplay) { + emojiDisplay.innerHTML = emojis; + } + if (okButton) { okButton.style.display = 'inline-block'; - } - } else { - if (emojiDisplay) { - emojiDisplay.innerHTML = ''; - } - if (okButton) { + } + } else { + if (emojiDisplay) { + emojiDisplay.innerHTML = ''; + } + if (okButton) { okButton.style.display = 'none'; - } - } - }); + } + } + }); - if (okButton) { + if (okButton) { okButton.addEventListener('click', () => { this.onOkButtonClick(); }); - } + } +} + + private async onOkButtonClick() { + const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value; + await this.sendPairingTx(addressInput); + } + + + public isPaired(): boolean | undefined { + try { + return this.sdkClient.is_linking(); + } catch (e) { + console.error("isPaired ~ Error:", e); + } + } + + public async unpairDevice(): Promise { + const service = await Services.getInstance() + await service.sdkClient.unpair_device() + const newDevice = await this.dumpDevice(); + await this.saveDevice(newDevice); + } + + private prepareProcessTx(myAddress: string, recipientAddress: string) { + const initial_session_privkey = new Uint8Array(32); + const initial_session_pubkey = new Uint8Array(32); + const pairingTemplate = { + "description": "AliceBob", + "roles": { + "owner": { + "members": + [{ sp_addresses: [myAddress, recipientAddress] }], + "validation_rules": + [ + { + "quorum": 1.0, + "fields": [ + "description", + "roles", + "session_privkey", + "session_pubkey", + "key_parity" + ], + "min_sig_member": 1.0 + } + ] + } + }, + "session_privkey": initial_session_privkey, + "session_pubkey": initial_session_pubkey, + "key_parity": true, } - private async onOkButtonClick() { - const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value; - await this.sendPairingTx(addressInput); - } - - - public isPaired(): boolean | undefined { - try { - return this.sdkClient.is_linking(); - } catch (e) { - console.error("isPaired ~ Error:", e); - } + + const apiReturn = this.sdkClient.create_update_transaction(undefined, JSON.stringify(pairingTemplate), 1) + return apiReturn + } + + public async sendPairingTx(spAddress: string): Promise { + const amount = this.sdkClient.get_available_amount(); + + if (amount === 0n) { + const faucetMsg = this.sdkClient.create_faucet_msg(); + await this.sendFaucetMessage(faucetMsg); } - public async unpairDevice(): Promise { - const service = await Services.getInstance() - await service.sdkClient.unpair_device() - const newDevice = await this.dumpDevice(); - await this.saveDevice(newDevice); - } - - private prepareProcessTx(myAddress: string, recipientAddress: string) { - const initial_session_privkey = new Uint8Array(32); - const initial_session_pubkey = new Uint8Array(32); - const pairingTemplate = { - "description": "AliceBob", - "roles": { - "owner": { - "members": - [{sp_addresses: [myAddress, recipientAddress]}], - "validation_rules": - [ - { - "quorum": 1.0, - "fields": [ - "description", - "roles", - "session_privkey", - "session_pubkey", - "key_parity" - ], - "min_sig_member": 1.0 - } - ] - } - }, - "session_privkey": initial_session_privkey, - "session_pubkey": initial_session_pubkey, - "key_parity": true, - } - - - const apiReturn = this.sdkClient.create_update_transaction(undefined, JSON.stringify(pairingTemplate), 1) - return apiReturn - } - - public async sendPairingTx(spAddress: string): Promise { - const amount = this.sdkClient.get_available_amount(); - - if (amount === 0n) { - const faucetMsg = this.sdkClient.create_faucet_msg(); - await this.sendFaucetMessage(faucetMsg); - } - - const localAddress = this.sdkClient.get_address(); - const emptyTxid = '0'.repeat(64) - - try { - let commitmentOutpoint = `${emptyTxid}:${U32_MAX}`; - this.sdkClient.pair_device(commitmentOutpoint, [spAddress]) - } catch (e) { - console.error("Services ~ Error:", e); - return - } - - setTimeout( async () => { - const apiReturn = this.prepareProcessTx(localAddress, spAddress) - await this.handleApiReturn(apiReturn); - }, 100) + const localAddress = this.sdkClient.get_address(); + const emptyTxid = '0'.repeat(64) + try { + let commitmentOutpoint = `${emptyTxid}:${U32_MAX}`; + this.sdkClient.pair_device(commitmentOutpoint, [spAddress]) + } catch (e) { + console.error("Services ~ Error:", e); return } - async resetDevice() { - await this.sdkClient.reset_device() - } + setTimeout(async () => { + const apiReturn = this.prepareProcessTx(localAddress, spAddress) + await this.handleApiReturn(apiReturn); + }, 100) - async sendNewTxMessage(message: string) { - if (!this.websocketConnection) { - throw new Error('No websocket connection'); + return + } + + async resetDevice() { + await this.sdkClient.reset_device() + } + + async sendNewTxMessage(message: string) { + if (!this.websocketConnection) { + throw new Error('No websocket connection'); + } + // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ newTxMessage:", message) + await this.websocketConnection.sendMessage('NewTx', message) + } + + async sendCommitMessage(message: string) { + // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ CommitMessage:", message) + await this.websocketConnection?.sendMessage('Commit', message) + } + + async sendCipherMessages(ciphers: string[]) { + for (let i = 0; i < ciphers.length; i++) { + const cipher = ciphers[i]; + await this.websocketConnection?.sendMessage('Cipher', cipher); + } + } + + async sendFaucetMessage(message: string): Promise { + // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ faucetMessage:", message) + await this.websocketConnection?.sendMessage('Faucet', message); + } + + async parseCipher(message: string) { + // try { + // JSON.parse(message) + // const router = await Routing.getInstance(); + // router.closeLoginModal() + // this.injectProcessListPage() + // } catch { + // console.log('Not proper format for cipher') + // } + try { + console.log('parsing new cipher'); + const apiReturn = await this.sdkClient.parse_cipher(message, 0.00001); + console.log("๐Ÿš€ ~ Services ~ parseCipher ~ apiReturn:", apiReturn); + await this.handleApiReturn(apiReturn) + } catch (e) { + console.log("Cipher isn't for us"); + } + // await this.saveCipherTxToDb(parsedTx) + } + + async parseNewTx(tx: string) { + try { + // console.log('==============> sending txxxxxxx parser', tx) + const parsedTx = await this.sdkClient.parse_new_tx(tx, 0, 0.0001) + if (parsedTx) { + console.log("๐Ÿš€ ~ Services ~ parseNewTx ~ parsedTx:", parsedTx) + try { + await this.handleApiReturn(parsedTx); + const newDevice = await this.dumpDevice(); + await this.saveDevice(newDevice); + } catch (e) { + console.error("Failed to update device with new tx"); + } } - // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ newTxMessage:", message) - await this.websocketConnection.sendMessage('NewTx', message) + } catch (e) { + console.trace(e); + } + } + + private async handleApiReturn(apiReturn: ApiReturn) { + if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length) { + await this.sendCipherMessages(apiReturn.ciphers_to_send) } - async sendCommitMessage(message: string) { - // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ CommitMessage:", message) - await this.websocketConnection?.sendMessage('Commit', message) - } + setTimeout(async () => { + if (apiReturn.updated_process && apiReturn.updated_process.length) { + const [processCommitment, process] = apiReturn.updated_process; + console.debug('Updated Process Commitment:', processCommitment); + console.debug('Process Details:', process); - async sendCipherMessages(ciphers: string[]) { - for (let i = 0; i < ciphers.length; i++) { - const cipher = ciphers[i]; - await this.websocketConnection?.sendMessage('Cipher', cipher); - } - } - - async sendFaucetMessage(message: string): Promise { - // console.log("๐Ÿš€ ~ WebSocketClient ~ this.ws.onopen= ~ faucetMessage:", message) - await this.websocketConnection?.sendMessage('Faucet', message); - } - - async parseCipher(message: string) { - // try { - // JSON.parse(message) - // const router = await Routing.getInstance(); - // router.closeLoginModal() - // this.injectProcessListPage() - // } catch { - // console.log('Not proper format for cipher') - // } - try { - console.log('parsing new cipher'); - const apiReturn = await this.sdkClient.parse_cipher(message, 0.00001); - console.log("๐Ÿš€ ~ Services ~ parseCipher ~ apiReturn:", apiReturn); - await this.handleApiReturn(apiReturn) - } catch (e) { - console.log("Cipher isn't for us"); - } - // await this.saveCipherTxToDb(parsedTx) - } - - async parseNewTx(tx: string) { - try { - // console.log('==============> sending txxxxxxx parser', tx) - const parsedTx = await this.sdkClient.parse_new_tx(tx, 0, 0.0001) - if(parsedTx) { - console.log("๐Ÿš€ ~ Services ~ parseNewTx ~ parsedTx:", parsedTx) - try { - await this.handleApiReturn(parsedTx); - const newDevice = await this.dumpDevice(); - await this.saveDevice(newDevice); - } catch (e) { - console.error("Failed to update device with new tx"); + // Save process to storage + localStorage.setItem(processCommitment, JSON.stringify(process)); + // Check if the newly updated process reveals some new information + try { + const proposals: string[] = this.sdkClient.get_update_proposals(processCommitment); + if (proposals && proposals.length != 0) { + const actual_proposal = JSON.parse(proposals[0]); // We just don't acknowledge concurrent proposals for now + console.info(actual_proposal); + let router = await Routing.getInstance(); + await router.openConfirmationModal(actual_proposal, processCommitment); } + } catch (e) { + console.error(e); } - } catch(e) { - console.trace(e); - } - } - - private async handleApiReturn(apiReturn: ApiReturn) { - if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length) { - await this.sendCipherMessages(apiReturn.ciphers_to_send) } - setTimeout(async () => { - if (apiReturn.updated_process && apiReturn.updated_process.length) { - const [processCommitment, process] = apiReturn.updated_process; - console.debug('Updated Process Commitment:', processCommitment); - console.debug('Process Details:', process); + if (apiReturn.updated_cached_msg && apiReturn.updated_cached_msg.length) { + apiReturn.updated_cached_msg.forEach((msg, index) => { + // console.debug(`CachedMessage ${index}:`, msg); + // Save the message to local storage + localStorage.setItem(msg.id.toString(), JSON.stringify(msg)); + }); + } - // Save process to storage - localStorage.setItem(processCommitment, JSON.stringify(process)); - // Check if the newly updated process reveals some new information - try { - const proposals: string[] = this.sdkClient.get_update_proposals(processCommitment); - if (proposals && proposals.length != 0) { - const actual_proposal = JSON.parse(proposals[0]); // We just don't acknowledge concurrent proposals for now - console.info(actual_proposal); - let router = await Routing.getInstance(); - await router.openConfirmationModal(actual_proposal, processCommitment); - } - } catch (e) { - console.error(e); - } - } + if (apiReturn.commit_to_send) { + const commit = apiReturn.commit_to_send; + await this.sendCommitMessage(JSON.stringify(commit)); + } - if(apiReturn.updated_cached_msg && apiReturn.updated_cached_msg.length) { - apiReturn.updated_cached_msg.forEach((msg, index) => { - // console.debug(`CachedMessage ${index}:`, msg); - // Save the message to local storage - localStorage.setItem(msg.id.toString(), JSON.stringify(msg)); - }); - } + if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) { + await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send)) + } + }, 0) + } - if (apiReturn.commit_to_send) { - const commit = apiReturn.commit_to_send; - await this.sendCommitMessage(JSON.stringify(commit)); - } + async pairDevice(prd: any, outpointCommitment: string) { + console.log("๐Ÿš€ ~ Services ~ pairDevice ~ prd:", prd) + // const service = await Services.getInstance(); + // const spAddress = await this.getDeviceAddress() as any; + // const sender = JSON.parse(prd?.sender) + // const senderAddress = sender?.sp_addresses?.find((address: string) => address !== spAddress) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ senderAddress:", senderAddress) + // if(senderAddress) { + // const proposal = service.sdkClient.get_update_proposals(outpointCommitment); + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ proposal:", proposal) + // // const pairingTx = proposal.pairing_tx.replace(/^\"+|\"+$/g, '') + // const parsedProposal = JSON.parse(proposal[0]) - if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) { - await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send)) - } - }, 0) - } + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ parsedProposal:", parsedProposal) + // const roles = JSON.parse(parsedProposal.roles) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ roles:", roles, Array.isArray(roles), !roles.owner) + // if(Array.isArray(roles) || !roles.owner) return + // const proposalMembers = roles?.owner?.members + // const isFirstDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === spAddress)) + // const isSecondDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === senderAddress)) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ proposalMembers:", proposalMembers) + // if(proposalMembers?.length !== 2 || !isFirstDevice || !isSecondDevice) return + // const pairingTx = parsedProposal?.pairing_tx?.replace(/^\"+|\"+$/g, '') - async pairDevice(prd: any, outpointCommitment: string) { - console.log("๐Ÿš€ ~ Services ~ pairDevice ~ prd:", prd) - // const service = await Services.getInstance(); - // const spAddress = await this.getDeviceAddress() as any; - // const sender = JSON.parse(prd?.sender) - // const senderAddress = sender?.sp_addresses?.find((address: string) => address !== spAddress) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ senderAddress:", senderAddress) - // if(senderAddress) { - // const proposal = service.sdkClient.get_update_proposals(outpointCommitment); - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ proposal:", proposal) - // // const pairingTx = proposal.pairing_tx.replace(/^\"+|\"+$/g, '') - // const parsedProposal = JSON.parse(proposal[0]) - - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ parsedProposal:", parsedProposal) - // const roles = JSON.parse(parsedProposal.roles) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ roles:", roles, Array.isArray(roles), !roles.owner) - // if(Array.isArray(roles) || !roles.owner) return - // const proposalMembers = roles?.owner?.members - // const isFirstDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === spAddress)) - // const isSecondDevice = proposalMembers.some((member: Member) => member.sp_addresses.some(address => address === senderAddress)) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ proposalMembers:", proposalMembers) - // if(proposalMembers?.length !== 2 || !isFirstDevice || !isSecondDevice) return - // const pairingTx = parsedProposal?.pairing_tx?.replace(/^\"+|\"+$/g, '') - - // let txid = '0'.repeat(64) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ pairingTx:", pairingTx, `${txid}:4294967295`) + // let txid = '0'.repeat(64) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ pairingTx:", pairingTx, `${txid}:4294967295`) - // const pairing = await service.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress]) - // const device = this.dumpDevice() - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ device:", device) - // this.saveDevice(device) - // // await service.sdkClient.pair_device(pairingTx, [senderAddress]) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ pairing:", pairing) - // // const process = await this.prepareProcessTx(spAddress, senderAddress) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ process:", outpointCommitment, prd, prd.payload) - // const prdString = JSON.stringify(prd).trim() - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ prdString:", prdString) - // let tx = await service.sdkClient.response_prd(outpointCommitment, prdString, true) - // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ tx:", tx) - // if(tx.ciphers_to_send) { - // tx.ciphers_to_send.forEach((cipher: string) => service.websocketConnection?.sendMessage('Cipher', cipher)) - // } - // this.injectProcessListPage() - // } - } - - // async saveTxToDb(tx: CachedMessage) { - // const database = await Database.getInstance(); - // const indexedDb = await database.getDb(); - // await database.writeObject(indexedDb, 'messages', tx, null); - // } - - // async saveCipherTxToDb(tx: string) { - // const database = await Database.getInstance(); - // const indexedDb = await database.getDb(); - - // if(tx) { - // await database.writeObject(indexedDb, database.getStoreList().AnkCipherMessages, tx, null); + // const pairing = await service.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress]) + // const device = this.dumpDevice() + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ device:", device) + // this.saveDevice(device) + // // await service.sdkClient.pair_device(pairingTx, [senderAddress]) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ pairing:", pairing) + // // const process = await this.prepareProcessTx(spAddress, senderAddress) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ process:", outpointCommitment, prd, prd.payload) + // const prdString = JSON.stringify(prd).trim() + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ prdString:", prdString) + // let tx = await service.sdkClient.response_prd(outpointCommitment, prdString, true) + // console.log("๐Ÿš€ ~ Services ~ pairDevice ~ tx:", tx) + // if(tx.ciphers_to_send) { + // tx.ciphers_to_send.forEach((cipher: string) => service.websocketConnection?.sendMessage('Cipher', cipher)) // } + // this.injectProcessListPage() // } + } - async getAmount() { - const amount = await this.sdkClient.get_available_amount() - console.log("๐Ÿš€ ~ Services ~ getAmount ~ amount:", amount) - return amount + // async saveTxToDb(tx: CachedMessage) { + // const database = await Database.getInstance(); + // const indexedDb = await database.getDb(); + // await database.writeObject(indexedDb, 'messages', tx, null); + // } + + // async saveCipherTxToDb(tx: string) { + // const database = await Database.getInstance(); + // const indexedDb = await database.getDb(); + + // if(tx) { + // await database.writeObject(indexedDb, database.getStoreList().AnkCipherMessages, tx, null); + // } + // } + + async getAmount() { + const amount = await this.sdkClient.get_available_amount() + console.log("๐Ÿš€ ~ Services ~ getAmount ~ amount:", amount) + return amount + } + + async getDeviceAddress() { + return await this.sdkClient.get_address(); + } + + async dumpDevice() { + const device = await this.sdkClient.dump_device() + // console.log("๐Ÿš€ ~ Services ~ dumpDevice ~ device:", device) + return device + } + + async saveDevice(device: any): Promise { + // console.log("๐Ÿš€ ~ Services ~ saveDevice ~ device:", device) + localStorage.setItem('wallet', device); + } + + async getDevice(): Promise { + return localStorage.getItem('wallet') + } + + async dumpWallet() { + const wallet = await this.sdkClient.dump_wallet() + console.log("๐Ÿš€ ~ Services ~ dumpWallet ~ wallet:", wallet) + return wallet + } + + async createFaucetMessage() { + const message = await this.sdkClient.create_faucet_msg() + console.log("๐Ÿš€ ~ Services ~ createFaucetMessage ~ message:", message) + return message; + } + + private addSubscription(element: Element, event: string, eventHandler: string): void { + this.subscriptions.push({ element, event, eventHandler }); + element.addEventListener(event, (this as any)[eventHandler].bind(this)); + } + + async createNewDevice() { + let spAddress = ''; + try { + spAddress = await this.sdkClient.create_new_device(0, 'regtest') + const device = await this.dumpDevice() + console.log("๐Ÿš€ ~ Services ~ device:", device) + await this.saveDevice(device) + } catch (e) { + console.error("Services ~ Error:", e); } - async getDeviceAddress() { - return await this.sdkClient.get_address(); - } + this.generateQRCode(spAddress || '') + //Adress to Emoji integration + this.displayEmojis(spAddress) + //Adress to Emoji integration - async dumpDevice() { - const device = await this.sdkClient.dump_device() - // console.log("๐Ÿš€ ~ Services ~ dumpDevice ~ device:", device) - return device - } - async saveDevice(device: any): Promise { - // console.log("๐Ÿš€ ~ Services ~ saveDevice ~ device:", device) - localStorage.setItem('wallet', device); - } - - async getDevice(): Promise { - return localStorage.getItem('wallet') - } - - async dumpWallet() { - const wallet = await this.sdkClient.dump_wallet() - console.log("๐Ÿš€ ~ Services ~ dumpWallet ~ wallet:", wallet) - return wallet - } - - async createFaucetMessage() { - const message = await this.sdkClient.create_faucet_msg() - console.log("๐Ÿš€ ~ Services ~ createFaucetMessage ~ message:", message) - return message; - } - - private addSubscription(element: Element, event: string, eventHandler: string): void { - this.subscriptions.push({ element, event, eventHandler }); - element.addEventListener(event, (this as any)[eventHandler].bind(this)); - } - - async createNewDevice() { - let spAddress = ''; - try { - spAddress = await this.sdkClient.create_new_device(0, 'regtest') - const device = await this.dumpDevice() - console.log("๐Ÿš€ ~ Services ~ device:", device) - await this.saveDevice(device) - } catch (e) { - console.error("Services ~ Error:", e); - } + return spAddress; + } + async restoreDevice(device: string) { + try { + await this.sdkClient.restore_device(device) + const spAddress = this.sdkClient.get_address(); this.generateQRCode(spAddress || '') //Adress to Emoji integration this.displayEmojis(spAddress) //Adress to Emoji integration - - - return spAddress; + } catch (e) { + console.error(e); + } + } + + private getProcessesCache(): ProcessesCache { + // Regular expression to match 64-character hexadecimal strings + const hexU32KeyRegex: RegExp = /^[0-9a-fA-F]{64}:\d+$/; + const hexObjects: ProcessesCache = {} + + // Iterate over all keys in localStorage + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + + if (!key) { + return hexObjects; + } + + // Check if the key matches the 32-byte hex pattern + if (hexU32KeyRegex.test(key)) { + const value = localStorage.getItem(key); + if (!value) { + continue; + } + + hexObjects[key] = JSON.parse(value); + } } - async restoreDevice(device: string) { + return hexObjects; + } + + private getCachedMessages(): string[] { + const u32KeyRegex = /^\d+$/; + const U32_MAX = 4294967295; + const messages: string[] = []; + + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + + if (!key) { + return messages; + } + + if (u32KeyRegex.test(key)) { + const num = parseInt(key, 10); + if (num < 0 || num > U32_MAX) { + console.warn(`Key ${key} is outside the u32 range and will be ignored.`); + continue; + } + + const value = localStorage.getItem(key); + if (!value) { + console.warn(`No value found for key: ${key}`); + continue; + } + + messages.push(value); + } + } + + return messages; + } + + public async restoreProcesses() { + const processesCache = this.getProcessesCache(); + console.log("๐Ÿš€ ~ Services ~ restoreProcesses ~ processesCache:", processesCache); + + if (processesCache.length == 0) { + console.debug("๐Ÿš€ ~ Services ~ restoreProcesses ~ no processes in local storage"); + return; + } + + try { + await this.sdkClient.set_process_cache(JSON.stringify(processesCache)); + } catch (e) { + console.error('Services ~ restoreProcesses ~ Error:', e); + } + } + + public async restoreMessages() { + const cachedMessages = this.getCachedMessages(); + console.log("๐Ÿš€ ~ Services ~ restoreMessages ~ chachedMessages:", cachedMessages); + + if (cachedMessages && cachedMessages.length != 0) { try { - await this.sdkClient.restore_device(device) - const spAddress = this.sdkClient.get_address(); - this.generateQRCode(spAddress || '') - //Adress to Emoji integration - this.displayEmojis(spAddress) - //Adress to Emoji integration + await this.sdkClient.set_message_cache(cachedMessages); } catch (e) { - console.error(e); + console.error('Services ~ restoreMessages ~ Error:', e); } } - private getProcessesCache(): ProcessesCache { - // Regular expression to match 64-character hexadecimal strings - const hexU32KeyRegex: RegExp = /^[0-9a-fA-F]{64}:\d+$/; - const hexObjects: ProcessesCache = {} + } - // Iterate over all keys in localStorage - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); + private cleanSubscriptions(): void { + for (const sub of this.subscriptions) { + const el = sub.element; + const eventHandler = sub.eventHandler; + el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this)); + } + this.subscriptions = []; + } - if (!key) { - return hexObjects; - } - - // Check if the key matches the 32-byte hex pattern - if (hexU32KeyRegex.test(key)) { - const value = localStorage.getItem(key); - if (!value) { - continue; - } + async injectProcessListPage(): Promise { + const container = document.getElementById('containerId'); - hexObjects[key] = JSON.parse(value); - } - } - - return hexObjects; + if (!container) { + console.error("No html container"); + return; } - private getCachedMessages(): string[] { - const u32KeyRegex = /^\d+$/; - const U32_MAX = 4294967295; - const messages: string[] = []; + this.cleanSubscriptions() - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); + // const user = services.sdkClient.create_user('Test', 'test', 10, 1, 'Messaging') + // console.log("๐Ÿš€ ~ Services ~ injectProcessListPage ~ user:", user) - if (!key) { - return messages; - } + // const database = await Database.getInstance(); + // const indexedDb = await database.getDb(); + // await database.writeObject(indexedDb, database.getStoreList().AnkUser, user.user, null); + container.innerHTML = processPage; + const newScript = document.createElement('script'); + newScript.setAttribute('type', 'module') + newScript.textContent = processScript; + document.head.appendChild(newScript).parentNode?.removeChild(newScript); - if (u32KeyRegex.test(key)) { - const num = parseInt(key, 10); - if (num < 0 || num > U32_MAX) { - console.warn(`Key ${key} is outside the u32 range and will be ignored.`); - continue; - } - - const value = localStorage.getItem(key); - if (!value) { - console.warn(`No value found for key: ${key}`); - continue; - } - - messages.push(value); - } - } - - return messages; + this.processes = await this.getProcesses(); + if (this.processes) { + this.setProcessesInSelectElement(this.processes) } + } - public async restoreProcesses() { - const processesCache = this.getProcessesCache(); - console.log("๐Ÿš€ ~ Services ~ restoreProcesses ~ processesCache:", processesCache); - - if (processesCache.length == 0) { - console.debug("๐Ÿš€ ~ Services ~ restoreProcesses ~ no processes in local storage"); - return; - } - - try { - await this.sdkClient.set_process_cache(JSON.stringify(processesCache)); - } catch (e) { - console.error('Services ~ restoreProcesses ~ Error:', e); + public async setProcessesInSelectElement(processList: any[]) { + const select = document.querySelector(".select-field"); + if (select) { + for (const process of processList) { + const option = document.createElement("option"); + option.setAttribute("value", process.name); + option.innerText = process.name; + select.appendChild(option); } } - - public async restoreMessages() { - const cachedMessages = this.getCachedMessages(); - console.log("๐Ÿš€ ~ Services ~ restoreMessages ~ chachedMessages:", cachedMessages); - - if (cachedMessages && cachedMessages.length != 0) { - try { - await this.sdkClient.set_message_cache(cachedMessages); - } catch (e) { - console.error('Services ~ restoreMessages ~ Error:', e); - } - } - - } - - private cleanSubscriptions(): void { - for (const sub of this.subscriptions) { - const el = sub.element; - const eventHandler = sub.eventHandler; - el.removeEventListener(sub.event, (this as any)[eventHandler].bind(this)); - } - this.subscriptions = []; - } - - async injectProcessListPage(): Promise { - const container = document.getElementById('containerId'); - - if (!container) { - console.error("No html container"); - return; - } - - this.cleanSubscriptions() - - // const user = services.sdkClient.create_user('Test', 'test', 10, 1, 'Messaging') - // console.log("๐Ÿš€ ~ Services ~ injectProcessListPage ~ user:", user) - - // const database = await Database.getInstance(); - // const indexedDb = await database.getDb(); - // await database.writeObject(indexedDb, database.getStoreList().AnkUser, user.user, null); - container.innerHTML = processPage; - const newScript = document.createElement('script'); - newScript.setAttribute('type', 'module') - newScript.textContent = processScript; - document.head.appendChild(newScript).parentNode?.removeChild(newScript); - - this.processes = await this.getProcesses(); - if(this.processes) { - this.setProcessesInSelectElement(this.processes) - } - } - - public async setProcessesInSelectElement(processList: any[]) { - const select = document.querySelector(".select-field"); - if(select) { - for (const process of processList) { - const option = document.createElement("option"); - option.setAttribute("value", process.name); - option.innerText = process.name; - select.appendChild(option); - } - } - const optionList = document.querySelector('.autocomplete-list'); - if(optionList) { - const observer = new MutationObserver((mutations, observer) => { - const options = optionList.querySelectorAll('li') - if(options) { - for(const option of options) { - this.addSubscription(option, 'click', 'showSelectedProcess') - } - } - }); - observer.observe(document, { - subtree: true, - attributes: true, - }); - } - } - - public async listenToOptionListPopulating(event: Event) { - const target = event.target as HTMLUListElement; - const options = target?.querySelectorAll('li') - } - - public async showSelectedProcess(event: MouseEvent) { - const elem = event.target; - if(elem) { - - const cardContent = document.querySelector(".card-content"); - - const processes = await this.getProcesses(); - console.log("๐Ÿš€ ~ Services ~ showSelectedProcess ~ processes:", processes) - const process = processes.find((process: any) => process.name === (elem as any).dataset.value); - if (process) { - const processDiv = document.createElement("div"); - processDiv.className = "process"; - processDiv.id = process.name; - const titleDiv = document.createElement("div"); - titleDiv.className = "process-title"; - titleDiv.innerHTML = `${process.name} : ${process.description}`; - processDiv.appendChild(titleDiv); - for (const zone of process.zoneList) { - const zoneElement = document.createElement("div"); - zoneElement.className = "process-element"; - zoneElement.setAttribute('zone-id', zone.id.toString()) - zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`; - this.addSubscription(zoneElement, 'click', 'goToProcessPage') - processDiv.appendChild(zoneElement); - } - if(cardContent) cardContent.appendChild(processDiv); - } - } - } - - goToProcessPage(event: MouseEvent) { - const target = event.target as HTMLDivElement; - const zoneId = target?.getAttribute('zone-id'); - const processList = document.querySelectorAll('.process-element'); - if(processList) { - for(const process of processList) { - process.classList.remove('selected') + const optionList = document.querySelector('.autocomplete-list'); + if (optionList) { + const observer = new MutationObserver((mutations, observer) => { + const options = optionList.querySelectorAll('li') + if (options) { + for (const option of options) { + this.addSubscription(option, 'click', 'showSelectedProcess') } } - target.classList.add('selected') + }); + observer.observe(document, { + subtree: true, + attributes: true, + }); + } + } - console.log('=======================> going to process page', zoneId) + public async listenToOptionListPopulating(event: Event) { + const target = event.target as HTMLUListElement; + const options = target?.querySelectorAll('li') + } + + public async showSelectedProcess(event: MouseEvent) { + const elem = event.target; + if (elem) { + + const cardContent = document.querySelector(".card-content"); + + const processes = await this.getProcesses(); + console.log("๐Ÿš€ ~ Services ~ showSelectedProcess ~ processes:", processes) + const process = processes.find((process: any) => process.name === (elem as any).dataset.value); + if (process) { + const processDiv = document.createElement("div"); + processDiv.className = "process"; + processDiv.id = process.name; + const titleDiv = document.createElement("div"); + titleDiv.className = "process-title"; + titleDiv.innerHTML = `${process.name} : ${process.description}`; + processDiv.appendChild(titleDiv); + for (const zone of process.zoneList) { + const zoneElement = document.createElement("div"); + zoneElement.className = "process-element"; + zoneElement.setAttribute('zone-id', zone.id.toString()) + zoneElement.innerHTML = `Zone ${zone.id} : ${zone.name}`; + this.addSubscription(zoneElement, 'click', 'goToProcessPage') + processDiv.appendChild(zoneElement); + } + if (cardContent) cardContent.appendChild(processDiv); } + } + } - async getProcesses(): Promise { - const processes = this.sdkClient.get_processes() - console.log("๐Ÿš€ ~ Services ~ getProcesses ~ processes:", processes) - return [ + goToProcessPage(event: MouseEvent) { + const target = event.target as HTMLDivElement; + const zoneId = target?.getAttribute('zone-id'); + const processList = document.querySelectorAll('.process-element'); + if (processList) { + for (const process of processList) { + process.classList.remove('selected') + } + } + target.classList.add('selected') + + console.log('=======================> going to process page', zoneId) + } + + async getProcesses(): Promise { + const processes = this.sdkClient.get_processes() + console.log("๐Ÿš€ ~ Services ~ getProcesses ~ processes:", processes) + return [ + { + id: 1, + name: "Messaging", + description: "Encrypted messages", + zoneList: [ { id: 1, - name: "Messaging", - description: "Encrypted messages", - zoneList: [ - { - id: 1, - name: "General", - path: '/test' - }, - ], + name: "General", + path: '/test' + }, + ], + }, + { + id: 2, + name: "Storage", + description: "Distributed storage", + zoneList: [ + { + id: 1, + name: "Paris", + path: '/test' }, { id: 2, - name: "Storage", - description: "Distributed storage", - zoneList: [ - { - id: 1, - name: "Paris", - path: '/test' - }, - { - id: 2, - name: "Normandy", - path: '/test' - }, - { - id: 3, - name: "New York", - path: '/test' - }, - { - id: 4, - name: "Moscow", - path: '/test' - }, - ], - }, - ]; - } - - getNotifications(): INotification[] { - return [ - { - id: 1, - title: 'Notif 1', - description: 'A normal notification', - sendToNotificationPage: false, - path: '/notif1' - }, - { - id: 2, - title: 'Notif 2', - description: 'A normal notification', - sendToNotificationPage: false, - path: '/notif2' + name: "Normandy", + path: '/test' }, { id: 3, - title: 'Notif 3', - description: 'A normal notification', - sendToNotificationPage: false, - path: '/notif3' - } - ] - } + name: "New York", + path: '/test' + }, + { + id: 4, + name: "Moscow", + path: '/test' + }, + ], + }, + ]; + } - async setNotification(): Promise { - const badge = document.querySelector('.notification-badge') as HTMLDivElement - const notifications = this.notifications - const noNotifications = document.querySelector('.no-notification') as HTMLDivElement - if(notifications?.length) { - badge.innerText = notifications.length.toString() - const notificationBoard = document.querySelector('.notification-board') as HTMLDivElement - noNotifications.style.display = 'none' - for(const notif of notifications) { - const notifElement = document.createElement("div"); - notifElement.className = "notification-element"; - notifElement.setAttribute('notif-id', notif.id.toString()) - notifElement.innerHTML = ` + getNotifications(): INotification[] { + return [ + { + id: 1, + title: 'Notif 1', + description: 'A normal notification', + sendToNotificationPage: false, + path: '/notif1' + }, + { + id: 2, + title: 'Notif 2', + description: 'A normal notification', + sendToNotificationPage: false, + path: '/notif2' + }, + { + id: 3, + title: 'Notif 3', + description: 'A normal notification', + sendToNotificationPage: false, + path: '/notif3' + } + ] + } + + async setNotification(): Promise { + const badge = document.querySelector('.notification-badge') as HTMLDivElement + const notifications = this.notifications + const noNotifications = document.querySelector('.no-notification') as HTMLDivElement + if (notifications?.length) { + badge.innerText = notifications.length.toString() + const notificationBoard = document.querySelector('.notification-board') as HTMLDivElement + noNotifications.style.display = 'none' + for (const notif of notifications) { + const notifElement = document.createElement("div"); + notifElement.className = "notification-element"; + notifElement.setAttribute('notif-id', notif.id.toString()) + notifElement.innerHTML = `
${notif.title}
${notif.description}
`; - // this.addSubscription(notifElement, 'click', 'goToProcessPage') - notificationBoard.appendChild(notifElement); - } - } else { - noNotifications.style.display = 'block' - - } + // this.addSubscription(notifElement, 'click', 'goToProcessPage') + notificationBoard.appendChild(notifElement); } + } else { + noNotifications.style.display = 'block' + + } + } }