From ffb5823b2af1ffc0afb95648504e198a3d8bf90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 16 Mar 2021 20:37:12 +0100 Subject: [PATCH] Adding the ability to specify a custom Jitsi URL directly in the map This feature allows to add a "jitsiUrl" property in the map. As a result, you can use for a given Jitsi room a custom instance of Jitsi. Using "jitsiUrl" will only work with public Jitsi instances (authentication is not supported when "jitsiUrl" property is provided) The Jitsi external_api.js script is now lazily loaded. --- front/src/Phaser/Game/GameScene.ts | 6 +- front/src/WebRtc/JitsiFactory.ts | 38 +++++++++++- front/src/index.ts | 7 --- maps/tests/jitsi_custom_url.json | 94 ++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 maps/tests/jitsi_custom_url.json diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index a90cb6b1..24594a44 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -682,7 +682,8 @@ export class GameScene extends ResizableScene implements CenterListener { }else{ const openJitsiRoomFunction = () => { const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance); - if (JITSI_PRIVATE_MODE) { + const jitsiUrl = allProps.get("jitsiUrl") as string|undefined; + if (JITSI_PRIVATE_MODE && !jitsiUrl) { const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; this.connection.emitQueryJitsiJwtMessage(roomName, adminTag); @@ -1258,8 +1259,9 @@ export class GameScene extends ResizableScene implements CenterListener { const allProps = this.gameMap.getCurrentProperties(); const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined, 'jitsiConfig'); const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined, 'jitsiInterfaceConfig'); + const jitsiUrl = allProps.get("jitsiUrl") as string|undefined; - jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig); + jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl); this.connection.setSilent(true); mediaManager.hideGameOverlay(); diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 70ee66bf..983b08e2 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -72,6 +72,7 @@ class JitsiFactory { private audioCallback = this.onAudioChange.bind(this); private videoCallback = this.onVideoChange.bind(this); private previousConfigMeet? : jitsiConfigInterface; + private jitsiScriptLoaded: boolean = false; /** * Slugifies the room name and prepends the room name with the instance @@ -80,11 +81,11 @@ class JitsiFactory { return slugify(instance.replace('/', '-') + "-" + roomName); } - public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object): void { + public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object, jitsiUrl?: string): void { //save previous config this.previousConfigMeet = getDefaultConfig(); - coWebsiteManager.insertCoWebsite((cowebsiteDiv => { + coWebsiteManager.insertCoWebsite((async cowebsiteDiv => { // Jitsi meet external API maintains some data in local storage // which is sent via the appData URL parameter when joining a // conference. Problem is that this data grows indefinitely. Thus @@ -93,7 +94,12 @@ class JitsiFactory { // clear jitsi local storage before starting a new conference. window.localStorage.removeItem("jitsiLocalStorage"); - const domain = JITSI_URL; + const domain = jitsiUrl || JITSI_URL; + if (domain === undefined) { + throw new Error('Missing JITSI_URL environment variable or jitsiUrl parameter in the map.') + } + await this.loadJitsiScript(domain); + const options: any = { // eslint-disable-line @typescript-eslint/no-explicit-any roomName: roomName, jwt: jwt, @@ -157,6 +163,32 @@ class JitsiFactory { mediaManager.enableCamera(); } } + + private async loadJitsiScript(domain: string): Promise { + return new Promise((resolve, reject) => { + if (this.jitsiScriptLoaded) { + resolve(); + return; + } + + this.jitsiScriptLoaded = true; + + // Load Jitsi if the environment variable is set. + const jitsiScript = document.createElement('script'); + jitsiScript.src = 'https://' + domain + '/external_api.js'; + jitsiScript.onload = () => { + resolve(); + } + jitsiScript.onerror = () => { + reject(); + } + + document.head.appendChild(jitsiScript); + + }) + + + } } export const jitsiFactory = new JitsiFactory(); diff --git a/front/src/index.ts b/front/src/index.ts index 94b1df43..b1da5ce4 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -15,13 +15,6 @@ import {MenuScene} from "./Phaser/Menu/MenuScene"; import {localUserStore} from "./Connexion/LocalUserStore"; import {ErrorScene} from "./Phaser/Reconnecting/ErrorScene"; -// Load Jitsi if the environment variable is set. -if (JITSI_URL) { - const jitsiScript = document.createElement('script'); - jitsiScript.src = 'https://' + JITSI_URL + '/external_api.js'; - document.head.appendChild(jitsiScript); -} - const {width, height} = coWebsiteManager.getGameSize(); const valueGameQuality = localUserStore.getGameQualityValue(); diff --git a/maps/tests/jitsi_custom_url.json b/maps/tests/jitsi_custom_url.json new file mode 100644 index 00000000..65e3be9f --- /dev/null +++ b/maps/tests/jitsi_custom_url.json @@ -0,0 +1,94 @@ +{ "compressionlevel":-1, + "editorsettings": + { + "export": + { + "target":"." + } + }, + "height":10, + "infinite":false, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":10, + "id":1, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":5, + "name":"jitsiConf", + "opacity":1, + "properties":[ + { + "name":"jitsiRoom", + "type":"string", + "value":"myRoom" + }, + { + "name":"jitsiUrl", + "type":"string", + "value":"meet.jit.si" + }], + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":6, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.3.3", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.2, + "width":10 +} \ No newline at end of file