Merge branch 'develop' into action-button

This commit is contained in:
Gregoire Parant 2020-11-23 20:08:19 +01:00
commit 2812387650
6 changed files with 178 additions and 31 deletions

View File

@ -72,7 +72,11 @@
</div> </div>
</div> </div>
<div id="cowebsite" class="cowebsite hidden"></div> <div id="cowebsite" class="cowebsite hidden">
<button class="close-btn" id="cowebsite-close">
<img src="resources/logos/close.svg"/>
</button>
</div>
<div class="audio-playing"> <div class="audio-playing">
<img src="/resources/logos/megaphone.svg"/> <img src="/resources/logos/megaphone.svg"/>
</div> </div>

View File

@ -284,6 +284,23 @@ body {
#cowebsite.hidden { #cowebsite.hidden {
transform: translateX(100%); transform: translateX(100%);
} }
#cowebsite .close-btn{
position: absolute;
top: 10px;
right: -100px;
background: none;
border: none;
cursor: pointer;
animation: right .2s ease;
}
#cowebsite .close-btn img{
height: 15px;
right: 15px;
}
#cowebsite:hover .close-btn{
right: 10px;
}
} }
@media (max-aspect-ratio: 1/1) { @media (max-aspect-ratio: 1/1) {
.game-overlay { .game-overlay {

View File

@ -932,6 +932,7 @@ export class GameScene extends ResizableScene implements CenterListener {
* @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/ */
update(time: number, delta: number) : void { update(time: number, delta: number) : void {
mediaManager.setLastUpdateScene();
this.currentTick = time; this.currentTick = time;
this.CurrentPlayer.moveUser(delta); this.CurrentPlayer.moveUser(delta);
@ -1227,12 +1228,19 @@ export class GameScene extends ResizableScene implements CenterListener {
jitsiFactory.start(roomName, gameManager.getPlayerName(), jwt); jitsiFactory.start(roomName, gameManager.getPlayerName(), jwt);
this.connection.setSilent(true); this.connection.setSilent(true);
mediaManager.hideGameOverlay(); mediaManager.hideGameOverlay();
//permit to stop jitsi when user close iframe
mediaManager.addTriggerCloseJitsiFrameButton('close-jisi',() => {
this.stopJitsi();
});
} }
public stopJitsi(): void { public stopJitsi(): void {
this.connection.setSilent(false); this.connection.setSilent(false);
jitsiFactory.stop(); jitsiFactory.stop();
mediaManager.showGameOverlay(); mediaManager.showGameOverlay();
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
} }
private loadSpritesheet(name: string, url: string): Promise<void> { private loadSpritesheet(name: string, url: string): Promise<void> {

View File

@ -44,7 +44,9 @@ class CoWebsiteManager {
public loadCoWebsite(url: string): void { public loadCoWebsite(url: string): void {
this.load(); this.load();
this.cowebsiteDiv.innerHTML = ''; this.cowebsiteDiv.innerHTML = `<button class="close-btn" id="cowebsite-close">
<img src="resources/logos/close.svg">
</button>`;
const iframe = document.createElement('iframe'); const iframe = document.createElement('iframe');
iframe.id = 'cowebsite-iframe'; iframe.id = 'cowebsite-iframe';
@ -83,7 +85,9 @@ class CoWebsiteManager {
this.close(); this.close();
this.fire(); this.fire();
setTimeout(() => { setTimeout(() => {
this.cowebsiteDiv.innerHTML = ''; this.cowebsiteDiv.innerHTML = `<button class="close-btn" id="cowebsite-close">
<img src="resources/logos/close.svg">
</button>`;
resolve(); resolve();
}, animationTime) }, animationTime)
})); }));

View File

@ -40,12 +40,20 @@ export class MediaManager {
private cinemaBtn: HTMLDivElement; private cinemaBtn: HTMLDivElement;
private monitorBtn: HTMLDivElement; private monitorBtn: HTMLDivElement;
private previousConstraint : MediaStreamConstraints;
private focused : boolean = true;
private lastUpdateScene : Date = new Date();
private setTimeOutlastUpdateScene? : NodeJS.Timeout;
private discussionManager: DiscussionManager; private discussionManager: DiscussionManager;
private userInputManager?: UserInputManager; private userInputManager?: UserInputManager;
private hasCamera = true; private hasCamera = true;
private triggerCloseJistiFrame : Map<String, Function> = new Map<String, Function>();
constructor() { constructor() {
this.myCamVideo = HtmlUtils.getElementByIdOrFail<HTMLVideoElement>('myCamVideo'); this.myCamVideo = HtmlUtils.getElementByIdOrFail<HTMLVideoElement>('myCamVideo');
@ -98,9 +106,35 @@ export class MediaManager {
//update tracking //update tracking
}); });
this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia));
this.pingCameraStatus();
this.checkActiveUser();
this.discussionManager = new DiscussionManager(this,''); this.discussionManager = new DiscussionManager(this,'');
} }
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 { public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void {
this.updatedLocalStreamCallBacks.add(callback); this.updatedLocalStreamCallBacks.add(callback);
} }
@ -138,20 +172,27 @@ export class MediaManager {
public showGameOverlay(){ public showGameOverlay(){
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay'); const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
gameOverlay.classList.add('active'); gameOverlay.classList.add('active');
const buttonCloseFrame = HtmlUtils.getElementByIdOrFail('cowebsite-close');
const functionTrigger = () => {
this.triggerCloseJitsiFrameButton();
}
buttonCloseFrame.removeEventListener('click', functionTrigger);
} }
public hideGameOverlay(){ public hideGameOverlay(){
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay'); const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
gameOverlay.classList.remove('active'); gameOverlay.classList.remove('active');
const buttonCloseFrame = HtmlUtils.getElementByIdOrFail('cowebsite-close');
const functionTrigger = () => {
this.triggerCloseJitsiFrameButton();
}
buttonCloseFrame.addEventListener('click', functionTrigger);
} }
public enableCamera() { public enableCamera() {
if(!this.hasCamera){ this.enableCameraStyle();
return;
}
this.cinemaClose.style.display = "none";
this.cinemaBtn.classList.remove("disabled");
this.cinema.style.display = "block";
this.constraintsMedia.video = videoConstraint; this.constraintsMedia.video = videoConstraint;
this.getCamera().then((stream: MediaStream) => { this.getCamera().then((stream: MediaStream) => {
this.triggerUpdatedLocalStreamCallbacks(stream); this.triggerUpdatedLocalStreamCallbacks(stream);
@ -159,7 +200,8 @@ export class MediaManager {
} }
public async disableCamera() { public async disableCamera() {
this.disabledCameraView(); this.disableCameraStyle();
if (this.constraintsMedia.audio !== false) { if (this.constraintsMedia.audio !== false) {
const stream = await this.getCamera(); const stream = await this.getCamera();
this.triggerUpdatedLocalStreamCallbacks(stream); this.triggerUpdatedLocalStreamCallbacks(stream);
@ -168,19 +210,8 @@ export class MediaManager {
} }
} }
private disabledCameraView(){
this.cinemaClose.style.display = "block";
this.cinema.style.display = "none";
this.cinemaBtn.classList.add("disabled");
this.constraintsMedia.video = false;
this.myCamVideo.srcObject = null;
this.stopCamera();
}
public enableMicrophone() { public enableMicrophone() {
this.microphoneClose.style.display = "none"; this.enableMicrophoneStyle();
this.microphone.style.display = "block";
this.microphoneBtn.classList.remove("disabled");
this.constraintsMedia.audio = true; this.constraintsMedia.audio = true;
this.getCamera().then((stream) => { this.getCamera().then((stream) => {
@ -189,10 +220,7 @@ export class MediaManager {
} }
public async disableMicrophone() { public async disableMicrophone() {
this.microphoneClose.style.display = "block"; this.disableMicrophoneStyle();
this.microphone.style.display = "none";
this.microphoneBtn.classList.add("disabled");
this.constraintsMedia.audio = false;
this.stopMicrophone(); this.stopMicrophone();
if (this.constraintsMedia.video !== false) { if (this.constraintsMedia.video !== false) {
@ -203,6 +231,52 @@ 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;
this.stopCamera();
}
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() { private enableScreenSharing() {
this.monitorClose.style.display = "none"; this.monitorClose.style.display = "none";
this.monitor.style.display = "block"; this.monitor.style.display = "block";
@ -285,7 +359,7 @@ export class MediaManager {
return this.getLocalStream().catch(() => { return this.getLocalStream().catch(() => {
console.info('Error get camera, trying with video option at null'); console.info('Error get camera, trying with video option at null');
this.disabledCameraView(); this.disableCameraStyle();
return this.getLocalStream().then((stream : MediaStream) => { return this.getLocalStream().then((stream : MediaStream) => {
this.hasCamera = false; this.hasCamera = false;
return stream; return stream;
@ -594,6 +668,30 @@ export class MediaManager {
public removeParticipant(userId: number|string){ public removeParticipant(userId: number|string){
this.discussionManager.removeParticipant(userId); this.discussionManager.removeParticipant(userId);
} }
public addTriggerCloseJitsiFrameButton(id: String, Function: Function){
this.triggerCloseJistiFrame.set(id, Function);
}
public removeTriggerCloseJitsiFrameButton(id: String){
this.triggerCloseJistiFrame.delete(id);
}
private triggerCloseJitsiFrameButton(): void {
for (const callback of this.triggerCloseJistiFrame.values()) {
callback();
}
}
/**
* 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');
this.triggerUpdatedLocalStreamCallbacks(this.localStream);
this.pingCameraStatus();
}, 30000);
}
public addNewMessage(name: string, message: string, isMe: boolean = false){ public addNewMessage(name: string, message: string, isMe: boolean = false){
this.discussionManager.addMessage(name, message, isMe); this.discussionManager.addMessage(name, message, isMe);
@ -615,6 +713,22 @@ export class MediaManager {
public setUserInputManager(userInputManager : UserInputManager){ public setUserInputManager(userInputManager : UserInputManager){
this.discussionManager.setUserInputManager(userInputManager); this.discussionManager.setUserInputManager(userInputManager);
} }
//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(); export const mediaManager = new MediaManager();

View File

@ -2251,9 +2251,9 @@
} }
}, },
"dot-prop": { "dot-prop": {
"version": "4.2.0", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
"integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"is-obj": "^1.0.0" "is-obj": "^1.0.0"