From 199ed1266a1ce419d398e8c527acb5b65a4483fa Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sat, 24 Oct 2020 14:13:23 +0200 Subject: [PATCH 01/11] Switch off camera when user is not focused on WorkAdventure windows Feature to switch off camera when user is not focused on WorkAdventure windows after 10 seconds --- front/src/WebRtc/MediaManager.ts | 84 ++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 557f12fb..070f27f9 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -38,6 +38,9 @@ export class MediaManager { private cinemaBtn: HTMLDivElement; private monitorBtn: HTMLDivElement; + private previousConstraint : MediaStreamConstraints; + private timeoutBlurWindows?: NodeJS.Timeout; + constructor() { this.myCamVideo = this.getElementByIdOrFail('myCamVideo'); @@ -89,6 +92,23 @@ export class MediaManager { this.disableScreenSharing(); //update tracking }); + + this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia)); + window.addEventListener('blur', () => { + if(this.timeoutBlurWindows){ + clearTimeout(this.timeoutBlurWindows); + } + this.timeoutBlurWindows = setTimeout(() => { + this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia)); + this.disableCamera(); + }, 10000); + }); + window.addEventListener('focus', () => { + if(this.timeoutBlurWindows){ + clearTimeout(this.timeoutBlurWindows); + } + this.applyPreviousConfig(); + }); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -136,9 +156,7 @@ export class MediaManager { } private enableCamera() { - this.cinemaClose.style.display = "none"; - this.cinemaBtn.classList.remove("disabled"); - this.cinema.style.display = "block"; + this.enableCameraStyle(); this.constraintsMedia.video = videoConstraint; this.getCamera().then((stream: MediaStream) => { this.triggerUpdatedLocalStreamCallbacks(stream); @@ -146,11 +164,7 @@ export class MediaManager { } private async disableCamera() { - this.cinemaClose.style.display = "block"; - this.cinema.style.display = "none"; - this.cinemaBtn.classList.add("disabled"); - this.constraintsMedia.video = false; - this.myCamVideo.srcObject = null; + this.disableCameraStyle(); this.stopCamera(); if (this.constraintsMedia.audio !== false) { @@ -162,9 +176,7 @@ export class MediaManager { } private enableMicrophone() { - this.microphoneClose.style.display = "none"; - this.microphone.style.display = "block"; - this.microphoneBtn.classList.remove("disabled"); + this.enableMicrophoneStyle(); this.constraintsMedia.audio = true; this.getCamera().then((stream) => { @@ -173,10 +185,7 @@ export class MediaManager { } private async disableMicrophone() { - this.microphoneClose.style.display = "block"; - this.microphone.style.display = "none"; - this.microphoneBtn.classList.add("disabled"); - this.constraintsMedia.audio = false; + this.disableMicrophoneStyle(); this.stopMicrophone(); if (this.constraintsMedia.video !== false) { @@ -187,6 +196,51 @@ export class MediaManager { } } + private applyPreviousConfig() { + this.constraintsMedia = this.previousConstraint; + if(!this.constraintsMedia.video){ + this.disableCameraStyle(); + }else{ + this.enableCameraStyle(); + } + if(!this.constraintsMedia.audio){ + this.disableMicrophoneStyle() + }else{ + this.enableMicrophoneStyle() + } + + this.getCamera().then((stream: MediaStream) => { + this.triggerUpdatedLocalStreamCallbacks(stream); + }); + } + + private enableCameraStyle(){ + this.cinemaClose.style.display = "none"; + this.cinemaBtn.classList.remove("disabled"); + this.cinema.style.display = "block"; + } + + private disableCameraStyle(){ + this.cinemaClose.style.display = "block"; + this.cinema.style.display = "none"; + this.cinemaBtn.classList.add("disabled"); + this.constraintsMedia.video = false; + this.myCamVideo.srcObject = null; + } + + private enableMicrophoneStyle(){ + this.microphoneClose.style.display = "none"; + this.microphone.style.display = "block"; + this.microphoneBtn.classList.remove("disabled"); + } + + private disableMicrophoneStyle(){ + this.microphoneClose.style.display = "block"; + this.microphone.style.display = "none"; + this.microphoneBtn.classList.add("disabled"); + this.constraintsMedia.audio = false; + } + private enableScreenSharing() { this.monitorClose.style.display = "none"; this.monitor.style.display = "block"; From 69f3e511aba0a6c3d89c71ef93f20193bde9dc4c Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sat, 24 Oct 2020 14:40:51 +0200 Subject: [PATCH 02/11] Ping status camera and microphone --- front/src/WebRtc/MediaManager.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 070f27f9..28771f63 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -109,6 +109,7 @@ export class MediaManager { } this.applyPreviousConfig(); }); + this.pingCameraStatus(); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -619,6 +620,17 @@ export class MediaManager { mainContainer.appendChild(divReport); } + //ping always 30 seconds data on stream + private pingCameraStatus(){ + setTimeout(() => { + console.log('ping camera status'); + this.getCamera().then((stream: MediaStream) => { + this.triggerUpdatedLocalStreamCallbacks(stream); + this.pingCameraStatus(); + }); + }, 30000); + } + } From 997acd17ad8216ba2d4e0f641fa36823a2fdb0dc Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 26 Oct 2020 22:39:52 +0100 Subject: [PATCH 03/11] Update to use update function scene --- front/src/Phaser/Game/GameScene.ts | 7 ++-- front/src/WebRtc/MediaManager.ts | 60 +++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index bfc6402e..46efc5e5 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -324,7 +324,7 @@ export class GameScene extends ResizableScene implements CenterListener { // Let's alter browser history let path = this.room.id; if (this.room.hash) { - path += '#'+this.room.hash; + path += '#' + this.room.hash; } window.history.pushState({}, 'WorkAdventure', path); @@ -486,7 +486,7 @@ export class GameScene extends ResizableScene implements CenterListener { this.stopJitsi(); } else { if (JITSI_PRIVATE_MODE) { - const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined; + const adminTag = allProps.get("jitsiRoomAdminTag") as string | undefined; this.connection.emitQueryJitsiJwtMessage(this.instance.replace('/', '-') + "-" + newValue, adminTag); } else { @@ -634,7 +634,6 @@ export class GameScene extends ResizableScene implements CenterListener { this.gameMap.setPosition(event.x, event.y); }) - this.scene.wake(); this.scene.sleep(ReconnectingSceneName); @@ -973,6 +972,8 @@ export class GameScene extends ResizableScene implements CenterListener { this.scene.remove(this.scene.key); this.scene.start(nextSceneKey.key); } + + mediaManager.setLastUpdateScene(); } private checkToExit(): {key: string, hash: string} | null { diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 28771f63..1cb1bdbb 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -39,7 +39,10 @@ export class MediaManager { private monitorBtn: HTMLDivElement; private previousConstraint : MediaStreamConstraints; - private timeoutBlurWindows?: NodeJS.Timeout; + private focused : boolean = true; + + private lastUpdateScene : Date = new Date(); + private setTimeOutlastUpdateScene? : NodeJS.Timeout; constructor() { @@ -94,22 +97,30 @@ export class MediaManager { }); this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia)); - window.addEventListener('blur', () => { - if(this.timeoutBlurWindows){ - clearTimeout(this.timeoutBlurWindows); - } - this.timeoutBlurWindows = setTimeout(() => { - this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia)); - this.disableCamera(); - }, 10000); - }); - window.addEventListener('focus', () => { - if(this.timeoutBlurWindows){ - clearTimeout(this.timeoutBlurWindows); - } - this.applyPreviousConfig(); - }); this.pingCameraStatus(); + + this.checkActiveUser(); + } + + public setLastUpdateScene(){ + this.lastUpdateScene = new Date(); + } + + public blurCamera() { + if(!this.focused){ + return; + } + this.focused = false; + this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia)); + this.disableCamera(); + } + + public focusCamera() { + if(this.focused){ + return; + } + this.focused = true; + this.applyPreviousConfig(); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -631,7 +642,22 @@ export class MediaManager { }, 30000); } - + //check if user is active + private checkActiveUser(){ + if(this.setTimeOutlastUpdateScene){ + clearTimeout(this.setTimeOutlastUpdateScene); + } + this.setTimeOutlastUpdateScene = setTimeout(() => { + const now = new Date(); + //if last update is more of 10 sec + if( (now.getTime() - this.lastUpdateScene.getTime()) > 10000) { + this.blurCamera(); + }else{ + this.focusCamera(); + } + this.checkActiveUser(); + }, this.focused ? 10000 : 1000); + } } export const mediaManager = new MediaManager(); From df49ea856a9d446c9f87742443eb763bac2e7045 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 27 Oct 2020 20:51:11 +0100 Subject: [PATCH 04/11] Fix conflict error --- front/src/WebRtc/MediaManager.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 1cb1bdbb..672b09ae 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -167,7 +167,7 @@ export class MediaManager { gameOverlay.classList.remove('active'); } - private enableCamera() { + public enableCamera() { this.enableCameraStyle(); this.constraintsMedia.video = videoConstraint; this.getCamera().then((stream: MediaStream) => { @@ -175,7 +175,7 @@ export class MediaManager { }); } - private async disableCamera() { + public async disableCamera() { this.disableCameraStyle(); this.stopCamera(); @@ -187,7 +187,7 @@ export class MediaManager { } } - private enableMicrophone() { + public enableMicrophone() { this.enableMicrophoneStyle(); this.constraintsMedia.audio = true; @@ -196,7 +196,7 @@ export class MediaManager { }); } - private async disableMicrophone() { + public async disableMicrophone() { this.disableMicrophoneStyle(); this.stopMicrophone(); @@ -574,7 +574,7 @@ export class MediaManager { return elem as T; } - private showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ + public showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ //create report text area const mainContainer = this.getElementByIdOrFail('main-container'); From 47a049ecafd689ece1cb2e7fc1b4edc2a1ec6414 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Wed, 4 Nov 2020 12:42:33 +0100 Subject: [PATCH 05/11] Feedback comment @moufmouf --- front/src/WebRtc/MediaManager.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 672b09ae..37a23578 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -631,7 +631,10 @@ export class MediaManager { mainContainer.appendChild(divReport); } - //ping always 30 seconds data on stream + /** + * For some reasons, the microphone muted icon or the stream is not always up to date. + * Here, every 30 seconds, we are "reseting" the streams and sending again the constraints to the other peers via the data channel again (see SimplePeer::pushVideoToRemoteUser) + **/ private pingCameraStatus(){ setTimeout(() => { console.log('ping camera status'); From b8bafe9c7effb600a077b8f1025cc1e1e0e3b2e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Nov 2020 14:26:58 +0000 Subject: [PATCH 06/11] Bump dot-prop from 4.2.0 to 4.2.1 in /website Bumps [dot-prop](https://github.com/sindresorhus/dot-prop) from 4.2.0 to 4.2.1. - [Release notes](https://github.com/sindresorhus/dot-prop/releases) - [Commits](https://github.com/sindresorhus/dot-prop/compare/v4.2.0...v4.2.1) Signed-off-by: dependabot[bot] --- website/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 286ca3f0..947eb4ff 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -2251,9 +2251,9 @@ } }, "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz", + "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==", "dev": true, "requires": { "is-obj": "^1.0.0" From 62a1732e53c5f9a15ba7ae673a8068db7f3295e6 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 18 Nov 2020 08:40:42 +0100 Subject: [PATCH 07/11] wording changes --- website/dist/index.html | 96 +++++++++++++++++---- website/dist/static/images/facebook_bw.png | Bin 0 -> 1409 bytes website/dist/static/images/linkedin_bw.png | Bin 0 -> 1712 bytes website/dist/static/images/twitter_bw.png | Bin 0 -> 1455 bytes website/src/sass/styles.scss | 45 +++++----- 5 files changed, 100 insertions(+), 41 deletions(-) create mode 100644 website/dist/static/images/facebook_bw.png create mode 100644 website/dist/static/images/linkedin_bw.png create mode 100644 website/dist/static/images/twitter_bw.png diff --git a/website/dist/index.html b/website/dist/index.html index 1e06204a..167cea49 100644 --- a/website/dist/index.html +++ b/website/dist/index.html @@ -10,6 +10,9 @@ gtag('js', new Date()); gtag('config', 'UA-10196481-11'); + if (window.location.host.endsWith("localhost")){ + window['ga-disable-UA-10196481-11'] = true; + } @@ -82,22 +85,32 @@
-

Your workplace
but better

-

You are impatient to discover this new world? Click on "Work online" and meet new people or share this adventure with your colleagues and friends by clicking on "Work in private"

+

Meet your teammates

+

+ WorkAdventure preserves your social interaction while COVID is still out there. +

+

+ Stay connected with your teamworkers, by creating your own online workspace to work remotely. +

+

+ Stay connected with your clients by providing a dedicated digital place to organize meetings, workshops. +

+

+ Stay connected with your future collaborators by organizing online event. +

@@ -107,7 +120,7 @@
@@ -158,7 +171,7 @@

Click the button below to come and say hi!

- START IN PUBLIC MODE + TRY IT NOW !

@@ -166,10 +179,11 @@

You can also create a private room with your friends or your team !

To try, press button work in private

-

- - START WORKING IN PRIVATE -

+

+ + + CHOOSE YOU OWN MAP +

Don’t forget to activate your mic and camera, let’s play

@@ -179,7 +193,6 @@ @@ -82,22 +85,32 @@
-

Your workplace
but better

-

You are impatient to discover this new world? Click on "Work online" and meet new people or share this adventure with your colleagues and friends by clicking on "Work in private"

+

Meet your teammates

+

+ WorkAdventure preserves your social interaction while COVID is still out there. +

+

+ Stay connected with your teamworkers, by creating your own online workspace to work remotely. +

+

+ Stay connected with your clients by providing a dedicated digital place to organize meetings, workshops. +

+

+ Stay connected with your future collaborators by organizing online event. +

@@ -107,7 +120,7 @@
@@ -158,7 +171,7 @@

Click the button below to come and say hi!

- START IN PUBLIC MODE + TRY IT NOW !

@@ -166,10 +179,11 @@

You can also create a private room with your friends or your team !

To try, press button work in private

-

- - START WORKING IN PRIVATE -

+

+ + + CHOOSE YOU OWN MAP +

Don’t forget to activate your mic and camera, let’s play

@@ -179,7 +193,6 @@