213 lines
6.1 KiB
Svelte
213 lines
6.1 KiB
Svelte
<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';
|
|
|
|
async function getJitsiJwt(
|
|
display_name: string,
|
|
email: string,
|
|
is_moderator: boolean,
|
|
room_name: string,
|
|
user_id: string
|
|
) {
|
|
const token_endpoint = '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(token_endpoint, {
|
|
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;
|
|
|
|
// --- Start with fallback data from URL ---
|
|
let user_id = url_params.uuid;
|
|
let display_name = url_params.full_name ?? 'Guest';
|
|
let email = (url_params.email ?? 'guest@example.com').replace(/\s+/g, '+');
|
|
let is_moderator = false;
|
|
const room_name = url_params.room ?? 'Default-Room';
|
|
const domain = url_params.domain ?? 'jitsi.dgrzone.com';
|
|
|
|
if (!user_id) {
|
|
const container = document.getElementById(jitsi_container_id);
|
|
if (container) {
|
|
container.innerHTML =
|
|
'<h1>User ID (uuid) is missing. Cannot start meeting.</h1>';
|
|
}
|
|
return;
|
|
}
|
|
|
|
// --- Fetch dynamic data from Novi API ---
|
|
const novi_api_key = 'CmNdWgdPmgluBWjiTd8xsUCk5mio8F1O9DYAh0pVDcg=';
|
|
const novi_api_headers = new Headers();
|
|
novi_api_headers.append('Authorization', `Basic ${novi_api_key}`);
|
|
const requestOptions = {
|
|
method: 'GET',
|
|
headers: novi_api_headers
|
|
};
|
|
|
|
try {
|
|
// Fetch the list of moderators from the Novi group
|
|
const mod_group_guid = 'd76d2c00-962d-40f6-a2e8-ed9c85594d96';
|
|
const mod_list_url = `https://www.idaa.org/api/groups/${mod_group_guid}/members?pageSize=200`;
|
|
console.log(`Fetching moderator list from Novi API: ${mod_list_url}`);
|
|
const mods_response = await fetch(mod_list_url, requestOptions);
|
|
|
|
if (mods_response.ok) {
|
|
const moderatorsRaw = await mods_response.json();
|
|
console.log('Fetched moderators raw:', moderatorsRaw);
|
|
|
|
// Normalise the payload: support both Array and { Results: Array } shapes
|
|
let modList: any[] = [];
|
|
if (Array.isArray(moderatorsRaw)) {
|
|
modList = moderatorsRaw;
|
|
} else if (Array.isArray(moderatorsRaw.Results)) {
|
|
modList = moderatorsRaw.Results;
|
|
} else if (Array.isArray(moderatorsRaw.Members)) {
|
|
modList = moderatorsRaw.Members;
|
|
} else {
|
|
console.warn('Moderator list format is unexpected. Falling back to empty list.', moderatorsRaw);
|
|
modList = [];
|
|
}
|
|
|
|
// Build a set of normalized IDs from a few possible fields
|
|
const modIdSet = new Set(
|
|
modList
|
|
.map((m: any) => (m?.UniqueID ?? m?.UniqueId ?? m?.DuesPayerUniqueID ?? m?.id ?? ''))
|
|
.filter(Boolean)
|
|
.map((id: string) => id.toLowerCase().trim())
|
|
);
|
|
|
|
const normalizedUserId = String(user_id ?? '').toLowerCase().trim();
|
|
|
|
console.log(`Moderator IDs (${modIdSet.size}) sample:`, Array.from(modIdSet).slice(0, 10));
|
|
if (normalizedUserId && modIdSet.has(normalizedUserId)) {
|
|
is_moderator = true;
|
|
console.log(`User ${user_id} is a moderator (matched by UniqueID).`);
|
|
} else {
|
|
// Also check by matching name/email if needed (optional)
|
|
console.log(`User ${user_id} is not a moderator.`);
|
|
}
|
|
} else {
|
|
console.warn('Could not fetch moderator list from Novi API.');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching data from Novi API:', error);
|
|
// Fallback to data from URL params is the default behavior
|
|
}
|
|
|
|
// --- Initialize Jitsi ---
|
|
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>
|