diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 610988ed..80bd99d4 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -107,6 +107,7 @@ class IframeListener { } else if (payload.type === 'openPopup' && isOpenPopupEvent(payload.data)) { this._openPopupStream.next(payload.data); } else if (payload.type === 'closePopup' && isClosePopupEvent(payload.data)) { + console.log(payload); this._closePopupStream.next(payload.data); } else if (payload.type === 'openTab' && isOpenTabEvent(payload.data)) { diff --git a/front/src/Api/iframe/ui.ts b/front/src/Api/iframe/ui.ts index 629d3c36..260bcb64 100644 --- a/front/src/Api/iframe/ui.ts +++ b/front/src/Api/iframe/ui.ts @@ -36,7 +36,7 @@ class WorkAdventureUiCommands extends IframeApiContribution void>(); @@ -63,7 +63,8 @@ class WorkAdventureUiCommands extends IframeApiContribution; + Terrains: Array; CurrentPlayer!: Player; MapPlayers!: Phaser.Physics.Arcade.Group; - MapPlayersByKey : Map = new Map(); + MapPlayersByKey: Map = new Map(); Map!: Phaser.Tilemaps.Tilemap; Layers!: Array; Objects!: Array; @@ -149,10 +149,10 @@ export class GameScene extends DirtyScene implements CenterListener { startY!: number; circleTexture!: CanvasTexture; circleRedTexture!: CanvasTexture; - pendingEvents: Queue = new Queue(); - private initPosition: PositionInterface|null = null; + pendingEvents: Queue = new Queue(); + private initPosition: PositionInterface | null = null; private playersPositionInterpolator = new PlayersPositionInterpolator(); - public connection: RoomConnection|undefined; + public connection: RoomConnection | undefined; private simplePeer!: SimplePeer; private GlobalMessageManager!: GlobalMessageManager; public ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager; @@ -161,7 +161,7 @@ export class GameScene extends DirtyScene implements CenterListener { // A promise that will resolve when the "create" method is called (signaling loading is ended) private createPromise: Promise; private createPromiseResolve!: (value?: void | PromiseLike) => void; - private iframeSubscriptionList! : Array; + private iframeSubscriptionList!: Array; private peerStoreUnsubscribe!: () => void; MapUrlFile: string; RoomId: string; @@ -181,22 +181,22 @@ export class GameScene extends DirtyScene implements CenterListener { private gameMap!: GameMap; private actionableItems: Map = new Map(); // The item that can be selected by pressing the space key. - private outlinedItem: ActionableItem|null = null; + private outlinedItem: ActionableItem | null = null; public userInputManager!: UserInputManager; - private isReconnecting: boolean|undefined = undefined; + private isReconnecting: boolean | undefined = undefined; private startLayerName!: string | null; private openChatIcon!: OpenChatIcon; private playerName!: string; private characterLayers!: string[]; - private companion!: string|null; - private messageSubscription: Subscription|null = null; - private popUpElements : Map = new Map(); - private originalMapUrl: string|undefined; - private pinchManager: PinchManager|undefined; + private companion!: string | null; + private messageSubscription: Subscription | null = null; + private popUpElements: Map = new Map(); + private originalMapUrl: string | undefined; + private pinchManager: PinchManager | undefined; private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time. private emoteManager!: EmoteManager; - constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) { + constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) { super({ key: customKey ?? room.id }); @@ -220,14 +220,14 @@ export class GameScene extends DirtyScene implements CenterListener { preload(): void { const localUser = localUserStore.getLocalUser(); const textures = localUser?.textures; - if (textures) { - for (const texture of textures) { + if(textures) { + for(const texture of textures) { loadCustomTexture(this.load, texture); } } this.load.image(openChatIconName, 'resources/objects/talk.png'); - if (touchScreenManager.supportTouchScreen) { + if(touchScreenManager.supportTouchScreen) { this.load.image(joystickBaseKey, joystickBaseImg); this.load.image(joystickThumbKey, joystickThumbImg); } @@ -238,11 +238,11 @@ export class GameScene extends DirtyScene implements CenterListener { this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => { // If we happen to be in HTTP and we are trying to load a URL in HTTPS only... (this happens only in dev environments) - if (window.location.protocol === 'http:' && file.src === this.MapUrlFile && file.src.startsWith('http:') && this.originalMapUrl === undefined) { + if(window.location.protocol === 'http:' && file.src === this.MapUrlFile && file.src.startsWith('http:') && this.originalMapUrl === undefined) { this.originalMapUrl = this.MapUrlFile; this.MapUrlFile = this.MapUrlFile.replace('http://', 'https://'); this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); - this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => { + this.load.on('filecomplete-tilemapJSON-' + this.MapUrlFile, (key: string, type: string, data: unknown) => { this.onMapLoad(data); }); return; @@ -252,11 +252,11 @@ export class GameScene extends DirtyScene implements CenterListener { // See https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure const url = new URL(file.src); const host = url.host.split(':')[0]; - if (window.location.protocol === 'https:' && file.src === this.MapUrlFile && (host === '127.0.0.1' || host === 'localhost' || host.endsWith('.localhost')) && this.originalMapUrl === undefined) { + if(window.location.protocol === 'https:' && file.src === this.MapUrlFile && (host === '127.0.0.1' || host === 'localhost' || host.endsWith('.localhost')) && this.originalMapUrl === undefined) { this.originalMapUrl = this.MapUrlFile; this.MapUrlFile = this.MapUrlFile.replace('https://', 'http://'); this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); - this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => { + this.load.on('filecomplete-tilemapJSON-' + this.MapUrlFile, (key: string, type: string, data: unknown) => { this.onMapLoad(data); }); return; @@ -269,14 +269,14 @@ export class GameScene extends DirtyScene implements CenterListener { }); }); this.load.scenePlugin('AnimatedTiles', AnimatedTiles, 'animatedTiles', 'animatedTiles'); - this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => { + this.load.on('filecomplete-tilemapJSON-' + this.MapUrlFile, (key: string, type: string, data: unknown) => { this.onMapLoad(data); }); //TODO strategy to add access token this.load.tilemapTiledJSON(this.MapUrlFile, this.MapUrlFile); // If the map has already been loaded as part of another GameScene, the "on load" event will not be triggered. // In this case, we check in the cache to see if the map is here and trigger the event manually. - if (this.cache.tilemap.exists(this.MapUrlFile)) { + if(this.cache.tilemap.exists(this.MapUrlFile)) { const data = this.cache.tilemap.get(this.MapUrlFile); this.onMapLoad(data); } @@ -303,7 +303,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.mapFile = data.data; const url = this.MapUrlFile.substr(0, this.MapUrlFile.lastIndexOf('/')); this.mapFile.tilesets.forEach((tileset) => { - if (typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') { + if(typeof tileset.name === 'undefined' || typeof tileset.image === 'undefined') { console.warn("Don't know how to handle tileset ", tileset) return; } @@ -314,15 +314,15 @@ export class GameScene extends DirtyScene implements CenterListener { // Scan the object layers for objects to load and load them. const objects = new Map(); - for (const layer of this.mapFile.layers) { - if (layer.type === 'objectgroup') { - for (const object of layer.objects) { - let objectsOfType: ITiledMapObject[]|undefined; - if (!objects.has(object.type)) { + for(const layer of this.mapFile.layers) { + if(layer.type === 'objectgroup') { + for(const object of layer.objects) { + let objectsOfType: ITiledMapObject[] | undefined; + if(!objects.has(object.type)) { objectsOfType = new Array(); } else { objectsOfType = objects.get(object.type); - if (objectsOfType === undefined) { + if(objectsOfType === undefined) { throw new Error('Unexpected object type not found'); } } @@ -332,12 +332,12 @@ export class GameScene extends DirtyScene implements CenterListener { } } - for (const [itemType, objectsOfType] of objects) { + for(const [itemType, objectsOfType] of objects) { // FIXME: we would ideally need for the loader to WAIT for the import to be performed, which means writing our own loader plugin. let itemFactory: ItemFactoryInterface; - switch (itemType) { + switch(itemType) { case 'computer': { const module = await import('../Items/Computer/computer'); itemFactory = module.default; @@ -345,7 +345,7 @@ export class GameScene extends DirtyScene implements CenterListener { } default: continue; - //throw new Error('Unsupported object type: "'+ itemType +'"'); + //throw new Error('Unsupported object type: "'+ itemType +'"'); } itemFactory.preload(this.load); @@ -359,7 +359,7 @@ export class GameScene extends DirtyScene implements CenterListener { const roomJoinedAnswer = await this.connectionAnswerPromise; - for (const object of objectsOfType) { + for(const object of objectsOfType) { // TODO: we should pass here a factory to create sprites (maybe?) // Do we have a state for this object? @@ -374,17 +374,17 @@ export class GameScene extends DirtyScene implements CenterListener { // Now, let's load the script, if any const scripts = this.getScriptUrls(this.mapFile); - for (const script of scripts) { + for(const script of scripts) { iframeListener.registerScript(script); } } //hook initialisation - init(initData : GameSceneInitInterface) { - if (initData.initPosition !== undefined) { + init(initData: GameSceneInitInterface) { + if(initData.initPosition !== undefined) { this.initPosition = initData.initPosition; //todo: still used? } - if (initData.initPosition !== undefined) { + if(initData.initPosition !== undefined) { this.isReconnecting = initData.reconnecting; } } @@ -397,14 +397,14 @@ export class GameScene extends DirtyScene implements CenterListener { urlManager.pushRoomIdToUrl(this.room); this.startLayerName = urlManager.getStartLayerNameFromUrl(); - if (touchScreenManager.supportTouchScreen) { + if(touchScreenManager.supportTouchScreen) { this.pinchManager = new PinchManager(this); } this.messageSubscription = worldFullMessageStream.stream.subscribe((message) => this.showWorldFullError(message)) const playerName = gameManager.getPlayerName(); - if (!playerName) { + if(!playerName) { throw 'playerName is not set'; } this.playerName = playerName; @@ -425,31 +425,31 @@ export class GameScene extends DirtyScene implements CenterListener { //add layer on map this.Layers = new Array(); let depth = -2; - for (const layer of this.gameMap.layersIterator) { - if (layer.type === 'tilelayer') { + for(const layer of this.gameMap.layersIterator) { + if(layer.type === 'tilelayer') { this.addLayer(this.Map.createLayer(layer.name, this.Terrains, 0, 0).setDepth(depth)); const exitSceneUrl = this.getExitSceneUrl(layer); - if (exitSceneUrl !== undefined) { + if(exitSceneUrl !== undefined) { this.loadNextGame(exitSceneUrl); } const exitUrl = this.getExitUrl(layer); - if (exitUrl !== undefined) { + if(exitUrl !== undefined) { this.loadNextGame(exitUrl); } } - if (layer.type === 'objectgroup' && layer.name === 'floorLayer') { + if(layer.type === 'objectgroup' && layer.name === 'floorLayer') { depth = DEPTH_OVERLAY_INDEX; } - if (layer.type === 'objectgroup') { - for (const object of layer.objects) { - if (object.text) { + if(layer.type === 'objectgroup') { + for(const object of layer.objects) { + if(object.text) { TextUtils.createTextFromITiledMapObject(this, object); } } } } - if (depth === -2) { + if(depth === -2) { throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at. This layer cannot be contained in a group.'); } @@ -466,7 +466,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.userInputManager = new UserInputManager(this); mediaManager.setUserInputManager(this.userInputManager); - if (localUserStore.getFullscreen()) { + if(localUserStore.getFullscreen()) { document.querySelector('body')?.requestFullscreen(); } @@ -480,16 +480,16 @@ export class GameScene extends DirtyScene implements CenterListener { this.initCirclesCanvas(); // Let's pause the scene if the connection is not established yet - if (!this.room.isDisconnected()) { - if (this.isReconnecting) { + if(!this.room.isDisconnected()) { + if(this.isReconnecting) { setTimeout(() => { this.scene.sleep(); this.scene.launch(ReconnectingSceneName); }, 0); - } else if (this.connection === undefined) { + } else if(this.connection === undefined) { // Let's wait 1 second before printing the "connecting" screen to avoid blinking setTimeout(() => { - if (this.connection === undefined) { + if(this.connection === undefined) { this.scene.sleep(); this.scene.launch(ReconnectingSceneName); } @@ -523,7 +523,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.listenToIframeEvents(); - if (!this.room.isDisconnected()) { + if(!this.room.isDisconnected()) { this.connect(); } @@ -532,11 +532,11 @@ export class GameScene extends DirtyScene implements CenterListener { let oldPeerNumber = 0; this.peerStoreUnsubscribe = peerStore.subscribe((peers) => { const newPeerNumber = peers.size; - if (newPeerNumber > oldPeerNumber) { + if(newPeerNumber > oldPeerNumber) { this.sound.play('audio-webrtc-in', { volume: 0.2 }); - } else if (newPeerNumber < oldPeerNumber) { + } else if(newPeerNumber < oldPeerNumber) { this.sound.play('audio-webrtc-out', { volume: 0.2 }); @@ -566,7 +566,7 @@ export class GameScene extends DirtyScene implements CenterListener { bottom: camera.scrollY + camera.height, }, this.companion - ).then((onConnect: OnConnectInterface) => { + ).then((onConnect: OnConnectInterface) => { this.connection = onConnect.connection; this.connection.onUserJoins((message: MessageUserJoined) => { @@ -583,7 +583,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.connection.onUserMoved((message: UserMovedMessage) => { const position = message.getPosition(); - if (position === undefined) { + if(position === undefined) { throw new Error('Position missing from UserMovedMessage'); } @@ -606,7 +606,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.connection.onGroupDeleted((groupId: number) => { try { this.deleteGroup(groupId); - } catch (e) { + } catch(e) { console.error(e); } }) @@ -632,7 +632,7 @@ export class GameScene extends DirtyScene implements CenterListener { this.connection.onActionableEvent((message => { const item = this.actionableItems.get(message.itemId); - if (item === undefined) { + if(item === undefined) { console.warn('Received an event about object "' + message.itemId + '" but cannot find this item on the map.'); return; } @@ -661,7 +661,7 @@ export class GameScene extends DirtyScene implements CenterListener { audioManager.decreaseVolume(); }, onDisconnect(userId: number) { - if (self.simplePeer.getNbConnections() === 0) { + if(self.simplePeer.getNbConnections() === 0) { self.presentationModeSprite.setVisible(false); self.chatModeSprite.setVisible(false); self.openChatIcon.setVisible(false); @@ -695,12 +695,12 @@ export class GameScene extends DirtyScene implements CenterListener { private initCirclesCanvas(): void { // Let's generate the circle for the group delimiter let circleElement = Object.values(this.textures.list).find((object: Texture) => object.key === 'circleSprite-white'); - if (circleElement) { + if(circleElement) { this.textures.remove('circleSprite-white'); } circleElement = Object.values(this.textures.list).find((object: Texture) => object.key === 'circleSprite-red'); - if (circleElement) { + if(circleElement) { this.textures.remove('circleSprite-red'); } @@ -719,14 +719,14 @@ export class GameScene extends DirtyScene implements CenterListener { const contextRed = this.circleRedTexture.context; contextRed.beginPath(); contextRed.arc(48, 48, 48, 0, 2 * Math.PI, false); - //context.lineWidth = 5; + //context.lineWidth = 5; contextRed.strokeStyle = '#ff0000'; contextRed.stroke(); this.circleRedTexture.refresh(); } - private safeParseJSONstring(jsonString: string|undefined, propertyName: string) { + private safeParseJSONstring(jsonString: string | undefined, propertyName: string) { try { return jsonString ? JSON.parse(jsonString) : {}; } catch(e) { @@ -735,18 +735,18 @@ export class GameScene extends DirtyScene implements CenterListener { } } - private triggerOnMapLayerPropertyChange(){ + private triggerOnMapLayerPropertyChange() { this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => { - if (newValue) this.onMapExit(newValue as string); + if(newValue) this.onMapExit(newValue as string); }); this.gameMap.onPropertyChange('exitUrl', (newValue, oldValue) => { - if (newValue) this.onMapExit(newValue as string); + if(newValue) this.onMapExit(newValue as string); }); this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue, allProps) => { - if (newValue === undefined) { + if(newValue === undefined) { layoutManager.removeActionButton('openWebsite', this.userInputManager); coWebsiteManager.closeCoWebsite(); - }else{ + } else { const openWebsiteFunction = () => { coWebsiteManager.loadCoWebsite(newValue as string, this.MapUrlFile, allProps.get('openWebsiteAllowApi') as boolean | undefined, allProps.get('openWebsitePolicy') as string | undefined); layoutManager.removeActionButton('openWebsite', this.userInputManager); @@ -755,27 +755,27 @@ export class GameScene extends DirtyScene implements CenterListener { const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); if(openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { let message = allProps.get(WEBSITE_MESSAGE_PROPERTIES); - if(message === undefined){ + if(message === undefined) { message = 'Press SPACE or touch here to open web site'; } layoutManager.addActionButton('openWebsite', message.toString(), () => { openWebsiteFunction(); }, this.userInputManager); - }else{ + } else { openWebsiteFunction(); } } }); this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => { - if (newValue === undefined) { + if(newValue === undefined) { layoutManager.removeActionButton('jitsiRoom', this.userInputManager); this.stopJitsi(); - }else{ + } else { const openJitsiRoomFunction = () => { const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance); - const jitsiUrl = allProps.get("jitsiUrl") as string|undefined; - if (JITSI_PRIVATE_MODE && !jitsiUrl) { - const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; + 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); } else { @@ -787,27 +787,27 @@ export class GameScene extends DirtyScene implements CenterListener { const jitsiTriggerValue = allProps.get(TRIGGER_JITSI_PROPERTIES); if(jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { let message = allProps.get(JITSI_MESSAGE_PROPERTIES); - if (message === undefined) { + if(message === undefined) { message = 'Press SPACE or touch here to enter Jitsi Meet room'; } layoutManager.addActionButton('jitsiRoom', message.toString(), () => { openJitsiRoomFunction(); }, this.userInputManager); - }else{ + } else { openJitsiRoomFunction(); } } }); this.gameMap.onPropertyChange('silent', (newValue, oldValue) => { - if (newValue === undefined || newValue === false || newValue === '') { + if(newValue === undefined || newValue === false || newValue === '') { this.connection?.setSilent(false); } else { this.connection?.setSilent(true); } }); this.gameMap.onPropertyChange('playAudio', (newValue, oldValue, allProps) => { - const volume = allProps.get(AUDIO_VOLUME_PROPERTY) as number|undefined; - const loop = allProps.get(AUDIO_LOOP_PROPERTY) as boolean|undefined; + const volume = allProps.get(AUDIO_VOLUME_PROPERTY) as number | undefined; + const loop = allProps.get(AUDIO_LOOP_PROPERTY) as boolean | undefined; newValue === undefined ? audioManager.unloadAudio() : audioManager.playAudio(newValue, this.getMapDirUrl(), volume, loop); }); // TODO: This legacy property should be removed at some point @@ -816,7 +816,7 @@ export class GameScene extends DirtyScene implements CenterListener { }); this.gameMap.onPropertyChange('zone', (newValue, oldValue) => { - if (newValue === undefined || newValue === false || newValue === '') { + if(newValue === undefined || newValue === false || newValue === '') { iframeListener.sendLeaveEvent(oldValue as string); } else { @@ -826,13 +826,13 @@ export class GameScene extends DirtyScene implements CenterListener { } private listenToIframeEvents(): void { - this.iframeSubscriptionList = []; - this.iframeSubscriptionList.push(iframeListener.openPopupStream.subscribe((openPopupEvent) => { + this.iframeSubscriptionList = []; + this.iframeSubscriptionList.push(iframeListener.openPopupStream.subscribe((openPopupEvent) => { - let objectLayerSquare : ITiledMapObject; + let objectLayerSquare: ITiledMapObject; const targetObjectData = this.getObjectLayerData(openPopupEvent.targetObject); - if (targetObjectData !== undefined){ - objectLayerSquare = targetObjectData; + if(targetObjectData !== undefined) { + objectLayerSquare = targetObjectData; } else { console.error("Error while opening a popup. Cannot find an object on the map with name '" + openPopupEvent.targetObject + "'. The first parameter of WA.openPopup() must be the name of a rectangle object in your map."); return; @@ -840,22 +840,22 @@ export class GameScene extends DirtyScene implements CenterListener { const escapedMessage = HtmlUtils.escapeHtml(openPopupEvent.message); let html = `