1 Commits

Author SHA1 Message Date
Elijah Duffy
b3a1419ed3 0.0.2 2026-02-02 18:44:46 -08:00
5 changed files with 92 additions and 690 deletions

1
.nvmrc
View File

@@ -1 +0,0 @@
24.12.0

View File

@@ -1,3 +1,65 @@
# Jitsi iFrame Svelte Integration
# Svelte library
This package provides a component and typed API for the Jitsi Meet iFrame. If you prefer to build your own component, refer directly to the exported type definitions for the Jitsi iFrame API.
Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```sh
# create a new project in the current directory
npx sv create
# create a new project in my-app
npx sv create my-app
```
To recreate this project with the same configuration:
```sh
# recreate this project
pnpm dlx sv create --template library --types ts --add prettier eslint devtools-json --install pnpm jitsi
```
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```sh
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
```
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
## Building
To build your library:
```sh
npm pack
```
To create a production version of your showcase app:
```sh
npm run build
```
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
## Publishing
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
To publish your library to [npm](https://www.npmjs.com):
```sh
npm publish
```

View File

@@ -1,7 +1,6 @@
{
"name": "@svelte-toolkit/jitsi",
"version": "0.1.1",
"license": "BSD-3-Clause",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://gitea.auvem.com/svelte-toolkit/jitsi.git"

View File

@@ -1,23 +1,6 @@
<!-- @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 several callbacks that
allow you to respond to basic meeting events such as joining and leaving. For advanced event
handling, use the getAPI() method to interact with the Jitsi instance directly.
WARNING: While properties are reactive, in most cases changing them after the API has
initialized will trigger a complete re-render of the component, which will destroy the
existing Jitsi instance and interrupt any ongoing meetings. Use the getAPI() method to
interact with the Jitsi instance directly without causing a re-render.
-->
<script lang="ts">
import { onMount, type Snippet } from 'svelte';
import type {
JitsiMeetExternalAPIOptions,
JitsiMeetExternalAPI,
VideoConferenceJoinedEvent,
VideoConferenceLeftEvent
} from '$lib/jitsi-iframe-api.d.ts';
import { onMount } from 'svelte';
import { type JitsiMeetExternalAPIOptions, JitsiMeetExternalAPI } from './jitsi-iframe-api.js';
import type { ClassValue } from 'svelte/elements';
interface Props {
@@ -35,95 +18,27 @@ interact with the Jitsi instance directly without causing a re-render.
* Additional CSS classes to apply to the Jitsi container.
*/
class?: ClassValue;
/**
* Optional snippet rendered until the API is initialized and the meeting
* is joined. Can be used to provide a loading indicator or placeholder content.
*/
loading?: Snippet;
/** Whether to hold loading state until the meeting is joined (default: false). */
holdLoadingUntilJoined?: boolean;
/**
* Optional snippet rendered after the API is initialized and the meeting is joined.
* Can be used to provide additional UI elements or controls related to the meeting.
* Overlay has pointer-events disabled to allow interaction with the underlying Jitsi
* interface.
*/
joinedOverlay?: Snippet<[api: JitsiMeetExternalAPI]>;
/**
* 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.
*/
onapiready?: (api: JitsiMeetExternalAPI) => void;
/** Callback triggered when the local user joins the meeting. */
onjoin?: (ev: VideoConferenceJoinedEvent) => void;
/** Callback triggered when the local user leaves the meeting. */
onleave?: (ev: VideoConferenceLeftEvent) => void;
}
let {
domain = 'https://meet.jit.si',
options,
class: classValue,
loading,
holdLoadingUntilJoined = false,
joinedOverlay,
onapiready,
onjoin,
onleave
}: Props = $props();
let { domain = 'https://meet.jit.si', options, class: classValue }: Props = $props();
const src = $derived(`${new URL('external_api.js', domain).toString()}`);
let container: HTMLDivElement;
/** tracks whether the Jitsi API is ready */
let apiReady = $state(false);
/** tracks whether the local user has joined the meeting */
let joinedMeeting = $state(false);
/** tracks whether the local user has left the meeting */
let leftMeeting = $state(false);
/** whether to display the loading state */
const showLoading = $derived(holdLoadingUntilJoined ? !joinedMeeting : !apiReady);
let api = $state<JitsiMeetExternalAPI | null>(null);
onMount(() => {
// check if we have a duplicate container
if (document.querySelectorAll('#jitsi-iframe').length > 1) {
if (document.querySelectorAll('#jitsi-container').length > 1) {
console.warn('Duplicate Jitsi container detected. This may lead to unexpected behavior.');
}
});
/** handles Jitsi script load event */
const handleScriptLoad = () => {
if (typeof window.JitsiMeetExternalAPI === 'undefined') {
console.error('Jitsi Meet External API is not available on the window object.');
return;
}
apiReady = true;
// Initialize the Jitsi Meet External API
api = new window.JitsiMeetExternalAPI(new URL(domain).host, {
api = new JitsiMeetExternalAPI(new URL(domain).host, {
...options,
parentNode: container
});
if (api === null) {
console.error('Failed to initialize Jitsi Meet External API.');
return;
}
// Call the onapiready callback if provided
onapiready?.(api);
// Attach event listeners for meeting join and leave events
api.addListener('videoConferenceJoined', (ev: VideoConferenceJoinedEvent) => {
joinedMeeting = true;
onjoin?.(ev);
});
api.addListener('videoConferenceLeft', (ev: VideoConferenceLeftEvent) => {
leftMeeting = true;
onleave?.(ev);
});
};
/**
* Get the Jitsi Meet External API instance.
@@ -135,43 +50,7 @@ interact with the Jitsi instance directly without causing a re-render.
</script>
<svelte:head>
<script {src} onload={handleScriptLoad}></script>
<script {src}></script>
</svelte:head>
<div class={['jitsi-container', classValue]}>
{#if showLoading}
<div class="overlay-container">{@render loading?.()}</div>
{/if}
{#if joinedMeeting && api && joinedOverlay}
<div class="overlay-container passthrough">{@render joinedOverlay(api)}</div>
{/if}
<div
id="jitsi-iframe"
bind:this={container}
class="fill-container"
style={leftMeeting ? 'display: none;' : undefined}
></div>
</div>
<style lang="css">
.jitsi-container {
position: relative;
}
.fill-container {
width: 100%;
height: 100%;
min-width: 0px;
}
.overlay-container {
position: absolute;
inset: 0;
}
.passthrough {
pointer-events: none;
}
</style>
<div id="jitsi-container" bind:this={container} class={[classValue]}></div>

View File

@@ -438,521 +438,28 @@ export interface JitsiMeetExternalAPIOptions {
}
interface ConfigOverwrite {
// Audio settings
startWithAudioMuted?: boolean;
startAudioMuted?: number;
startAudioOnly?: boolean;
startSilent?: boolean;
enableNoisyMicDetection?: boolean;
enableOpusRed?: boolean;
audioQuality?: {
stereo?: boolean;
opusMaxAverageBitrate?: number | null;
enableOpusDtx?: boolean;
};
noiseSuppression?: {
krisp?: {
enabled?: boolean;
logProcessStats?: boolean;
debugLogs?: boolean;
useBVC?: boolean;
bufferOverflowMS?: number;
};
};
disableAEC?: boolean;
disableAGC?: boolean;
disableAP?: boolean;
disableNS?: boolean;
// Video settings
startWithVideoMuted?: boolean;
startVideoMuted?: number;
maxFullResolutionParticipants?: number;
disableSimulcast?: boolean;
disableResponsiveTiles?: boolean;
constraints?: {
video?: {
height?: {
ideal?: number;
max?: number;
min?: number;
};
};
};
desktopSharingFrameRate?: {
min?: number;
max?: number;
};
screenShareSettings?: {
desktopPreferCurrentTab?: boolean;
desktopSystemAudio?: 'include' | 'exclude';
desktopSurfaceSwitching?: 'include' | 'exclude';
desktopDisplaySurface?: string;
desktopSelfBrowserSurface?: 'include' | 'exclude';
};
videoQuality?: {
codecPreferenceOrder?: ('AV1' | 'VP9' | 'VP8' | 'H264')[];
mobileCodecPreferenceOrder?: ('AV1' | 'VP9' | 'VP8' | 'H264')[];
screenshareCodec?: string;
mobileScreenshareCodec?: string;
enableAdaptiveMode?: boolean;
minHeightForQualityLvl?: Record<number, 'low' | 'standard' | 'high'>;
};
// Prejoin configuration (replaces prejoinPageEnabled)
prejoinConfig?: {
enabled?: boolean;
hideDisplayName?: boolean;
hideExtraJoinButtons?: ('no-audio' | 'by-phone')[];
preCallTestEnabled?: boolean;
preCallTestICEUrl?: string;
showHangUp?: boolean;
};
/** @deprecated Use prejoinConfig.enabled instead */
prejoinPageEnabled?: boolean;
// Lobby configuration
lobby?: {
autoKnock?: boolean;
enableChat?: boolean;
showHangUp?: boolean;
};
/** @deprecated Use lobby.autoKnock instead */
autoKnockLobby?: boolean;
/** @deprecated Use lobby.enableChat instead */
enableLobbyChat?: boolean;
// Security UI configuration
securityUi?: {
hideLobbyButton?: boolean;
disableLobbyPassword?: boolean;
};
/** @deprecated Use securityUi.hideLobbyButton instead */
hideLobbyButton?: boolean;
// Deep linking configuration
deeplinking?: {
disabled?: boolean;
hideLogo?: boolean;
desktop?: {
appName?: string;
appScheme?: string;
download?: {
linux?: string;
macos?: string;
windows?: string;
};
enabled?: boolean;
};
ios?: {
appName?: string;
appScheme?: string;
downloadLink?: string;
};
android?: {
appName?: string;
appScheme?: string;
downloadLink?: string;
appPackage?: string;
fDroidUrl?: string;
};
};
/** @deprecated Use deeplinking.disabled instead */
disableDeepLinking?: boolean;
// Welcome page configuration
welcomePage?: {
disabled?: boolean;
customUrl?: string;
};
// Recording configuration
recordings?: {
recordAudioAndVideo?: boolean;
suggestRecording?: boolean;
showPrejoinWarning?: boolean;
showRecordingLink?: boolean;
requireConsent?: boolean;
skipConsentInMeeting?: boolean;
consentLearnMoreLink?: string;
};
recordingService?: {
enabled?: boolean;
sharingEnabled?: boolean;
hideStorageWarning?: boolean;
};
localRecording?: {
disable?: boolean;
notifyAllParticipants?: boolean;
disableSelfRecording?: boolean;
};
// Live streaming configuration
liveStreaming?: {
enabled?: boolean;
termsLink?: string;
dataPrivacyLink?: string;
validatorRegExpString?: string;
helpLink?: string;
};
// Transcription configuration
transcription?: {
enabled?: boolean;
useAppLanguage?: boolean;
preferredLanguage?: string;
customLanguages?: Record<string, string>;
autoTranscribeOnRecord?: boolean;
autoCaptionOnTranscribe?: boolean;
disableClosedCaptions?: boolean;
};
// Toolbar configuration
toolbarButtons?: ToolbarButton[];
mainToolbarButtons?: ToolbarButton[][];
reducedUImainToolbarButtons?: ToolbarButton[];
reducedUIEnabled?: boolean;
buttonsWithNotifyClick?: (ToolbarButton | ButtonWithNotifyClick)[];
participantMenuButtonsWithNotifyClick?: (string | ButtonWithNotifyClick)[];
hiddenPremeetingButtons?: (
| 'microphone'
| 'camera'
| 'select-background'
| 'invite'
| 'settings'
)[];
customToolbarButtons?: Array<{
icon: string;
id: string;
text: string;
backgroundColor?: string;
}>;
customParticipantMenuButtons?: Array<{ icon: string; id: string; text: string }>;
toolbar?: {
initialTimeout?: number;
timeout?: number;
alwaysVisible?: boolean;
autoHideWhileChatIsOpen?: boolean;
};
// UI settings
prejoinPageEnabled?: boolean;
enableNoisyMicDetection?: boolean;
enableClosePage?: boolean;
disableInviteFunctions?: boolean;
disableModeratorIndicator?: boolean;
enableLobbyChat?: boolean;
hideLobbyButton?: boolean;
enableInsecureRoomNameWarning?: boolean;
disableReactions?: boolean;
disableReactionsModeration?: boolean;
disableReactionsInChat?: boolean;
disablePolls?: boolean;
disableChat?: boolean;
disableSelfDemote?: boolean;
disableSelfView?: boolean;
disableSelfViewSettings?: boolean;
showChatPermissionsModeratorSetting?: boolean;
disableShortcuts?: boolean;
disableInitialGUM?: boolean;
disable1On1Mode?: boolean | null;
defaultLocalDisplayName?: string;
defaultRemoteDisplayName?: string;
hideDisplayName?: boolean;
hideDominantSpeakerBadge?: boolean;
defaultLanguage?: string;
disableProfile?: boolean;
hideEmailInSettings?: boolean;
requireDisplayName?: boolean;
readOnlyName?: boolean;
enableWebHIDFeature?: boolean;
doNotStoreRoom?: boolean;
disableLocalVideoFlip?: boolean;
doNotFlipLocalVideo?: boolean;
disableVirtualBackground?: boolean;
disableAddingBackgroundImages?: boolean;
backgroundAlpha?: number;
disableTileView?: boolean;
disableTileEnlargement?: boolean;
hideConferenceSubject?: boolean;
hideConferenceTimer?: boolean;
hideRecordingLabel?: boolean;
hideParticipantsStats?: boolean;
subject?: string;
localSubject?: string;
disableChatSmileys?: boolean;
disableFilmstripAutohiding?: boolean;
disableCameraTintForeground?: boolean;
// Filmstrip configuration
filmstrip?: {
disabled?: boolean;
disableResizable?: boolean;
disableStageFilmstrip?: boolean;
stageFilmstripParticipants?: number;
disableTopPanel?: boolean;
minParticipantCountForTopPanel?: number;
initialWidth?: number;
alwaysShowResizeBar?: boolean;
};
// Tile view configuration
tileView?: {
disabled?: boolean;
numberOfVisibleTiles?: number;
};
// Participants pane configuration
participantsPane?: {
enabled?: boolean;
hideModeratorSettingsTab?: boolean;
hideMoreActionsButton?: boolean;
hideMuteAllButton?: boolean;
};
// Breakout rooms configuration
breakoutRooms?: {
hideAddRoomButton?: boolean;
hideAutoAssignButton?: boolean;
hideJoinRoomButton?: boolean;
};
// Raised hands configuration
raisedHands?: {
disableLowerHandByModerator?: boolean;
disableLowerHandNotification?: boolean;
disableNextSpeakerNotification?: boolean;
disableRemoveRaisedHandOnFocus?: boolean;
};
disableRemoveRaisedHandOnFocus?: boolean;
// Speaker stats configuration
speakerStats?: {
disabled?: boolean;
disableSearch?: boolean;
order?: ('role' | 'name' | 'hasLeft')[];
};
// Connection indicators configuration
connectionIndicators?: {
autoHide?: boolean;
autoHideTimeout?: number;
disabled?: boolean;
disableDetails?: boolean;
inactiveDisabled?: boolean;
};
// Remote video menu configuration
remoteVideoMenu?: {
disabled?: boolean;
disableDemote?: boolean;
disableKick?: boolean;
disableGrantModerator?: boolean;
disablePrivateChat?: 'all' | 'allow-moderator-chat' | 'disable-visitor-chat';
};
disableRemoteMute?: boolean;
// Face landmarks configuration
faceLandmarks?: {
enableFaceCentering?: boolean;
enableFaceExpressionsDetection?: boolean;
enableDisplayFaceExpressions?: boolean;
enableRTCStats?: boolean;
faceCenteringThreshold?: number;
captureInterval?: number;
};
// Notification settings
notificationTimeouts?: {
short?: number;
medium?: number;
long?: number;
extraLong?: number;
sticky?: number;
};
notifications?: string[];
disabledNotifications?: string[];
// Conference info configuration
conferenceInfo?: {
alwaysVisible?: string[];
autoHide?: string[];
};
// Giphy configuration
giphy?: {
enabled?: boolean;
sdkKey?: string;
displayMode?: 'tile' | 'chat' | 'all';
tileTime?: number;
rating?: 'g' | 'pg' | 'pg-13' | 'r';
};
// Whiteboard configuration
whiteboard?: {
enabled?: boolean;
collabServerBaseUrl?: string;
userLimit?: number;
limitUrl?: string;
};
// E2EE configuration
e2ee?: {
labels?: {
description?: string;
label?: string;
tooltip?: string;
warning?: string;
};
externallyManagedKey?: boolean;
};
// Visitors configuration
visitors?: {
enableMediaOnPromote?: {
audio?: boolean;
video?: boolean;
};
hideVisitorCountForVisitors?: boolean;
showJoinMeetingDialog?: boolean;
};
// P2P configuration
p2p?: {
enabled?: boolean;
iceTransportPolicy?: 'all' | 'relay';
codecPreferenceOrder?: ('AV1' | 'VP9' | 'VP8' | 'H264')[];
mobileCodecPreferenceOrder?: ('AV1' | 'VP9' | 'VP8' | 'H264')[];
screenshareCodec?: string;
mobileScreenshareCodec?: string;
backToP2PDelay?: number;
stunServers?: Array<{ urls: string }>;
};
// Testing/experimental features
testing?: {
assumeBandwidth?: boolean;
enableAV1ForFF?: boolean;
enableCodecSelectionAPI?: boolean;
p2pTestMode?: boolean;
testMode?: boolean;
noAutoPlayVideo?: boolean;
skipInterimTranscriptions?: boolean;
dumpTranscript?: boolean;
debugAudioLevels?: boolean;
failICE?: boolean;
showSpotConsentDialog?: boolean;
};
// Analytics configuration
analytics?: {
disabled?: boolean;
rtcstatsEnabled?: boolean;
rtcstatsStoreLogs?: boolean;
rtcstatsEndpoint?: string;
rtcstatsPollInterval?: number;
rtcstatsSendSdp?: boolean;
watchRTCEnabled?: boolean;
};
// Gravatar configuration
gravatar?: {
baseUrl?: string;
disabled?: boolean;
};
// Legal URLs
legalUrls?: {
helpCentre?: string;
privacy?: string;
terms?: string;
};
// Other settings
apiLogLevels?: LogLevel[];
toolbarButtons?: ToolbarButton[];
buttonsWithNotifyClick?: (ToolbarButton | ButtonWithNotifyClick)[];
mouseMoveCallbackInterval?: number;
channelLastN?: number;
startLastN?: number;
useHostPageLocalStorage?: boolean;
disableRtx?: boolean;
enableTcc?: boolean;
enableRemb?: boolean;
enableForcedReload?: boolean;
useTurnUdp?: boolean;
enableEncodedTransformSupport?: boolean;
disableThirdPartyRequests?: boolean;
enableCalendarIntegration?: boolean;
notifyOnConferenceDestruction?: boolean;
feedbackPercentage?: number;
roomPasswordNumberOfDigits?: number | false;
noticeMessage?: string;
enableTalkWhileMuted?: boolean;
forceTurnRelay?: boolean;
hideLoginButton?: boolean;
disableWebrtcStats?: boolean;
disableShowMoreStats?: boolean;
etherpad_base?: string;
openSharedDocumentOnJoin?: boolean;
screenshotCapture?: {
enabled?: boolean;
mode?: 'recording' | 'always';
faceLandmarks?: {
faceCenteringThreshold?: number;
};
webrtcIceUdpDisable?: boolean;
webrtcIceTcpDisable?: boolean;
disableBeforeUnloadHandlers?: boolean;
// Logging configuration
logging?: {
defaultLogLevel?: 'trace' | 'debug' | 'info' | 'log' | 'warn' | 'error';
disableLogCollector?: boolean;
loggers?: Record<string, string>;
};
// File sharing configuration
fileSharing?: {
apiUrl?: string;
enabled?: boolean;
maxFileSize?: number;
};
// Dropbox integration
dropbox?: {
appKey?: string;
redirectURI?: string;
};
// Dynamic branding
dynamicBrandingUrl?: string;
// Shared video allowed domains
sharedVideoAllowedURLDomains?: string[];
// CORS avatar URLs
corsAvatarURLs?: string[];
// Recording limit
recordingLimit?: {
limit?: number;
appName?: string;
appURL?: string;
};
// Chrome extension banner
chromeExtensionBanner?: {
url?: string;
edgeUrl?: string;
chromeExtensionsInfo?: Array<{
id: string;
path: string;
}>;
};
// Allow any additional config options
apiLogLevels?: LogLevel[];
[key: string]: unknown;
}
/**
* @deprecated Most interfaceConfig options are being migrated to config.js.
* Use configOverwrite instead where possible.
*/
interface InterfaceConfigOverwrite {
/** @deprecated Use config.disableModeratorIndicator instead */
DISABLE_DOMINANT_SPEAKER_INDICATOR?: boolean;
TILE_VIEW_MAX_COLUMNS?: number;
SHOW_JITSI_WATERMARK?: boolean;
@@ -960,7 +467,6 @@ interface InterfaceConfigOverwrite {
SHOW_BRAND_WATERMARK?: boolean;
SHOW_POWERED_BY?: boolean;
SHOW_PROMOTIONAL_CLOSE_PAGE?: boolean;
/** @deprecated Use config.toolbarButtons instead */
TOOLBAR_BUTTONS?: ToolbarButton[];
SETTINGS_SECTIONS?: SettingsSection[];
VIDEO_LAYOUT_FIT?: 'both' | 'width' | 'height';
@@ -968,44 +474,8 @@ interface InterfaceConfigOverwrite {
FILM_STRIP_MAX_HEIGHT?: number;
MOBILE_APP_PROMO?: boolean;
HIDE_INVITE_MORE_HEADER?: boolean;
/** @deprecated Use config.disabledSounds instead */
DISABLE_JOIN_LEAVE_NOTIFICATIONS?: boolean;
DISABLE_VIDEO_BACKGROUND?: boolean;
DEFAULT_BACKGROUND?: string;
DEFAULT_WELCOME_PAGE_LOGO_URL?: string;
DEFAULT_LOGO_URL?: string;
JITSI_WATERMARK_LINK?: string;
BRAND_WATERMARK_LINK?: string;
APP_NAME?: string;
NATIVE_APP_NAME?: string;
PROVIDER_NAME?: string;
LANG_DETECTION?: boolean;
ENFORCE_NOTIFICATION_AUTO_DISMISS_TIMEOUT?: number;
MAXIMUM_ZOOMING_COEFFICIENT?: number;
SUPPORT_URL?: string;
CONNECTION_INDICATOR_AUTO_HIDE_ENABLED?: boolean;
CONNECTION_INDICATOR_AUTO_HIDE_TIMEOUT?: number;
CONNECTION_INDICATOR_DISABLED?: boolean;
AUTO_PIN_LATEST_SCREEN_SHARE?: string;
DISABLE_FOCUS_INDICATOR?: boolean;
DISABLE_PRESENCE_STATUS?: boolean;
DISABLE_TRANSCRIPTION_SUBTITLES?: boolean;
DISABLE_RINGING?: boolean;
AUDIO_LEVEL_PRIMARY_COLOR?: string;
AUDIO_LEVEL_SECONDARY_COLOR?: string;
FILMSTRIP_MAX_HEIGHT?: number;
GENERATE_ROOMNAMES_ON_WELCOME_PAGE?: boolean;
HIDE_DEEP_LINKING_LOGO?: boolean;
INITIAL_TOOLBAR_TIMEOUT?: number;
TOOLBAR_TIMEOUT?: number;
TOOLBAR_ALWAYS_VISIBLE?: boolean;
LOCAL_THUMBNAIL_RATIO?: number;
REMOTE_THUMBNAIL_RATIO?: number;
LIVE_STREAMING_HELP_LINK?: string;
POLICY_LOGO?: string;
RECENT_LIST_ENABLED?: boolean;
SHOW_CHROME_EXTENSION_BANNER?: boolean;
VIDEO_QUALITY_LABEL_DISABLED?: boolean;
[key: string]: unknown;
}
@@ -1430,7 +900,6 @@ interface FaceLandmarkDetectedEvent {
}
interface ErrorOccurredEvent {
error: {
/** Additional error details. */
details?: Record<string, unknown>;
/** The error message. */
@@ -1441,7 +910,6 @@ interface ErrorOccurredEvent {
type: ErrorType;
/** Whether this is a fatal error which triggered a reconnect overlay. */
isFatal: boolean;
};
}
interface KnockingParticipantEvent {
@@ -1810,26 +1278,21 @@ type ToolbarButton =
| 'dock-iframe'
| 'download'
| 'embedmeeting'
| 'end-meeting'
| 'etherpad'
| 'feedback'
| 'filmstrip'
| 'fullscreen'
| 'hangup'
| 'hangup-menu'
| 'help'
| 'highlight'
| 'invite'
| 'linktosalesforce'
| 'livestreaming'
| 'microphone'
| 'mute-everyone'
| 'mute-video-everyone'
| 'noisesuppression'
| 'participants-pane'
| 'profile'
| 'raisehand'
| 'reactions'
| 'recording'
| 'security'
| 'select-background'