Compare commits

...

2 Commits

Author SHA1 Message Date
Elijah Duffy
c912ec8387 0.0.3 2026-02-04 16:51:32 -08:00
Elijah Duffy
f6ad918d00 add onload & fallback rendering
fixes API trying to initialize before it has loaded
2026-02-04 16:51:24 -08:00
2 changed files with 51 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@svelte-toolkit/jitsi",
"version": "0.0.2",
"version": "0.0.3",
"repository": {
"type": "git",
"url": "https://gitea.auvem.com/svelte-toolkit/jitsi.git"

View File

@@ -1,5 +1,15 @@
<!-- @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 { onMount, type Snippet } from 'svelte';
import type {
JitsiMeetExternalAPIOptions,
JitsiMeetExternalAPI
@@ -21,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(() => {
@@ -35,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 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.
@@ -53,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>