Add a config.json option to skip the built-in Jitsi welcome screen (#21190)

* Add a config.json option to skip the built-in Jitsi welcome screen

Stop-gap for https://github.com/vector-im/element-web/issues/20503

* Spelling
This commit is contained in:
Travis Ralston 2022-02-28 11:02:03 -07:00 committed by GitHub
parent c8127dc4b6
commit 65adc3ba93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 1 deletions

View File

@ -123,7 +123,12 @@ For a good example, see https://develop.element.io/config.json.
`/.well-known/matrix/client` in its well-known location, and the JSON file `/.well-known/matrix/client` in its well-known location, and the JSON file
at that location has a key `m.vector.riot.jitsi`. In this case, the at that location has a key `m.vector.riot.jitsi`. In this case, the
configuration found in the well-known location is used instead. configuration found in the well-known location is used instead.
1. `jitsiWidget`: Options to change the built-in Jitsi widget behaviour. `jitsi` controls
how the widget gets created, but not how it behaves.
1. `skipBuiltInWelcomeScreen`: If you'd like to skip the default "Join Conference"
behaviour, set this to `true`. This will cause the widget to assume that there's
a Jitsi welcome screen set up and point the user towards that. Note that this can
cause the camera/microphone to flicker as "in use" while Jitsi tests the devices.
1. `enable_presence_by_hs_url`: The property key should be the URL of the homeserver 1. `enable_presence_by_hs_url`: The property key should be the URL of the homeserver
and its value defines whether to enable/disable the presence status display and its value defines whether to enable/disable the presence status display
from that homeserver. If no options are configured, presence is shown for all from that homeserver. If no options are configured, presence is shown for all

View File

@ -24,6 +24,8 @@ import {
import { ElementWidgetActions } from "matrix-react-sdk/src/stores/widgets/ElementWidgetActions"; import { ElementWidgetActions } from "matrix-react-sdk/src/stores/widgets/ElementWidgetActions";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { getVectorConfig } from "../getconfig";
// We have to trick webpack into loading our CSS for us. // We have to trick webpack into loading our CSS for us.
require("./index.scss"); require("./index.scss");
@ -50,9 +52,14 @@ let startAudioOnly: boolean;
let widgetApi: WidgetApi; let widgetApi: WidgetApi;
let meetApi: any; // JitsiMeetExternalAPI let meetApi: any; // JitsiMeetExternalAPI
let skipOurWelcomeScreen = false;
(async function() { (async function() {
try { try {
// Queue a config.json lookup asap, so we can use it later on. We want this to be concurrent with
// other setup work and therefore do not block.
const configPromise = getVectorConfig('..');
// The widget's options are encoded into the fragment to avoid leaking info to the server. // The widget's options are encoded into the fragment to avoid leaking info to the server.
const widgetQuery = new URLSearchParams(window.location.hash.substring(1)); const widgetQuery = new URLSearchParams(window.location.hash.substring(1));
// The widget spec on the other hand requires the widgetId and parentUrl to show up in the regular query string. // The widget spec on the other hand requires the widgetId and parentUrl to show up in the regular query string.
@ -110,6 +117,16 @@ let meetApi: any; // JitsiMeetExternalAPI
roomName = qsParam('roomName', true); roomName = qsParam('roomName', true);
startAudioOnly = qsParam('isAudioOnly', true) === "true"; startAudioOnly = qsParam('isAudioOnly', true) === "true";
// We've reached the point where we have to wait for the config, so do that then parse it.
const instanceConfig = await configPromise;
skipOurWelcomeScreen = instanceConfig?.['jitsiWidget']?.['skipBuiltInWelcomeScreen'] || false;
// If we're meant to skip our screen, skip to the part where we show Jitsi instead of us.
// We don't set up the call yet though as this might lead to failure without the widget API.
if (skipOurWelcomeScreen) {
toggleConferenceVisibility(true);
}
if (widgetApi) { if (widgetApi) {
await readyPromise; await readyPromise;
await widgetApi.setAlwaysOnScreen(false); // start off as detachable from the screen await widgetApi.setAlwaysOnScreen(false); // start off as detachable from the screen
@ -147,6 +164,11 @@ let meetApi: any; // JitsiMeetExternalAPI
); );
} }
// Now that everything should be set up, skip to the Jitsi splash screen if needed
if (skipOurWelcomeScreen) {
skipToJitsiSplashScreen();
}
enableJoinButton(); // always enable the button enableJoinButton(); // always enable the button
} catch (e) { } catch (e) {
logger.error("Error setting up Jitsi widget", e); logger.error("Error setting up Jitsi widget", e);
@ -160,10 +182,24 @@ function enableJoinButton() {
function switchVisibleContainers() { function switchVisibleContainers() {
inConference = !inConference; inConference = !inConference;
// Our welcome screen is managed by other code, so just don't switch to it ever
// if we're not supposed to.
if (!skipOurWelcomeScreen) {
toggleConferenceVisibility(inConference);
}
}
function toggleConferenceVisibility(inConference: boolean) {
document.getElementById("jitsiContainer").style.visibility = inConference ? 'unset' : 'hidden'; document.getElementById("jitsiContainer").style.visibility = inConference ? 'unset' : 'hidden';
document.getElementById("joinButtonContainer").style.visibility = inConference ? 'hidden' : 'unset'; document.getElementById("joinButtonContainer").style.visibility = inConference ? 'hidden' : 'unset';
} }
function skipToJitsiSplashScreen() {
// really just a function alias for self-documenting code
joinConference();
}
/** /**
* Create a JWT token fot jitsi openidtoken-jwt auth * Create a JWT token fot jitsi openidtoken-jwt auth
* *
@ -267,5 +303,9 @@ function joinConference() { // event handler bound in HTML
document.getElementById("jitsiContainer").innerHTML = ""; document.getElementById("jitsiContainer").innerHTML = "";
meetApi = null; meetApi = null;
if (skipOurWelcomeScreen) {
skipToJitsiSplashScreen();
}
}); });
} }