@@ -127,7 +127,7 @@ const ack = (ev: CustomEvent<IWidgetApiRequest>) => widgetApi.transport.reply(ev
127127 const instanceConfig = new SnakedObject < IConfigOptions > ( ( await configPromise ) ?? < IConfigOptions > { } ) ;
128128 const jitsiConfig = instanceConfig . get ( "jitsi_widget" ) ?? { } ;
129129 skipOurWelcomeScreen = ( new SnakedObject < IConfigOptions [ "jitsi_widget" ] > ( jitsiConfig ) )
130- . get ( "skip_built_in_welcome_screen" ) || isVideoChannel ;
130+ . get ( "skip_built_in_welcome_screen" ) ?? false ;
131131
132132 // Either reveal the prejoin screen, or skip straight to Jitsi depending on the config.
133133 // We don't set up the call yet though as this might lead to failure without the widget API.
@@ -145,7 +145,8 @@ const ack = (ev: CustomEvent<IWidgetApiRequest>) => widgetApi.transport.reply(ev
145145
146146 widgetApi . on ( `action:${ ElementWidgetActions . JoinCall } ` ,
147147 ( ev : CustomEvent < IWidgetApiRequest > ) => {
148- joinConference ( ) ;
148+ const { audioDevice, videoDevice } = ev . detail . data ;
149+ joinConference ( audioDevice as string , videoDevice as string ) ;
149150 ack ( ev ) ;
150151 } ,
151152 ) ;
@@ -211,6 +212,13 @@ const ack = (ev: CustomEvent<IWidgetApiRequest>) => widgetApi.transport.reply(ev
211212 }
212213
213214 enableJoinButton ( ) ; // always enable the button
215+
216+ // Inform the client that we're ready to receive events
217+ try {
218+ await widgetApi ?. transport . send ( ElementWidgetActions . WidgetReady , { } ) ;
219+ } catch ( e ) {
220+ logger . error ( e ) ;
221+ }
214222 } catch ( e ) {
215223 logger . error ( "Error setting up Jitsi widget" , e ) ;
216224 document . getElementById ( "widgetActionContainer" ) . innerText = "Failed to load Jitsi widget" ;
@@ -293,7 +301,8 @@ async function notifyHangup() {
293301 }
294302}
295303
296- function joinConference ( ) { // event handler bound in HTML
304+ // event handler bound in HTML
305+ function joinConference ( audioDevice ?: string , videoDevice ?: string ) {
297306 let jwt ;
298307 if ( jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH ) {
299308 if ( ! openIdToken ?. access_token ) { // eslint-disable-line camelcase
@@ -318,6 +327,10 @@ function joinConference() { // event handler bound in HTML
318327 height : "100%" ,
319328 parentNode : document . querySelector ( "#jitsiContainer" ) ,
320329 roomName : conferenceId ,
330+ devices : {
331+ audioInput : audioDevice ,
332+ videoInput : videoDevice ,
333+ } ,
321334 interfaceConfigOverwrite : {
322335 SHOW_JITSI_WATERMARK : false ,
323336 SHOW_WATERMARK_FOR_GUESTS : false ,
@@ -326,15 +339,17 @@ function joinConference() { // event handler bound in HTML
326339 } ,
327340 configOverwrite : {
328341 startAudioOnly,
342+ startWithAudioMuted : ! audioDevice ,
343+ startWithVideoMuted : ! videoDevice ,
329344 } as any ,
330345 jwt : jwt ,
331346 } ;
332347
333348 // Video channel widgets need some more tailored config options
334349 if ( isVideoChannel ) {
335- // Ensure that we start on Jitsi Meet's native prejoin screen, for
336- // deployments that skip straight to the conference by default
337- options . configOverwrite . prejoinConfig = { enabled : true } ;
350+ // Ensure that we skip Jitsi Meet's native prejoin screen, for
351+ // deployments that have it enabled
352+ options . configOverwrite . prejoinConfig = { enabled : false } ;
338353 // Use a simplified set of toolbar buttons
339354 options . configOverwrite . toolbarButtons = [
340355 "microphone" , "camera" , "desktop" , "tileview" , "hangup" ,
0 commit comments