Merge branch 'develop' of github.com:thecodingmachine/workadventure into use-tiled-objects
This commit is contained in:
commit
ecda1a21a0
@ -11,7 +11,7 @@ In order to create Jitsi meet zones:
|
|||||||
|
|
||||||
* You must create a specific object.
|
* You must create a specific object.
|
||||||
* Object must be of type "`area`"
|
* Object must be of type "`area`"
|
||||||
* In object 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 object 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 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 object (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).
|
You can have this object (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).
|
||||||
@ -86,3 +86,15 @@ and not
|
|||||||
{.alert.alert-info}
|
{.alert.alert-info}
|
||||||
When you use `jitsiUrl`, the targeted Jitsi instance must be public. You cannot use moderation features or the JWT
|
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.
|
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.
|
||||||
|
@ -15,14 +15,9 @@ export interface RoomRedirect {
|
|||||||
|
|
||||||
export class Room {
|
export class Room {
|
||||||
public readonly id: string;
|
public readonly id: string;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
private readonly isPublic: boolean;
|
|
||||||
private _authenticationMandatory: boolean = DISABLE_ANONYMOUS;
|
private _authenticationMandatory: boolean = DISABLE_ANONYMOUS;
|
||||||
private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER;
|
private _iframeAuthentication?: string = OPID_LOGIN_SCREEN_PROVIDER;
|
||||||
private _mapUrl: string | undefined;
|
private _mapUrl: string | undefined;
|
||||||
private instance: string | undefined;
|
|
||||||
private readonly _search: URLSearchParams;
|
private readonly _search: URLSearchParams;
|
||||||
private _contactPage: string | undefined;
|
private _contactPage: string | undefined;
|
||||||
private _group: string | null = null;
|
private _group: string | null = null;
|
||||||
@ -37,13 +32,6 @@ export class Room {
|
|||||||
if (this.id.startsWith("/")) {
|
if (this.id.startsWith("/")) {
|
||||||
this.id = this.id.substr(1);
|
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);
|
this._search = new URLSearchParams(roomUrl.search);
|
||||||
}
|
}
|
||||||
@ -84,8 +72,10 @@ export class Room {
|
|||||||
|
|
||||||
const currentRoom = new Room(baseUrl);
|
const currentRoom = new Room(baseUrl);
|
||||||
let instance: string = "global";
|
let instance: string = "global";
|
||||||
if (currentRoom.isPublic) {
|
if (currentRoom.id.startsWith("_/") || currentRoom.id.startsWith("*/")) {
|
||||||
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;
|
baseUrl.pathname = "/_/" + instance + "/" + absoluteExitSceneUrl.host + absoluteExitSceneUrl.pathname;
|
||||||
@ -151,31 +141,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 {
|
public isDisconnected(): boolean {
|
||||||
const alone = this._search.get("alone");
|
const alone = this._search.get("alone");
|
||||||
if (alone && alone !== "0" && alone.toLowerCase() !== "false") {
|
if (alone && alone !== "0" && alone.toLowerCase() !== "false") {
|
||||||
|
@ -16,6 +16,7 @@ export enum GameMapProperties {
|
|||||||
JITSI_TRIGGER_MESSAGE = "jitsiTriggerMessage",
|
JITSI_TRIGGER_MESSAGE = "jitsiTriggerMessage",
|
||||||
JITSI_URL = "jitsiUrl",
|
JITSI_URL = "jitsiUrl",
|
||||||
JITSI_WIDTH = "jitsiWidth",
|
JITSI_WIDTH = "jitsiWidth",
|
||||||
|
JITSI_NO_PREFIX = "jitsiNoPrefix",
|
||||||
NAME = "name",
|
NAME = "name",
|
||||||
OPEN_TAB = "openTab",
|
OPEN_TAB = "openTab",
|
||||||
OPEN_WEBSITE = "openWebsite",
|
OPEN_WEBSITE = "openWebsite",
|
||||||
|
@ -79,7 +79,11 @@ export class GameMapPropertiesListener {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const openJitsiRoomFunction = () => {
|
const openJitsiRoomFunction = () => {
|
||||||
const roomName = jitsiFactory.getRoomName(newValue.toString(), this.scene.instance);
|
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;
|
const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined;
|
||||||
|
|
||||||
if (JITSI_PRIVATE_MODE && !jitsiUrl) {
|
if (JITSI_PRIVATE_MODE && !jitsiUrl) {
|
||||||
|
@ -185,7 +185,6 @@ export class GameScene extends DirtyScene {
|
|||||||
private biggestAvailableAreaStoreUnsubscribe!: () => void;
|
private biggestAvailableAreaStoreUnsubscribe!: () => void;
|
||||||
MapUrlFile: string;
|
MapUrlFile: string;
|
||||||
roomUrl: string;
|
roomUrl: string;
|
||||||
instance: string;
|
|
||||||
|
|
||||||
currentTick!: number;
|
currentTick!: number;
|
||||||
lastSentTick!: number; // The last tick at which a position was sent.
|
lastSentTick!: number; // The last tick at which a position was sent.
|
||||||
@ -234,7 +233,6 @@ export class GameScene extends DirtyScene {
|
|||||||
});
|
});
|
||||||
this.Terrains = [];
|
this.Terrains = [];
|
||||||
this.groups = new Map<number, Sprite>();
|
this.groups = new Map<number, Sprite>();
|
||||||
this.instance = room.getInstance();
|
|
||||||
|
|
||||||
this.MapUrlFile = MapUrlFile;
|
this.MapUrlFile = MapUrlFile;
|
||||||
this.roomUrl = room.key;
|
this.roomUrl = room.key;
|
||||||
|
@ -9,4 +9,21 @@ export class StringUtils {
|
|||||||
}
|
}
|
||||||
return { x: values[0], y: values[1] };
|
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);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { get } from "svelte/store";
|
|||||||
import CancelablePromise from "cancelable-promise";
|
import CancelablePromise from "cancelable-promise";
|
||||||
import { gameManager } from "../Phaser/Game/GameManager";
|
import { gameManager } from "../Phaser/Game/GameManager";
|
||||||
import { jitsiParticipantsCountStore, userIsJitsiDominantSpeakerStore } from "../Stores/GameStore";
|
import { jitsiParticipantsCountStore, userIsJitsiDominantSpeakerStore } from "../Stores/GameStore";
|
||||||
|
import { StringUtils } from "../Utils/StringUtils";
|
||||||
|
|
||||||
interface jitsiConfigInterface {
|
interface jitsiConfigInterface {
|
||||||
startWithAudioMuted: boolean;
|
startWithAudioMuted: boolean;
|
||||||
@ -120,7 +121,7 @@ const slugify = (...args: (string | number)[]): string => {
|
|||||||
.replace(/[\u0300-\u036f]/g, "") // remove all previously split accents
|
.replace(/[\u0300-\u036f]/g, "") // remove all previously split accents
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.trim()
|
.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
|
.replace(/\s+/g, "-"); // separator
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,8 +136,8 @@ class JitsiFactory {
|
|||||||
/**
|
/**
|
||||||
* Slugifies the room name and prepends the room name with the instance
|
* Slugifies the room name and prepends the room name with the instance
|
||||||
*/
|
*/
|
||||||
public getRoomName(roomName: string, instance: string): string {
|
public getRoomName(roomName: string, roomId: string, addPrefix: boolean): string {
|
||||||
return slugify(instance.replace("/", "-") + "-" + roomName);
|
return slugify((addPrefix ? StringUtils.shortHash(roomId) + "-" : "") + roomName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(
|
public start(
|
||||||
|
@ -8,7 +8,8 @@ const report: NonNullable<Translation["report"]> = {
|
|||||||
block: "Blockiere diesen Nutzer",
|
block: "Blockiere diesen Nutzer",
|
||||||
},
|
},
|
||||||
title: "Melden",
|
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: {
|
message: {
|
||||||
title: "Deine Nachricht: ",
|
title: "Deine Nachricht: ",
|
||||||
empty: "Bitte Text eingeben.",
|
empty: "Bitte Text eingeben.",
|
||||||
|
@ -43,6 +43,11 @@
|
|||||||
"type":"string",
|
"type":"string",
|
||||||
"value":"{\"DEFAULT_BACKGROUND\":\"#77ee77\"}"
|
"value":"{\"DEFAULT_BACKGROUND\":\"#77ee77\"}"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name":"jitsiNoPrefix",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name":"jitsiRoom",
|
"name":"jitsiRoom",
|
||||||
"type":"string",
|
"type":"string",
|
||||||
@ -65,7 +70,7 @@
|
|||||||
"name":"floorLayer",
|
"name":"floorLayer",
|
||||||
"objects":[
|
"objects":[
|
||||||
{
|
{
|
||||||
"height":83.6666666666666,
|
"height":110.891622876526,
|
||||||
"id":1,
|
"id":1,
|
||||||
"name":"",
|
"name":"",
|
||||||
"rotation":0,
|
"rotation":0,
|
||||||
@ -73,14 +78,14 @@
|
|||||||
{
|
{
|
||||||
"fontfamily":"Sans Serif",
|
"fontfamily":"Sans Serif",
|
||||||
"pixelsize":13,
|
"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
|
"wrap":true
|
||||||
},
|
},
|
||||||
"type":"",
|
"type":"",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"width":315.4375,
|
"width":315.4375,
|
||||||
"x":2.28125,
|
"x":1.48051599382768,
|
||||||
"y":235.166666666667
|
"y":209.535838407429
|
||||||
}],
|
}],
|
||||||
"opacity":1,
|
"opacity":1,
|
||||||
"type":"objectgroup",
|
"type":"objectgroup",
|
||||||
|
Loading…
Reference in New Issue
Block a user