@@ -228,13 +228,20 @@ export interface UrlConfiguration {
228228 */
229229 waitForCallPickup : boolean ;
230230}
231+ interface IntentAndPlatformDerivedConfiguration {
232+ defaultAudioEnabled ?: boolean ;
233+ defaultVideoEnabled ?: boolean ;
234+ }
231235
232236// If you need to add a new flag to this interface, prefer a name that describes
233237// a specific behavior (such as 'confineToRoom'), rather than one that describes
234238// the situations that call for this behavior ('isEmbedded'). This makes it
235239// clearer what each flag means, and helps us avoid coupling Element Call's
236240// behavior to the needs of specific consumers.
237- export interface UrlParams extends UrlProperties , UrlConfiguration { }
241+ export interface UrlParams
242+ extends UrlProperties ,
243+ UrlConfiguration ,
244+ IntentAndPlatformDerivedConfiguration { }
238245
239246// This is here as a stopgap, but what would be far nicer is a function that
240247// takes a UrlParams and returns a query string. That would enable us to
@@ -310,6 +317,11 @@ class ParamParser {
310317 }
311318}
312319
320+ let urlParamCache : {
321+ search ?: string ;
322+ hash ?: string ;
323+ params ?: UrlParams ;
324+ } = { } ;
313325/**
314326 * Gets the app parameters for the current URL.
315327 * @param search The URL search string
@@ -319,7 +331,18 @@ class ParamParser {
319331export const getUrlParams = (
320332 search = window . location . search ,
321333 hash = window . location . hash ,
334+ /** Skipping the cache might be needed in tests, to allow recomputing based on mocked platform changes. */
335+ skipCache = false ,
322336) : UrlParams => {
337+ // Only run the param configuration if we do not yet have it cached for this url.
338+ if (
339+ urlParamCache . search === search &&
340+ urlParamCache . hash === hash &&
341+ urlParamCache . params &&
342+ ! skipCache
343+ ) {
344+ return urlParamCache . params ;
345+ }
323346 const parser = new ParamParser ( search , hash ) ;
324347
325348 const fontScale = parseFloat ( parser . getParam ( "fontScale" ) ?? "" ) ;
@@ -343,8 +366,7 @@ export const getUrlParams = (
343366 ? UserIntent . Unknown
344367 : ( parser . getEnumParam ( "intent" , UserIntent ) ?? UserIntent . Unknown ) ;
345368 // Here we only use constants and `platform` to determine the intent preset.
346- let intentPreset : UrlConfiguration ;
347- const inAppDefault = {
369+ let intentPreset : UrlConfiguration = {
348370 confineToRoom : true ,
349371 appPrompt : false ,
350372 preload : false ,
@@ -362,31 +384,22 @@ export const getUrlParams = (
362384 } ;
363385 switch ( intent ) {
364386 case UserIntent . StartNewCall :
365- intentPreset = {
366- ...inAppDefault ,
367- skipLobby : true ,
368- } ;
387+ intentPreset . skipLobby = true ;
369388 break ;
370389 case UserIntent . JoinExistingCall :
371- intentPreset = {
372- ...inAppDefault ,
373- skipLobby : false ,
374- } ;
390+ // On desktop this will be overridden based on which button was used to join the call
391+ intentPreset . skipLobby = false ;
375392 break ;
376393 case UserIntent . StartNewCallDM :
377- intentPreset = {
378- ...inAppDefault ,
379- skipLobby : true ,
380- autoLeaveWhenOthersLeft : true ,
381- waitForCallPickup : true ,
382- } ;
394+ intentPreset . skipLobby = true ;
395+ intentPreset . autoLeaveWhenOthersLeft = true ;
396+ intentPreset . waitForCallPickup = true ;
397+
383398 break ;
384399 case UserIntent . JoinExistingCallDM :
385- intentPreset = {
386- ...inAppDefault ,
387- skipLobby : true ,
388- autoLeaveWhenOthersLeft : true ,
389- } ;
400+ // On desktop this will be overridden based on which button was used to join the call
401+ intentPreset . skipLobby = true ;
402+ intentPreset . autoLeaveWhenOthersLeft = true ;
390403 break ;
391404 // Non widget usecase defaults
392405 default :
@@ -408,6 +421,24 @@ export const getUrlParams = (
408421 } ;
409422 }
410423
424+ const intentAndPlatformDerivedConfiguration : IntentAndPlatformDerivedConfiguration =
425+ { } ;
426+ // Desktop also includes web. Its anything that is not mobile.
427+ const desktopMobile = platform === "desktop" ? "desktop" : "mobile" ;
428+ switch ( desktopMobile ) {
429+ case "desktop" :
430+ case "mobile" :
431+ switch ( intent ) {
432+ case UserIntent . StartNewCall :
433+ case UserIntent . JoinExistingCall :
434+ case UserIntent . StartNewCallDM :
435+ case UserIntent . JoinExistingCallDM :
436+ intentAndPlatformDerivedConfiguration . defaultAudioEnabled = true ;
437+ intentAndPlatformDerivedConfiguration . defaultVideoEnabled = true ;
438+ break ;
439+ }
440+ }
441+
411442 const properties : UrlProperties = {
412443 widgetId,
413444 parentUrl,
@@ -460,11 +491,29 @@ export const getUrlParams = (
460491 autoLeaveWhenOthersLeft : parser . getFlag ( "autoLeave" ) ,
461492 } ;
462493
463- return {
494+ // Log the final configuration for debugging purposes.
495+ // This will only log when the cache is not yet set.
496+ logger . info (
497+ "UrlParams: final set of url params\n" ,
498+ "intent:" ,
499+ intent ,
500+ "\nproperties:" ,
501+ properties ,
502+ "configuration:" ,
503+ configuration ,
504+ "intentAndPlatformDerivedConfiguration:" ,
505+ intentAndPlatformDerivedConfiguration ,
506+ ) ;
507+
508+ const params = {
464509 ...properties ,
465510 ...intentPreset ,
466511 ...pickBy ( configuration , ( v ?: unknown ) => v !== undefined ) ,
512+ ...intentAndPlatformDerivedConfiguration ,
467513 } ;
514+ urlParamCache = { search, hash, params } ;
515+
516+ return params ;
468517} ;
469518
470519/**
0 commit comments