From 0f08e3d1b5785c7210f9c212c14bb141cfd179f4 Mon Sep 17 00:00:00 2001 From: Alban Bruder Date: Tue, 12 Apr 2022 12:14:25 -0400 Subject: [PATCH 1/8] Compute instance in pusher /map endpoint --- front/src/Connexion/Room.ts | 1 + messages/JsonMessages/MapDetailsData.ts | 1 + pusher/src/Controller/MapController.ts | 10 ++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index a76e3f31..a3be5f53 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -130,6 +130,7 @@ export class Room { this._canReport = data.canReport ?? false; this._loadingLogo = data.loadingLogo ?? undefined; this._loginSceneLogo = data.loginSceneLogo ?? undefined; + this.instance = data.instance; return new MapDetail(data.mapUrl); } else { console.log(data); diff --git a/messages/JsonMessages/MapDetailsData.ts b/messages/JsonMessages/MapDetailsData.ts index 5ee5432c..503ddbf1 100644 --- a/messages/JsonMessages/MapDetailsData.ts +++ b/messages/JsonMessages/MapDetailsData.ts @@ -13,6 +13,7 @@ export const isMapDetailsData = z.object({ roomSlug: z.nullable(z.string()), // deprecated contactPage: z.nullable(z.string()), group: z.nullable(z.string()), + instance: z.string(), iframeAuthentication: z.optional(z.nullable(z.string())), // The date (in ISO 8601 format) at which the room will expire diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index 19131a24..be910c09 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -76,6 +76,10 @@ export class MapController extends BaseHttpController { * type: string|null * description: The group this room is part of (maps the notion of "world" in WorkAdventure SAAS) * example: myorg/myworld + * instance: + * type: string + * description: The instance of this map. In a public URL: the second part of the URL (_/[instance]/map.json) + * example: global * iframeAuthentication: * type: string|null * description: The URL of the authentication Iframe @@ -111,14 +115,15 @@ export class MapController extends BaseHttpController { if (!ADMIN_API_URL) { const roomUrl = new URL(query.playUri); - const match = /\/_\/[^/]+\/(.+)/.exec(roomUrl.pathname); + const match = /\/_\/([^/]+)\/(.+)/.exec(roomUrl.pathname); if (!match) { res.status(404); res.json({}); return; } - const mapUrl = roomUrl.protocol + "//" + match[1]; + const instance = match[1]; + const mapUrl = roomUrl.protocol + "//" + match[2]; res.json({ mapUrl, @@ -128,6 +133,7 @@ export class MapController extends BaseHttpController { tags: [], contactPage: null, authenticationMandatory: DISABLE_ANONYMOUS, + instance, } as MapDetailsData); return; From 82be015fc53cd254956dbfe32e0cdc8a906b1166 Mon Sep 17 00:00:00 2001 From: Alban Bruder Date: Tue, 12 Apr 2022 12:28:36 -0400 Subject: [PATCH 2/8] Compute instance in back getMapDetails --- back/src/Model/GameRoom.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts index 5b1e13bf..ae907114 100644 --- a/back/src/Model/GameRoom.ts +++ b/back/src/Model/GameRoom.ts @@ -562,13 +562,14 @@ export class GameRoom { if (!ADMIN_API_URL) { const roomUrlObj = new URL(roomUrl); - const match = /\/_\/[^/]+\/(.+)/.exec(roomUrlObj.pathname); + const match = /\/_\/([^/]+)\/(.+)/.exec(roomUrlObj.pathname); if (!match) { console.error("Unexpected room URL", roomUrl); throw new Error('Unexpected room URL "' + roomUrl + '"'); } - const mapUrl = roomUrlObj.protocol + "//" + match[1]; + const instance = match[1]; + const mapUrl = roomUrlObj.protocol + "//" + match[2]; return { mapUrl, @@ -578,6 +579,7 @@ export class GameRoom { roomSlug: null, contactPage: null, group: null, + instance }; } From 6a202fff4918274ac4f058460a04332fe9aec0f5 Mon Sep 17 00:00:00 2001 From: Alban Bruder Date: Tue, 12 Apr 2022 12:31:13 -0400 Subject: [PATCH 3/8] run pretty --- back/src/Model/GameRoom.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts index ae907114..e12e307b 100644 --- a/back/src/Model/GameRoom.ts +++ b/back/src/Model/GameRoom.ts @@ -579,7 +579,7 @@ export class GameRoom { roomSlug: null, contactPage: null, group: null, - instance + instance, }; } From 1781b8423cefde9d49f54c2f0006366d2e3d78d0 Mon Sep 17 00:00:00 2001 From: Alban Bruder Date: Tue, 12 Apr 2022 12:56:48 -0400 Subject: [PATCH 4/8] Replace Room.getInstance with getter function --- front/src/Connexion/Room.ts | 40 +++++++++--------------------- front/src/Phaser/Game/GameScene.ts | 2 +- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index a3be5f53..a79e2604 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -22,7 +22,7 @@ export class Room { private _authenticationMandatory: boolean = DISABLE_ANONYMOUS; private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER; private _mapUrl: string | undefined; - private instance: string | undefined; + private _instance: string | undefined; private readonly _search: URLSearchParams; private _contactPage: string | undefined; private _group: string | null = null; @@ -85,7 +85,9 @@ export class Room { const currentRoom = new Room(baseUrl); let instance: string = "global"; if (currentRoom.isPublic) { - instance = currentRoom.getInstance(); + const match = /[_*]\/([^/]+)\/.+/.exec(currentRoom.id); + if (!match) throw new Error('Could not extract instance from "' + currentRoom.id + '"'); + instance = match[1]; } baseUrl.pathname = "/_/" + instance + "/" + absoluteExitSceneUrl.host + absoluteExitSceneUrl.pathname; @@ -130,7 +132,7 @@ export class Room { this._canReport = data.canReport ?? false; this._loadingLogo = data.loadingLogo ?? undefined; this._loginSceneLogo = data.loginSceneLogo ?? undefined; - this.instance = data.instance; + this._instance = data.instance; return new MapDetail(data.mapUrl); } else { console.log(data); @@ -152,31 +154,6 @@ export class Room { } } - /** - * Instance name is: - * - In a public URL: the second part of the URL ( _/[instance]/map.json) - * - In a private URL: [organizationId/worldId] - * - * @deprecated - */ - public getInstance(): string { - if (this.instance !== undefined) { - return this.instance; - } - - if (this.isPublic) { - const match = /[_*]\/([^/]+)\/.+/.exec(this.id); - if (!match) throw new Error('Could not extract instance from "' + this.id + '"'); - this.instance = match[1]; - return this.instance; - } else { - const match = /@\/([^/]+)\/([^/]+)\/.+/.exec(this.id); - if (!match) throw new Error('Could not extract instance from "' + this.id + '"'); - this.instance = match[1] + "/" + match[2]; - return this.instance; - } - } - public isDisconnected(): boolean { const alone = this._search.get("alone"); if (alone && alone !== "0" && alone.toLowerCase() !== "false") { @@ -234,6 +211,13 @@ export class Room { return this._group; } + get instance(): string { + if (!this._instance) { + throw new Error("Instance not fetched yet"); + } + return this._instance; + } + get expireOn(): Date | undefined { return this._expireOn; } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index ab8f572c..ffef7588 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -234,7 +234,7 @@ export class GameScene extends DirtyScene { }); this.Terrains = []; this.groups = new Map(); - this.instance = room.getInstance(); + this.instance = room.instance; this.MapUrlFile = MapUrlFile; this.roomUrl = room.key; From 184aeb354a1ddbbeaace1397bb3c3667cdc056bf Mon Sep 17 00:00:00 2001 From: Alban Bruder Date: Tue, 12 Apr 2022 13:28:41 -0400 Subject: [PATCH 5/8] Remove differentiation between private and public rooms --- front/src/Connexion/Room.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index a79e2604..9a2a3e52 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -15,10 +15,6 @@ export interface RoomRedirect { export class Room { public readonly id: string; - /** - * @deprecated - */ - private readonly isPublic: boolean; private _authenticationMandatory: boolean = DISABLE_ANONYMOUS; private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER; private _mapUrl: string | undefined; @@ -37,13 +33,6 @@ export class Room { if (this.id.startsWith("/")) { this.id = this.id.substr(1); } - if (this.id.startsWith("_/") || this.id.startsWith("*/")) { - this.isPublic = true; - } else if (this.id.startsWith("@/")) { - this.isPublic = false; - } else { - throw new Error("Invalid room ID"); - } this._search = new URLSearchParams(roomUrl.search); } @@ -84,7 +73,7 @@ export class Room { const currentRoom = new Room(baseUrl); let instance: string = "global"; - if (currentRoom.isPublic) { + if (currentRoom.id.startsWith("_/") || currentRoom.id.startsWith("*/")) { const match = /[_*]\/([^/]+)\/.+/.exec(currentRoom.id); if (!match) throw new Error('Could not extract instance from "' + currentRoom.id + '"'); instance = match[1]; From b89997c9f1a69e5da82b107a47291b53866d4b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 15 Apr 2022 21:12:00 +0200 Subject: [PATCH 6/8] Changes the prefix added in front of the jitsiRoomName Previously, the prefix was computed using the org/world (in SAAS) or the instance part of public URLs. Neither was guaranteeing the Jitsi Room would be unique accross rooms. The new system computes a hash of the room URL and prepends it to the jitsi room name. BREAKING CHANGE: this means the URL of the Jitsi room will change for all maps. Users having bookmarked the Jitsi room (for instance in the Jitsi mobile app) will need to update their bookmarks. --- back/src/Model/GameRoom.ts | 6 ++---- front/src/Connexion/Room.ts | 9 --------- .../Phaser/Game/GameMapPropertiesListener.ts | 2 +- front/src/Phaser/Game/GameScene.ts | 2 -- front/src/Utils/StringUtils.ts | 17 +++++++++++++++++ front/src/WebRtc/JitsiFactory.ts | 7 ++++--- messages/JsonMessages/MapDetailsData.ts | 1 - pusher/src/Controller/MapController.ts | 10 ++-------- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts index e12e307b..5b1e13bf 100644 --- a/back/src/Model/GameRoom.ts +++ b/back/src/Model/GameRoom.ts @@ -562,14 +562,13 @@ export class GameRoom { if (!ADMIN_API_URL) { const roomUrlObj = new URL(roomUrl); - const match = /\/_\/([^/]+)\/(.+)/.exec(roomUrlObj.pathname); + const match = /\/_\/[^/]+\/(.+)/.exec(roomUrlObj.pathname); if (!match) { console.error("Unexpected room URL", roomUrl); throw new Error('Unexpected room URL "' + roomUrl + '"'); } - const instance = match[1]; - const mapUrl = roomUrlObj.protocol + "//" + match[2]; + const mapUrl = roomUrlObj.protocol + "//" + match[1]; return { mapUrl, @@ -579,7 +578,6 @@ export class GameRoom { roomSlug: null, contactPage: null, group: null, - instance, }; } diff --git a/front/src/Connexion/Room.ts b/front/src/Connexion/Room.ts index 9a2a3e52..4e896572 100644 --- a/front/src/Connexion/Room.ts +++ b/front/src/Connexion/Room.ts @@ -18,7 +18,6 @@ export class Room { private _authenticationMandatory: boolean = DISABLE_ANONYMOUS; private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER; private _mapUrl: string | undefined; - private _instance: string | undefined; private readonly _search: URLSearchParams; private _contactPage: string | undefined; private _group: string | null = null; @@ -121,7 +120,6 @@ export class Room { this._canReport = data.canReport ?? false; this._loadingLogo = data.loadingLogo ?? undefined; this._loginSceneLogo = data.loginSceneLogo ?? undefined; - this._instance = data.instance; return new MapDetail(data.mapUrl); } else { console.log(data); @@ -200,13 +198,6 @@ export class Room { return this._group; } - get instance(): string { - if (!this._instance) { - throw new Error("Instance not fetched yet"); - } - return this._instance; - } - get expireOn(): Date | undefined { return this._expireOn; } diff --git a/front/src/Phaser/Game/GameMapPropertiesListener.ts b/front/src/Phaser/Game/GameMapPropertiesListener.ts index 1dffd434..449e8708 100644 --- a/front/src/Phaser/Game/GameMapPropertiesListener.ts +++ b/front/src/Phaser/Game/GameMapPropertiesListener.ts @@ -67,7 +67,7 @@ export class GameMapPropertiesListener { }); } else { const openJitsiRoomFunction = () => { - const roomName = jitsiFactory.getRoomName(newValue.toString(), this.scene.instance); + const roomName = jitsiFactory.getRoomName(newValue.toString(), this.scene.roomUrl); const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined; if (JITSI_PRIVATE_MODE && !jitsiUrl) { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index ffef7588..2d2b6d03 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -185,7 +185,6 @@ export class GameScene extends DirtyScene { private biggestAvailableAreaStoreUnsubscribe!: () => void; MapUrlFile: string; roomUrl: string; - instance: string; currentTick!: number; lastSentTick!: number; // The last tick at which a position was sent. @@ -234,7 +233,6 @@ export class GameScene extends DirtyScene { }); this.Terrains = []; this.groups = new Map(); - this.instance = room.instance; this.MapUrlFile = MapUrlFile; this.roomUrl = room.key; diff --git a/front/src/Utils/StringUtils.ts b/front/src/Utils/StringUtils.ts index 1f168c15..8c5f16db 100644 --- a/front/src/Utils/StringUtils.ts +++ b/front/src/Utils/StringUtils.ts @@ -9,4 +9,21 @@ export class StringUtils { } return { x: values[0], y: values[1] }; } + + /** + * Computes a "short URL" hash of the string passed in parameter. + */ + public static shortHash = function (s: string): string { + let hash = 0; + const strLength = s.length; + if (strLength === 0) { + return ""; + } + for (let i = 0; i < strLength; i++) { + const c = s.charCodeAt(i); + hash = (hash << 5) - hash + c; + hash = hash & hash; // Convert to 32bit integer + } + return Math.abs(hash).toString(36); + }; } diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 3d17b5b8..c8824f0e 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -5,6 +5,7 @@ import { get } from "svelte/store"; import CancelablePromise from "cancelable-promise"; import { gameManager } from "../Phaser/Game/GameManager"; import { jitsiParticipantsCountStore, userIsJitsiDominantSpeakerStore } from "../Stores/GameStore"; +import { StringUtils } from "../Utils/StringUtils"; interface jitsiConfigInterface { startWithAudioMuted: boolean; @@ -120,7 +121,7 @@ const slugify = (...args: (string | number)[]): string => { .replace(/[\u0300-\u036f]/g, "") // remove all previously split accents .toLowerCase() .trim() - .replace(/[^a-z0-9 ]/g, "") // remove all chars not letters, numbers and spaces (to be replaced) + .replace(/[^a-z0-9-_ ]/g, "") // remove all chars not letters, numbers, dash, underscores and spaces (to be replaced) .replace(/\s+/g, "-"); // separator }; @@ -135,8 +136,8 @@ class JitsiFactory { /** * Slugifies the room name and prepends the room name with the instance */ - public getRoomName(roomName: string, instance: string): string { - return slugify(instance.replace("/", "-") + "-" + roomName); + public getRoomName(roomName: string, roomId: string): string { + return slugify(StringUtils.shortHash(roomId) + "-" + roomName); } public start( diff --git a/messages/JsonMessages/MapDetailsData.ts b/messages/JsonMessages/MapDetailsData.ts index 503ddbf1..5ee5432c 100644 --- a/messages/JsonMessages/MapDetailsData.ts +++ b/messages/JsonMessages/MapDetailsData.ts @@ -13,7 +13,6 @@ export const isMapDetailsData = z.object({ roomSlug: z.nullable(z.string()), // deprecated contactPage: z.nullable(z.string()), group: z.nullable(z.string()), - instance: z.string(), iframeAuthentication: z.optional(z.nullable(z.string())), // The date (in ISO 8601 format) at which the room will expire diff --git a/pusher/src/Controller/MapController.ts b/pusher/src/Controller/MapController.ts index be910c09..19131a24 100644 --- a/pusher/src/Controller/MapController.ts +++ b/pusher/src/Controller/MapController.ts @@ -76,10 +76,6 @@ export class MapController extends BaseHttpController { * type: string|null * description: The group this room is part of (maps the notion of "world" in WorkAdventure SAAS) * example: myorg/myworld - * instance: - * type: string - * description: The instance of this map. In a public URL: the second part of the URL (_/[instance]/map.json) - * example: global * iframeAuthentication: * type: string|null * description: The URL of the authentication Iframe @@ -115,15 +111,14 @@ export class MapController extends BaseHttpController { if (!ADMIN_API_URL) { const roomUrl = new URL(query.playUri); - const match = /\/_\/([^/]+)\/(.+)/.exec(roomUrl.pathname); + const match = /\/_\/[^/]+\/(.+)/.exec(roomUrl.pathname); if (!match) { res.status(404); res.json({}); return; } - const instance = match[1]; - const mapUrl = roomUrl.protocol + "//" + match[2]; + const mapUrl = roomUrl.protocol + "//" + match[1]; res.json({ mapUrl, @@ -133,7 +128,6 @@ export class MapController extends BaseHttpController { tags: [], contactPage: null, authenticationMandatory: DISABLE_ANONYMOUS, - instance, } as MapDetailsData); return; From 8c5c680cfbcf3a84c0e5dab260c4d5256f7498bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Sat, 16 Apr 2022 11:36:10 +0200 Subject: [PATCH 7/8] Adding a new "jitsiNoPrefix" property. When set to "true", WorkAdventure will NOT prefix the Jitsi room name with a hash, gicing full control to the user over the Jitsi room name. --- docs/maps/meeting-rooms.md | 14 +++++++++++++- front/src/Phaser/Game/GameMapProperties.ts | 1 + front/src/Phaser/Game/GameMapPropertiesListener.ts | 6 +++++- front/src/WebRtc/JitsiFactory.ts | 4 ++-- maps/tests/jitsi_config.json | 13 +++++++++---- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/docs/maps/meeting-rooms.md b/docs/maps/meeting-rooms.md index 9c3963ed..bab732a5 100644 --- a/docs/maps/meeting-rooms.md +++ b/docs/maps/meeting-rooms.md @@ -10,7 +10,7 @@ On your map, you can define special zones (meeting rooms) that will trigger the In order to create Jitsi meet zones: * You must create a specific layer. -* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms) +* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with a hash of the room URL * You may also use "jitsiWidth" property (of type "number" between 0 and 100) to control the width of the iframe containing the meeting room. You can have this layer (i.e. your meeting area) to be selectable as the precise location for your meeting using the [Google Calendar integration for Work Adventure](/integrations/google-calendar). To do so, you must set the `meetingRoomLabel` property. You can provide any name that you would like your meeting room to have (as a string). @@ -82,3 +82,15 @@ and not {.alert.alert-info} When you use `jitsiUrl`, the targeted Jitsi instance must be public. You cannot use moderation features or the JWT tokens authentication with maps configured using the `jitsiUrl` property. + +## Full control over the Jitsi room name + +By default, the name of the room will be "slugified" and prepended with a hash of the room URL. +This is what you want most of the time. Indeed, different maps with the same Jitsi room name (the same `jitsiRoom` property) will not share the same Jitsi room instance. + +However, sometimes, you may actually want to have different WorkAdventure meeting rooms that are actually sharing +the same Jitsi meet meeting room. Or if you are pointing to a custom Jitsi server (using the `jitsiUrl` property), +you may want to point to a specific existing room. + +For all those use cases, you can use `jitsiNoPrefix: true`. This will remove the automatic prefixing +of the hash and will give you full control on the Jitsi room name. diff --git a/front/src/Phaser/Game/GameMapProperties.ts b/front/src/Phaser/Game/GameMapProperties.ts index b77bd02b..f25ea4b3 100644 --- a/front/src/Phaser/Game/GameMapProperties.ts +++ b/front/src/Phaser/Game/GameMapProperties.ts @@ -15,6 +15,7 @@ export enum GameMapProperties { JITSI_TRIGGER_MESSAGE = "jitsiTriggerMessage", JITSI_URL = "jitsiUrl", JITSI_WIDTH = "jitsiWidth", + JITSI_NO_PREFIX = "jitsiNoPrefix", NAME = "name", OPEN_TAB = "openTab", OPEN_WEBSITE = "openWebsite", diff --git a/front/src/Phaser/Game/GameMapPropertiesListener.ts b/front/src/Phaser/Game/GameMapPropertiesListener.ts index 449e8708..de6bdefe 100644 --- a/front/src/Phaser/Game/GameMapPropertiesListener.ts +++ b/front/src/Phaser/Game/GameMapPropertiesListener.ts @@ -67,7 +67,11 @@ export class GameMapPropertiesListener { }); } else { const openJitsiRoomFunction = () => { - const roomName = jitsiFactory.getRoomName(newValue.toString(), this.scene.roomUrl); + let addPrefix = true; + if (allProps.get(GameMapProperties.JITSI_NO_PREFIX)) { + addPrefix = false; + } + const roomName = jitsiFactory.getRoomName(newValue.toString(), this.scene.roomUrl, addPrefix); const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined; if (JITSI_PRIVATE_MODE && !jitsiUrl) { diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index c8824f0e..62800888 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -136,8 +136,8 @@ class JitsiFactory { /** * Slugifies the room name and prepends the room name with the instance */ - public getRoomName(roomName: string, roomId: string): string { - return slugify(StringUtils.shortHash(roomId) + "-" + roomName); + public getRoomName(roomName: string, roomId: string, addPrefix: boolean): string { + return slugify((addPrefix ? StringUtils.shortHash(roomId) + "-" : "") + roomName); } public start( diff --git a/maps/tests/jitsi_config.json b/maps/tests/jitsi_config.json index 9a812cc8..d0a446e1 100644 --- a/maps/tests/jitsi_config.json +++ b/maps/tests/jitsi_config.json @@ -43,6 +43,11 @@ "type":"string", "value":"{\"DEFAULT_BACKGROUND\":\"#77ee77\"}" }, + { + "name":"jitsiNoPrefix", + "type":"bool", + "value":true + }, { "name":"jitsiRoom", "type":"string", @@ -65,7 +70,7 @@ "name":"floorLayer", "objects":[ { - "height":83.6666666666666, + "height":110.891622876526, "id":1, "name":"", "rotation":0, @@ -73,14 +78,14 @@ { "fontfamily":"Sans Serif", "pixelsize":13, - "text":"Test:\nWalk on the carpet and press space\nResult:\nJitsi opens, background in green and audio\/video is muted", + "text":"Test:\nWalk on the carpet and press space\nResult:\nJitsi opens, background in green and audio\/video is muted.\nThe name of the room (displayed at the top of Jitsi) is \"Myroom Avec Espace EA\"", "wrap":true }, "type":"", "visible":true, "width":315.4375, - "x":2.28125, - "y":235.166666666667 + "x":1.48051599382768, + "y":209.535838407429 }], "opacity":1, "type":"objectgroup", From 638a32e1b01b0e577a7088a3b3fd4bd0d3732d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 19 Apr 2022 08:37:42 +0200 Subject: [PATCH 8/8] Fixing DE lang linting --- front/src/i18n/de-DE/report.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/front/src/i18n/de-DE/report.ts b/front/src/i18n/de-DE/report.ts index 438642eb..7ddb530f 100644 --- a/front/src/i18n/de-DE/report.ts +++ b/front/src/i18n/de-DE/report.ts @@ -8,7 +8,8 @@ const report: NonNullable = { block: "Blockiere diesen Nutzer", }, title: "Melden", - content: "Verfasse eine Beschwerde an die Administratoren dieses Raums. Diese können den Nutzer anschließend bannen.", + content: + "Verfasse eine Beschwerde an die Administratoren dieses Raums. Diese können den Nutzer anschließend bannen.", message: { title: "Deine Nachricht: ", empty: "Bitte Text eingeben.",