First version of moving the Jitsi code to a new IDAA module under video_conferences.

This commit is contained in:
Scott Idem
2025-12-05 12:15:24 -05:00
parent 2403b41529
commit 3f0ff46f51
3 changed files with 181 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
<script lang="ts">
interface Props {
children: import('svelte').Snippet;
}
let { children }: Props = $props();
</script>
{@render children()}

View File

@@ -0,0 +1,151 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
interface Props {
data: any;
}
let { data }: Props = $props();
let jitsi_api: any = null;
const jitsi_container_id = 'jitsi_meet_external_api_container';
// Hardcoded moderator list, as in the original HTML file.
const novi_jitsi_mod_li = [
'2b078deb-b4e7-4203-99da-9f7cd62159a5',
'c9ea07b5-06b0-4a43-a2d0-8d06558c8a82',
'58db22ee-4b0a-49a7-9f34-53d2ba85a84b',
'5724aad7-6d89-47e7-8943-966fd22911bd',
'182d1db3-caa9-41bc-b04a-2facc6859aeb'
];
async function getJitsiJwt(
display_name: string,
email: string,
is_moderator: boolean,
room_name: string,
user_id: string
) {
const tokenEndpoint = 'https://dev-api.oneskyit.com/api/jitsi_token';
const payload = {
name: display_name,
email: email,
is_moderator: is_moderator,
room: room_name,
user: {
id: user_id,
name: display_name,
email: email,
moderator: is_moderator
},
features: {
livestreaming: false,
recording: false,
transcription: false,
'outbound-call': false
},
settings: {
startMuted: data.params.start_muted === 'true',
startHidden: data.params.start_hidden === 'true',
reactionsMuted: data.params.reactions_muted === 'true'
},
config: {
'prejoinConfig.enabled': false
}
};
try {
const response = await fetch(tokenEndpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!response.ok) throw new Error('Failed to fetch JWT token from the server.');
const result = await response.json();
return result.token;
} catch (err) {
console.error('Error getting JWT:', err);
return null;
}
}
onMount(async () => {
const url_params = data.params;
const user_id = url_params.uuid;
const display_name = url_params.full_name ?? 'Guest';
let email = (url_params.email ?? 'guest@example.com').replace(/\s+/g, '+');
const room_name = url_params.room ?? 'Default-Room';
const domain = url_params.domain ?? 'jitsi.dgrzone.com';
const is_moderator = novi_jitsi_mod_li.includes(user_id);
let jwtToken = null;
if (is_moderator) {
jwtToken = await getJitsiJwt(display_name, email, is_moderator, room_name, user_id);
if (!jwtToken) {
const container = document.getElementById(jitsi_container_id);
if (container) {
container.innerHTML = '<h1>Authentication Failed. Please try again.</h1>';
}
return;
}
}
const disabled_sounds = [
url_params.incoming_msg_sound === 'true' ? 'INCOMING_MSG_SOUND' : null,
url_params.participant_joined_sound === 'true' ? 'PARTICIPANT_JOINED_SOUND' : null,
url_params.participant_left_sound === 'true' ? 'PARTICIPANT_LEFT_SOUND' : null,
url_params.reaction_sound === 'true' ? 'REACTION_SOUND' : null,
url_params.raise_hand_sound === 'true' ? 'RAISE_HAND_SOUND' : null
].filter((sound) => sound);
const options = {
roomName: room_name,
width: '100%',
height: '100%',
parentNode: document.getElementById(jitsi_container_id),
userInfo: { displayName: display_name, email: email },
configOverwrite: {
prejoinPageEnabled: false,
startWithAudioMuted: true,
startWithVideoMuted: true,
enableLobby: is_moderator,
disableReactionsModeration: false,
disabledSounds: disabled_sounds
},
interfaceConfigOverwrite: {
DISABLE_JOIN_LEAVE_NOTIFICATIONS: true,
NOTIFICATION_SOUND_URL: ''
},
jwt: jwtToken
};
// @ts-ignore
jitsi_api = new JitsiMeetExternalAPI(domain, options);
});
onDestroy(() => {
if (jitsi_api) {
jitsi_api.dispose();
}
});
</script>
<svelte:head>
<script src="https://jitsi.dgrzone.com/external_api.js"></script>
</svelte:head>
<div id="{jitsi_container_id}" class="jitsi-container"></div>
<style>
.jitsi-container {
height: 100vh;
width: 100vw;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,22 @@
/** @type {import('./$types').PageLoad} */
export function load({ url }) {
return {
params: {
uuid: url.searchParams.get('uuid'),
email: url.searchParams.get('email'),
full_name: url.searchParams.get('full_name'),
moderator: url.searchParams.get('moderator'),
room: url.searchParams.get('room'),
domain: url.searchParams.get('domain'),
incoming_msg_sound: url.searchParams.get('incoming_msg_sound'),
participant_joined_sound: url.searchParams.get('participant_joined_sound'),
participant_left_sound: url.searchParams.get('participant_left_sound'),
reaction_sound: url.searchParams.get('reaction_sound'),
raise_hand_sound: url.searchParams.get('raise_hand_sound'),
start_muted: url.searchParams.get('start_muted'),
start_hidden: url.searchParams.get('start_hidden'),
reactions_muted: url.searchParams.get('reactions_muted')
}
};
}