refactor by separating sp address view from service

This commit is contained in:
AnisHADJARAB 2024-11-06 15:30:37 +00:00
parent 46622e2a7a
commit 4a59424d05
9 changed files with 270 additions and 276 deletions

View File

@ -193,7 +193,7 @@ body {
align-items: center;
}
.process-container {
grid-column: 3 / 5;
grid-column: 3 / 6;
grid-row: 3 ;
.card {

View File

@ -1,4 +1,5 @@
import { currentRoute } from '../../router';
import { INotification } from '~/models/notification.model';
import { currentRoute, navigate } from '../../router';
import Services from '../../services/service';
let notifications = [];
@ -6,6 +7,7 @@ let notifications = [];
export async function unpair() {
const service = await Services.getInstance();
await service.unpairDevice();
navigate('home')
}
(window as any).unpair = unpair;
@ -25,8 +27,7 @@ function toggleMenu() {
async function getNotifications() {
const service = await Services.getInstance();
notifications = service.getNotifications();
const badge = document.querySelector('.notification-badge') as HTMLDivElement;
if (badge) badge.innerHTML = notifications.length.toString();
return notifications
}
function openCloseNotifications() {
const notifications = document.querySelector('.notification-board') as HTMLDivElement;
@ -39,7 +40,7 @@ export async function initHeader() {
if (currentRoute === 'home') {
hideSomeFunctionnalities();
} else {
getNotifications();
launchNotificationWorker()
}
}
@ -55,3 +56,43 @@ function hideSomeFunctionnalities() {
}
}
}
async function setNotification(notifications: INotification[]): Promise<void> {
const badge = document.querySelector('.notification-badge') as HTMLDivElement;
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 = `
<div>${notif.title}</div>
<div>${notif.description}</div>
`;
// this.addSubscription(notifElement, 'click', 'goToProcessPage')
notificationBoard.appendChild(notifElement);
}
} else {
noNotifications.style.display = 'block';
}
}
function launchNotificationWorker() {
if (window.Worker) {
// Initialize the worker
const worker = new Worker('/src/workers/notification.worker.ts', { type: 'module' });
// Listen for messages from the worker
worker.addEventListener('message', (event) => {
const data = event.data;
console.log('Received data from worker:', data);
setNotification(data);
});
} else {
console.error('Your browser doesn\'t support web workers.');
}
}

View File

@ -1,6 +1,8 @@
import { Html5QrcodeScanner } from 'html5-qrcode';
import Routing from '../../services/routing.service';
import Routing from '../../services/modal.service';
import Services from '../../services/service';
import { addSubscription } from '../../utils/subscription.utils';
import { displayEmojis } from '../../utils/sp-address.utils';
let resultContainer = document.getElementById('qr-reader-results');
let lastResult: any,
@ -21,9 +23,10 @@ export async function initHomePage(): Promise<void> {
const service = await Services.getInstance();
const spAddress = await service.getDeviceAddress()
service.generateQRCode(spAddress)
service.displayEmojis(spAddress)
displayEmojis(spAddress)
document.getElementById('notification-bell')?.addEventListener('click', openCloseNotifications);
const notifBell = document.getElementById('notification-bell')
if(notifBell) addSubscription(notifBell, 'click', openCloseNotifications)
var html5QrcodeScanner = new Html5QrcodeScanner('qr-reader', { fps: 10, qrbox: 250 }, undefined);
html5QrcodeScanner.render(onScanSuccess, undefined);

View File

@ -1,3 +1,4 @@
import { addSubscription } from '../../utils/subscription.utils';
import { navigate } from '../../router';
import Services from '../../services/service';
@ -6,7 +7,7 @@ export async function init() {
const element = document.querySelector('select') as HTMLSelectElement;
// Create div that wroaps all the elements inside (select, elements selected, search div) to put select inside
const wrapper = document.createElement('div');
wrapper.addEventListener('click', clickOnWrapper);
if(wrapper) addSubscription(wrapper, 'click', clickOnWrapper)
wrapper.classList.add('multi-select-component');
wrapper.classList.add('input-field');
@ -17,14 +18,16 @@ export async function init() {
input.classList.add('selected-input');
input.setAttribute('autocomplete', 'off');
input.setAttribute('tabindex', '0');
input.addEventListener('keyup', inputChange);
input.addEventListener('keydown', deletePressed);
input.addEventListener('click', openOptions);
if(input) {
addSubscription(input, 'keyup', inputChange)
addSubscription(input, 'keydown', deletePressed)
addSubscription(input, 'click', openOptions)
}
const dropdown_icon = document.createElement('a');
dropdown_icon.classList.add('dropdown-icon');
dropdown_icon.addEventListener('click', clickDropdown);
if(dropdown_icon) addSubscription(dropdown_icon, 'click', clickDropdown)
const autocomplete_list = document.createElement('ul');
autocomplete_list.classList.add('autocomplete-list');
search_div.appendChild(input);
@ -128,7 +131,7 @@ function createToken(wrapper: HTMLElement, value: any) {
close.setAttribute('data-option', value);
close.setAttribute('data-hits', '0');
close.innerText = 'x';
close.addEventListener('click', removeToken);
if(close) addSubscription(close, 'click', removeToken)
token.appendChild(token_span);
token.appendChild(close);
inputInderline?.appendChild(token);
@ -185,7 +188,7 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop
const li = document.createElement('li');
li.innerText = options_to_show[0];
li.setAttribute('data-value', options_to_show[0]);
li.addEventListener('click', selectOption);
if(li) addSubscription(li, 'click', selectOption)
autocomplete_list?.appendChild(li);
if (query.length == options_to_show[0].length) {
const event = new Event('click');
@ -196,7 +199,7 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop
const li = document.createElement('li');
li.innerText = options_to_show[i];
li.setAttribute('data-value', options_to_show[i]);
li.addEventListener('click', selectOption);
if(li) addSubscription(li, 'click', selectOption)
autocomplete_list?.appendChild(li);
}
} else {
@ -299,10 +302,10 @@ function removeToken(e: Event) {
}
// Listen for 2 sequence of hits on the delete key, if this happens delete the last token if exist
function deletePressed(e: KeyboardEvent) {
function deletePressed(e: Event) {
const input_search = e.target as HTMLInputElement;
const wrapper = input_search?.parentNode?.parentNode;
const key = e.keyCode || e.charCode;
const key = (e as KeyboardEvent).keyCode || (e as KeyboardEvent).charCode;
const tokens = wrapper?.querySelectorAll('.selected-wrapper');
if (tokens?.length) {
@ -327,7 +330,7 @@ function deletePressed(e: KeyboardEvent) {
}
// Dismiss on outside click
document.addEventListener('click', () => {
addSubscription(document, 'click', () => {
// get select that has the options available
const select = document.querySelectorAll('[data-multi-select-plugin]');
for (let i = 0; i < select.length; i++) {
@ -345,7 +348,7 @@ document.addEventListener('click', () => {
}
}
}
});
})
async function showSelectedProcess(elem: MouseEvent) {
if (elem) {
@ -369,9 +372,7 @@ async function showSelectedProcess(elem: MouseEvent) {
zoneElement.setAttribute('process-title', process[1].title);
zoneElement.setAttribute('process-id', `${process[0]}_${zone.id}`);
zoneElement.innerHTML = `${zone.title}: ${zone.description}`;
const service = await Services.getInstance();
// service.addSubscription(zoneElement, 'click', 'goToProcessPage');
zoneElement.addEventListener('click', select);
addSubscription(zoneElement, 'click', select);
processDiv.appendChild(zoneElement);
}
if (cardContent) cardContent.appendChild(processDiv);
@ -379,7 +380,7 @@ async function showSelectedProcess(elem: MouseEvent) {
}
}
function select(event: MouseEvent) {
function select(event: Event) {
const target = event.target as HTMLElement;
const oldSelectedProcess = document.querySelector('.selected-process-zone');
oldSelectedProcess?.classList.remove('selected-process-zone');
@ -406,7 +407,6 @@ function goToProcessPage() {
async function getProcesses(): Promise<any[]> {
const service = await Services.getInstance();
const processes = await service.getProcesses();
console.log('🚀 ~ Services ~ getProcesses ~ processes:', processes);
return processes;
}

View File

@ -1,6 +1,7 @@
import '../public/style/4nk.css';
import { initHeader } from './components/header/header';
import Services from './services/service';
import { cleanSubscriptions } from './utils/subscription.utils';
const routes: { [key: string]: string } = {
home: '/src/pages/home/home.html',
@ -11,6 +12,7 @@ const routes: { [key: string]: string } = {
export let currentRoute = '';
export async function navigate(path: string) {
cleanSubscriptions()
path = path.replace(/^\//, '');
if (path.includes('/')) {
const parsedPath = path.split('/')[0];
@ -86,7 +88,7 @@ async function init(): Promise<void> {
if (pairingAddress) {
setTimeout(async () => await services.sendPairingTx(pairingAddress), 2000);
}
await navigate('home');
await navigate('process');
}
}, 200);
} catch (error) {

View File

@ -5,9 +5,10 @@ import confirmationModalScript from '../html/confirmation-modal.js?raw';
import Services from './service';
import { U32_MAX } from './service';
import { navigate } from '../router';
import { addressToEmoji } from '../utils/sp-address.utils';
export default class Routing {
private static instance: Routing;
export default class ModalService {
private static instance: ModalService;
private sdkClient: any;
private currentPrd: any;
private currentOutpoint?: string;
@ -15,16 +16,11 @@ export default class Routing {
private paired_addresses: string[] = [];
// Method to access the singleton instance of Services
public static async getInstance(): Promise<Routing> {
if (!Routing.instance) {
Routing.instance = new Routing();
await Routing.instance.init();
public static async getInstance(): Promise<ModalService> {
if (!ModalService.instance) {
ModalService.instance = new ModalService();
}
return Routing.instance;
}
public async init(): Promise<void> {
this.sdkClient = await import('../../dist/pkg/sdk_client');
return ModalService.instance;
}
public openLoginModal(myAddress: string, receiverAddress: string) {
@ -43,23 +39,22 @@ export default class Routing {
}
public async openConfirmationModal(pcd: any, outpointCommitment: string) {
console.log('');
let roles = JSON.parse(pcd['roles']); // ['members'][0];
console.log(roles);
let members = roles['owner']['members'];
console.log(members);
// We take all the addresses except our own
const local_address = this.sdkClient.get_address();
const service = await Services.getInstance()
const localAddress = await service.getDeviceAddress();
console.log('🚀 ~ Routing ~ openConfirmationModal ~ pcd:', pcd);
for (const address of members[0]['sp_addresses']) {
if (address !== local_address) {
if (address !== localAddress) {
this.paired_addresses.push(address);
}
}
let html = confirmationModalHtml;
let services = await Services.getInstance();
html = html.replace('{{device1}}', await services.addressToEmoji(members[0]['sp_addresses'][0]));
html = html.replace('{{device2}}', await services.addressToEmoji(members[0]['sp_addresses'][1]));
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1]));
this.currentOutpoint = outpointCommitment as string;
const container = document.querySelector('.page-container');
@ -99,7 +94,7 @@ export default class Routing {
const commitmentOutpoint = `${emptyTxid}:${U32_MAX}`;
// We take the paired device(s) from the contract
await this.sdkClient.pair_device(commitmentOutpoint, this.paired_addresses);
await service.pairDevice(commitmentOutpoint, this.paired_addresses);
this.paired_addresses = [];
const newDevice = await service.dumpDevice();
await service.saveDevice(newDevice);

View File

@ -5,8 +5,9 @@ import { IProcess } from '~/models/process.model';
import { WebSocketClient } from '../websockets';
import QRCode from 'qrcode';
import { ApiReturn, Member } from '../../dist/pkg/sdk_client';
import Routing from './routing.service';
import { currentRoute, navigate } from '../router';
import ModalService from './modal.service';
import { navigate } from '../router';
import { copyToClipboard } from '../utils/sp-address.utils';
type ProcessesCache = {
[key: string]: any;
@ -25,6 +26,7 @@ export default class Services {
private notifications: INotification[] | null = null;
private subscriptions: { element: Element; event: string; eventHandler: string }[] = [];
private database: any;
private routingInstance!: ModalService;
// Private constructor to prevent direct instantiation from outside
private constructor() {}
@ -38,6 +40,7 @@ export default class Services {
Services.initializing = (async () => {
const instance = new Services();
await instance.init();
instance.routingInstance = await ModalService.getInstance()
return instance;
})();
}
@ -79,162 +82,13 @@ export default class Services {
}
const copyBtn = document.getElementById('copyBtn');
if (copyBtn) {
copyBtn.addEventListener('click', () => this.copyToClipboard(currentUrl + '?sp_address=' + text));
copyBtn.addEventListener('click', () => 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<string> => {
//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
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.");
}
if (address) {
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) {
okButton.style.display = 'none';
}
}
});
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();
@ -382,8 +236,7 @@ export default class Services {
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);
await this.routingInstance.openConfirmationModal(actual_proposal, processCommitment);
}
} catch (e) {
console.error(e);
@ -409,15 +262,18 @@ export default class Services {
}, 0);
}
async pairDevice(prd: any, outpointCommitment: string) {
async pairDevice(commitmentTx: string, spAddressList: string[]) {
await this.sdkClient.pair_device(commitmentTx, spAddressList);
}
async validatePairingDevice(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);
const proposal = this.sdkClient.get_update_proposals(outpointCommitment);
console.log('🚀 ~ Services ~ pairDevice ~ proposal:', proposal);
// const pairingTx = proposal.pairing_tx.replace(/^\"+|\"+$/g, '')
const parsedProposal = JSON.parse(proposal[0]);
@ -436,7 +292,7 @@ export default class Services {
let txid = '0'.repeat(64);
console.log('🚀 ~ Services ~ pairDevice ~ pairingTx:', pairingTx, `${txid}:4294967295`);
const pairing = await service.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress]);
const pairing = await this.sdkClient.pair_device(`${txid}:4294967295`, [senderAddress]);
const device = this.dumpDevice();
console.log('🚀 ~ Services ~ pairDevice ~ device:', device);
this.saveDevice(device);
@ -446,10 +302,10 @@ export default class Services {
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);
let tx = await this.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));
tx.ciphers_to_send.forEach((cipher: string) => this.websocketConnection?.sendMessage('Cipher', cipher));
}
navigate('process');
}
@ -505,12 +361,7 @@ export default class Services {
console.log('🚀 ~ Services ~ createFaucetMessage ~ message:', message);
return message;
}
addSubscription(element: Element, event: string, eventHandler: string): void {
this.subscriptions.push({ element, event, eventHandler });
element.addEventListener(event, (this as any)[eventHandler]);
}
async createNewDevice() {
let spAddress = '';
try {
@ -696,48 +547,6 @@ export default class Services {
}
}
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 = [];
}
public async setProcessesInSelectElement(processList: any[]) {
console.log('🚀 ~ Services ~ setProcessesInSelectElement ~ processList:', processList);
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');
}
getNotifications(): INotification[] {
return [
{
@ -763,28 +572,4 @@ export default class Services {
},
];
}
async setNotification(): Promise<void> {
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 = `
<div>${notif.title}</div>
<div>${notif.description}</div>
`;
// this.addSubscription(notifElement, 'click', 'goToProcessPage')
notificationBoard.appendChild(notifElement);
}
} else {
noNotifications.style.display = 'block';
}
}
}

View File

@ -0,0 +1,152 @@
import Services from "../services/service";
import { addSubscription } from "./subscription.utils";
//Copy Address
export async function 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
export function 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
export async function addressToEmoji(text: string): Promise<string> {
//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 = generateEmojiList();
const emojis = Array.from(bytes)
.map((byte) => emojiList[byte])
.join('');
return emojis;
};
//Get emojis from other device
async function 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 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
export async function displayEmojis(text: string) {
console.log('🚀 ~ Services ~ adressToEmoji');
try {
const container = document.getElementById('containerId');
const emojis = await addressToEmoji(text);
const emojiDisplay = container?.querySelector('.emoji-display');
if (emojiDisplay) {
emojiDisplay.textContent = emojis;
}
emojisPairingRequest();
initAddressInput();
} catch (err) {
console.error(err);
}
};
// Verify Other address
export function initAddressInput() {
const addressInput = document.getElementById('addressInput') as HTMLInputElement;
const emojiDisplay = document.getElementById('emoji-display-2');
const okButton = document.getElementById('okButton');
addSubscription(addressInput, '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.");
}
if (address) {
const emojis = await addressToEmoji(address);
if (emojiDisplay) {
emojiDisplay.innerHTML = emojis;
}
if (okButton) {
okButton.style.display = 'inline-block';
}
} else {
if (emojiDisplay) {
emojiDisplay.innerHTML = '';
}
if (okButton) {
okButton.style.display = 'none';
}
}
})
if (okButton) {
okButton.addEventListener('click', () => {
onOkButtonClick();
});
}
}
async function onOkButtonClick() {
const service = await Services.getInstance()
const addressInput = (document.getElementById('addressInput') as HTMLInputElement).value;
await service.sendPairingTx(addressInput);
}

View File

@ -0,0 +1,16 @@
let subscriptions: { element: Element | Document, event: any, eventHandler: EventListenerOrEventListenerObject }[] = [];
export function cleanSubscriptions(): void {
console.log("🚀 ~ cleanSubscriptions ~ sub:", subscriptions)
for (const sub of subscriptions) {
const el = sub.element;
const eventHandler = sub.eventHandler;
el.removeEventListener(sub.event, eventHandler);
}
subscriptions = [];
}
export function addSubscription(element: Element | Document, event: any, eventHandler: EventListenerOrEventListenerObject): void {
subscriptions.push({ element, event, eventHandler });
element.addEventListener(event, eventHandler);
}