|
|
|
|
@@ -1,6 +1,19 @@
|
|
|
|
|
<!-- @component
|
|
|
|
|
The Jitsi component is a lightweight wrapper that manages loading the Jitsi Meet External API
|
|
|
|
|
and joining a Jitsi meeting room. It accepts configuration options and provides a callback
|
|
|
|
|
when the API is ready for use.
|
|
|
|
|
|
|
|
|
|
WARNING: Assume that ALL properties are NOT reactive. Due to the nature of the Jitsi Meet
|
|
|
|
|
External API, changing properties after initialization will NOT update the Jitsi instance.
|
|
|
|
|
Instead, use the getAPI() method to interact with the Jitsi instance directly.
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
|
import { onMount } from 'svelte';
|
|
|
|
|
import { type JitsiMeetExternalAPIOptions, JitsiMeetExternalAPI } from './jitsi-iframe-api.js';
|
|
|
|
|
import { onMount, type Snippet } from 'svelte';
|
|
|
|
|
import type {
|
|
|
|
|
JitsiMeetExternalAPIOptions,
|
|
|
|
|
JitsiMeetExternalAPI
|
|
|
|
|
} from '$lib/jitsi-iframe-api.d.ts';
|
|
|
|
|
import type { ClassValue } from 'svelte/elements';
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
@@ -18,13 +31,30 @@
|
|
|
|
|
* Additional CSS classes to apply to the Jitsi container.
|
|
|
|
|
*/
|
|
|
|
|
class?: ClassValue;
|
|
|
|
|
/**
|
|
|
|
|
* Children are rendered inside the Jitsi container until the API is initialized.
|
|
|
|
|
*/
|
|
|
|
|
children?: Snippet;
|
|
|
|
|
/**
|
|
|
|
|
* Callback function that is called when the Jitsi API is loaded. Can
|
|
|
|
|
* be used to provide a loading indicator until the API is ready.
|
|
|
|
|
* @param api The Jitsi Meet External API instance.
|
|
|
|
|
*/
|
|
|
|
|
onready?: (api: JitsiMeetExternalAPI) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let { domain = 'https://meet.jit.si', options, class: classValue }: Props = $props();
|
|
|
|
|
let {
|
|
|
|
|
domain = 'https://meet.jit.si',
|
|
|
|
|
options,
|
|
|
|
|
class: classValue,
|
|
|
|
|
children,
|
|
|
|
|
onready
|
|
|
|
|
}: Props = $props();
|
|
|
|
|
|
|
|
|
|
const src = $derived(`${new URL('external_api.js', domain).toString()}`);
|
|
|
|
|
|
|
|
|
|
let container: HTMLDivElement;
|
|
|
|
|
let ready = $state(false);
|
|
|
|
|
let api = $state<JitsiMeetExternalAPI | null>(null);
|
|
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
|
@@ -32,13 +62,27 @@
|
|
|
|
|
if (document.querySelectorAll('#jitsi-container').length > 1) {
|
|
|
|
|
console.warn('Duplicate Jitsi container detected. This may lead to unexpected behavior.');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onload = () => {
|
|
|
|
|
if (typeof window.JitsiMeetExternalAPI === 'undefined') {
|
|
|
|
|
console.error('Jitsi Meet External API is not available on the window object.');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ready = true;
|
|
|
|
|
// Initialize the Jitsi Meet External API
|
|
|
|
|
api = new JitsiMeetExternalAPI(new URL(domain).host, {
|
|
|
|
|
api = new window.JitsiMeetExternalAPI(new URL(domain).host, {
|
|
|
|
|
...options,
|
|
|
|
|
parentNode: container
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
if (api === null) {
|
|
|
|
|
console.error('Failed to initialize Jitsi Meet External API.');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Call the onready callback if provided
|
|
|
|
|
onready?.(api);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the Jitsi Meet External API instance.
|
|
|
|
|
@@ -50,7 +94,11 @@
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<svelte:head>
|
|
|
|
|
<script {src}></script>
|
|
|
|
|
<script {src} {onload}></script>
|
|
|
|
|
</svelte:head>
|
|
|
|
|
|
|
|
|
|
<div id="jitsi-container" bind:this={container} class={[classValue]}></div>
|
|
|
|
|
<div id="jitsi-container" bind:this={container} class={[classValue]}>
|
|
|
|
|
{#if !ready}
|
|
|
|
|
{@render children?.()}
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
|
|
|
|
|