latest dev
This commit is contained in:
commit
e796503810
7
.github/workflows/continuous_integration.yml
vendored
7
.github/workflows/continuous_integration.yml
vendored
@ -62,18 +62,13 @@ jobs:
|
||||
working-directory: "front"
|
||||
|
||||
- name: "Pretty"
|
||||
run: yarn run pretty
|
||||
run: yarn run pretty-check
|
||||
working-directory: "front"
|
||||
|
||||
- name: "Jasmine"
|
||||
run: yarn test
|
||||
working-directory: "front"
|
||||
|
||||
# We will enable prettier checks on front in a few month, when most PRs without prettier have been merged
|
||||
# - name: "Prettier"
|
||||
# run: yarn run pretty-check
|
||||
# working-directory: "front"
|
||||
|
||||
continuous-integration-pusher:
|
||||
name: "Continuous Integration Pusher"
|
||||
|
||||
|
@ -2,7 +2,7 @@ import * as tg from "generic-type-guard";
|
||||
|
||||
export const isCloseCoWebsite = new tg.IsInterface()
|
||||
.withProperties({
|
||||
id: tg.isOptional(tg.isString)
|
||||
id: tg.isOptional(tg.isString),
|
||||
})
|
||||
.get();
|
||||
|
||||
|
@ -24,9 +24,7 @@ import type { EmbeddedWebsite } from "../iframe/Room/EmbeddedWebsite";
|
||||
import { isCreateEmbeddedWebsiteEvent } from "./EmbeddedWebsiteEvent";
|
||||
import type { LoadTilesetEvent } from "./LoadTilesetEvent";
|
||||
import { isLoadTilesetEvent } from "./LoadTilesetEvent";
|
||||
import type {
|
||||
MessageReferenceEvent,
|
||||
} from "./ui/TriggerActionMessageEvent";
|
||||
import type { MessageReferenceEvent } from "./ui/TriggerActionMessageEvent";
|
||||
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
|
||||
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
|
||||
import type { ChangeLayerEvent } from "./ChangeLayerEvent";
|
||||
@ -122,19 +120,19 @@ export const iframeQueryMapTypeGuards = {
|
||||
},
|
||||
openCoWebsite: {
|
||||
query: isOpenCoWebsiteEvent,
|
||||
answer: isCoWebsite
|
||||
answer: isCoWebsite,
|
||||
},
|
||||
getCoWebsites: {
|
||||
query: tg.isUndefined,
|
||||
answer: tg.isArray(isCoWebsite)
|
||||
answer: tg.isArray(isCoWebsite),
|
||||
},
|
||||
closeCoWebsite: {
|
||||
query: tg.isString,
|
||||
answer: tg.isUndefined
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
closeCoWebsites: {
|
||||
query: tg.isUndefined,
|
||||
answer: tg.isUndefined
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
triggerActionMessage: {
|
||||
query: isTriggerActionMessageEvent,
|
||||
|
@ -5,7 +5,7 @@ export const isOpenCoWebsiteEvent = new tg.IsInterface()
|
||||
url: tg.isString,
|
||||
allowApi: tg.isOptional(tg.isBoolean),
|
||||
allowPolicy: tg.isOptional(tg.isString),
|
||||
position: tg.isOptional(tg.isNumber)
|
||||
position: tg.isOptional(tg.isNumber),
|
||||
})
|
||||
.get();
|
||||
|
||||
|
@ -57,7 +57,7 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
|
||||
async getCoWebSites(): Promise<CoWebsite[]> {
|
||||
const result = await queryWorkadventure({
|
||||
type: "getCoWebsites",
|
||||
data: undefined
|
||||
data: undefined,
|
||||
});
|
||||
return result.map((cowebsiteEvent) => new CoWebsite(cowebsiteEvent.id, cowebsiteEvent.position));
|
||||
}
|
||||
|
@ -128,6 +128,10 @@ export abstract class Character extends Container {
|
||||
}
|
||||
|
||||
public addTextures(textures: string[], frame?: string | number): void {
|
||||
if (textures.length < 1) {
|
||||
throw new TextureError("no texture given");
|
||||
}
|
||||
|
||||
for (const texture of textures) {
|
||||
if (this.scene && !this.scene.textures.exists(texture)) {
|
||||
throw new TextureError("texture not found");
|
||||
|
@ -69,13 +69,11 @@ export const lazyLoadPlayerCharacterTextures = (
|
||||
}
|
||||
|
||||
//If the loading fail, we render the default model instead.
|
||||
return returnPromise
|
||||
.then((keys) =>
|
||||
keys.map((key) => {
|
||||
return typeof key !== "string" ? key.name : key;
|
||||
})
|
||||
)
|
||||
.catch(() => lazyLoadPlayerCharacterTextures(loadPlugin, ["color_22", "eyes_23"]));
|
||||
return returnPromise.then((keys) =>
|
||||
keys.map((key) => {
|
||||
return typeof key !== "string" ? key.name : key;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const getRessourceDescriptor = (
|
||||
|
@ -12,8 +12,7 @@ export type PropertyChangeCallback = (
|
||||
|
||||
export type layerChangeCallback = (
|
||||
layersChangedByAction: Array<ITiledMapLayer>,
|
||||
allLayersOnNewPosition: Array<ITiledMapLayer>,
|
||||
|
||||
allLayersOnNewPosition: Array<ITiledMapLayer>
|
||||
) => void;
|
||||
|
||||
/**
|
||||
@ -81,7 +80,7 @@ export class GameMap {
|
||||
}
|
||||
|
||||
private getLayersByKey(key: number): Array<ITiledMapLayer> {
|
||||
return this.flatLayers.filter(flatLayer => flatLayer.type === 'tilelayer' && flatLayer.data[key] !== 0);
|
||||
return this.flatLayers.filter((flatLayer) => flatLayer.type === "tilelayer" && flatLayer.data[key] !== 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,14 +133,13 @@ export class GameMap {
|
||||
const enterLayers = new Set(layersByNewKey);
|
||||
const leaveLayers = new Set(layersByOldKey);
|
||||
|
||||
enterLayers.forEach(layer => {
|
||||
enterLayers.forEach((layer) => {
|
||||
if (leaveLayers.has(layer)) {
|
||||
leaveLayers.delete(layer);
|
||||
enterLayers.delete(layer);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (enterLayers.size > 0) {
|
||||
const layerArray = Array.from(enterLayers);
|
||||
for (const callback of this.enterLayerCallbacks) {
|
||||
|
@ -1,37 +1,37 @@
|
||||
export enum GameMapProperties {
|
||||
ALLOW_API = 'allowApi',
|
||||
AUDIO_LOOP = 'audioLoop',
|
||||
AUDIO_VOLUME = 'audioVolume',
|
||||
COLLIDES = 'collides',
|
||||
DEFAULT = 'default',
|
||||
EXIT_URL = 'exitUrl',
|
||||
EXIT_SCENE_URL = 'exitSceneUrl',
|
||||
FONT_FAMILY = 'font-family',
|
||||
JITSI_ADMIN_ROOM_TAG = 'jitsiRoomAdminTag',
|
||||
JITSI_CONFIG = 'jitsiConfig',
|
||||
JITSI_INTERFACE_CONFIG = 'jitsiInterfaceConfig',
|
||||
JITSI_ROOM = 'jitsiRoom',
|
||||
JITSI_TRIGGER = 'jitsiTrigger',
|
||||
JITSI_TRIGGER_MESSAGE = 'jitsiTriggerMessage',
|
||||
JITSI_URL = 'jitsiUrl',
|
||||
JITSI_WIDTH = 'jitsiWidth',
|
||||
NAME = 'name',
|
||||
OPEN_TAB = 'openTab',
|
||||
OPEN_WEBSITE = 'openWebsite',
|
||||
OPEN_WEBSITE_ALLOW_API = 'openWebsiteAllowApi',
|
||||
OPEN_WEBSITE_POLICY = 'openWebsitePolicy',
|
||||
OPEN_WEBSITE_WIDTH = 'openWebsiteWidth',
|
||||
OPEN_WEBSITE_POSITION = 'openWebsitePosition',
|
||||
OPEN_WEBSITE_TRIGGER = 'openWebsiteTrigger',
|
||||
OPEN_WEBSITE_TRIGGER_MESSAGE = 'openWebsiteTriggerMessage',
|
||||
PLAY_AUDIO = 'playAudio',
|
||||
PLAY_AUDIO_LOOP = 'playAudioLoop',
|
||||
READABLE_BY = 'readableBy',
|
||||
SCRIPT = 'script',
|
||||
SILENT = 'silent',
|
||||
START = 'start',
|
||||
START_LAYER = 'startLayer',
|
||||
URL = 'url',
|
||||
WRITABLE_BY = 'writableBy',
|
||||
ZONE = 'zone',
|
||||
ALLOW_API = "allowApi",
|
||||
AUDIO_LOOP = "audioLoop",
|
||||
AUDIO_VOLUME = "audioVolume",
|
||||
COLLIDES = "collides",
|
||||
DEFAULT = "default",
|
||||
EXIT_URL = "exitUrl",
|
||||
EXIT_SCENE_URL = "exitSceneUrl",
|
||||
FONT_FAMILY = "font-family",
|
||||
JITSI_ADMIN_ROOM_TAG = "jitsiRoomAdminTag",
|
||||
JITSI_CONFIG = "jitsiConfig",
|
||||
JITSI_INTERFACE_CONFIG = "jitsiInterfaceConfig",
|
||||
JITSI_ROOM = "jitsiRoom",
|
||||
JITSI_TRIGGER = "jitsiTrigger",
|
||||
JITSI_TRIGGER_MESSAGE = "jitsiTriggerMessage",
|
||||
JITSI_URL = "jitsiUrl",
|
||||
JITSI_WIDTH = "jitsiWidth",
|
||||
NAME = "name",
|
||||
OPEN_TAB = "openTab",
|
||||
OPEN_WEBSITE = "openWebsite",
|
||||
OPEN_WEBSITE_ALLOW_API = "openWebsiteAllowApi",
|
||||
OPEN_WEBSITE_POLICY = "openWebsitePolicy",
|
||||
OPEN_WEBSITE_WIDTH = "openWebsiteWidth",
|
||||
OPEN_WEBSITE_POSITION = "openWebsitePosition",
|
||||
OPEN_WEBSITE_TRIGGER = "openWebsiteTrigger",
|
||||
OPEN_WEBSITE_TRIGGER_MESSAGE = "openWebsiteTriggerMessage",
|
||||
PLAY_AUDIO = "playAudio",
|
||||
PLAY_AUDIO_LOOP = "playAudioLoop",
|
||||
READABLE_BY = "readableBy",
|
||||
SCRIPT = "script",
|
||||
SILENT = "silent",
|
||||
START = "start",
|
||||
START_LAYER = "startLayer",
|
||||
URL = "url",
|
||||
WRITABLE_BY = "writableBy",
|
||||
ZONE = "zone",
|
||||
}
|
||||
|
@ -4,10 +4,8 @@ import { scriptUtils } from "../../Api/ScriptUtils";
|
||||
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
|
||||
import { coWebsiteManager, CoWebsiteState } from "../../WebRtc/CoWebsiteManager";
|
||||
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
|
||||
import { get } from 'svelte/store';
|
||||
import {
|
||||
ON_ACTION_TRIGGER_BUTTON, ON_ACTION_TRIGGER_DISABLE,
|
||||
} from "../../WebRtc/LayoutManager";
|
||||
import { get } from "svelte/store";
|
||||
import { ON_ACTION_TRIGGER_BUTTON, ON_ACTION_TRIGGER_DISABLE } from "../../WebRtc/LayoutManager";
|
||||
import type { ITiledMapLayer } from "../Map/ITiledMap";
|
||||
import { GameMapProperties } from "./GameMapProperties";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
@ -21,8 +19,8 @@ enum OpenCoWebsiteState {
|
||||
}
|
||||
|
||||
interface OpenCoWebsite {
|
||||
coWebsite: CoWebsite | undefined,
|
||||
state: OpenCoWebsiteState
|
||||
coWebsite: CoWebsite | undefined;
|
||||
state: OpenCoWebsiteState;
|
||||
}
|
||||
|
||||
export class GameMapPropertiesListener {
|
||||
@ -33,7 +31,7 @@ export class GameMapPropertiesListener {
|
||||
constructor(private scene: GameScene, private gameMap: GameMap) {}
|
||||
|
||||
register() {
|
||||
this.gameMap.onPropertyChange(GameMapProperties.OPEN_TAB, (newValue, oldvalue, allProps) => {
|
||||
this.gameMap.onPropertyChange(GameMapProperties.OPEN_TAB, (newValue, oldValue, allProps) => {
|
||||
if (newValue === undefined) {
|
||||
layoutManagerActionStore.removeAction("openTab");
|
||||
}
|
||||
@ -57,10 +55,10 @@ export class GameMapPropertiesListener {
|
||||
}
|
||||
});
|
||||
|
||||
// Open a new co-website by the property.
|
||||
// Open a new co-website by the property.
|
||||
this.gameMap.onEnterLayer((newLayers) => {
|
||||
const handler = () => {
|
||||
newLayers.forEach(layer => {
|
||||
newLayers.forEach((layer) => {
|
||||
if (!layer.properties) {
|
||||
return;
|
||||
}
|
||||
@ -73,8 +71,8 @@ export class GameMapPropertiesListener {
|
||||
let websiteTriggerProperty: string | undefined;
|
||||
let websiteTriggerMessageProperty: string | undefined;
|
||||
|
||||
layer.properties.forEach(property => {
|
||||
switch(property.name) {
|
||||
layer.properties.forEach((property) => {
|
||||
switch (property.name) {
|
||||
case GameMapProperties.OPEN_WEBSITE:
|
||||
openWebsiteProperty = property.value as string | undefined;
|
||||
break;
|
||||
@ -115,26 +113,28 @@ export class GameMapPropertiesListener {
|
||||
});
|
||||
|
||||
const openWebsiteFunction = () => {
|
||||
coWebsiteManager.loadCoWebsite(
|
||||
openWebsiteProperty as string,
|
||||
this.scene.MapUrlFile,
|
||||
allowApiProperty,
|
||||
websitePolicyProperty,
|
||||
websiteWidthProperty,
|
||||
websitePositionProperty,
|
||||
).then(coWebsite => {
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite);
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
this.coWebsitesActionTriggerByLayer.delete(layer);
|
||||
} else {
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite,
|
||||
state: OpenCoWebsiteState.OPENED
|
||||
});
|
||||
}
|
||||
});
|
||||
coWebsiteManager
|
||||
.loadCoWebsite(
|
||||
openWebsiteProperty as string,
|
||||
this.scene.MapUrlFile,
|
||||
allowApiProperty,
|
||||
websitePolicyProperty,
|
||||
websiteWidthProperty,
|
||||
websitePositionProperty
|
||||
)
|
||||
.then((coWebsite) => {
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite);
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
this.coWebsitesActionTriggerByLayer.delete(layer);
|
||||
} else {
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite,
|
||||
state: OpenCoWebsiteState.OPENED,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
layoutManagerActionStore.removeAction(actionUuid);
|
||||
};
|
||||
@ -186,7 +186,7 @@ export class GameMapPropertiesListener {
|
||||
// Close opened co-websites on leave the layer who contain the property.
|
||||
this.gameMap.onLeaveLayer((oldLayers) => {
|
||||
const handler = () => {
|
||||
oldLayers.forEach(layer => {
|
||||
oldLayers.forEach((layer) => {
|
||||
if (!layer.properties) {
|
||||
return;
|
||||
}
|
||||
@ -194,8 +194,8 @@ export class GameMapPropertiesListener {
|
||||
let openWebsiteProperty: string | undefined;
|
||||
let websiteTriggerProperty: string | undefined;
|
||||
|
||||
layer.properties.forEach(property => {
|
||||
switch(property.name) {
|
||||
layer.properties.forEach((property) => {
|
||||
switch (property.name) {
|
||||
case GameMapProperties.OPEN_WEBSITE:
|
||||
openWebsiteProperty = property.value as string | undefined;
|
||||
break;
|
||||
@ -245,9 +245,10 @@ export class GameMapPropertiesListener {
|
||||
return;
|
||||
}
|
||||
|
||||
const action = actionStore && actionStore.length > 0 ?
|
||||
actionStore.find(action => action.uuid === actionTriggerUuid) : undefined;
|
||||
|
||||
const action =
|
||||
actionStore && actionStore.length > 0
|
||||
? actionStore.find((action) => action.uuid === actionTriggerUuid)
|
||||
: undefined;
|
||||
|
||||
if (action) {
|
||||
layoutManagerActionStore.removeAction(actionTriggerUuid);
|
||||
|
@ -9,9 +9,7 @@ export interface LayoutManagerAction {
|
||||
userInputManager: UserInputManager | undefined;
|
||||
}
|
||||
|
||||
|
||||
function createLayoutManagerAction() {
|
||||
|
||||
const { subscribe, set, update } = writable<LayoutManagerAction[]>([]);
|
||||
|
||||
return {
|
||||
|
@ -144,51 +144,55 @@ class JitsiFactory {
|
||||
jitsiUrl?: string,
|
||||
jitsiWidth?: number
|
||||
): void {
|
||||
coWebsiteManager.addCoWebsite(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
|
||||
// after some time the URLs get so huge that loading the iframe
|
||||
// becomes slow and eventually breaks completely. Thus lets just
|
||||
// clear jitsi local storage before starting a new conference.
|
||||
window.localStorage.removeItem("jitsiLocalStorage");
|
||||
coWebsiteManager.addCoWebsite(
|
||||
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
|
||||
// after some time the URLs get so huge that loading the iframe
|
||||
// becomes slow and eventually breaks completely. Thus lets just
|
||||
// clear jitsi local storage before starting a new conference.
|
||||
window.localStorage.removeItem("jitsiLocalStorage");
|
||||
|
||||
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: JitsiOptions = {
|
||||
roomName: roomName,
|
||||
jwt: jwt,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
parentNode: cowebsiteDiv,
|
||||
configOverwrite: mergeConfig(config),
|
||||
interfaceConfigOverwrite: { ...defaultInterfaceConfig, ...interfaceConfig },
|
||||
};
|
||||
if (!options.jwt) {
|
||||
delete options.jwt;
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const doResolve = (): void => {
|
||||
const iframe = cowebsiteDiv.querySelector<HTMLIFrameElement>('[id*="jitsi" i]');
|
||||
if (iframe === null) {
|
||||
throw new Error("Could not find Jitsi Iframe");
|
||||
}
|
||||
resolve(iframe);
|
||||
const domain = jitsiUrl || JITSI_URL;
|
||||
if (domain === undefined) {
|
||||
throw new Error("Missing JITSI_URL environment variable or jitsiUrl parameter in the map.");
|
||||
}
|
||||
options.onload = () => doResolve(); //we want for the iframe to be loaded before triggering animations.
|
||||
setTimeout(() => doResolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load
|
||||
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||
this.jitsiApi.executeCommand("displayName", playerName);
|
||||
await this.loadJitsiScript(domain);
|
||||
|
||||
this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback);
|
||||
});
|
||||
}, jitsiWidth, 0);
|
||||
const options: JitsiOptions = {
|
||||
roomName: roomName,
|
||||
jwt: jwt,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
parentNode: cowebsiteDiv,
|
||||
configOverwrite: mergeConfig(config),
|
||||
interfaceConfigOverwrite: { ...defaultInterfaceConfig, ...interfaceConfig },
|
||||
};
|
||||
if (!options.jwt) {
|
||||
delete options.jwt;
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const doResolve = (): void => {
|
||||
const iframe = cowebsiteDiv.querySelector<HTMLIFrameElement>('[id*="jitsi" i]');
|
||||
if (iframe === null) {
|
||||
throw new Error("Could not find Jitsi Iframe");
|
||||
}
|
||||
resolve(iframe);
|
||||
};
|
||||
options.onload = () => doResolve(); //we want for the iframe to be loaded before triggering animations.
|
||||
setTimeout(() => doResolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load
|
||||
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||
this.jitsiApi.executeCommand("displayName", playerName);
|
||||
|
||||
this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback);
|
||||
});
|
||||
},
|
||||
jitsiWidth,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
public stop() {
|
||||
|
Loading…
Reference in New Issue
Block a user