ci: docker_tag=ext - Update ihm_client configuration and dependencies
This commit is contained in:
parent
ae58d95e39
commit
30a3960b2e
@ -1,50 +1,50 @@
|
|||||||
import { interpolate } from '../../utils/html.utils';
|
import { interpolate } from '../../utils/html.utils';
|
||||||
import Services from '../../services/service';
|
import Services from '../../services/service';
|
||||||
import { Process } from '../../pkg/sdk_client.js';
|
import { Process } from '../../pkg/sdk_client.js';
|
||||||
import { getCorrectDOM } from '~/utils/document.utils';
|
import { getCorrectDOM } from '~/utils/document.utils';
|
||||||
|
|
||||||
let currentPageStyle: HTMLStyleElement | null = null;
|
let currentPageStyle: HTMLStyleElement | null = null;
|
||||||
|
|
||||||
export async function initProcessElement(id: string, zone: string) {
|
export async function initProcessElement(id: string, zone: string) {
|
||||||
const processes = await getProcesses();
|
const processes = await getProcesses();
|
||||||
const container = getCorrectDOM('process-4nk-component');
|
const container = getCorrectDOM('process-4nk-component');
|
||||||
// const currentProcess = processes.find((process) => process[0] === id)[1];
|
// const currentProcess = processes.find((process) => process[0] === id)[1];
|
||||||
// const currentProcess = {title: 'Hello', html: '', css: ''};
|
// const currentProcess = {title: 'Hello', html: '', css: ''};
|
||||||
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
|
// await loadPage({ processTitle: currentProcess.title, inputValue: 'Hello World !' });
|
||||||
// const wrapper = document.querySelector('.process-container');
|
// const wrapper = document.querySelector('.process-container');
|
||||||
// if (wrapper) {
|
// if (wrapper) {
|
||||||
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
|
// wrapper.innerHTML = interpolate(currentProcess.html, { processTitle: currentProcess.title, inputValue: 'Hello World !' });
|
||||||
// injectCss(currentProcess.css);
|
// injectCss(currentProcess.css);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadPage(data?: any) {
|
async function loadPage(data?: any) {
|
||||||
const content = document.getElementById('containerId');
|
const content = document.getElementById('containerId');
|
||||||
if (content && data) {
|
if (content && data) {
|
||||||
if (data) {
|
if (data) {
|
||||||
content.innerHTML = interpolate(content.innerHTML, data);
|
content.innerHTML = interpolate(content.innerHTML, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function injectCss(cssContent: string) {
|
function injectCss(cssContent: string) {
|
||||||
removeCss(); // Ensure that the previous CSS is removed
|
removeCss(); // Ensure that the previous CSS is removed
|
||||||
|
|
||||||
currentPageStyle = document.createElement('style');
|
currentPageStyle = document.createElement('style');
|
||||||
currentPageStyle.type = 'text/css';
|
currentPageStyle.type = 'text/css';
|
||||||
currentPageStyle.appendChild(document.createTextNode(cssContent));
|
currentPageStyle.appendChild(document.createTextNode(cssContent));
|
||||||
document.head.appendChild(currentPageStyle);
|
document.head.appendChild(currentPageStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeCss() {
|
function removeCss() {
|
||||||
if (currentPageStyle) {
|
if (currentPageStyle) {
|
||||||
document.head.removeChild(currentPageStyle);
|
document.head.removeChild(currentPageStyle);
|
||||||
currentPageStyle = null;
|
currentPageStyle = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getProcesses(): Promise<Record<string, Process>> {
|
async function getProcesses(): Promise<Record<string, Process>> {
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
const processes = await service.getProcesses();
|
const processes = await service.getProcesses();
|
||||||
return processes;
|
return processes;
|
||||||
}
|
}
|
||||||
|
1900
src/router.ts
1900
src/router.ts
File diff suppressed because it is too large
Load Diff
@ -1,230 +1,230 @@
|
|||||||
import modalHtml from '../components/login-modal/login-modal.html?raw';
|
import modalHtml from '../components/login-modal/login-modal.html?raw';
|
||||||
import modalScript from '../components/login-modal/login-modal.js?raw';
|
import modalScript from '../components/login-modal/login-modal.js?raw';
|
||||||
import validationModalStyle from '../components/validation-modal/validation-modal.css?raw';
|
import validationModalStyle from '../components/validation-modal/validation-modal.css?raw';
|
||||||
import Services from './service';
|
import Services from './service';
|
||||||
import { init, navigate } from '../router';
|
import { init, navigate } from '../router';
|
||||||
import { addressToEmoji } from '../utils/sp-address.utils';
|
import { addressToEmoji } from '../utils/sp-address.utils';
|
||||||
import { RoleDefinition } from '../../pkg/sdk_client.js';
|
import { RoleDefinition } from '../../pkg/sdk_client.js';
|
||||||
import { initValidationModal } from '~/components/validation-modal/validation-modal';
|
import { initValidationModal } from '~/components/validation-modal/validation-modal';
|
||||||
import { interpolate } from '~/utils/html.utils';
|
import { interpolate } from '~/utils/html.utils';
|
||||||
|
|
||||||
interface ConfirmationModalOptions {
|
interface ConfirmationModalOptions {
|
||||||
title: string;
|
title: string;
|
||||||
content: string;
|
content: string;
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ModalService {
|
export default class ModalService {
|
||||||
private static instance: ModalService;
|
private static instance: ModalService;
|
||||||
private stateId: string | null = null;
|
private stateId: string | null = null;
|
||||||
private processId: string | null = null;
|
private processId: string | null = null;
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
private paired_addresses: string[] = [];
|
private paired_addresses: string[] = [];
|
||||||
private modal: HTMLElement | null = null;
|
private modal: HTMLElement | null = null;
|
||||||
|
|
||||||
// Method to access the singleton instance of Services
|
// Method to access the singleton instance of Services
|
||||||
public static async getInstance(): Promise<ModalService> {
|
public static async getInstance(): Promise<ModalService> {
|
||||||
if (!ModalService.instance) {
|
if (!ModalService.instance) {
|
||||||
ModalService.instance = new ModalService();
|
ModalService.instance = new ModalService();
|
||||||
}
|
}
|
||||||
return ModalService.instance;
|
return ModalService.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public openLoginModal(myAddress: string, receiverAddress: string) {
|
public openLoginModal(myAddress: string, receiverAddress: string) {
|
||||||
const container = document.querySelector('.page-container');
|
const container = document.querySelector('.page-container');
|
||||||
let html = modalHtml;
|
let html = modalHtml;
|
||||||
html = html.replace('{{device1}}', myAddress);
|
html = html.replace('{{device1}}', myAddress);
|
||||||
html = html.replace('{{device2}}', receiverAddress);
|
html = html.replace('{{device2}}', receiverAddress);
|
||||||
if (container) container.innerHTML += html;
|
if (container) container.innerHTML += html;
|
||||||
const modal = document.getElementById('login-modal');
|
const modal = document.getElementById('login-modal');
|
||||||
if (modal) modal.style.display = 'flex';
|
if (modal) modal.style.display = 'flex';
|
||||||
const newScript = document.createElement('script');
|
const newScript = document.createElement('script');
|
||||||
|
|
||||||
newScript.setAttribute('type', 'module');
|
newScript.setAttribute('type', 'module');
|
||||||
newScript.textContent = modalScript;
|
newScript.textContent = modalScript;
|
||||||
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
document.head.appendChild(newScript).parentNode?.removeChild(newScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
async injectModal(members: any[]) {
|
async injectModal(members: any[]) {
|
||||||
const container = document.querySelector('#containerId');
|
const container = document.querySelector('#containerId');
|
||||||
if (container) {
|
if (container) {
|
||||||
let html = await fetch('/src/components/modal/confirmation-modal.html').then((res) => res.text());
|
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('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
|
||||||
html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1]));
|
html = html.replace('{{device2}}', await addressToEmoji(members[0]['sp_addresses'][1]));
|
||||||
container.innerHTML += html;
|
container.innerHTML += html;
|
||||||
|
|
||||||
// Dynamically load the header JS
|
// Dynamically load the header JS
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = '/src/components/modal/confirmation-modal.ts';
|
script.src = '/src/components/modal/confirmation-modal.ts';
|
||||||
script.type = 'module';
|
script.type = 'module';
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async injectCreationModal(members: any[]) {
|
async injectCreationModal(members: any[]) {
|
||||||
const container = document.querySelector('#containerId');
|
const container = document.querySelector('#containerId');
|
||||||
if (container) {
|
if (container) {
|
||||||
let html = await fetch('/src/components/modal/creation-modal.html').then((res) => res.text());
|
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]));
|
html = html.replace('{{device1}}', await addressToEmoji(members[0]['sp_addresses'][0]));
|
||||||
container.innerHTML += html;
|
container.innerHTML += html;
|
||||||
|
|
||||||
// Dynamically load the header JS
|
// Dynamically load the header JS
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.src = '/src/components/modal/confirmation-modal.ts';
|
script.src = '/src/components/modal/confirmation-modal.ts';
|
||||||
script.type = 'module';
|
script.type = 'module';
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Device 1 wait Device 2
|
// Device 1 wait Device 2
|
||||||
async injectWaitingModal() {
|
async injectWaitingModal() {
|
||||||
const container = document.querySelector('#containerId');
|
const container = document.querySelector('#containerId');
|
||||||
if (container) {
|
if (container) {
|
||||||
let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text());
|
let html = await fetch('/src/components/modal/waiting-modal.html').then((res) => res.text());
|
||||||
container.innerHTML += html;
|
container.innerHTML += html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async injectValidationModal(processDiff: any) {
|
async injectValidationModal(processDiff: any) {
|
||||||
const container = document.querySelector('#containerId');
|
const container = document.querySelector('#containerId');
|
||||||
if (container) {
|
if (container) {
|
||||||
let html = await fetch('/src/components/validation-modal/validation-modal.html').then((res) => res.text());
|
let html = await fetch('/src/components/validation-modal/validation-modal.html').then((res) => res.text());
|
||||||
html = interpolate(html, {processId: processDiff.processId})
|
html = interpolate(html, {processId: processDiff.processId})
|
||||||
container.innerHTML += html;
|
container.innerHTML += html;
|
||||||
|
|
||||||
// Dynamically load the header JS
|
// Dynamically load the header JS
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.id = 'validation-modal-script';
|
script.id = 'validation-modal-script';
|
||||||
script.src = '/src/components/validation-modal/validation-modal.ts';
|
script.src = '/src/components/validation-modal/validation-modal.ts';
|
||||||
script.type = 'module';
|
script.type = 'module';
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
const css = document.createElement('style');
|
const css = document.createElement('style');
|
||||||
css.id = 'validation-modal-css';
|
css.id = 'validation-modal-css';
|
||||||
css.innerText = validationModalStyle;
|
css.innerText = validationModalStyle;
|
||||||
document.head.appendChild(css);
|
document.head.appendChild(css);
|
||||||
initValidationModal(processDiff)
|
initValidationModal(processDiff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeValidationModal() {
|
async closeValidationModal() {
|
||||||
const script = document.querySelector('#validation-modal-script');
|
const script = document.querySelector('#validation-modal-script');
|
||||||
const css = document.querySelector('#validation-modal-css');
|
const css = document.querySelector('#validation-modal-css');
|
||||||
const component = document.querySelector('#validation-modal');
|
const component = document.querySelector('#validation-modal');
|
||||||
script?.remove();
|
script?.remove();
|
||||||
css?.remove();
|
css?.remove();
|
||||||
component?.remove();
|
component?.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openPairingConfirmationModal(roleDefinition: Record<string, RoleDefinition>, processId: string, stateId: string) {
|
public async openPairingConfirmationModal(roleDefinition: Record<string, RoleDefinition>, processId: string, stateId: string) {
|
||||||
let members;
|
let members;
|
||||||
if (roleDefinition['pairing']) {
|
if (roleDefinition['pairing']) {
|
||||||
const owner = roleDefinition['pairing'];
|
const owner = roleDefinition['pairing'];
|
||||||
members = owner.members;
|
members = owner.members;
|
||||||
} else {
|
} else {
|
||||||
throw new Error('No "pairing" role');
|
throw new Error('No "pairing" role');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (members.length != 1) {
|
if (members.length != 1) {
|
||||||
throw new Error('Must have exactly 1 member');
|
throw new Error('Must have exactly 1 member');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("MEMBERS:", members);
|
console.log("MEMBERS:", members);
|
||||||
// We take all the addresses except our own
|
// We take all the addresses except our own
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
const localAddress = service.getDeviceAddress();
|
const localAddress = service.getDeviceAddress();
|
||||||
for (const member of members) {
|
for (const member of members) {
|
||||||
if (member.sp_addresses) {
|
if (member.sp_addresses) {
|
||||||
for (const address of member.sp_addresses) {
|
for (const address of member.sp_addresses) {
|
||||||
if (address !== localAddress) {
|
if (address !== localAddress) {
|
||||||
this.paired_addresses.push(address);
|
this.paired_addresses.push(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.processId = processId;
|
this.processId = processId;
|
||||||
this.stateId = stateId;
|
this.stateId = stateId;
|
||||||
|
|
||||||
if (members[0].sp_addresses.length === 1) {
|
if (members[0].sp_addresses.length === 1) {
|
||||||
await this.injectCreationModal(members);
|
await this.injectCreationModal(members);
|
||||||
this.modal = document.getElementById('creation-modal');
|
this.modal = document.getElementById('creation-modal');
|
||||||
console.log("LENGTH:", members[0].sp_addresses.length);
|
console.log("LENGTH:", members[0].sp_addresses.length);
|
||||||
} else {
|
} else {
|
||||||
await this.injectModal(members);
|
await this.injectModal(members);
|
||||||
this.modal = document.getElementById('modal');
|
this.modal = document.getElementById('modal');
|
||||||
console.log("LENGTH:", members[0].sp_addresses.length);
|
console.log("LENGTH:", members[0].sp_addresses.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.modal) this.modal.style.display = 'flex';
|
if (this.modal) this.modal.style.display = 'flex';
|
||||||
|
|
||||||
// Close modal when clicking outside of it
|
// Close modal when clicking outside of it
|
||||||
window.onclick = (event) => {
|
window.onclick = (event) => {
|
||||||
if (event.target === this.modal) {
|
if (event.target === this.modal) {
|
||||||
this.closeConfirmationModal();
|
this.closeConfirmationModal();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
confirmLogin() {
|
confirmLogin() {
|
||||||
console.log('=============> Confirm Login');
|
console.log('=============> Confirm Login');
|
||||||
}
|
}
|
||||||
async closeLoginModal() {
|
async closeLoginModal() {
|
||||||
if (this.modal) this.modal.style.display = 'none';
|
if (this.modal) this.modal.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
async showConfirmationModal(options: ConfirmationModalOptions, fullscreen: boolean = false): Promise<boolean> {
|
async showConfirmationModal(options: ConfirmationModalOptions, fullscreen: boolean = false): Promise<boolean> {
|
||||||
// Create modal element
|
// Create modal element
|
||||||
const modalElement = document.createElement('div');
|
const modalElement = document.createElement('div');
|
||||||
modalElement.id = 'confirmation-modal';
|
modalElement.id = 'confirmation-modal';
|
||||||
modalElement.innerHTML = `
|
modalElement.innerHTML = `
|
||||||
<div class="modal-overlay">
|
<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;"' : ''}>
|
<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>
|
<h2>${options.title}</h2>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
${options.content}
|
${options.content}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button>
|
<button id="cancel-button" class="btn btn-secondary">${options.cancelText || 'Annuler'}</button>
|
||||||
<button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button>
|
<button id="confirm-button" class="btn btn-primary">${options.confirmText || 'Confirmer'}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Add modal to document
|
// Add modal to document
|
||||||
document.body.appendChild(modalElement);
|
document.body.appendChild(modalElement);
|
||||||
|
|
||||||
// Return promise that resolves with user choice
|
// Return promise that resolves with user choice
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const confirmButton = modalElement.querySelector('#confirm-button');
|
const confirmButton = modalElement.querySelector('#confirm-button');
|
||||||
const cancelButton = modalElement.querySelector('#cancel-button');
|
const cancelButton = modalElement.querySelector('#cancel-button');
|
||||||
const modalOverlay = modalElement.querySelector('.modal-overlay');
|
const modalOverlay = modalElement.querySelector('.modal-overlay');
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
modalElement.remove();
|
modalElement.remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
confirmButton?.addEventListener('click', () => {
|
confirmButton?.addEventListener('click', () => {
|
||||||
cleanup();
|
cleanup();
|
||||||
resolve(true);
|
resolve(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
cancelButton?.addEventListener('click', () => {
|
cancelButton?.addEventListener('click', () => {
|
||||||
cleanup();
|
cleanup();
|
||||||
resolve(false);
|
resolve(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
modalOverlay?.addEventListener('click', (e) => {
|
modalOverlay?.addEventListener('click', (e) => {
|
||||||
if (e.target === modalOverlay) {
|
if (e.target === modalOverlay) {
|
||||||
cleanup();
|
cleanup();
|
||||||
resolve(false);
|
resolve(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeConfirmationModal() {
|
async closeConfirmationModal() {
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
await service.unpairDevice();
|
await service.unpairDevice();
|
||||||
if (this.modal) this.modal.style.display = 'none';
|
if (this.modal) this.modal.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,213 +1,213 @@
|
|||||||
import Services from '../services/service';
|
import Services from '../services/service';
|
||||||
import { getCorrectDOM } from './html.utils';
|
import { getCorrectDOM } from './html.utils';
|
||||||
import { addSubscription } from './subscription.utils';
|
import { addSubscription } from './subscription.utils';
|
||||||
import QRCode from 'qrcode';
|
import QRCode from 'qrcode';
|
||||||
|
|
||||||
//Copy Address
|
//Copy Address
|
||||||
export async function copyToClipboard(fullAddress: string) {
|
export async function copyToClipboard(fullAddress: string) {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(fullAddress);
|
await navigator.clipboard.writeText(fullAddress);
|
||||||
alert('Adresse copiée dans le presse-papiers !');
|
alert('Adresse copiée dans le presse-papiers !');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to copy the address: ', err);
|
console.error('Failed to copy the address: ', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generate emojis list
|
//Generate emojis list
|
||||||
export function generateEmojiList(): string[] {
|
export function generateEmojiList(): string[] {
|
||||||
const emojiRanges = [
|
const emojiRanges = [
|
||||||
[0x1f600, 0x1f64f],
|
[0x1f600, 0x1f64f],
|
||||||
[0x1f300, 0x1f5ff],
|
[0x1f300, 0x1f5ff],
|
||||||
[0x1f680, 0x1f6ff],
|
[0x1f680, 0x1f6ff],
|
||||||
[0x1f700, 0x1f77f],
|
[0x1f700, 0x1f77f],
|
||||||
];
|
];
|
||||||
|
|
||||||
const emojiList: string[] = [];
|
const emojiList: string[] = [];
|
||||||
for (const range of emojiRanges) {
|
for (const range of emojiRanges) {
|
||||||
const [start, end] = range;
|
const [start, end] = range;
|
||||||
for (let i = start; i <= end && emojiList.length < 256; i++) {
|
for (let i = start; i <= end && emojiList.length < 256; i++) {
|
||||||
emojiList.push(String.fromCodePoint(i));
|
emojiList.push(String.fromCodePoint(i));
|
||||||
}
|
}
|
||||||
if (emojiList.length >= 256) {
|
if (emojiList.length >= 256) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return emojiList.slice(0, 256);
|
return emojiList.slice(0, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Adress to emojis
|
//Adress to emojis
|
||||||
export async function addressToEmoji(text: string): Promise<string> {
|
export async function addressToEmoji(text: string): Promise<string> {
|
||||||
//Adress to Hash
|
//Adress to Hash
|
||||||
const encoder = new TextEncoder();
|
const encoder = new TextEncoder();
|
||||||
const data = encoder.encode(text);
|
const data = encoder.encode(text);
|
||||||
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
||||||
|
|
||||||
const hash = new Uint8Array(hashBuffer);
|
const hash = new Uint8Array(hashBuffer);
|
||||||
const bytes = hash.slice(-4);
|
const bytes = hash.slice(-4);
|
||||||
|
|
||||||
//Hash slice to emojis
|
//Hash slice to emojis
|
||||||
const emojiList = generateEmojiList();
|
const emojiList = generateEmojiList();
|
||||||
const emojis = Array.from(bytes)
|
const emojis = Array.from(bytes)
|
||||||
.map((byte) => emojiList[byte])
|
.map((byte) => emojiList[byte])
|
||||||
.join('');
|
.join('');
|
||||||
return emojis;
|
return emojis;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get emojis from other device
|
//Get emojis from other device
|
||||||
async function emojisPairingRequest() {
|
async function emojisPairingRequest() {
|
||||||
try {
|
try {
|
||||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||||
|
|
||||||
const urlParams: URLSearchParams = new URLSearchParams(window.location.search);
|
const urlParams: URLSearchParams = new URLSearchParams(window.location.search);
|
||||||
const sp_adress: string | null = urlParams.get('sp_address');
|
const sp_adress: string | null = urlParams.get('sp_address');
|
||||||
|
|
||||||
if (!sp_adress) {
|
if (!sp_adress) {
|
||||||
// console.error("No 'sp_adress' parameter found in the URL.");
|
// console.error("No 'sp_adress' parameter found in the URL.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emojis = await addressToEmoji(sp_adress);
|
const emojis = await addressToEmoji(sp_adress);
|
||||||
const emojiDisplay = container?.querySelector('.pairing-request');
|
const emojiDisplay = container?.querySelector('.pairing-request');
|
||||||
|
|
||||||
if (emojiDisplay) {
|
if (emojiDisplay) {
|
||||||
emojiDisplay.textContent = '(Request from: ' + emojis + ')';
|
emojiDisplay.textContent = '(Request from: ' + emojis + ')';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display address emojis and other device emojis
|
// Display address emojis and other device emojis
|
||||||
export async function displayEmojis(text: string) {
|
export async function displayEmojis(text: string) {
|
||||||
console.log('🚀 ~ Services ~ adressToEmoji');
|
console.log('🚀 ~ Services ~ adressToEmoji');
|
||||||
try {
|
try {
|
||||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
|
||||||
const emojis = await addressToEmoji(text);
|
const emojis = await addressToEmoji(text);
|
||||||
const emojiDisplay = container?.querySelector('.emoji-display');
|
const emojiDisplay = container?.querySelector('.emoji-display');
|
||||||
|
|
||||||
if (emojiDisplay) {
|
if (emojiDisplay) {
|
||||||
emojiDisplay.textContent = emojis;
|
emojiDisplay.textContent = emojis;
|
||||||
}
|
}
|
||||||
|
|
||||||
emojisPairingRequest();
|
emojisPairingRequest();
|
||||||
|
|
||||||
initAddressInput();
|
initAddressInput();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify Other address
|
// Verify Other address
|
||||||
export function initAddressInput() {
|
export function initAddressInput() {
|
||||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||||
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
|
const addressInput = container.querySelector('#addressInput') as HTMLInputElement;
|
||||||
const emojiDisplay = container.querySelector('#emoji-display-2');
|
const emojiDisplay = container.querySelector('#emoji-display-2');
|
||||||
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
|
const okButton = container.querySelector('#okButton') as HTMLButtonElement;
|
||||||
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
|
const createButton = container.querySelector('#createButton') as HTMLButtonElement;
|
||||||
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
|
const actionButton = container.querySelector('#actionButton') as HTMLButtonElement;
|
||||||
addSubscription(addressInput, 'input', async () => {
|
addSubscription(addressInput, 'input', async () => {
|
||||||
let address = addressInput.value;
|
let address = addressInput.value;
|
||||||
|
|
||||||
// Vérifie si l'adresse est une URL
|
// Vérifie si l'adresse est une URL
|
||||||
try {
|
try {
|
||||||
const url = new URL(address);
|
const url = new URL(address);
|
||||||
// Si c'est une URL valide, extraire le paramètre sp_address
|
// Si c'est une URL valide, extraire le paramètre sp_address
|
||||||
const urlParams = new URLSearchParams(url.search);
|
const urlParams = new URLSearchParams(url.search);
|
||||||
const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide
|
const extractedAddress = urlParams.get('sp_address') || ''; // Prend sp_address ou une chaîne vide
|
||||||
|
|
||||||
if (extractedAddress) {
|
if (extractedAddress) {
|
||||||
address = extractedAddress;
|
address = extractedAddress;
|
||||||
addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite
|
addressInput.value = address; // Met à jour l'input pour afficher uniquement l'adresse extraite
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Si ce n'est pas une URL valide, on garde l'adresse originale
|
// 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.");
|
console.log("Ce n'est pas une URL valide, on garde l'adresse originale.");
|
||||||
}
|
}
|
||||||
if (address) {
|
if (address) {
|
||||||
const emojis = await addressToEmoji(address);
|
const emojis = await addressToEmoji(address);
|
||||||
if (emojiDisplay) {
|
if (emojiDisplay) {
|
||||||
emojiDisplay.innerHTML = emojis;
|
emojiDisplay.innerHTML = emojis;
|
||||||
}
|
}
|
||||||
if (okButton) {
|
if (okButton) {
|
||||||
okButton.style.display = 'inline-block';
|
okButton.style.display = 'inline-block';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (emojiDisplay) {
|
if (emojiDisplay) {
|
||||||
emojiDisplay.innerHTML = '';
|
emojiDisplay.innerHTML = '';
|
||||||
}
|
}
|
||||||
if (okButton) {
|
if (okButton) {
|
||||||
okButton.style.display = 'none';
|
okButton.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (createButton) {
|
if (createButton) {
|
||||||
addSubscription(createButton, 'click', () => {
|
addSubscription(createButton, 'click', () => {
|
||||||
onCreateButtonClick();
|
onCreateButtonClick();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onCreateButtonClick() {
|
async function onCreateButtonClick() {
|
||||||
try {
|
try {
|
||||||
await prepareAndSendPairingTx();
|
await prepareAndSendPairingTx();
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
await service.confirmPairing();
|
await service.confirmPairing();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`onCreateButtonClick error: ${e}`);
|
console.error(`onCreateButtonClick error: ${e}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prepareAndSendPairingTx(): Promise<void> {
|
export async function prepareAndSendPairingTx(): Promise<void> {
|
||||||
const service = await Services.getInstance();
|
const service = await Services.getInstance();
|
||||||
|
|
||||||
// checkConnections requires a Process object, not an empty array
|
// checkConnections requires a Process object, not an empty array
|
||||||
// This call has been removed as it was causing TypeScript errors
|
// This call has been removed as it was causing TypeScript errors
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const relayAddress = service.getAllRelays();
|
const relayAddress = service.getAllRelays();
|
||||||
const createPairingProcessReturn = await service.createPairingProcess(
|
const createPairingProcessReturn = await service.createPairingProcess(
|
||||||
"",
|
"",
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!createPairingProcessReturn.updated_process) {
|
if (!createPairingProcessReturn.updated_process) {
|
||||||
throw new Error('createPairingProcess returned an empty new process');
|
throw new Error('createPairingProcess returned an empty new process');
|
||||||
}
|
}
|
||||||
|
|
||||||
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
service.setProcessId(createPairingProcessReturn.updated_process.process_id);
|
||||||
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
service.setStateId(createPairingProcessReturn.updated_process.current_process.states[0].state_id);
|
||||||
|
|
||||||
await service.handleApiReturn(createPairingProcessReturn);
|
await service.handleApiReturn(createPairingProcessReturn);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateQRCode(spAddress: string) {
|
export async function generateQRCode(spAddress: string) {
|
||||||
try {
|
try {
|
||||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||||
const currentUrl = 'https://' + window.location.host;
|
const currentUrl = 'https://' + window.location.host;
|
||||||
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
|
const url = await QRCode.toDataURL(currentUrl + '?sp_address=' + spAddress);
|
||||||
const qrCode = container?.querySelector('.qr-code img');
|
const qrCode = container?.querySelector('.qr-code img');
|
||||||
qrCode?.setAttribute('src', url);
|
qrCode?.setAttribute('src', url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateCreateBtn() {
|
export async function generateCreateBtn() {
|
||||||
try{
|
try{
|
||||||
//Generate CreateBtn
|
//Generate CreateBtn
|
||||||
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
const container = getCorrectDOM('login-4nk-component') as HTMLElement
|
||||||
const createBtn = container?.querySelector('.create-btn');
|
const createBtn = container?.querySelector('.create-btn');
|
||||||
if (createBtn) {
|
if (createBtn) {
|
||||||
createBtn.textContent = 'CREATE';
|
createBtn.textContent = 'CREATE';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,89 +1,89 @@
|
|||||||
import { AnkFlag } from '../../pkg/sdk_client.js';
|
import { AnkFlag } from '../../pkg/sdk_client.js';
|
||||||
import Services from './services/service';
|
import Services from './services/service';
|
||||||
|
|
||||||
let ws: WebSocket;
|
let ws: WebSocket;
|
||||||
let messageQueue: string[] = [];
|
let messageQueue: string[] = [];
|
||||||
export async function initWebsocket(url: string) {
|
export async function initWebsocket(url: string) {
|
||||||
ws = new WebSocket(url);
|
ws = new WebSocket(url);
|
||||||
|
|
||||||
if (ws !== null) {
|
if (ws !== null) {
|
||||||
ws.onopen = async (event) => {
|
ws.onopen = async (event) => {
|
||||||
console.log('WebSocket connection established');
|
console.log('WebSocket connection established');
|
||||||
|
|
||||||
while (messageQueue.length > 0) {
|
while (messageQueue.length > 0) {
|
||||||
const message = messageQueue.shift();
|
const message = messageQueue.shift();
|
||||||
if (message) {
|
if (message) {
|
||||||
ws.send(message);
|
ws.send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for messages
|
// Listen for messages
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
const msgData = event.data;
|
const msgData = event.data;
|
||||||
|
|
||||||
// console.log("Received text message: ", msgData);
|
// console.log("Received text message: ", msgData);
|
||||||
(async () => {
|
(async () => {
|
||||||
if (typeof msgData === 'string') {
|
if (typeof msgData === 'string') {
|
||||||
try {
|
try {
|
||||||
const parsedMessage = JSON.parse(msgData);
|
const parsedMessage = JSON.parse(msgData);
|
||||||
const services = await Services.getInstance();
|
const services = await Services.getInstance();
|
||||||
switch (parsedMessage.flag) {
|
switch (parsedMessage.flag) {
|
||||||
case 'Handshake':
|
case 'Handshake':
|
||||||
await services.handleHandshakeMsg(url, parsedMessage.content);
|
await services.handleHandshakeMsg(url, parsedMessage.content);
|
||||||
break;
|
break;
|
||||||
case 'NewTx':
|
case 'NewTx':
|
||||||
await services.parseNewTx(parsedMessage.content);
|
await services.parseNewTx(parsedMessage.content);
|
||||||
break;
|
break;
|
||||||
case 'Cipher':
|
case 'Cipher':
|
||||||
await services.parseCipher(parsedMessage.content);
|
await services.parseCipher(parsedMessage.content);
|
||||||
break;
|
break;
|
||||||
case 'Commit':
|
case 'Commit':
|
||||||
// Basically if we see this it means we have an error
|
// Basically if we see this it means we have an error
|
||||||
await services.handleCommitError(parsedMessage.content);
|
await services.handleCommitError(parsedMessage.content);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Received an invalid message:', error);
|
console.error('Received an invalid message:', error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Received a non-string message');
|
console.error('Received a non-string message');
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for possible errors
|
// Listen for possible errors
|
||||||
ws.onerror = (event) => {
|
ws.onerror = (event) => {
|
||||||
console.error('WebSocket error:', event);
|
console.error('WebSocket error:', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for when the connection is closed
|
// Listen for when the connection is closed
|
||||||
ws.onclose = (event) => {
|
ws.onclose = (event) => {
|
||||||
console.log('WebSocket is closed now.');
|
console.log('WebSocket is closed now.');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to send messages
|
// Method to send messages
|
||||||
export function sendMessage(flag: AnkFlag, message: string): void {
|
export function sendMessage(flag: AnkFlag, message: string): void {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
const networkMessage = {
|
const networkMessage = {
|
||||||
flag: flag,
|
flag: flag,
|
||||||
content: message,
|
content: message,
|
||||||
};
|
};
|
||||||
console.log('Sending message of type:', flag);
|
console.log('Sending message of type:', flag);
|
||||||
ws.send(JSON.stringify(networkMessage));
|
ws.send(JSON.stringify(networkMessage));
|
||||||
} else {
|
} else {
|
||||||
console.error('WebSocket is not open. ReadyState:', ws.readyState);
|
console.error('WebSocket is not open. ReadyState:', ws.readyState);
|
||||||
messageQueue.push(message);
|
messageQueue.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUrl(): string {
|
export function getUrl(): string {
|
||||||
return ws.url;
|
return ws.url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to close the WebSocket connection
|
// Method to close the WebSocket connection
|
||||||
export function close(): void {
|
export function close(): void {
|
||||||
ws.close();
|
ws.close();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user