From 8c99f5abed1313eca66703eb7d54d3f1732b3db7 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Fri, 30 Jan 2026 10:16:37 -0500 Subject: [PATCH] feat(idaa): implement jitsi report streaming and conference lifecycle improvements - Refactor Jitsi reports to use SvelteKit streaming with a skeleton loader. - Add conference lifecycle event listeners (left, close) to video conference page. - Implement manual Novi data re-sync and improve initialization robustness. - Fix skeleton visibility by using standard Tailwind colors. --- .../(idaa)/video_conferences/+page.svelte | 74 +++++--- src/routes/idaa/jitsi_reports/+page.svelte | 169 ++++++++++-------- src/routes/idaa/jitsi_reports/+page.ts | 10 +- 3 files changed, 150 insertions(+), 103 deletions(-) diff --git a/src/routes/idaa/(idaa)/video_conferences/+page.svelte b/src/routes/idaa/(idaa)/video_conferences/+page.svelte index 58d5c06b..19209797 100644 --- a/src/routes/idaa/(idaa)/video_conferences/+page.svelte +++ b/src/routes/idaa/(idaa)/video_conferences/+page.svelte @@ -117,7 +117,7 @@ api.on('videoConferenceJoined', async (jitsi_data: { id: string; displayName: string; roomName: string }) => { // Map Jitsi's camelCase to our internal snake_case const { id: participant_id, displayName: participant_name, roomName: jitsi_room_name } = jitsi_data; - + console.log('Jitsi Event: videoConferenceJoined', jitsi_data); meeting_start_time = new Date(); if (jitsi_meeting_id === null) jitsi_meeting_id = `${jitsi_room_name}-${Date.now()}`; @@ -215,17 +215,29 @@ }); // --- Discrete Event Logging --- - // NOTE: This does not seem to be triggered. api.on('raiseHandUpdated', (participant: { id:string; raisesHand: boolean }) => { if (participant.raisesHand) { const p_info = meeting_participants.get(participant.id); - console.log('Jitsi Event: raiseHandUpdated', p_info); - create_discrete_activity_log('jitsi_meeting_raise_hand', 'raiseHandUpdated', { - attendee_id: p_info.id, - full_name: p_info.displayName, - }); + if (p_info) { + console.log('Jitsi Event: raiseHandUpdated', p_info); + create_discrete_activity_log('jitsi_meeting_raise_hand', 'raiseHandUpdated', { + attendee_id: p_info.id, + full_name: p_info.displayName, + }); + } } }); + + api.on('videoConferenceLeft', () => { + console.log('Jitsi Event: videoConferenceLeft'); + if (duration_timer_id) clearInterval(duration_timer_id); + // meeting_duration = '00:00:00'; + }); + + api.on('readyToClose', () => { + console.log('Jitsi Event: readyToClose'); + show_jitsi_container = false; + }); } async function handle_profile_update() { @@ -277,7 +289,7 @@ settings: { startMuted: data.params.start_muted === 'true', startHidden: data.params.start_hidden === 'true', - reactionsMuted: data.params.reactions_muted === 'true' + reactionsMuted: disable_reaction_sound }, config: { 'prejoinConfig.enabled': false @@ -301,19 +313,13 @@ } } - onMount(async () => { - if (log_lvl) { - console.log('Jitsi: onMount - fetching user data and initializing Jitsi...'); - } + async function fetch_novi_data() { const url_params = data.params; - if (log_lvl > 1) { - console.log('Jitsi: url_params:', url_params); - } - // --- Start with fallback data from URL --- user_id = url_params.uuid; // Novi Customer GUID display_name = url_params.full_name ?? 'Guest'; // May be overridden email = (url_params.email ?? 'guest@example.com').replace(/\s+/g, '+'); // May be overridden + is_moderator = url_params.moderator === 'true'; // URL fallback room_name = url_params.room ?? 'Default-Room'; domain = url_params.domain ?? 'jitsi.dgrzone.com'; @@ -370,12 +376,26 @@ console.log(`Jitsi: User ${user_id} is not a moderator.`); } } else { - console.warn('Jitsi: Novi API not configured. Skipping user details/moderator check.'); + console.warn('Jitsi: Novi API not configured. Using URL fallback for user details/moderator check.'); } // Set initial value for the profile editor inputs name_input = display_name ?? ''; email_input = email ?? ''; + } + + async function handle_novi_resync() { + console.log('Jitsi: Manually re-syncing Novi Data...'); + await fetch_novi_data(); + await init_jitsi(); + } + + onMount(async () => { + if (log_lvl) { + console.log('Jitsi: onMount - fetching user data and initializing Jitsi...'); + } + + await fetch_novi_data(); // --- All data fetched, now initialize Jitsi --- await init_jitsi(); @@ -538,6 +558,17 @@ jitsi_api = null; } + // --- Check for Jitsi API script --- + // @ts-ignore + if (typeof JitsiMeetExternalAPI === 'undefined') { + console.error('Jitsi: JitsiMeetExternalAPI script not loaded yet.'); + const container = document.getElementById(jitsi_container_id); + if (container) { + container.innerHTML = '

Jitsi API script not loaded. Please refresh the page.

'; + } + return; + } + console.log('Jitsi: Initializing Jitsi meeting interface...'); // These variables are now expected to be set in the component's state @@ -869,10 +900,7 @@