ci: docker_tag=ext - Update ihm_client configuration and dependencies

This commit is contained in:
4NK CI Bot 2025-09-21 13:07:47 +00:00
parent ae58d95e39
commit 30a3960b2e
5 changed files with 1531 additions and 1531 deletions

View File

@ -1,50 +1,50 @@
import { interpolate } from '../../utils/html.utils';
import Services from '../../services/service';
import { Process } from '../../pkg/sdk_client.js';
import { getCorrectDOM } from '~/utils/document.utils';
let currentPageStyle: HTMLStyleElement | null = null;
export async function initProcessElement(id: string, zone: string) {
const processes = await getProcesses();
const container = getCorrectDOM('process-4nk-component');
// const currentProcess = processes.find((process) => process[0] === id)[1];
// const currentProcess = {title: 'Hello', html: '', css: ''};
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
// const wrapper = document.querySelector('.process-container');
// if (wrapper) {
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
// injectCss(currentProcess.css);
// }
}
async function loadPage(data?: any) {
const content = document.getElementById('containerId');
if (content && data) {
if (data) {
content.innerHTML = interpolate(content.innerHTML, data);
}
}
}
function injectCss(cssContent: string) {
removeCss(); // Ensure that the previous CSS is removed
currentPageStyle = document.createElement('style');
currentPageStyle.type = 'text/css';
currentPageStyle.appendChild(document.createTextNode(cssContent));
document.head.appendChild(currentPageStyle);
}
function removeCss() {
if (currentPageStyle) {
document.head.removeChild(currentPageStyle);
currentPageStyle = null;
}
}
async function getProcesses(): Promise<Record<string, Process>> {
const service = await Services.getInstance();
const processes = await service.getProcesses();
return processes;
}
import { interpolate } from '../../utils/html.utils';
import Services from '../../services/service';
import { Process } from '../../pkg/sdk_client.js';
import { getCorrectDOM } from '~/utils/document.utils';
let currentPageStyle: HTMLStyleElement | null = null;
export async function initProcessElement(id: string, zone: string) {
const processes = await getProcesses();
const container = getCorrectDOM('process-4nk-component');
// const currentProcess = processes.find((process) => process[0] === id)[1];
// const currentProcess = {title: 'Hello', html: '', css: ''};
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
// const wrapper = document.querySelector('.process-container');
// if (wrapper) {
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
// injectCss(currentProcess.css);
// }
}
async function loadPage(data?: any) {
const content = document.getElementById('containerId');
if (content && data) {
if (data) {
content.innerHTML = interpolate(content.innerHTML, data);
}
}
}
function injectCss(cssContent: string) {
removeCss(); // Ensure that the previous CSS is removed
currentPageStyle = document.createElement('style');
currentPageStyle.type = 'text/css';
currentPageStyle.appendChild(document.createTextNode(cssContent));
document.head.appendChild(currentPageStyle);
}
function removeCss() {
if (currentPageStyle) {
document.head.removeChild(currentPageStyle);
currentPageStyle = null;
}
}
async function getProcesses(): Promise<Record<string, Process>> {
const service = await Services.getInstance();
const processes = await service.getProcesses();
return processes;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,230 +1,230 @@
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.js';
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<ModalService> {
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 injectCreationModal(members: any[]) {
const container = document.querySelector('#containerId');
if (container) {
let html = await fetch('/src/components/modal/creation-modal.html').then((res) => res.text());
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
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);
}
}
// Device 1 wait Device 2
async injectWaitingModal() {
const container = document.querySelector('#containerId');
if (container) {
let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text());
container.innerHTML += html;
}
}
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<string, RoleDefinition>, 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;
if (members[0].sp_addresses.length === 1) {
await this.injectCreationModal(members);
this.modal = document.getElementById('creation-modal');
console.log("LENGTH:", members[0].sp_addresses.length);
} else {
await this.injectModal(members);
this.modal = document.getElementById('modal');
console.log("LENGTH:", members[0].sp_addresses.length);
}
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<boolean> {
// Create modal element
const modalElement = document.createElement('div');
modalElement.id = 'confirmation-modal';
modalElement.innerHTML = `
<div class="modal-overlay">
<div class="modal-content" ${fullscreen ? 'style="width: 100% !important; max-width: none !important; height: 100% !important; max-height: none !important; border-radius: 0 !important; margin: 0 !important;"' : ''}>
<h2>${options.title}</h2>
<div class="modal-body">
${options.content}
</div>
<div class="modal-footer">
<button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button>
<button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button>
</div>
</div>
</div>
`;
// 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';
}
}
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.js';
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<ModalService> {
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 injectCreationModal(members: any[]) {
const container = document.querySelector('#containerId');
if (container) {
let html = await fetch('/src/components/modal/creation-modal.html').then((res) => res.text());
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
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);
}
}
// Device 1 wait Device 2
async injectWaitingModal() {
const container = document.querySelector('#containerId');
if (container) {
let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text());
container.innerHTML += html;
}
}
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<string, RoleDefinition>, 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;
if (members[0].sp_addresses.length === 1) {
await this.injectCreationModal(members);
this.modal = document.getElementById('creation-modal');
console.log("LENGTH:", members[0].sp_addresses.length);
} else {
await this.injectModal(members);
this.modal = document.getElementById('modal');
console.log("LENGTH:", members[0].sp_addresses.length);
}
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<boolean> {
// Create modal element
const modalElement = document.createElement('div');
modalElement.id = 'confirmation-modal';
modalElement.innerHTML = `
<div class="modal-overlay">
<div class="modal-content" ${fullscreen ? 'style="width: 100% !important; max-width: none !important; height: 100% !important; max-height: none !important; border-radius: 0 !important; margin: 0 !important;"' : ''}>
<h2>${options.title}</h2>
<div class="modal-body">
${options.content}
</div>
<div class="modal-footer">
<button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button>
<button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button>
</div>
</div>
</div>
`;
// 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';
}
}

View File

@ -1,213 +1,213 @@
import Services from '../services/service';
import { getCorrectDOM } from './html.utils';
import { addSubscription } from './subscription.utils';
import QRCode from 'qrcode';
//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 = getCorrectDOM('login-4nk-component') as HTMLElement;
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 = getCorrectDOM('login-4nk-component') as HTMLElement;
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 container = getCorrectDOM('login-4nk-component') as HTMLElement
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
const emojiDisplay = container.querySelector('#emoji-display-2');
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
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 (createButton) {
addSubscription(createButton, 'click', () => {
onCreateButtonClick();
});
}
}
async function onCreateButtonClick() {
try {
await prepareAndSendPairingTx();
const service = await Services.getInstance();
await service.confirmPairing();
} catch (e) {
console.error(`onCreateButtonClick error: ${e}`);
}
}
export async function prepareAndSendPairingTx(): Promise<void> {
const service = await Services.getInstance();
// checkConnections requires a Process object, not an empty array
// This call has been removed as it was causing TypeScript errors
try {
const relayAddress = service.getAllRelays();
const createPairingProcessReturn = await service.createPairingProcess(
"",
[],
);
if (!createPairingProcessReturn.updated_process) {
throw new Error('createPairingProcess returned an empty new process');
}
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
await service.handleApiReturn(createPairingProcessReturn);
} catch (err) {
console.error(err);
}
}
export async function generateQRCode(spAddress: string) {
try {
const container = getCorrectDOM('login-4nk-component') as HTMLElement
const currentUrl = 'https://' + window.location.host;
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
const qrCode = container?.querySelector('.qr-code img');
qrCode?.setAttribute('src', url);
} catch (err) {
console.error(err);
}
}
export async function generateCreateBtn() {
try{
//Generate CreateBtn
const container = getCorrectDOM('login-4nk-component') as HTMLElement
const createBtn = container?.querySelector('.create-btn');
if (createBtn) {
createBtn.textContent = 'CREATE';
}
} catch (err) {
console.error(err);
}
import Services from '../services/service';
import { getCorrectDOM } from './html.utils';
import { addSubscription } from './subscription.utils';
import QRCode from 'qrcode';
//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 = getCorrectDOM('login-4nk-component') as HTMLElement;
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 = getCorrectDOM('login-4nk-component') as HTMLElement;
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 container = getCorrectDOM('login-4nk-component') as HTMLElement
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
const emojiDisplay = container.querySelector('#emoji-display-2');
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
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 (createButton) {
addSubscription(createButton, 'click', () => {
onCreateButtonClick();
});
}
}
async function onCreateButtonClick() {
try {
await prepareAndSendPairingTx();
const service = await Services.getInstance();
await service.confirmPairing();
} catch (e) {
console.error(`onCreateButtonClick error: ${e}`);
}
}
export async function prepareAndSendPairingTx(): Promise<void> {
const service = await Services.getInstance();
// checkConnections requires a Process object, not an empty array
// This call has been removed as it was causing TypeScript errors
try {
const relayAddress = service.getAllRelays();
const createPairingProcessReturn = await service.createPairingProcess(
"",
[],
);
if (!createPairingProcessReturn.updated_process) {
throw new Error('createPairingProcess returned an empty new process');
}
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
await service.handleApiReturn(createPairingProcessReturn);
} catch (err) {
console.error(err);
}
}
export async function generateQRCode(spAddress: string) {
try {
const container = getCorrectDOM('login-4nk-component') as HTMLElement
const currentUrl = 'https://' + window.location.host;
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
const qrCode = container?.querySelector('.qr-code img');
qrCode?.setAttribute('src', url);
} catch (err) {
console.error(err);
}
}
export async function generateCreateBtn() {
try{
//Generate CreateBtn
const container = getCorrectDOM('login-4nk-component') as HTMLElement
const createBtn = container?.querySelector('.create-btn');
if (createBtn) {
createBtn.textContent = 'CREATE';
}
} catch (err) {
console.error(err);
}
}

View File

@ -1,89 +1,89 @@
import { AnkFlag } from '../../pkg/sdk_client.js';
import Services from './services/service';
let ws: WebSocket;
let messageQueue: string[] = [];
export async function initWebsocket(url: string) {
ws = new WebSocket(url);
if (ws !== null) {
ws.onopen = async (event) => {
console.log('WebSocket connection established');
while (messageQueue.length > 0) {
const message = messageQueue.shift();
if (message) {
ws.send(message);
}
}
};
// Listen for messages
ws.onmessage = (event) => {
const msgData = event.data;
// console.log("Received text message: ", msgData);
(async () => {
if (typeof msgData === 'string') {
try {
const parsedMessage = JSON.parse(msgData);
const services = await Services.getInstance();
switch (parsedMessage.flag) {
case 'Handshake':
await services.handleHandshakeMsg(url, parsedMessage.content);
break;
case 'NewTx':
await services.parseNewTx(parsedMessage.content);
break;
case 'Cipher':
await services.parseCipher(parsedMessage.content);
break;
case 'Commit':
// Basically if we see this it means we have an error
await services.handleCommitError(parsedMessage.content);
break;
}
} catch (error) {
console.error('Received an invalid message:', error);
}
} else {
console.error('Received a non-string message');
}
})();
};
// Listen for possible errors
ws.onerror = (event) => {
console.error('WebSocket error:', event);
};
// Listen for when the connection is closed
ws.onclose = (event) => {
console.log('WebSocket is closed now.');
};
}
}
// Method to send messages
export function sendMessage(flag: AnkFlag, message: string): void {
if (ws.readyState === WebSocket.OPEN) {
const networkMessage = {
flag: flag,
content: message,
};
console.log('Sending message of type:', flag);
ws.send(JSON.stringify(networkMessage));
} else {
console.error('WebSocket is not open. ReadyState:', ws.readyState);
messageQueue.push(message);
}
}
export function getUrl(): string {
return ws.url;
}
// Method to close the WebSocket connection
export function close(): void {
ws.close();
}
import { AnkFlag } from '../../pkg/sdk_client.js';
import Services from './services/service';
let ws: WebSocket;
let messageQueue: string[] = [];
export async function initWebsocket(url: string) {
ws = new WebSocket(url);
if (ws !== null) {
ws.onopen = async (event) => {
console.log('WebSocket connection established');
while (messageQueue.length > 0) {
const message = messageQueue.shift();
if (message) {
ws.send(message);
}
}
};
// Listen for messages
ws.onmessage = (event) => {
const msgData = event.data;
// console.log("Received text message: ", msgData);
(async () => {
if (typeof msgData === 'string') {
try {
const parsedMessage = JSON.parse(msgData);
const services = await Services.getInstance();
switch (parsedMessage.flag) {
case 'Handshake':
await services.handleHandshakeMsg(url, parsedMessage.content);
break;
case 'NewTx':
await services.parseNewTx(parsedMessage.content);
break;
case 'Cipher':
await services.parseCipher(parsedMessage.content);
break;
case 'Commit':
// Basically if we see this it means we have an error
await services.handleCommitError(parsedMessage.content);
break;
}
} catch (error) {
console.error('Received an invalid message:', error);
}
} else {
console.error('Received a non-string message');
}
})();
};
// Listen for possible errors
ws.onerror = (event) => {
console.error('WebSocket error:', event);
};
// Listen for when the connection is closed
ws.onclose = (event) => {
console.log('WebSocket is closed now.');
};
}
}
// Method to send messages
export function sendMessage(flag: AnkFlag, message: string): void {
if (ws.readyState === WebSocket.OPEN) {
const networkMessage = {
flag: flag,
content: message,
};
console.log('Sending message of type:', flag);
ws.send(JSON.stringify(networkMessage));
} else {
console.error('WebSocket is not open. ReadyState:', ws.readyState);
messageQueue.push(message);
}
}
export function getUrl(): string {
return ws.url;
}
// Method to close the WebSocket connection
export function close(): void {
ws.close();
}