diff --git a/front/.gitignore b/front/.gitignore index e207e30a..e77b54d0 100644 --- a/front/.gitignore +++ b/front/.gitignore @@ -1,5 +1,6 @@ /node_modules/ /dist/bundle.js +/dist/tests/ /yarn-error.log /dist/webpack.config.js /dist/webpack.config.js.map diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index cc8f0d7c..10e16cfa 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -918,3 +918,31 @@ div.modal-report-user{ background-color: #ffffff; } + +/** Action button **/ +div.action{ + position: absolute; + width: 100%; + height: auto; + text-align: center; + bottom: 40px; + transition: all .5s ease; + animation: mymove .5s; + animation-iteration-count: infinite; + animation-timing-function: ease-in-out; +} +div.action p.action-body{ + padding: 10px; + background-color: #2d2d2dba; + color: #fff; + font-size: 12px; + text-align: center; + max-width: 150px; + margin-left: calc(50% - 75px); + border-radius: 15px; +} +@keyframes mymove { + 0% {bottom: 40px;} + 50% {bottom: 30px;} + 100% {bottom: 40px;} +} \ No newline at end of file diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 20eded64..45fb6a06 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -31,7 +31,12 @@ import {Queue} from 'queue-typescript'; import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; import {loadAllLayers, loadObject, loadPlayerCharacters} from "../Entity/body_character"; -import {CenterListener, layoutManager, LayoutMode} from "../../WebRtc/LayoutManager"; +import { + CenterListener, + layoutManager, + LayoutMode, + ON_ACTION_TRIGGER_BUTTON, TRIGGER_JITSI_PROPERTIES, TRIGGER_WEBSITE_PROPERTIES +} from "../../WebRtc/LayoutManager"; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; import CanvasTexture = Phaser.Textures.CanvasTexture; @@ -576,23 +581,49 @@ export class GameScene extends ResizableScene implements CenterListener { } private triggerOnMapLayerPropertyChange(){ - this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue) => { + this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue, allProps) => { if (newValue === undefined) { + layoutManager.removeActionButton('openWebsite', this.userInputManager); coWebsiteManager.closeCoWebsite(); - } else { - coWebsiteManager.loadCoWebsite(newValue as string); + }else{ + const openWebsiteFunction = () => { + coWebsiteManager.loadCoWebsite(newValue as string); + layoutManager.removeActionButton('openWebsite', this.userInputManager); + }; + + const openWebsiteTriggerValue = allProps.get(TRIGGER_WEBSITE_PROPERTIES); + if(openWebsiteTriggerValue && openWebsiteTriggerValue === ON_ACTION_TRIGGER_BUTTON) { + layoutManager.addActionButton('openWebsite', 'Click on SPACE to open the web site', () => { + openWebsiteFunction(); + }, this.userInputManager); + }else{ + openWebsiteFunction(); + } } }); this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => { if (newValue === undefined) { + layoutManager.removeActionButton('jitsiRoom', this.userInputManager); this.stopJitsi(); - } else { - if (JITSI_PRIVATE_MODE) { - const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; + }else{ + const openJitsiRoomFunction = () => { + if (JITSI_PRIVATE_MODE) { + const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; - this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); - } else { - this.startJitsi(newValue as string); + this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); + } else { + this.startJitsi(newValue as string); + } + layoutManager.removeActionButton('jitsiRoom', this.userInputManager); + } + + const jitsiTriggerValue = allProps.get(TRIGGER_JITSI_PROPERTIES); + if(jitsiTriggerValue && jitsiTriggerValue === ON_ACTION_TRIGGER_BUTTON) { + layoutManager.addActionButton('jitsiRoom', 'Click on SPACE to enter in jitsi meet room', () => { + openJitsiRoomFunction(); + }, this.userInputManager); + }else{ + openJitsiRoomFunction(); } } }) @@ -621,7 +652,7 @@ export class GameScene extends ResizableScene implements CenterListener { this.chatModeSprite.setFrame(3); } } - + private initStartXAndStartY() { // If there is an init position passed if (this.initPosition !== null) { @@ -677,7 +708,7 @@ export class GameScene extends ResizableScene implements CenterListener { if (!properties) { return undefined; } - const obj = properties.find((property: ITiledMapLayerProperty) => property.name === name); + const obj = properties.find((property: ITiledMapLayerProperty) => property.name.toLowerCase() === name.toLowerCase()); if (obj === undefined) { return undefined; } diff --git a/front/src/Phaser/UserInput/UserInputManager.ts b/front/src/Phaser/UserInput/UserInputManager.ts index 636783bc..c8d91609 100644 --- a/front/src/Phaser/UserInput/UserInputManager.ts +++ b/front/src/Phaser/UserInput/UserInputManager.ts @@ -79,4 +79,11 @@ export class UserInputManager { return event; }); } + + addSpaceEventListner(callback : Function){ + this.Scene.input.keyboard.addListener('keyup-SPACE', callback); + } + removeSpaceEventListner(callback : Function){ + this.Scene.input.keyboard.removeListener('keyup-SPACE', callback); + } } diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index 88e247d7..736b5244 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -63,6 +63,9 @@ class JitsiFactory { } public async stop(): Promise { + if(!this.jitsiApi){ + return; + } await coWebsiteManager.closeCoWebsite(); this.jitsiApi.removeListener('audioMuteStatusChanged', this.audioCallback); this.jitsiApi.removeListener('videoMuteStatusChanged', this.videoCallback); diff --git a/front/src/WebRtc/LayoutManager.ts b/front/src/WebRtc/LayoutManager.ts index dc013563..a6b9fa27 100644 --- a/front/src/WebRtc/LayoutManager.ts +++ b/front/src/WebRtc/LayoutManager.ts @@ -1,3 +1,4 @@ +import { UserInputManager } from "../Phaser/UserInput/UserInputManager"; import {HtmlUtils} from "./HtmlUtils"; export enum LayoutMode { @@ -22,6 +23,10 @@ export interface CenterListener { onCenterChange(): void; } +export const ON_ACTION_TRIGGER_BUTTON = 'onaction'; +export const TRIGGER_WEBSITE_PROPERTIES = 'openWebsiteTrigger'; +export const TRIGGER_JITSI_PROPERTIES = 'jitsiTrigger'; + /** * This class is in charge of the video-conference layout. * It receives positioning requests for videos and does its best to place them on the screen depending on the active layout mode. @@ -33,6 +38,9 @@ class LayoutManager { private normalDivs: Map = new Map(); private listener: CenterListener|null = null; + private actionButtonTrigger: Map = new Map(); + private actionButtonInformation: Map = new Map(); + public setListener(centerListener: CenterListener|null) { this.listener = centerListener; } @@ -305,6 +313,48 @@ class LayoutManager { } } } + + public addActionButton(id: string, text: string, callBack: Function, userInputManager: UserInputManager){ + //delete previous element + this.removeActionButton(id, userInputManager); + + //create div and text html component + const p = document.createElement('p'); + p.classList.add('action-body'); + p.innerText = text; + + const div = document.createElement('div'); + div.classList.add('action'); + div.id = id; + div.appendChild(p); + + this.actionButtonInformation.set(id, div); + + const mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); + mainContainer.appendChild(div); + + const callBackFunctionTrigger = (() => { + console.log('user click on space => ', id); + callBack(); + }); + + //add trigger action + this.actionButtonTrigger.set(id, callBackFunctionTrigger); + userInputManager.addSpaceEventListner(callBackFunctionTrigger); + } + + public removeActionButton(id: string, userInputManager: UserInputManager){ + //delete previous element + const previousDiv = this.actionButtonInformation.get(id); + if(previousDiv){ + previousDiv.remove(); + this.actionButtonInformation.delete(id); + } + const previousEventCallback = this.actionButtonTrigger.get(id); + if(previousEventCallback){ + userInputManager.removeSpaceEventListner(previousEventCallback); + } + } } const layoutManager = new LayoutManager(); diff --git a/maps/Floor0/floor0.json b/maps/Floor0/floor0.json index 7e6f179b..9d258f68 100644 --- a/maps/Floor0/floor0.json +++ b/maps/Floor0/floor0.json @@ -44,6 +44,11 @@ "name":"jitsiRoom", "type":"string", "value":"tcm-chillzone-2" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" }], "type":"tilelayer", "visible":true, @@ -61,7 +66,12 @@ { "name":"jitsiRoom", "type":"string", - "value":"tcm-chillzone-1" + "value":"tcm-chillzone-11" + }, + { + "name":"jitsiTrigger", + "type":"string", + "value":"onaction" }], "type":"tilelayer", "visible":true, @@ -128,6 +138,11 @@ "name":"openWebsite", "type":"string", "value":"https:\/\/app.swile.co\/" + }, + { + "name":"openWebsiteTrigger", + "type":"string", + "value":"onaction" }], "type":"tilelayer", "visible":true,