Merge branch 'develop' into action-button
This commit is contained in:
commit
2812387650
6
front/dist/index.html
vendored
6
front/dist/index.html
vendored
@ -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>
|
||||||
|
17
front/dist/resources/style/style.css
vendored
17
front/dist/resources/style/style.css
vendored
@ -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 {
|
||||||
|
@ -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> {
|
||||||
|
@ -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)
|
||||||
}));
|
}));
|
||||||
|
@ -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();
|
||||||
|
6
website/package-lock.json
generated
6
website/package-lock.json
generated
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user