From 7a05de3d36f40a984e19bc35fd957a3e44f5b9e0 Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Tue, 7 Jan 2025 17:04:58 +0100 Subject: [PATCH 01/18] [bug] Fix diffs handling --- src/services/service.ts | 76 +++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/src/services/service.ts b/src/services/service.ts index 73cab33..a2203e4 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -433,6 +433,37 @@ export default class Services { } } + public async tryFetchDiffValue(diffs: UserDiff[]): Promise<[UserDiff[], Record]>{ + if (diffs.length === 0) { + return [[], {}]; + } + + // We check if we have the value in diffs + let retrievedValues: Record = {}; + for (const diff of diffs) { + // Check if `new_value` is missing + if (diff.new_value === null) { + const hash = diff.value_commitment; + if (!hash) { + console.error('No commitment for diff'); + } + try { + const res = await this.fetchValueFromStorage(hash); + if (!res) { + console.error('Failed to fetch value for hash', hash); + } else { + diff.new_value = res['value']; + retrievedValues[hash] = res['value']; + } + } catch (error) { + console.error(`Failed to fetch new_value for diff: ${JSON.stringify(diff)}`, error); + } + } + } + + return [diffs, retrievedValues]; + } + public async handleApiReturn(apiReturn: ApiReturn) { if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) { await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send)); @@ -481,48 +512,25 @@ export default class Services { } const isPaired = this.isPaired(); - + if (updatedProcess.new_diffs.length != 0) { - // We check if we have the value in diffs - const diffs = updatedProcess.new_diffs; - const stateId = diffs[0].new_state_merkle_root; - let retrievedValues: Record = {}; - for (const diff of diffs) { - // Check if `new_value` is missing - if (diff.new_value === null) { - const hash = diff.value_commitment; - if (!hash) { - console.error('No commitment for diff'); - } - try { - const res = await this.fetchValueFromStorage(hash); - if (!res) { - console.error('Failed to fetch value for hash', hash); - } else { - diff.new_value = res['value']; - retrievedValues[hash] = res['value']; - } - } catch (error) { - console.error(`Failed to fetch new_value for diff: ${JSON.stringify(diff)}`, error); - } - } - } - + const [updatedDiffs, retrievedValues] = await this.tryFetchDiffValue(updatedProcess.new_diffs); if (Object.entries(retrievedValues).length != 0) { + const stateId = updatedDiffs[0].new_state_merkle_root; + const processId = updatedDiffs[0].process_id; // We update the process with the value we retrieved const hashToValues = JSON.stringify(retrievedValues); const apiReturn = this.sdkClient.update_process_state(processId, stateId, hashToValues); await this.handleApiReturn(apiReturn); - } - - if (isPaired) { + } else { try { - await this.saveDiffs(diffs); + await this.saveDiffs(updatedDiffs); } catch (e) { throw e; } - } else { - await this.openPairingConfirmationModal(diffs, updatedProcess.up_to_date_roles); + if (!isPaired) { + await this.openPairingConfirmationModal(updatedDiffs); + } } } @@ -544,7 +552,7 @@ export default class Services { }, 0); } - public async openPairingConfirmationModal(diffs: UserDiff[], roles: Record) { + public async openPairingConfirmationModal(diffs: UserDiff[]) { const rolesDiff = diffs.find((diff) => diff.field === 'roles'); if (!rolesDiff) { throw new Error('Pairing process must have roles'); @@ -552,7 +560,7 @@ export default class Services { const processId = rolesDiff.process_id; const stateId = rolesDiff.new_state_merkle_root; try { - await this.routingInstance.openPairingConfirmationModal(roles, processId, stateId); + await this.routingInstance.openPairingConfirmationModal(rolesDiff.new_value, processId, stateId); } catch (e) { throw new Error(`${e}`); } From b539bb8feed2c9c2a0c2eead3211d30e1d6fa78c Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 16:33:22 +0100 Subject: [PATCH 02/18] process_increment_ok --- src/pages/process/process.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/pages/process/process.ts b/src/pages/process/process.ts index 9de7994..188d0a3 100755 --- a/src/pages/process/process.ts +++ b/src/pages/process/process.ts @@ -188,8 +188,17 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop let options_to_show; - if (dropdown) options_to_show = autocomplete_options; - else options_to_show = autocomplete(query, autocomplete_options); + if (dropdown) { + let messagingCounter = 1; + options_to_show = autocomplete_options.map(option => { + if (option === 'messaging') { + return `messaging ${messagingCounter++}`; + } + return option; + }); + } else { + options_to_show = autocomplete(query, autocomplete_options); + } const wrapper = select.parentNode; const input_search = wrapper?.querySelector('.search-container'); From 1f4f9c22086be6f3bb20e72a9ee1bedff106d77b Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 16:36:47 +0100 Subject: [PATCH 03/18] process_loop_fix --- src/pages/process/process.ts | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/pages/process/process.ts b/src/pages/process/process.ts index 188d0a3..20b7f0d 100755 --- a/src/pages/process/process.ts +++ b/src/pages/process/process.ts @@ -36,23 +36,18 @@ export async function init() { search_div.appendChild(autocomplete_list); search_div.appendChild(dropdown_icon); - // This is temporary - // Create a new process with hardcoded members for demonstration purpose - await createMessagingProcess(); - setTimeout(async () => { - const processes = await getProcesses(); - for (const {key, value} of processes) { - const processName = await getDescription(key, value); - // const processName = value['description']; - if (processName) { - console.log('adding process name to list:', processName); - const opt = new Option(processName); - opt.value = processName; - element.add(opt); - } + const processes = await getProcesses(); + for (const {key, value} of processes) { + const processName = await getDescription(key, value); + if (processName) { + console.log('adding process name to list:', processName); + const opt = new Option(processName); + opt.value = processName; + element.add(opt); } - }, 1000) + } + // set the wrapper as child (instead of the element) element.parentNode?.replaceChild(wrapper, element); // set element as child of wrapper @@ -60,15 +55,6 @@ export async function init() { wrapper.appendChild(search_div); addPlaceholder(wrapper); - - // const select = document.querySelector(".select-field"); - // for (const process of processeList) { - // const option = document.createElement("option"); - // option.setAttribute("value", process.name); - // option.innerText = process.name; - - // select.appendChild(option); - // } } function removePlaceholder(wrapper: HTMLElement) { From 8952456aeaf2aa93678feb4a4c58ca636cfba258 Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 17:34:36 +0100 Subject: [PATCH 04/18] select_ok_waiting_for_id --- src/pages/process/process.ts | 11 +++++++++++ src/router.ts | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/pages/process/process.ts b/src/pages/process/process.ts index 20b7f0d..27f9752 100755 --- a/src/pages/process/process.ts +++ b/src/pages/process/process.ts @@ -44,6 +44,7 @@ export async function init() { console.log('adding process name to list:', processName); const opt = new Option(processName); opt.value = processName; + opt.setAttribute('data-process-id', key); element.add(opt); } } @@ -226,6 +227,16 @@ function selectOption(e: any) { const option = wrapper.querySelector(`select option[value="${e.target.dataset.value}"]`); console.log('🚀 ~ selectOption ~ option:', option); + if (e.target.dataset.value.includes('messaging')) { + const event = new CustomEvent('navigate', { + detail: { + page: 'chat', + processId: option?.getAttribute('data-process-id') || '' + } + }); + document.dispatchEvent(event); + return; + } option.setAttribute('selected', ''); createToken(wrapper, e.target.dataset.value); if (input_search.value) { diff --git a/src/router.ts b/src/router.ts index 78f37d7..71f8840 100755 --- a/src/router.ts +++ b/src/router.ts @@ -1,5 +1,6 @@ import '../public/style/4nk.css'; import { initHeader } from '../src/components/header/header'; +import { initChat } from '../src/pages/chat/chat'; import Database from './services/database.service'; import Services from './services/service'; import { cleanSubscriptions } from './utils/subscription.utils'; @@ -191,3 +192,18 @@ async function injectHeader() { } (window as any).navigate = navigate; + +document.addEventListener('navigate', ((e: Event) => { + const event = e as CustomEvent<{page: string, processId?: string}>; + if (event.detail.page === 'chat') { + const container = document.querySelector('.container'); + if (container) container.innerHTML = ''; + + initChat(); + + const chatElement = document.querySelector('chat-element'); + if (chatElement) { + chatElement.setAttribute('process-id', event.detail.processId || ''); + } + } +})); From 9764ef219c460a3187b68a9392fc60fce4c470be Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 17:57:37 +0100 Subject: [PATCH 05/18] fix_process_id --- src/pages/process/process.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/pages/process/process.ts b/src/pages/process/process.ts index 27f9752..a942c48 100755 --- a/src/pages/process/process.ts +++ b/src/pages/process/process.ts @@ -177,9 +177,19 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop if (dropdown) { let messagingCounter = 1; + const messagingOptions = autocomplete_options.filter(option => option === 'messaging'); + options_to_show = autocomplete_options.map(option => { if (option === 'messaging') { - return `messaging ${messagingCounter++}`; + const allMessagingOptions = select.querySelectorAll('option[value="messaging"]'); + const currentMessagingOption = allMessagingOptions[messagingCounter - 1]; + const processId = currentMessagingOption?.getAttribute('data-process-id'); + const optionText = `messaging ${messagingCounter}`; + + // Stocker le processId avec son index spécifique + select.setAttribute(`data-messaging-id-${messagingCounter}`, processId || ''); + messagingCounter++; + return optionText; } return option; }); @@ -221,17 +231,30 @@ function populateAutocompleteList(select: HTMLSelectElement, query: string, drop // Listener to autocomplete results when clicked set the selected property in the select option function selectOption(e: any) { - console.log('🚀 ~ selectOption ~ e:', e); + console.log('🎯 Click event:', e); + console.log('🎯 Target value:', e.target.dataset.value); + const wrapper = e.target.parentNode.parentNode.parentNode; + const select = wrapper.querySelector('select'); const input_search = wrapper.querySelector('.selected-input'); const option = wrapper.querySelector(`select option[value="${e.target.dataset.value}"]`); + + console.log('🎯 Selected option:', option); + console.log('🎯 Process ID:', option?.getAttribute('data-process-id')); - console.log('🚀 ~ selectOption ~ option:', option); if (e.target.dataset.value.includes('messaging')) { + const messagingNumber = parseInt(e.target.dataset.value.split(' ')[1]); + const processId = select.getAttribute(`data-messaging-id-${messagingNumber}`); + + console.log('🎯 Navigating to chat with process:', { + value: e.target.dataset.value, + processId: processId + }); + const event = new CustomEvent('navigate', { detail: { page: 'chat', - processId: option?.getAttribute('data-process-id') || '' + processId: processId || '' } }); document.dispatchEvent(event); From 1413cc19c9104d86d337da82ee7d3dcc24faeb04 Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 18:29:33 +0100 Subject: [PATCH 06/18] load_ok --- src/pages/chat/chat.ts | 55 ++++++++++++++++++++++++++++++++++++ src/pages/process/process.ts | 37 +++++++++++++++--------- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/pages/chat/chat.ts b/src/pages/chat/chat.ts index 75047a8..88f354c 100755 --- a/src/pages/chat/chat.ts +++ b/src/pages/chat/chat.ts @@ -108,6 +108,11 @@ class ChatElement extends HTMLElement { }); this.initMessageEvents(); this.initFileUpload(); + + document.addEventListener('newMessagingProcess', ((event: CustomEvent) => { + console.log('🎯 Received newMessagingProcess event:', event.detail); + this.addNewMessagingProcess(event.detail.processId, event.detail.processName); + }) as EventListener); } private initMessageEvents() { @@ -557,6 +562,56 @@ class ChatElement extends HTMLElement { this.loadMemberChat(this.selectedMemberId); } } + + private addNewMessagingProcess(processId: string, processName: string) { + console.log('🎯 Adding new messaging process:', { processId, processName }); + const groupList = this.shadowRoot?.querySelector('#group-list'); + if (!groupList) { + console.error('Group list not found in shadow DOM'); + return; + } + + // Vérifier si le processus existe déjà + const existingProcess = groupList.querySelector(`[data-process-id="${processId}"]`); + if (existingProcess) { + console.log('Process already exists:', processId); + return; + } + + // Créer le nouveau groupe + const li = document.createElement('li'); + li.className = 'group-list-item'; + li.setAttribute('data-process-id', processId); + + // Créer le conteneur flex + const container = document.createElement('div'); + container.className = 'group-item-container'; + + // Span pour le nom du processus + const nameSpan = document.createElement('span'); + nameSpan.textContent = processName; + nameSpan.className = 'process-name'; + + // Assembler les éléments + container.appendChild(nameSpan); + li.appendChild(container); + + // Créer la liste des rôles + const roleList = document.createElement('ul'); + roleList.className = 'role-list'; + roleList.style.display = 'none'; + + // Ajouter un rôle par défaut pour le messaging + const roleItem = document.createElement('li'); + roleItem.className = 'role-item'; + roleItem.textContent = 'Messaging'; + roleList.appendChild(roleItem); + + li.appendChild(roleList); + groupList.appendChild(li); + + console.log('🎯 New messaging process added successfully'); + } } customElements.define('chat-element', ChatElement); diff --git a/src/pages/process/process.ts b/src/pages/process/process.ts index a942c48..f5162db 100755 --- a/src/pages/process/process.ts +++ b/src/pages/process/process.ts @@ -171,24 +171,26 @@ function clearAutocompleteList(select: HTMLSelectElement) { // Populate the autocomplete list following a given query from the user function populateAutocompleteList(select: HTMLSelectElement, query: string, dropdown = false) { const { autocomplete_options } = getOptions(select); - console.log('🚀 ~ populateAutocompleteList ~ autocomplete_options:', autocomplete_options); let options_to_show; if (dropdown) { let messagingCounter = 1; - const messagingOptions = autocomplete_options.filter(option => option === 'messaging'); + const messagingOptions = select.querySelectorAll('option[value="messaging"]'); options_to_show = autocomplete_options.map(option => { if (option === 'messaging') { - const allMessagingOptions = select.querySelectorAll('option[value="messaging"]'); - const currentMessagingOption = allMessagingOptions[messagingCounter - 1]; - const processId = currentMessagingOption?.getAttribute('data-process-id'); - const optionText = `messaging ${messagingCounter}`; + // Récupérer l'élément option correspondant au compteur actuel + const currentOption = messagingOptions[messagingCounter - 1]; + const processId = currentOption?.getAttribute('data-process-id'); + console.log(`Mapping messaging ${messagingCounter} with processId:`, processId); - // Stocker le processId avec son index spécifique - select.setAttribute(`data-messaging-id-${messagingCounter}`, processId || ''); + const optionText = `messaging ${messagingCounter}`; messagingCounter++; + + // Stocker le processId dans un attribut data sur le select + select.setAttribute(`data-messaging-id-${messagingCounter - 1}`, processId || ''); + return optionText; } return option; @@ -246,18 +248,27 @@ function selectOption(e: any) { const messagingNumber = parseInt(e.target.dataset.value.split(' ')[1]); const processId = select.getAttribute(`data-messaging-id-${messagingNumber}`); - console.log('🎯 Navigating to chat with process:', { - value: e.target.dataset.value, - processId: processId + console.log('🚀 Dispatching newMessagingProcess event:', { + processId, + processName: `Messaging Process ${processId}` }); + + // Dispatch l'événement avant la navigation + document.dispatchEvent(new CustomEvent('newMessagingProcess', { + detail: { + processId: processId, + processName: `Messaging Process ${processId}` + } + })); - const event = new CustomEvent('navigate', { + // Navigation vers le chat + const navigateEvent = new CustomEvent('navigate', { detail: { page: 'chat', processId: processId || '' } }); - document.dispatchEvent(event); + document.dispatchEvent(navigateEvent); return; } option.setAttribute('selected', ''); From d6af8db8270e4bc74c7c2a78cb00d3769818f7d4 Mon Sep 17 00:00:00 2001 From: Pascal Date: Mon, 6 Jan 2025 19:08:17 +0100 Subject: [PATCH 07/18] can_see_process --- src/pages/chat/chat.ts | 93 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/src/pages/chat/chat.ts b/src/pages/chat/chat.ts index 88f354c..5338c01 100755 --- a/src/pages/chat/chat.ts +++ b/src/pages/chat/chat.ts @@ -37,6 +37,11 @@ export function initChat() { } class ChatElement extends HTMLElement { + static get observedAttributes() { + return ['process-id']; + } + + private processId: string | null = null; private selectedMemberId: string | null = null; private messagesMock: any[] = []; private dom: Node; @@ -58,6 +63,10 @@ class ChatElement extends HTMLElement { this.messagesMock = messageStore.getMessages(); this.dom = getCorrectDOM('signature-element'); + // Récupérer le processId depuis l'attribut du composant + this.processId = this.getAttribute('process-id'); + console.log('🔍 Constructor - Process ID from element:', this.processId); + this.shadowRoot!.innerHTML = `