diff --git a/front/dist/resources/html/helpCameraSettings.html b/front/dist/resources/html/helpCameraSettings.html index 6ec6fbac..d1c0e04d 100644 --- a/front/dist/resources/html/helpCameraSettings.html +++ b/front/dist/resources/html/helpCameraSettings.html @@ -76,7 +76,7 @@ margin: 0px 20px; } #helpCameraSettings section p.err{ - color: red; + color: #ff0000; } #helpCameraSettings section ul{ margin: 6px; @@ -101,9 +101,11 @@
  • Please ensure that you have a camera AND microphone plugged into your computer.
  • Once you've followed these steps, please refresh this page.

    - +

    If you prefer to continue without allowing camera and microphone access, click on Continue

    +

    +
    diff --git a/front/dist/resources/objects/help-setting-camera-permission.png b/front/dist/resources/objects/help-setting-camera-permission-chrome.png similarity index 100% rename from front/dist/resources/objects/help-setting-camera-permission.png rename to front/dist/resources/objects/help-setting-camera-permission-chrome.png diff --git a/front/dist/resources/objects/help-setting-camera-permission-firefox.png b/front/dist/resources/objects/help-setting-camera-permission-firefox.png new file mode 100644 index 00000000..7144f88b Binary files /dev/null and b/front/dist/resources/objects/help-setting-camera-permission-firefox.png differ diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 4dabf5cd..9580719d 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -63,6 +63,8 @@ import CanvasTexture = Phaser.Textures.CanvasTexture; import GameObject = Phaser.GameObjects.GameObject; import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR; import {Subscription} from "rxjs"; +import {tryCatch} from "rxjs/internal-compatibility"; +import {HtmlUtils} from "../../WebRtc/HtmlUtils"; export interface GameSceneInitInterface { initPosition: PointInterface|null, @@ -100,6 +102,7 @@ interface DeleteGroupEventInterface { } const defaultStartLayerName = 'start'; +const helpCameraSettings = 'helpCameraSettings'; export class GameScene extends ResizableScene implements CenterListener { Terrains : Array; @@ -127,6 +130,8 @@ export class GameScene extends ResizableScene 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 helpCameraSettingsElement!: Phaser.GameObjects.DOMElement; //#700 + private helpCameraSettingsOpened: boolean = false; //#700 MapUrlFile: string; RoomId: string; @@ -207,6 +212,7 @@ export class GameScene extends ResizableScene implements CenterListener { this.load.spritesheet('layout_modes', 'resources/objects/layout_modes.png', {frameWidth: 32, frameHeight: 32}); this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); + this.load.html(helpCameraSettings, 'resources/html/helpCameraSettings.html'); //#700 addLoader(this); } @@ -544,6 +550,27 @@ export class GameScene extends ResizableScene implements CenterListener { //init user position and play trigger to check layers properties this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y); + + // #700 + const middleX = (window.innerWidth / 3) - (370*0.85); + this.helpCameraSettingsElement = this.add.dom(middleX, -800, undefined, {overflow: 'scroll'}).createFromCache(helpCameraSettings); + this.revealMenusAfterInit(this.helpCameraSettingsElement, helpCameraSettings); + this.helpCameraSettingsElement.addListener('click'); + this.helpCameraSettingsElement.on('click', (event:MouseEvent) => { + event.preventDefault(); + if((event?.target as HTMLInputElement).id === 'helpCameraSettingsFormRefresh') { + window.location.reload(); + }else if((event?.target as HTMLInputElement).id === 'helpCameraSettingsFormContinue') { + this.closeHelpCameraSettingsOpened(); + } + }); + if(this.helpCameraSettingsElement.parent){ + (this.helpCameraSettingsElement.parent as HTMLDivElement).style.overflow = 'scroll'; + } + + if(!mediaManager.constraintsMedia.audio || !mediaManager.constraintsMedia.video){ + this.openHelpCameraSettingsOpened(); //#700 + } }); } @@ -967,43 +994,44 @@ export class GameScene extends ResizableScene implements CenterListener { */ update(time: number, delta: number) : void { mediaManager.setLastUpdateScene(); - this.currentTick = time; - this.CurrentPlayer.moveUser(delta); + if(!this.helpCameraSettingsOpened) { + this.currentTick = time; + this.CurrentPlayer.moveUser(delta); - // Let's handle all events - while (this.pendingEvents.length !== 0) { - const event = this.pendingEvents.dequeue(); - switch (event.type) { - case "InitUserPositionEvent": - this.doInitUsersPosition(event.event); - break; - case "AddPlayerEvent": - this.doAddPlayer(event.event); - break; - case "RemovePlayerEvent": - this.doRemovePlayer(event.userId); - break; - case "UserMovedEvent": - this.doUpdatePlayerPosition(event.event); - break; - case "GroupCreatedUpdatedEvent": - this.doShareGroupPosition(event.event); - break; - case "DeleteGroupEvent": - this.doDeleteGroup(event.groupId); - break; + // Let's handle all events + while (this.pendingEvents.length !== 0) { + const event = this.pendingEvents.dequeue(); + switch (event.type) { + case "InitUserPositionEvent": + this.doInitUsersPosition(event.event); + break; + case "AddPlayerEvent": + this.doAddPlayer(event.event); + break; + case "RemovePlayerEvent": + this.doRemovePlayer(event.userId); + break; + case "UserMovedEvent": + this.doUpdatePlayerPosition(event.event); + break; + case "GroupCreatedUpdatedEvent": + this.doShareGroupPosition(event.event); + break; + case "DeleteGroupEvent": + this.doDeleteGroup(event.groupId); + break; + } } + // Let's move all users + const updatedPlayersPositions = this.playersPositionInterpolator.getUpdatedPositions(time); + updatedPlayersPositions.forEach((moveEvent: HasMovedEvent, userId: number) => { + const player: RemotePlayer | undefined = this.MapPlayersByKey.get(userId); + if (player === undefined) { + throw new Error('Cannot find player with ID "' + userId + '"'); + } + player.updatePosition(moveEvent); + }); } - - // Let's move all users - const updatedPlayersPositions = this.playersPositionInterpolator.getUpdatedPositions(time); - updatedPlayersPositions.forEach((moveEvent: HasMovedEvent, userId: number) => { - const player : RemotePlayer | undefined = this.MapPlayersByKey.get(userId); - if (player === undefined) { - throw new Error('Cannot find player with ID "' + userId +'"'); - } - player.updatePosition(moveEvent); - }); } /** @@ -1248,4 +1276,53 @@ export class GameScene extends ResizableScene implements CenterListener { }); } } + + //#700 + private openHelpCameraSettingsOpened(): void{ + HtmlUtils.getElementByIdOrFail('webRtcSetup').style.display = 'none'; + this.helpCameraSettingsOpened = true; + let middleY = (window.innerHeight / 3) - 275; + if(middleY < 0){ + middleY = 0; + } + let middleX = (window.innerWidth / 3) - 50; + if(middleX < 0){ + middleX = 0; + } + if(window.navigator.userAgent.indexOf('Firefox') != -1){ + HtmlUtils.getElementByIdOrFail('browserHelpSetting').innerHTML =''; + }else if(window.navigator.userAgent.indexOf('Chrome') != -1){ + HtmlUtils.getElementByIdOrFail('browserHelpSetting').innerHTML =''; + } + this.tweens.add({ + targets: this.helpCameraSettingsElement, + y: this.startY - (370/2), + x: this.startX - (400/2), + duration: 1000, + ease: 'Power3', + overflow: 'scroll' + }); + } + + private closeHelpCameraSettingsOpened(): void{ + const helpCameraSettingsInfo = this.helpCameraSettingsElement.getChildByID('helpCameraSettings') as HTMLParagraphElement; + helpCameraSettingsInfo.innerText = ''; + helpCameraSettingsInfo.style.display = 'none'; + this.helpCameraSettingsOpened = false; + this.tweens.add({ + targets: this.helpCameraSettingsElement, + y: -400, + duration: 1000, + ease: 'Power3', + overflow: 'scroll' + }); + } + + private revealMenusAfterInit(menuElement: Phaser.GameObjects.DOMElement, rootDomId: string) { + //Dom elements will appear inside the viewer screen when creating before being moved out of it, which create a flicker effect. + //To prevent this, we put a 'hidden' attribute on the root element, we remove it only after the init is done. + setTimeout(() => { + (menuElement.getChildByID(rootDomId) as HTMLElement).hidden = false; + }, 250); + } } diff --git a/front/src/Phaser/Login/EnableCameraScene.ts b/front/src/Phaser/Login/EnableCameraScene.ts index dffe1042..3354d931 100644 --- a/front/src/Phaser/Login/EnableCameraScene.ts +++ b/front/src/Phaser/Login/EnableCameraScene.ts @@ -16,7 +16,6 @@ enum LoginTextures { arrowUp = "arrow_up" } -const helpCameraSettings = 'helpCameraSettings'; export class EnableCameraScene extends Phaser.Scene { private textField!: TextField; @@ -35,8 +34,6 @@ export class EnableCameraScene extends Phaser.Scene { private soundMeterSprite!: SoundMeterSprite; private microphoneNameField!: TextField; private repositionCallback!: (this: Window, ev: UIEvent) => void; - private helpCameraSettingsElement!: Phaser.GameObjects.DOMElement; - private helpCameraSettingsOpened: boolean = false; constructor() { super({ @@ -52,7 +49,6 @@ export class EnableCameraScene extends Phaser.Scene { this.load.image(LoginTextures.arrowUp, "resources/objects/arrow_up.png"); // Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap this.load.bitmapFont(LoginTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); - this.load.html(helpCameraSettings, 'resources/html/helpCameraSettings.html'); } create() { @@ -112,27 +108,6 @@ export class EnableCameraScene extends Phaser.Scene { this.soundMeterSprite.setVisible(false); this.add.existing(this.soundMeterSprite); - const middleX = (window.innerWidth / 3) - (370*0.85); - this.helpCameraSettingsElement = this.add.dom(middleX, -800, undefined, {overflow: 'scroll'}).createFromCache(helpCameraSettings); - this.revealMenusAfterInit(this.helpCameraSettingsElement, helpCameraSettings); - this.helpCameraSettingsElement.addListener('click'); - this.helpCameraSettingsElement.on('click', (event:MouseEvent) => { - event.preventDefault(); - if((event?.target as HTMLInputElement).id !== 'helpCameraSettingsFormRefresh') { - return; - } - const permission: Element = this.helpCameraSettingsElement.getChildByID('permissionError'); - permission.innerHTML = ''; - return mediaManager.getCamera().then(() => { - window.location.reload(); - }).catch((err) => { - permission.innerHTML = err.message; - }); - }); - if(this.helpCameraSettingsElement.parent){ - (this.helpCameraSettingsElement.parent as HTMLDivElement).style.overflow = 'scroll'; - } - this.repositionCallback = this.reposition.bind(this); window.addEventListener('resize', this.repositionCallback); } @@ -175,9 +150,6 @@ export class EnableCameraScene extends Phaser.Scene { * Function called each time a camera is changed */ private setupStream(stream: MediaStream): void { - if(this.helpCameraSettingsOpened){ - return; - } const img = HtmlUtils.getElementByIdOrFail('webRtcSetupNoVideo'); img.style.display = 'none'; @@ -284,27 +256,19 @@ export class EnableCameraScene extends Phaser.Scene { mediaManager.setLastUpdateScene(); } - private login(): Promise { - return mediaManager.getCamera() - .then((mediaStream: MediaStream) => { - HtmlUtils.getElementByIdOrFail('webRtcSetup').style.display = 'none'; - this.soundMeter.stop(); - window.removeEventListener('resize', this.repositionCallback); - mediaManager.stopCamera(); - mediaManager.stopMicrophone(); - this.scene.sleep(EnableCameraSceneName) - gameManager.goToStartingMap(this.scene); - return mediaStream; - }).catch((err) => { - this.openHelpCameraSettingsOpened(); - throw err; - }); + private login(): void { + HtmlUtils.getElementByIdOrFail('webRtcSetup').style.display = 'none'; + this.soundMeter.stop(); + window.removeEventListener('resize', this.repositionCallback); + + mediaManager.stopCamera(); + mediaManager.stopMicrophone(); + + this.scene.sleep(EnableCameraSceneName) + gameManager.goToStartingMap(this.scene); } private async getDevices() { - if(this.helpCameraSettingsOpened){ - return; - } const mediaDeviceInfos = await navigator.mediaDevices.enumerateDevices(); for (const mediaDeviceInfo of mediaDeviceInfos) { if (mediaDeviceInfo.kind === 'audioinput') { @@ -316,36 +280,6 @@ export class EnableCameraScene extends Phaser.Scene { this.updateWebCamName(); } - private openHelpCameraSettingsOpened(): void{ - this.reset(); - HtmlUtils.getElementByIdOrFail('webRtcSetup').style.display = 'none'; - this.helpCameraSettingsOpened = true; - let middleY = (window.innerHeight / 3) - (495); - if(middleY < 0){ - middleY = 0; - } - let middleX = (window.innerWidth / 3) - (370*0.85); - if(middleX < 0){ - middleX = 0; - } - this.tweens.add({ - targets: this.helpCameraSettingsElement, - y: middleY, - x: middleX, - duration: 1000, - ease: 'Power3', - overflow: 'scroll' - }); - } - - private revealMenusAfterInit(menuElement: Phaser.GameObjects.DOMElement, rootDomId: string) { - //Dom elements will appear inside the viewer screen when creating before being moved out of it, which create a flicker effect. - //To prevent this, we put a 'hidden' attribute on the root element, we remove it only after the init is done. - setTimeout(() => { - (menuElement.getChildByID(rootDomId) as HTMLElement).hidden = false; - }, 250); - } - private reset(){ this.textField.destroy(); this.pressReturnField.destroy();