From b6fe9e72e1aaf3622471e094839271a51a72710b Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sun, 25 Oct 2020 19:38:00 +0100 Subject: [PATCH 01/18] Fix style and refactor --- front/dist/resources/style/style.css | 7 ++-- front/src/Phaser/Login/EnableCameraScene.ts | 24 ++++-------- front/src/WebRtc/MediaManager.ts | 43 ++++++++------------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 5f5d37f2..d0f0e68b 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -72,8 +72,9 @@ body .message-info.warning{ #div-myCamVideo { position: absolute; - right: 0; - bottom: 0; + right: 15px; + bottom: 15px; + border-radius: 15px; } video#myCamVideo{ @@ -419,7 +420,7 @@ body { max-height: 80%; top: -80%; left: 10%; - background: #000000a6; + background: #333333; z-index: 200; transition: all 0.1s ease-out; } diff --git a/front/src/Phaser/Login/EnableCameraScene.ts b/front/src/Phaser/Login/EnableCameraScene.ts index 32037858..56502704 100644 --- a/front/src/Phaser/Login/EnableCameraScene.ts +++ b/front/src/Phaser/Login/EnableCameraScene.ts @@ -7,6 +7,7 @@ import {mediaManager} from "../../WebRtc/MediaManager"; import {RESOLUTION} from "../../Enum/EnvironmentVariable"; import {SoundMeter} from "../Components/SoundMeter"; import {SoundMeterSprite} from "../Components/SoundMeterSprite"; +import {HtmlUtils} from "../../WebRtc/HtmlUtils"; export const EnableCameraSceneName = "EnableCameraScene"; enum LoginTextures { @@ -93,7 +94,7 @@ export class EnableCameraScene extends Phaser.Scene { this.login(); }); - this.getElementByIdOrFail('webRtcSetup').classList.add('active'); + HtmlUtils.getElementByIdOrFail('webRtcSetup').classList.add('active'); const mediaPromise = mediaManager.getCamera(); mediaPromise.then(this.getDevices.bind(this)); @@ -150,10 +151,10 @@ export class EnableCameraScene extends Phaser.Scene { * Function called each time a camera is changed */ private setupStream(stream: MediaStream): void { - const img = this.getElementByIdOrFail('webRtcSetupNoVideo'); + const img = HtmlUtils.getElementByIdOrFail('webRtcSetupNoVideo'); img.style.display = 'none'; - const div = this.getElementByIdOrFail('myCamVideoSetup'); + const div = HtmlUtils.getElementByIdOrFail('myCamVideoSetup'); div.srcObject = stream; this.soundMeter.connectToSource(stream, new window.AudioContext()); @@ -164,7 +165,7 @@ export class EnableCameraScene extends Phaser.Scene { private updateWebCamName(): void { if (this.camerasList.length > 1) { - const div = this.getElementByIdOrFail('myCamVideoSetup'); + const div = HtmlUtils.getElementByIdOrFail('myCamVideoSetup'); let label = this.camerasList[this.cameraSelected].label; // remove text in parenthesis @@ -211,10 +212,10 @@ export class EnableCameraScene extends Phaser.Scene { } private reposition(): void { - let div = this.getElementByIdOrFail('myCamVideoSetup'); + let div = HtmlUtils.getElementByIdOrFail('myCamVideoSetup'); let bounds = div.getBoundingClientRect(); if (!div.srcObject) { - div = this.getElementByIdOrFail('webRtcSetup'); + div = HtmlUtils.getElementByIdOrFail('webRtcSetup'); bounds = div.getBoundingClientRect(); } @@ -255,7 +256,7 @@ export class EnableCameraScene extends Phaser.Scene { } private login(): void { - this.getElementByIdOrFail('webRtcSetup').style.display = 'none'; + HtmlUtils.getElementByIdOrFail('webRtcSetup').style.display = 'none'; this.soundMeter.stop(); window.removeEventListener('resize', this.repositionCallback); @@ -276,13 +277,4 @@ export class EnableCameraScene extends Phaser.Scene { } this.updateWebCamName(); } - - private getElementByIdOrFail(id: string): T { - const elem = document.getElementById(id); - if (elem === null) { - throw new Error("Cannot find HTML element with id '"+id+"'"); - } - // FIXME: does not check the type of the returned type - return elem as T; - } } diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 557f12fb..9c3563ad 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -40,49 +40,49 @@ export class MediaManager { constructor() { - this.myCamVideo = this.getElementByIdOrFail('myCamVideo'); - this.webrtcInAudio = this.getElementByIdOrFail('audio-webrtc-in'); + this.myCamVideo = HtmlUtils.getElementByIdOrFail('myCamVideo'); + this.webrtcInAudio = HtmlUtils.getElementByIdOrFail('audio-webrtc-in'); this.webrtcInAudio.volume = 0.2; - this.microphoneBtn = this.getElementByIdOrFail('btn-micro'); - this.microphoneClose = this.getElementByIdOrFail('microphone-close'); + this.microphoneBtn = HtmlUtils.getElementByIdOrFail('btn-micro'); + this.microphoneClose = HtmlUtils.getElementByIdOrFail('microphone-close'); this.microphoneClose.style.display = "none"; this.microphoneClose.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.enableMicrophone(); //update tracking }); - this.microphone = this.getElementByIdOrFail('microphone'); + this.microphone = HtmlUtils.getElementByIdOrFail('microphone'); this.microphone.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.disableMicrophone(); //update tracking }); - this.cinemaBtn = this.getElementByIdOrFail('btn-video'); - this.cinemaClose = this.getElementByIdOrFail('cinema-close'); + this.cinemaBtn = HtmlUtils.getElementByIdOrFail('btn-video'); + this.cinemaClose = HtmlUtils.getElementByIdOrFail('cinema-close'); this.cinemaClose.style.display = "none"; this.cinemaClose.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.enableCamera(); //update tracking }); - this.cinema = this.getElementByIdOrFail('cinema'); + this.cinema = HtmlUtils.getElementByIdOrFail('cinema'); this.cinema.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.disableCamera(); //update tracking }); - this.monitorBtn = this.getElementByIdOrFail('btn-monitor'); - this.monitorClose = this.getElementByIdOrFail('monitor-close'); + this.monitorBtn = HtmlUtils.getElementByIdOrFail('btn-monitor'); + this.monitorClose = HtmlUtils.getElementByIdOrFail('monitor-close'); this.monitorClose.style.display = "block"; this.monitorClose.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.enableScreenSharing(); //update tracking }); - this.monitor = this.getElementByIdOrFail('monitor'); + this.monitor = HtmlUtils.getElementByIdOrFail('monitor'); this.monitor.style.display = "none"; this.monitor.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); @@ -126,12 +126,12 @@ export class MediaManager { } public showGameOverlay(){ - const gameOverlay = this.getElementByIdOrFail('game-overlay'); + const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay'); gameOverlay.classList.add('active'); } public hideGameOverlay(){ - const gameOverlay = this.getElementByIdOrFail('game-overlay'); + const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay'); gameOverlay.classList.remove('active'); } @@ -355,14 +355,14 @@ export class MediaManager { layoutManager.add(DivImportance.Normal, userId, html); if (reportCallBack) { - const reportBtn = this.getElementByIdOrFail(`report-${userId}`); + const reportBtn = HtmlUtils.getElementByIdOrFail(`report-${userId}`); reportBtn.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); this.showReportModal(userId, userName, reportCallBack); }); } - this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); + this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail(userId)); } addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){ @@ -376,7 +376,7 @@ export class MediaManager { layoutManager.add(divImportance, userId, html); - this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); + this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail(userId)); } disabledMicrophoneByUserId(userId: number){ @@ -499,18 +499,9 @@ export class MediaManager { return color; } - private getElementByIdOrFail(id: string): T { - const elem = document.getElementById(id); - if (elem === null) { - throw new Error("Cannot find HTML element with id '"+id+"'"); - } - // FIXME: does not check the type of the returned type - return elem as T; - } - private showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ //create report text area - const mainContainer = this.getElementByIdOrFail('main-container'); + const mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); const divReport = document.createElement('div'); divReport.classList.add('modal-report-user'); From f344adc48bba3e612d7636ae711d2a75efbf5d7e Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sun, 25 Oct 2020 19:39:15 +0100 Subject: [PATCH 02/18] Create discussion - Add new discussion class - Feature to discuss and report user --- front/dist/resources/logos/boy.svg | 77 +++++++++++++ front/dist/resources/logos/discussion.svg | 1 + front/dist/resources/style/style.css | 125 ++++++++++++++++++++++ front/src/Phaser/Login/LoginScene.ts | 8 ++ front/src/WebRtc/Discussion.ts | 124 +++++++++++++++++++++ 5 files changed, 335 insertions(+) create mode 100644 front/dist/resources/logos/boy.svg create mode 100644 front/dist/resources/logos/discussion.svg create mode 100644 front/src/WebRtc/Discussion.ts diff --git a/front/dist/resources/logos/boy.svg b/front/dist/resources/logos/boy.svg new file mode 100644 index 00000000..d6d9582e --- /dev/null +++ b/front/dist/resources/logos/boy.svg @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/front/dist/resources/logos/discussion.svg b/front/dist/resources/logos/discussion.svg new file mode 100644 index 00000000..1b4572b3 --- /dev/null +++ b/front/dist/resources/logos/discussion.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index d0f0e68b..d1f5e7f7 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -686,3 +686,128 @@ div.modal-report-user{ max-width: calc(800px - 60px); /* size of modal - padding*/ } +/*MESSAGE*/ +.discussion{ + position: fixed; + right: -300px; + width: 220px; + height: 100%; + background-color: #000000; + padding: 20px; +} +.discussion.active{ + right: 0; +} +.discussion .toggle-btn{ + display: none; + cursor: pointer; + height: 50px; + width: 50px; + background-color: #2d2d2dba; + position: absolute; + top: calc(50% - 25px); + margin-left: -125px; + border-radius: 50%; + border: none; + transition: all 0.5s ease; +} +.discussion .toggle-btn.active{ + display: block; +} +.discussion .toggle-btn:hover { + transform: scale(1.1) rotateY(3.142rad); +} +.discussion .toggle-btn img{ + width: 26px; + height: 26px; + margin: 13px 5px; +} +.discussion p{ + color: white; + font-size: 22px; + padding-left: 10px; + margin: 0; +} + +.discussion .participants{ + height: 200px; + margin: 10px 0; +} + +.discussion .participants .participant{ + display: flex; + margin: 5px 10px; + background-color: #ffffff69; + padding: 5px; + border-radius: 15px; + cursor: pointer; +} + +.discussion .participants .participant:hover{ + background-color: #ffffff; +} +.discussion .participants .participant:hover p{ + color: black; +} + +.discussion .participants .participant:before { + content: ''; + height: 10px; + width: 10px; + background-color: #1e7e34; + position: absolute; + margin-left: 18px; + border-radius: 50%; + margin-top: 18px; +} + +.discussion .participants .participant img{ + width: 26px; + height: 26px; +} + +.discussion .participants .participant p{ + font-size: 16px; + margin-left: 10px; + margin-top: 8px; +} + +.discussion .participants .participant button.report-btn{ + cursor: pointer; + position: absolute; + background-color: #2d2d2dba; + right: 34px; + margin: 0px; + padding: 6px 0px; + border-radius: 15px; + border: none; + color: white; + width: 0px; + overflow: hidden; + transition: all .5s ease; +} + +.discussion .participants .participant:hover button.report-btn{ + width: 70px; +} + +.discussion .messages{ + position: absolute; + height: calc(100% - 300px); +} + +.discussion .messages .message{ + margin: 5px; + float: right; + text-align: right; +} + +.discussion .messages .message.me{ + float: left; + text-align: left; +} + +.discussion .messages .message p{ + font-size: 12px; +} + diff --git a/front/src/Phaser/Login/LoginScene.ts b/front/src/Phaser/Login/LoginScene.ts index 2c5c1882..55321124 100644 --- a/front/src/Phaser/Login/LoginScene.ts +++ b/front/src/Phaser/Login/LoginScene.ts @@ -9,6 +9,7 @@ import {cypressAsserter} from "../../Cypress/CypressAsserter"; import {SelectCharacterSceneName} from "./SelectCharacterScene"; import {ResizableScene} from "./ResizableScene"; import {localUserStore} from "../../Connexion/LocalUserStore"; +import {Discussion} from "../../WebRtc/Discussion"; //todo: put this constants in a dedicated file export const LoginSceneName = "LoginScene"; @@ -74,6 +75,13 @@ export class LoginScene extends ResizableScene { }); cypressAsserter.initFinished(); + + const discussion = new Discussion('test'); + discussion.addParticipant('GRP'); + discussion.addParticipant('LOL'); + + discussion.addMessage('GRP', 'ceci est un test d\'envoi de message', true); + discussion.addMessage('LOL', 'ceci est un test d\'envoi de message'); } update(time: number, delta: number): void { diff --git a/front/src/WebRtc/Discussion.ts b/front/src/WebRtc/Discussion.ts new file mode 100644 index 00000000..b7307745 --- /dev/null +++ b/front/src/WebRtc/Discussion.ts @@ -0,0 +1,124 @@ +import {HtmlUtils} from "./HtmlUtils"; + +export class Discussion { + + private mainContainer: HTMLDivElement; + + private divDiscuss?: HTMLDivElement; + private divParticipants?: HTMLDivElement; + private nbpParticipants?: HTMLParagraphElement; + private divMessages?: HTMLParagraphElement; + + private participants: Map = new Map(); + + private activeDiscussion: boolean = false; + + constructor(name: string) { + this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); + this.createDiscussPart(name); + } + + private createDiscussPart(name: string) { + this.divDiscuss = document.createElement('div'); + this.divDiscuss.classList.add('discussion'); + + const buttonToggleDiscussion = document.createElement('button'); + buttonToggleDiscussion.classList.add('toggle-btn'); + buttonToggleDiscussion.classList.add('active'); + buttonToggleDiscussion.innerHTML = ``; + buttonToggleDiscussion.addEventListener('click', () => { + if(this.activeDiscussion){ + this.activeDiscussion = false; + this.divDiscuss?.classList.remove('active'); + buttonToggleDiscussion.classList.add('active'); + }else{ + this.activeDiscussion = true; + this.divDiscuss?.classList.add('active'); + buttonToggleDiscussion.classList.remove('active'); + } + }); + this.divDiscuss.appendChild(buttonToggleDiscussion); + + const myName = document.createElement('p'); + myName.innerText = name.toUpperCase(); + this.nbpParticipants = document.createElement('p'); + this.nbpParticipants.innerText = 'PARTICIPANTS (1)'; + + this.divParticipants = document.createElement('div'); + this.divParticipants.classList.add('participants'); + + this.divMessages = document.createElement('div'); + this.divMessages.classList.add('messages'); + + this.divDiscuss.appendChild(myName); + this.divDiscuss.appendChild(this.nbpParticipants); + this.divDiscuss.appendChild(this.divParticipants); + this.divDiscuss.appendChild(this.divMessages); + + //append in main container + this.mainContainer.appendChild(this.divDiscuss); + } + + public addParticipant(name: string, img?: string) { + const divParticipant = document.createElement('div'); + divParticipant.classList.add('participant'); + + const divImgParticipant = document.createElement('img'); + divImgParticipant.src = 'resources/logos/boy.svg'; + if (img) { + divImgParticipant.src = img; + } + const divPParticipant = document.createElement('p'); + divPParticipant.innerText = name; + + const reportBanUserAction = document.createElement('button'); + reportBanUserAction.classList.add('report-btn') + reportBanUserAction.innerText = 'Report'; + reportBanUserAction.addEventListener('click', () => { + //TODO report user + console.log('report'); + }); + + divParticipant.appendChild(divImgParticipant); + divParticipant.appendChild(divPParticipant); + divParticipant.appendChild(reportBanUserAction); + + this.divParticipants?.appendChild(divParticipant); + this.participants.set(name, divParticipant); + + this.updateParticipant(this.participants.size); + } + + public updateParticipant(nb: number) { + if (!this.nbpParticipants) { + return; + } + this.nbpParticipants.innerText = `PARTICIPANTS (${nb})`; + } + + public addMessage(name: string, message: string, isMe: boolean = false) { + const divMessage = document.createElement('div'); + divMessage.classList.add('message'); + if(isMe){ + divMessage.classList.add('me'); + } + + const pMessage = document.createElement('p'); + const date = new Date(); + if(isMe){ + name = 'Moi'; + } + pMessage.innerHTML = `${name} + + ${date.getHours()}:${date.getMinutes()} + `; + divMessage.appendChild(pMessage); + + const userMessage = document.createElement('p'); + userMessage.innerText = message; + divMessage.appendChild(userMessage); + + this.divMessages?.appendChild(divMessage); + } + +} \ No newline at end of file From 1945c24704e96baab1be4673581ef65e2ecc13a6 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sun, 25 Oct 2020 21:59:14 +0100 Subject: [PATCH 03/18] Create send data discussion --- front/dist/resources/style/style.css | 77 ++++++++++-- front/src/Phaser/Login/LoginScene.ts | 8 -- front/src/WebRtc/Discussion.ts | 124 ------------------- front/src/WebRtc/DiscussionManager.ts | 169 ++++++++++++++++++++++++++ front/src/WebRtc/MediaManager.ts | 25 ++++ front/src/WebRtc/ScreenSharingPeer.ts | 3 +- front/src/WebRtc/SimplePeer.ts | 10 +- front/src/WebRtc/VideoPeer.ts | 34 ++++-- 8 files changed, 294 insertions(+), 156 deletions(-) delete mode 100644 front/src/WebRtc/Discussion.ts create mode 100644 front/src/WebRtc/DiscussionManager.ts diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index d1f5e7f7..dec0630f 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -689,16 +689,17 @@ div.modal-report-user{ /*MESSAGE*/ .discussion{ position: fixed; - right: -300px; + left: -300px; width: 220px; height: 100%; - background-color: #000000; + background-color: #333333; padding: 20px; + transition: all 0.5s ease; } .discussion.active{ - right: 0; + left: 0; } -.discussion .toggle-btn{ +.discussion .active-btn{ display: none; cursor: pointer; height: 50px; @@ -706,22 +707,36 @@ div.modal-report-user{ background-color: #2d2d2dba; position: absolute; top: calc(50% - 25px); - margin-left: -125px; + margin-left: 315px; border-radius: 50%; border: none; transition: all 0.5s ease; } -.discussion .toggle-btn.active{ +.discussion .active-btn.active{ display: block; } -.discussion .toggle-btn:hover { +.discussion .active-btn:hover { transform: scale(1.1) rotateY(3.142rad); } -.discussion .toggle-btn img{ +.discussion .active-btn img{ width: 26px; height: 26px; margin: 13px 5px; } + +.discussion .close-btn{ + position: absolute; + top: 0; + right: 10px; + background: none; + border: none; + cursor: pointer; +} +.discussion .close-btn img{ + height: 15px; + right: 15px; +} + .discussion p{ color: white; font-size: 22px; @@ -793,13 +808,22 @@ div.modal-report-user{ .discussion .messages{ position: absolute; - height: calc(100% - 300px); + height: calc(100% - 360px); + overflow-x: hidden; + overflow-y: scroll; + max-width: calc(100% - 40px); + width: calc(100% - 40px); +} + +.discussion .messages h2{ + color: white; } .discussion .messages .message{ margin: 5px; float: right; text-align: right; + width: 100%; } .discussion .messages .message.me{ @@ -811,3 +835,38 @@ div.modal-report-user{ font-size: 12px; } +.discussion .messages .message p.body{ + font-size: 16px; + overflow: hidden; + white-space: pre-wrap; + word-wrap: break-word; +} + +.discussion .send-message{ + position: absolute; + bottom: 45px; + width: 220px; + height: 26px; +} + +.discussion .send-message input{ + position: absolute; + width: calc(100% - 10px); + height: 20px; + background-color: #171717; + color: white; + border-radius: 15px; + border: none; +} + +.discussion .send-message img{ + position: absolute; + margin-right: 10px; + width: 20px; + height: 20px; + background-color: #ffffff69; +} +.discussion .send-message img:hover{ + background-color: #ffffff; +} + diff --git a/front/src/Phaser/Login/LoginScene.ts b/front/src/Phaser/Login/LoginScene.ts index 55321124..2c5c1882 100644 --- a/front/src/Phaser/Login/LoginScene.ts +++ b/front/src/Phaser/Login/LoginScene.ts @@ -9,7 +9,6 @@ import {cypressAsserter} from "../../Cypress/CypressAsserter"; import {SelectCharacterSceneName} from "./SelectCharacterScene"; import {ResizableScene} from "./ResizableScene"; import {localUserStore} from "../../Connexion/LocalUserStore"; -import {Discussion} from "../../WebRtc/Discussion"; //todo: put this constants in a dedicated file export const LoginSceneName = "LoginScene"; @@ -75,13 +74,6 @@ export class LoginScene extends ResizableScene { }); cypressAsserter.initFinished(); - - const discussion = new Discussion('test'); - discussion.addParticipant('GRP'); - discussion.addParticipant('LOL'); - - discussion.addMessage('GRP', 'ceci est un test d\'envoi de message', true); - discussion.addMessage('LOL', 'ceci est un test d\'envoi de message'); } update(time: number, delta: number): void { diff --git a/front/src/WebRtc/Discussion.ts b/front/src/WebRtc/Discussion.ts deleted file mode 100644 index b7307745..00000000 --- a/front/src/WebRtc/Discussion.ts +++ /dev/null @@ -1,124 +0,0 @@ -import {HtmlUtils} from "./HtmlUtils"; - -export class Discussion { - - private mainContainer: HTMLDivElement; - - private divDiscuss?: HTMLDivElement; - private divParticipants?: HTMLDivElement; - private nbpParticipants?: HTMLParagraphElement; - private divMessages?: HTMLParagraphElement; - - private participants: Map = new Map(); - - private activeDiscussion: boolean = false; - - constructor(name: string) { - this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); - this.createDiscussPart(name); - } - - private createDiscussPart(name: string) { - this.divDiscuss = document.createElement('div'); - this.divDiscuss.classList.add('discussion'); - - const buttonToggleDiscussion = document.createElement('button'); - buttonToggleDiscussion.classList.add('toggle-btn'); - buttonToggleDiscussion.classList.add('active'); - buttonToggleDiscussion.innerHTML = ``; - buttonToggleDiscussion.addEventListener('click', () => { - if(this.activeDiscussion){ - this.activeDiscussion = false; - this.divDiscuss?.classList.remove('active'); - buttonToggleDiscussion.classList.add('active'); - }else{ - this.activeDiscussion = true; - this.divDiscuss?.classList.add('active'); - buttonToggleDiscussion.classList.remove('active'); - } - }); - this.divDiscuss.appendChild(buttonToggleDiscussion); - - const myName = document.createElement('p'); - myName.innerText = name.toUpperCase(); - this.nbpParticipants = document.createElement('p'); - this.nbpParticipants.innerText = 'PARTICIPANTS (1)'; - - this.divParticipants = document.createElement('div'); - this.divParticipants.classList.add('participants'); - - this.divMessages = document.createElement('div'); - this.divMessages.classList.add('messages'); - - this.divDiscuss.appendChild(myName); - this.divDiscuss.appendChild(this.nbpParticipants); - this.divDiscuss.appendChild(this.divParticipants); - this.divDiscuss.appendChild(this.divMessages); - - //append in main container - this.mainContainer.appendChild(this.divDiscuss); - } - - public addParticipant(name: string, img?: string) { - const divParticipant = document.createElement('div'); - divParticipant.classList.add('participant'); - - const divImgParticipant = document.createElement('img'); - divImgParticipant.src = 'resources/logos/boy.svg'; - if (img) { - divImgParticipant.src = img; - } - const divPParticipant = document.createElement('p'); - divPParticipant.innerText = name; - - const reportBanUserAction = document.createElement('button'); - reportBanUserAction.classList.add('report-btn') - reportBanUserAction.innerText = 'Report'; - reportBanUserAction.addEventListener('click', () => { - //TODO report user - console.log('report'); - }); - - divParticipant.appendChild(divImgParticipant); - divParticipant.appendChild(divPParticipant); - divParticipant.appendChild(reportBanUserAction); - - this.divParticipants?.appendChild(divParticipant); - this.participants.set(name, divParticipant); - - this.updateParticipant(this.participants.size); - } - - public updateParticipant(nb: number) { - if (!this.nbpParticipants) { - return; - } - this.nbpParticipants.innerText = `PARTICIPANTS (${nb})`; - } - - public addMessage(name: string, message: string, isMe: boolean = false) { - const divMessage = document.createElement('div'); - divMessage.classList.add('message'); - if(isMe){ - divMessage.classList.add('me'); - } - - const pMessage = document.createElement('p'); - const date = new Date(); - if(isMe){ - name = 'Moi'; - } - pMessage.innerHTML = `${name} - - ${date.getHours()}:${date.getMinutes()} - `; - divMessage.appendChild(pMessage); - - const userMessage = document.createElement('p'); - userMessage.innerText = message; - divMessage.appendChild(userMessage); - - this.divMessages?.appendChild(divMessage); - } - -} \ No newline at end of file diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts new file mode 100644 index 00000000..4663adcf --- /dev/null +++ b/front/src/WebRtc/DiscussionManager.ts @@ -0,0 +1,169 @@ +import {HtmlUtils} from "./HtmlUtils"; +import {UpdatedLocalStreamCallback} from "./MediaManager"; +export type SendMessageCallback = (message:string) => void; + +export class DiscussionManager { + + private mainContainer: HTMLDivElement; + + private divDiscuss?: HTMLDivElement; + private divParticipants?: HTMLDivElement; + private nbpParticipants?: HTMLParagraphElement; + private divMessages?: HTMLParagraphElement; + + private participants: Map = new Map(); + + private activeDiscussion: boolean = false; + + private sendMessageCallBack : Set = new Set(); + + constructor(name: string) { + this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); + this.createDiscussPart(name); + } + + private createDiscussPart(name: string) { + this.divDiscuss = document.createElement('div'); + this.divDiscuss.classList.add('discussion'); + + const buttonCloseDiscussion: HTMLButtonElement = document.createElement('button'); + const buttonActiveDiscussion: HTMLButtonElement = document.createElement('button'); + buttonCloseDiscussion.classList.add('close-btn'); + buttonCloseDiscussion.innerHTML = ``; + buttonCloseDiscussion.addEventListener('click', () => { + this.activeDiscussion = false; + this.divDiscuss?.classList.remove('active'); + buttonActiveDiscussion.classList.add('active'); + }); + buttonActiveDiscussion.classList.add('active-btn'); + buttonActiveDiscussion.classList.add('active'); + buttonActiveDiscussion.innerHTML = ``; + buttonActiveDiscussion.addEventListener('click', () => { + this.activeDiscussion = true; + this.divDiscuss?.classList.add('active'); + buttonActiveDiscussion.classList.remove('active'); + }); + this.divDiscuss.appendChild(buttonCloseDiscussion); + this.divDiscuss.appendChild(buttonActiveDiscussion); + + const myName: HTMLParagraphElement = document.createElement('p'); + myName.innerText = name.toUpperCase(); + this.nbpParticipants = document.createElement('p'); + this.nbpParticipants.innerText = 'PARTICIPANTS (1)'; + + this.divParticipants = document.createElement('div'); + this.divParticipants.classList.add('participants'); + + this.divMessages = document.createElement('div'); + this.divMessages.classList.add('messages'); + this.divMessages.innerHTML = "

Local messages

" + + this.divDiscuss.appendChild(myName); + this.divDiscuss.appendChild(this.nbpParticipants); + this.divDiscuss.appendChild(this.divParticipants); + this.divDiscuss.appendChild(this.divMessages); + + const sendDivMessage: HTMLDivElement = document.createElement('div'); + sendDivMessage.classList.add('send-message'); + const inputMessage: HTMLInputElement = document.createElement('input'); + inputMessage.type = "text"; + inputMessage.addEventListener('keyup', (event: KeyboardEvent) => { + if (event.key === 'Enter') { + event.preventDefault(); + this.addMessage(name, inputMessage.value, true); + for(const callback of this.sendMessageCallBack) { + callback(inputMessage.value); + } + inputMessage.value = ""; + } + }); + sendDivMessage.appendChild(inputMessage); + this.divDiscuss.appendChild(sendDivMessage); + + //append in main container + this.mainContainer.appendChild(this.divDiscuss); + + this.addParticipant('me', 'Moi', undefined, true); + } + + public addParticipant(userId: number|string, name: string|undefined, img?: string|undefined, isMe: boolean = false) { + const divParticipant: HTMLDivElement = document.createElement('div'); + divParticipant.classList.add('participant'); + divParticipant.id = `participant-${userId}`; + + const divImgParticipant: HTMLImageElement = document.createElement('img'); + divImgParticipant.src = 'resources/logos/boy.svg'; + if (img !== undefined) { + divImgParticipant.src = img; + } + const divPParticipant: HTMLParagraphElement = document.createElement('p'); + if(!name){ + name = 'Anonymous'; + } + divPParticipant.innerText = name; + + divParticipant.appendChild(divImgParticipant); + divParticipant.appendChild(divPParticipant); + + if(!isMe) { + const reportBanUserAction: HTMLButtonElement = document.createElement('button'); + reportBanUserAction.classList.add('report-btn') + reportBanUserAction.innerText = 'Report'; + reportBanUserAction.addEventListener('click', () => { + //TODO report user + console.log('report'); + }); + divParticipant.appendChild(reportBanUserAction); + } + + this.divParticipants?.appendChild(divParticipant); + this.participants.set(userId, divParticipant); + + this.updateParticipant(this.participants.size); + } + + public updateParticipant(nb: number) { + if (!this.nbpParticipants) { + return; + } + this.nbpParticipants.innerText = `PARTICIPANTS (${nb})`; + } + + public addMessage(name: string, message: string, isMe: boolean = false) { + const divMessage: HTMLDivElement = document.createElement('div'); + divMessage.classList.add('message'); + if(isMe){ + divMessage.classList.add('me'); + } + + const pMessage: HTMLParagraphElement = document.createElement('p'); + const date = new Date(); + if(isMe){ + name = 'Moi'; + } + pMessage.innerHTML = `${name} + + ${date.getHours()}:${date.getMinutes()} + `; + divMessage.appendChild(pMessage); + + const userMessage: HTMLParagraphElement = document.createElement('p'); + userMessage.innerText = message; + userMessage.classList.add('body'); + divMessage.appendChild(userMessage); + + this.divMessages?.appendChild(divMessage); + } + + public removeParticipant(userId: number|string){ + const element = this.participants.get(userId); + if(element){ + element.remove(); + } + } + + public onSendMessageCallback(callback: SendMessageCallback): void { + this.sendMessageCallBack.add(callback); + } + +} \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 9c3563ad..660aa599 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -1,5 +1,6 @@ import {DivImportance, layoutManager} from "./LayoutManager"; import {HtmlUtils} from "./HtmlUtils"; +import {DiscussionManager, SendMessageCallback} from "./DiscussionManager"; declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any const videoConstraint: boolean|MediaTrackConstraints = { @@ -38,6 +39,8 @@ export class MediaManager { private cinemaBtn: HTMLDivElement; private monitorBtn: HTMLDivElement; + private discussionManager: DiscussionManager; + constructor() { this.myCamVideo = HtmlUtils.getElementByIdOrFail('myCamVideo'); @@ -89,6 +92,8 @@ export class MediaManager { this.disableScreenSharing(); //update tracking }); + + this.discussionManager = new DiscussionManager('test'); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -363,6 +368,9 @@ export class MediaManager { } this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail(userId)); + + //permit to create participant in discussion part + this.addNewParticipant(userId, userName); } addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){ @@ -437,6 +445,9 @@ export class MediaManager { removeActiveVideo(userId: string){ layoutManager.remove(userId); this.remoteVideo.delete(userId); + + //permit to remove user in discussion part + this.removeParticipant(userId); } removeActiveScreenSharingVideo(userId: string) { this.removeActiveVideo(`screen-sharing-${userId}`) @@ -556,7 +567,21 @@ export class MediaManager { mainContainer.appendChild(divReport); } + public addNewParticipant(userId: number|string, name: string|undefined, img?: string){ + this.discussionManager.addParticipant(userId, name, img); + } + public removeParticipant(userId: number|string){ + this.discussionManager.removeParticipant(userId) + } + + public addNewMessage(name: string, message: string, isMe: boolean = false){ + this.discussionManager.addMessage(name, message, isMe) + } + + public addSendMessageCallback(callback: SendMessageCallback){ + this.discussionManager.onSendMessageCallback(callback) + } } export const mediaManager = new MediaManager(); diff --git a/front/src/WebRtc/ScreenSharingPeer.ts b/front/src/WebRtc/ScreenSharingPeer.ts index 3efee1c3..a6cf679b 100644 --- a/front/src/WebRtc/ScreenSharingPeer.ts +++ b/front/src/WebRtc/ScreenSharingPeer.ts @@ -2,6 +2,7 @@ import * as SimplePeerNamespace from "simple-peer"; import {mediaManager} from "./MediaManager"; import {TURN_SERVER, TURN_USER, TURN_PASSWORD} from "../Enum/EnvironmentVariable"; import {RoomConnection} from "../Connexion/RoomConnection"; +import {MESSAGE_TYPE_CONSTRAINT} from "./VideoPeer"; const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer'); @@ -148,6 +149,6 @@ export class ScreenSharingPeer extends Peer { public stopPushingScreenSharingToRemoteUser(stream: MediaStream) { this.removeStream(stream); - this.write(new Buffer(JSON.stringify({streamEnded: true}))); + this.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, streamEnded: true}))); } } diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index eb2ee42b..a9c24f17 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -10,7 +10,7 @@ import { UpdatedLocalStreamCallback } from "./MediaManager"; import {ScreenSharingPeer} from "./ScreenSharingPeer"; -import {VideoPeer} from "./VideoPeer"; +import {MESSAGE_TYPE_CONSTRAINT, MESSAGE_TYPE_MESSAGE, VideoPeer} from "./VideoPeer"; import {RoomConnection} from "../Connexion/RoomConnection"; export interface UserSimplePeerInterface{ @@ -145,6 +145,12 @@ export class SimplePeer { mediaManager.addActiveVideo("" + user.userId, reportCallback, name); const peer = new VideoPeer(user.userId, user.initiator ? user.initiator : false, this.Connection); + + //permit to send message + mediaManager.addSendMessageCallback((message: string) => { + peer.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_MESSAGE, name: name?.toUpperCase(), message: message}))); + }); + peer.toClose = false; // When a connection is established to a video stream, and if a screen sharing is taking place, // the user sharing screen should also initiate a connection to the remote user! @@ -318,7 +324,7 @@ export class SimplePeer { throw new Error('While adding media, cannot find user with ID ' + userId); } const localStream: MediaStream | null = mediaManager.localStream; - PeerConnection.write(new Buffer(JSON.stringify(mediaManager.constraintsMedia))); + PeerConnection.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, ...mediaManager.constraintsMedia}))); if(!localStream){ return; diff --git a/front/src/WebRtc/VideoPeer.ts b/front/src/WebRtc/VideoPeer.ts index fb34f29e..f8bfa3f9 100644 --- a/front/src/WebRtc/VideoPeer.ts +++ b/front/src/WebRtc/VideoPeer.ts @@ -5,6 +5,8 @@ import {RoomConnection} from "../Connexion/RoomConnection"; const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer'); +export const MESSAGE_TYPE_CONSTRAINT = 'constraint'; +export const MESSAGE_TYPE_MESSAGE = 'message'; /** * A peer connection used to transmit video / audio signals between 2 peers. */ @@ -78,19 +80,27 @@ export class VideoPeer extends Peer { }); this.on('data', (chunk: Buffer) => { - const constraint = JSON.parse(chunk.toString('utf8')); - console.log("data", constraint); - if (constraint.audio) { - mediaManager.enabledMicrophoneByUserId(this.userId); - } else { - mediaManager.disabledMicrophoneByUserId(this.userId); + const message = JSON.parse(chunk.toString('utf8')); + console.log("data", message); + + if(message.type === MESSAGE_TYPE_CONSTRAINT) { + const constraint = message; + if (constraint.audio) { + mediaManager.enabledMicrophoneByUserId(this.userId); + } else { + mediaManager.disabledMicrophoneByUserId(this.userId); + } + + if (constraint.video || constraint.screen) { + mediaManager.enabledVideoByUserId(this.userId); + } else { + this.stream(undefined); + mediaManager.disabledVideoByUserId(this.userId); + } } - if (constraint.video || constraint.screen) { - mediaManager.enabledVideoByUserId(this.userId); - } else { - this.stream(undefined); - mediaManager.disabledVideoByUserId(this.userId); + if(message.type === 'message') { + mediaManager.addNewMessage(message.name, message.message); } }); @@ -163,7 +173,7 @@ export class VideoPeer extends Peer { private pushVideoToRemoteUser() { try { const localStream: MediaStream | null = mediaManager.localStream; - this.write(new Buffer(JSON.stringify(mediaManager.constraintsMedia))); + this.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, ...mediaManager.constraintsMedia}))); if(!localStream){ return; From bdb504722ff75c4add12a3e25cc4f4c74c14b516 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Sun, 25 Oct 2020 22:41:31 +0100 Subject: [PATCH 04/18] Fix style -webkit-focus --- front/dist/resources/style/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index dec0630f..234425aa 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -1,6 +1,11 @@ body{ overflow: hidden; } +body button:focus, +body img:focus, +body input:focus { + outline: -webkit-focus-ring-color auto 0; +} body .message-info{ width: 20%; height: auto; From 1e096af43b3026a5e8ced762eb35da853d750d27 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 26 Oct 2020 00:03:30 +0100 Subject: [PATCH 05/18] Fix font family --- front/dist/resources/style/style.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 234425aa..762b44cd 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -1,3 +1,6 @@ +*{ + font-family: 'Open Sans', sans-serif; +} body{ overflow: hidden; } From 850be63284419a83a287ff146a320a90c1838cba Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 26 Oct 2020 00:26:10 +0100 Subject: [PATCH 06/18] Fix style --- front/dist/resources/style/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 762b44cd..4b06d926 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -792,7 +792,7 @@ div.modal-report-user{ .discussion .participants .participant p{ font-size: 16px; margin-left: 10px; - margin-top: 8px; + margin-top: 2px; } .discussion .participants .participant button.report-btn{ From f95f38b09251a6a796e3a7b16bf27d365056ea9f Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 26 Oct 2020 14:13:51 +0100 Subject: [PATCH 07/18] Permit to remove callback --- front/src/WebRtc/DiscussionManager.ts | 9 +++++---- front/src/WebRtc/MediaManager.ts | 4 ++-- front/src/WebRtc/SimplePeer.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index 4663adcf..d2a52632 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -15,7 +15,7 @@ export class DiscussionManager { private activeDiscussion: boolean = false; - private sendMessageCallBack : Set = new Set(); + private sendMessageCallBack : Map = new Map(); constructor(name: string) { this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); @@ -71,7 +71,7 @@ export class DiscussionManager { if (event.key === 'Enter') { event.preventDefault(); this.addMessage(name, inputMessage.value, true); - for(const callback of this.sendMessageCallBack) { + for(const callback of this.sendMessageCallBack.values()) { callback(inputMessage.value); } inputMessage.value = ""; @@ -160,10 +160,11 @@ export class DiscussionManager { if(element){ element.remove(); } + this.sendMessageCallBack.delete(userId); } - public onSendMessageCallback(callback: SendMessageCallback): void { - this.sendMessageCallBack.add(callback); + public onSendMessageCallback(userId: string|number, callback: SendMessageCallback): void { + this.sendMessageCallBack.set(userId, callback); } } \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 660aa599..6c33bc32 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -579,8 +579,8 @@ export class MediaManager { this.discussionManager.addMessage(name, message, isMe) } - public addSendMessageCallback(callback: SendMessageCallback){ - this.discussionManager.onSendMessageCallback(callback) + public addSendMessageCallback(userId: string|number, callback: SendMessageCallback){ + this.discussionManager.onSendMessageCallback(userId, callback) } } diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index a9c24f17..72c9d890 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -147,7 +147,7 @@ export class SimplePeer { const peer = new VideoPeer(user.userId, user.initiator ? user.initiator : false, this.Connection); //permit to send message - mediaManager.addSendMessageCallback((message: string) => { + mediaManager.addSendMessageCallback(user.userId,(message: string) => { peer.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_MESSAGE, name: name?.toUpperCase(), message: message}))); }); From 55c1bcee66ab8db8c86af4649d34a74a44c6b339 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 27 Oct 2020 20:18:25 +0100 Subject: [PATCH 08/18] Add callback report in discussion part --- front/dist/resources/style/style.css | 8 +++++--- front/src/WebRtc/DiscussionManager.ts | 18 ++++++++++++------ front/src/WebRtc/MediaManager.ts | 10 +++++----- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 4b06d926..6eb6f2b5 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -82,13 +82,14 @@ body .message-info.warning{ position: absolute; right: 15px; bottom: 15px; - border-radius: 15px; + border-radius: 15px 15px 15px 15px; } video#myCamVideo{ width: 15vw; -webkit-transform: scaleX(-1); transform: scaleX(-1); + border-radius: 15px 15px 15px 15px; /*width: 200px;*/ /*height: 113px;*/ } @@ -365,6 +366,7 @@ body { margin: 2%; transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, max-height 0.2s, max-width 0.2s; cursor: pointer; + border-radius: 15px 15px 15px 15px; } .sidebar > div:hover { @@ -525,7 +527,7 @@ body { border: 1px solid black; background-color: #00000000; color: #ffda01; - border-radius: 10px; + border-radius: 15px; padding: 10px 30px; transition: all .2s ease; } @@ -662,7 +664,7 @@ div.modal-report-user{ border: 1px solid black; background-color: #00000000; color: #ffda01; - border-radius: 10px; + border-radius: 15px; padding: 10px 30px; transition: all .2s ease; } diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index d2a52632..a65ede25 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -1,9 +1,8 @@ import {HtmlUtils} from "./HtmlUtils"; -import {UpdatedLocalStreamCallback} from "./MediaManager"; +import {MediaManager, ReportCallback, UpdatedLocalStreamCallback} from "./MediaManager"; export type SendMessageCallback = (message:string) => void; export class DiscussionManager { - private mainContainer: HTMLDivElement; private divDiscuss?: HTMLDivElement; @@ -17,7 +16,7 @@ export class DiscussionManager { private sendMessageCallBack : Map = new Map(); - constructor(name: string) { + constructor(private mediaManager: MediaManager, name: string) { this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); this.createDiscussPart(name); } @@ -86,7 +85,13 @@ export class DiscussionManager { this.addParticipant('me', 'Moi', undefined, true); } - public addParticipant(userId: number|string, name: string|undefined, img?: string|undefined, isMe: boolean = false) { + public addParticipant( + userId: number|string, + name: string|undefined, + img?: string|undefined, + isMe: boolean = false, + reportCallback?: ReportCallback + ) { const divParticipant: HTMLDivElement = document.createElement('div'); divParticipant.classList.add('participant'); divParticipant.id = `participant-${userId}`; @@ -110,8 +115,9 @@ export class DiscussionManager { reportBanUserAction.classList.add('report-btn') reportBanUserAction.innerText = 'Report'; reportBanUserAction.addEventListener('click', () => { - //TODO report user - console.log('report'); + if(reportCallback) { + this.mediaManager.showReportModal(`${userId}`, name ?? '', reportCallback); + } }); divParticipant.appendChild(reportBanUserAction); } diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 6c33bc32..9ad2438d 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -93,7 +93,7 @@ export class MediaManager { //update tracking }); - this.discussionManager = new DiscussionManager('test'); + this.discussionManager = new DiscussionManager(this,'test'); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -370,7 +370,7 @@ export class MediaManager { this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail(userId)); //permit to create participant in discussion part - this.addNewParticipant(userId, userName); + this.addNewParticipant(userId, userName, undefined, reportCallBack); } addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){ @@ -510,7 +510,7 @@ export class MediaManager { return color; } - private showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ + public showReportModal(userId: string, userName: string, reportCallBack: ReportCallback){ //create report text area const mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); @@ -567,8 +567,8 @@ export class MediaManager { mainContainer.appendChild(divReport); } - public addNewParticipant(userId: number|string, name: string|undefined, img?: string){ - this.discussionManager.addParticipant(userId, name, img); + public addNewParticipant(userId: number|string, name: string|undefined, img?: string, reportCallBack?: ReportCallback){ + this.discussionManager.addParticipant(userId, name, img, false, reportCallBack); } public removeParticipant(userId: number|string){ From 80355e6b85c331c1197546c94b33d101d58d1384 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 27 Oct 2020 20:46:53 +0100 Subject: [PATCH 09/18] fix layout mode click when discussion is activated --- front/dist/resources/style/style.css | 3 +++ front/src/Phaser/Game/GameScene.ts | 4 ++++ front/src/WebRtc/DiscussionManager.ts | 3 +++ front/src/WebRtc/MediaManager.ts | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 6eb6f2b5..a01b1723 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -379,6 +379,7 @@ body { justify-content: center; flex-direction: column; overflow: hidden; + border-radius: 15px; } .chat-mode { @@ -622,6 +623,7 @@ div.modal-report-user{ left: calc(50% - 400px); top: 100px; background-color: #000000ad; + border-radius: 15px; } .modal-report-user textarea{ @@ -633,6 +635,7 @@ div.modal-report-user{ color: white; width: calc(100% - 60px); margin: 30px; + border-radius: 15px; } .modal-report-user img{ diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index bfc6402e..39b40c74 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -643,6 +643,10 @@ export class GameScene extends ResizableScene implements CenterListener { } private switchLayoutMode(): void { + //if discussion is activated, this layout cannot be activated + if(mediaManager.activatedDiscussion){ + return; + } const mode = layoutManager.getLayoutMode(); if (mode === LayoutMode.Presentation) { layoutManager.switchLayoutMode(LayoutMode.VideoChat); diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index a65ede25..cd063996 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -173,4 +173,7 @@ export class DiscussionManager { this.sendMessageCallBack.set(userId, callback); } + get activatedDiscussion(){ + return this.activeDiscussion; + } } \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 9ad2438d..9ce449c0 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -582,6 +582,10 @@ export class MediaManager { public addSendMessageCallback(userId: string|number, callback: SendMessageCallback){ this.discussionManager.onSendMessageCallback(userId, callback) } + + get activatedDiscussion(){ + return this.discussionManager.activatedDiscussion; + } } export const mediaManager = new MediaManager(); From a2dd3bd6ab1b530542741a6a6ebabbc9e6198752 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Fri, 30 Oct 2020 20:35:45 +0100 Subject: [PATCH 10/18] Fix style --- front/dist/resources/style/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index 9e14340e..e26256b8 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -719,6 +719,7 @@ div.modal-report-user{ .discussion{ position: fixed; left: -300px; + top: 0px; width: 220px; height: 100%; background-color: #333333; From 6ef2148a34aeacc8de7caedea3810d3df63d391b Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Wed, 4 Nov 2020 13:07:38 +0100 Subject: [PATCH 11/18] Fix feedback @moufmouf --- front/src/WebRtc/DiscussionManager.ts | 36 +++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index cd063996..37767ffa 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -9,6 +9,7 @@ export class DiscussionManager { private divParticipants?: HTMLDivElement; private nbpParticipants?: HTMLParagraphElement; private divMessages?: HTMLParagraphElement; + private buttonActiveDiscussion?: HTMLButtonElement; private participants: Map = new Map(); @@ -26,24 +27,23 @@ export class DiscussionManager { this.divDiscuss.classList.add('discussion'); const buttonCloseDiscussion: HTMLButtonElement = document.createElement('button'); - const buttonActiveDiscussion: HTMLButtonElement = document.createElement('button'); + this.buttonActiveDiscussion = document.createElement('button'); buttonCloseDiscussion.classList.add('close-btn'); buttonCloseDiscussion.innerHTML = ``; buttonCloseDiscussion.addEventListener('click', () => { this.activeDiscussion = false; this.divDiscuss?.classList.remove('active'); - buttonActiveDiscussion.classList.add('active'); + this.showButtonDiscussionBtn(); }); - buttonActiveDiscussion.classList.add('active-btn'); - buttonActiveDiscussion.classList.add('active'); - buttonActiveDiscussion.innerHTML = ``; - buttonActiveDiscussion.addEventListener('click', () => { + this.buttonActiveDiscussion.classList.add('active-btn'); + this.buttonActiveDiscussion.innerHTML = ``; + this.buttonActiveDiscussion.addEventListener('click', () => { this.activeDiscussion = true; this.divDiscuss?.classList.add('active'); - buttonActiveDiscussion.classList.remove('active'); + this.hideButtonDiscussionBtn(); }); this.divDiscuss.appendChild(buttonCloseDiscussion); - this.divDiscuss.appendChild(buttonActiveDiscussion); + this.divDiscuss.appendChild(this.buttonActiveDiscussion); const myName: HTMLParagraphElement = document.createElement('p'); myName.innerText = name.toUpperCase(); @@ -123,7 +123,9 @@ export class DiscussionManager { } this.divParticipants?.appendChild(divParticipant); + this.participants.set(userId, divParticipant); + this.showButtonDiscussionBtn(); this.updateParticipant(this.participants.size); } @@ -165,7 +167,13 @@ export class DiscussionManager { const element = this.participants.get(userId); if(element){ element.remove(); + this.participants.delete(userId); } + //if all participant leave, hide discussion button + if(this.participants.size === 1){ + this.hideButtonDiscussionBtn(); + } + this.sendMessageCallBack.delete(userId); } @@ -176,4 +184,16 @@ export class DiscussionManager { get activatedDiscussion(){ return this.activeDiscussion; } + + private showButtonDiscussionBtn(){ + //if it's first participant, show discussion button + if(this.activatedDiscussion || this.participants.size === 1) { + return; + } + this.buttonActiveDiscussion?.classList.add('active'); + } + + private hideButtonDiscussionBtn(){ + this.buttonActiveDiscussion?.classList.remove('active'); + } } \ No newline at end of file From 3333b3cee3beae37606c7f0cae7f7c5afd0dfe5e Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 10 Nov 2020 12:38:32 +0100 Subject: [PATCH 12/18] Fix feedback moufmouf --- front/dist/resources/style/style.css | 3 ++- front/src/Phaser/Game/GameScene.ts | 1 + front/src/WebRtc/DiscussionManager.ts | 36 ++++++++++++++++++++++++--- front/src/WebRtc/MediaManager.ts | 15 ++++++++--- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/front/dist/resources/style/style.css b/front/dist/resources/style/style.css index e26256b8..fc055941 100644 --- a/front/dist/resources/style/style.css +++ b/front/dist/resources/style/style.css @@ -840,7 +840,7 @@ div.modal-report-user{ position: absolute; height: calc(100% - 360px); overflow-x: hidden; - overflow-y: scroll; + overflow-y: auto; max-width: calc(100% - 40px); width: calc(100% - 40px); } @@ -887,6 +887,7 @@ div.modal-report-user{ color: white; border-radius: 15px; border: none; + padding: 6px; } .discussion .send-message img{ diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index dd2694f8..6aa678a4 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -387,6 +387,7 @@ export class GameScene extends ResizableScene implements CenterListener { //create input to move this.userInputManager = new UserInputManager(this); + mediaManager.setUserInputManager(this.userInputManager); //notify game manager can to create currentUser in map this.createCurrentPlayer(); diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index 37767ffa..1671f661 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -1,5 +1,6 @@ import {HtmlUtils} from "./HtmlUtils"; import {MediaManager, ReportCallback, UpdatedLocalStreamCallback} from "./MediaManager"; +import {UserInputManager} from "../Phaser/UserInput/UserInputManager"; export type SendMessageCallback = (message:string) => void; export class DiscussionManager { @@ -17,6 +18,8 @@ export class DiscussionManager { private sendMessageCallBack : Map = new Map(); + private userInputManager?: UserInputManager; + constructor(private mediaManager: MediaManager, name: string) { this.mainContainer = HtmlUtils.getElementByIdOrFail('main-container'); this.createDiscussPart(name); @@ -31,15 +34,13 @@ export class DiscussionManager { buttonCloseDiscussion.classList.add('close-btn'); buttonCloseDiscussion.innerHTML = ``; buttonCloseDiscussion.addEventListener('click', () => { - this.activeDiscussion = false; - this.divDiscuss?.classList.remove('active'); + this.hideDiscussion(); this.showButtonDiscussionBtn(); }); this.buttonActiveDiscussion.classList.add('active-btn'); this.buttonActiveDiscussion.innerHTML = ``; this.buttonActiveDiscussion.addEventListener('click', () => { - this.activeDiscussion = true; - this.divDiscuss?.classList.add('active'); + this.showDiscussion(); this.hideButtonDiscussionBtn(); }); this.divDiscuss.appendChild(buttonCloseDiscussion); @@ -69,6 +70,11 @@ export class DiscussionManager { inputMessage.addEventListener('keyup', (event: KeyboardEvent) => { if (event.key === 'Enter') { event.preventDefault(); + if(inputMessage.value === null + || inputMessage.value === '' + || inputMessage.value === undefined) { + return; + } this.addMessage(name, inputMessage.value, true); for(const callback of this.sendMessageCallBack.values()) { callback(inputMessage.value); @@ -117,6 +123,8 @@ export class DiscussionManager { reportBanUserAction.addEventListener('click', () => { if(reportCallback) { this.mediaManager.showReportModal(`${userId}`, name ?? '', reportCallback); + }else{ + console.info('report feature is not activated!'); } }); divParticipant.appendChild(reportBanUserAction); @@ -193,7 +201,27 @@ export class DiscussionManager { this.buttonActiveDiscussion?.classList.add('active'); } + private showDiscussion(){ + this.activeDiscussion = true; + if(this.userInputManager) { + this.userInputManager.clearAllInputKeyboard(); + } + this.divDiscuss?.classList.add('active'); + } + + private hideDiscussion(){ + this.activeDiscussion = false; + if(this.userInputManager) { + this.userInputManager.initKeyBoardEvent(); + } + this.divDiscuss?.classList.remove('active'); + } + private hideButtonDiscussionBtn(){ this.buttonActiveDiscussion?.classList.remove('active'); } + + public setUserInputManager(userInputManager : UserInputManager){ + this.userInputManager = userInputManager; + } } \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 6dc35008..907b2c0b 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -1,6 +1,7 @@ import {DivImportance, layoutManager} from "./LayoutManager"; import {HtmlUtils} from "./HtmlUtils"; import {DiscussionManager, SendMessageCallback} from "./DiscussionManager"; +import {UserInputManager} from "../Phaser/UserInput/UserInputManager"; declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any const videoConstraint: boolean|MediaTrackConstraints = { @@ -41,6 +42,8 @@ export class MediaManager { private discussionManager: DiscussionManager; + private userInputManager?: UserInputManager; + constructor() { this.myCamVideo = HtmlUtils.getElementByIdOrFail('myCamVideo'); @@ -93,7 +96,7 @@ export class MediaManager { //update tracking }); - this.discussionManager = new DiscussionManager(this,'test'); + this.discussionManager = new DiscussionManager(this,''); } public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void { @@ -572,20 +575,24 @@ export class MediaManager { } public removeParticipant(userId: number|string){ - this.discussionManager.removeParticipant(userId) + this.discussionManager.removeParticipant(userId); } public addNewMessage(name: string, message: string, isMe: boolean = false){ - this.discussionManager.addMessage(name, message, isMe) + this.discussionManager.addMessage(name, message, isMe); } public addSendMessageCallback(userId: string|number, callback: SendMessageCallback){ - this.discussionManager.onSendMessageCallback(userId, callback) + this.discussionManager.onSendMessageCallback(userId, callback); } get activatedDiscussion(){ return this.discussionManager.activatedDiscussion; } + + public setUserInputManager(userInputManager : UserInputManager){ + this.discussionManager.setUserInputManager(userInputManager); + } } export const mediaManager = new MediaManager(); From 0acbe20bbf9d2db310b25b1410c9c3a1a17911f1 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 10 Nov 2020 13:00:14 +0100 Subject: [PATCH 13/18] Fix name send in message --- front/src/Phaser/Game/GameScene.ts | 2 +- front/src/WebRtc/SimplePeer.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 6aa678a4..d34541dd 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -603,7 +603,7 @@ export class GameScene extends ResizableScene implements CenterListener { }); // When connection is performed, let's connect SimplePeer - this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic); + this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.GameManager.getPlayerName()); this.GlobalMessageManager = new GlobalMessageManager(this.connection); this.UserMessageManager = new UserMessageManager(this.connection); diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 72c9d890..195b57b3 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -38,7 +38,7 @@ export class SimplePeer { private readonly stopLocalScreenSharingStreamCallback: StopScreenSharingCallback; private readonly peerConnectionListeners: Array = new Array(); - constructor(private Connection: RoomConnection, private enableReporting: boolean) { + constructor(private Connection: RoomConnection, private enableReporting: boolean, private myName: string) { // We need to go through this weird bound function pointer in order to be able to "free" this reference later. this.sendLocalVideoStreamCallback = this.sendLocalVideoStream.bind(this); this.sendLocalScreenSharingStreamCallback = this.sendLocalScreenSharingStream.bind(this); @@ -148,7 +148,7 @@ export class SimplePeer { //permit to send message mediaManager.addSendMessageCallback(user.userId,(message: string) => { - peer.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_MESSAGE, name: name?.toUpperCase(), message: message}))); + peer.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_MESSAGE, name: this.myName.toUpperCase(), message: message}))); }); peer.toClose = false; From 73fa0ecbfc9eabb5fb6a51386fe64632dad99d25 Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 10 Nov 2020 17:00:23 +0100 Subject: [PATCH 14/18] Fix init position and trigger layers properties --- front/src/Phaser/Game/GameScene.ts | 68 +++++++++++++++++------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 96648255..d632045f 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -466,35 +466,7 @@ export class GameScene extends ResizableScene implements CenterListener { // From now, this game scene will be notified of reposition events layoutManager.setListener(this); - - this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue) => { - if (newValue === undefined) { - coWebsiteManager.closeCoWebsite(); - } else { - coWebsiteManager.loadCoWebsite(newValue as string); - } - }); - this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => { - if (newValue === undefined) { - this.stopJitsi(); - } else { - 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.gameMap.onPropertyChange('silent', (newValue, oldValue) => { - if (newValue === undefined || newValue === false || newValue === '') { - this.connection.setSilent(false); - } else { - this.connection.setSilent(true); - } - }); + this.triggerOnMapLayerPropertyChange(); const camera = this.cameras.main; @@ -627,14 +599,49 @@ export class GameScene extends ResizableScene implements CenterListener { this.gameMap.setPosition(event.x, event.y); }) - this.scene.wake(); this.scene.sleep(ReconnectingSceneName); + //init connection in silent mode + this.connection.setSilent(true); + + //init user position and play trigger to check layers properties + this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y); + return connection; }); } + private triggerOnMapLayerPropertyChange(){ + this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue) => { + if (newValue === undefined) { + coWebsiteManager.closeCoWebsite(); + } else { + coWebsiteManager.loadCoWebsite(newValue as string); + } + }); + this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => { + if (newValue === undefined) { + this.stopJitsi(); + } else { + 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.gameMap.onPropertyChange('silent', (newValue, oldValue) => { + if (newValue === undefined || newValue === false || newValue === '') { + this.connection.setSilent(false); + } else { + this.connection.setSilent(true); + } + }); + } + private switchLayoutMode(): void { const mode = layoutManager.getLayoutMode(); if (mode === LayoutMode.Presentation) { @@ -713,6 +720,7 @@ export class GameScene extends ResizableScene implements CenterListener { */ //todo: push that into the gameManager private loadNextGame(layer: ITiledMapLayer, mapWidth: number, roomId: string){ + const room = new Room(roomId); gameManager.loadMap(room, this.scene); const exitSceneKey = roomId; From 2d0fc1072ff984fa96a91c2cece2222eea35d54f Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Mon, 16 Nov 2020 15:05:51 +0100 Subject: [PATCH 15/18] Fix feedback --- front/src/Phaser/Game/GameScene.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d632045f..7c467862 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -602,9 +602,6 @@ export class GameScene extends ResizableScene implements CenterListener { this.scene.wake(); this.scene.sleep(ReconnectingSceneName); - //init connection in silent mode - this.connection.setSilent(true); - //init user position and play trigger to check layers properties this.gameMap.setPosition(this.CurrentPlayer.x, this.CurrentPlayer.y); From 64d00bda562bf58dac42d3ffc606a9375bdc842e Mon Sep 17 00:00:00 2001 From: Gregoire Parant Date: Tue, 17 Nov 2020 16:46:46 +0100 Subject: [PATCH 16/18] Add function to show when message received --- front/src/WebRtc/DiscussionManager.ts | 8 ++++++-- front/src/WebRtc/MediaManager.ts | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/front/src/WebRtc/DiscussionManager.ts b/front/src/WebRtc/DiscussionManager.ts index 1671f661..097bf3a3 100644 --- a/front/src/WebRtc/DiscussionManager.ts +++ b/front/src/WebRtc/DiscussionManager.ts @@ -40,8 +40,7 @@ export class DiscussionManager { this.buttonActiveDiscussion.classList.add('active-btn'); this.buttonActiveDiscussion.innerHTML = ``; this.buttonActiveDiscussion.addEventListener('click', () => { - this.showDiscussion(); - this.hideButtonDiscussionBtn(); + this.showDiscussionPart(); }); this.divDiscuss.appendChild(buttonCloseDiscussion); this.divDiscuss.appendChild(this.buttonActiveDiscussion); @@ -224,4 +223,9 @@ export class DiscussionManager { public setUserInputManager(userInputManager : UserInputManager){ this.userInputManager = userInputManager; } + + public showDiscussionPart(){ + this.showDiscussion(); + this.hideButtonDiscussionBtn(); + } } \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 1c60dda8..ce1878fb 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -597,6 +597,11 @@ export class MediaManager { public addNewMessage(name: string, message: string, isMe: boolean = false){ this.discussionManager.addMessage(name, message, isMe); + + //when there are new message, show discussion + if(!this.discussionManager.activatedDiscussion) { + this.discussionManager.showDiscussionPart(); + } } public addSendMessageCallback(userId: string|number, callback: SendMessageCallback){ From 25f6fa7d2acae06e3833b92011185240c89788d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 17 Nov 2020 18:27:33 +0100 Subject: [PATCH 17/18] Migrating to rlespinasse/github-slug-action@3.1.0 --- .github/workflows/build-and-deploy.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index 390f2556..4cf2a8fb 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -20,7 +20,7 @@ jobs: # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@1.1.1 + - uses: rlespinasse/github-slug-action@3.1.0 - name: "Build and push front image" uses: docker/build-push-action@v1 @@ -43,7 +43,7 @@ jobs: uses: actions/checkout@v2 # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@1.1.1 + - uses: rlespinasse/github-slug-action@3.1.0 - name: "Build and push back image" uses: docker/build-push-action@v1 @@ -66,7 +66,7 @@ jobs: uses: actions/checkout@v2 # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@1.1.1 + - uses: rlespinasse/github-slug-action@3.1.0 - name: "Build and push back image" uses: docker/build-push-action@v1 @@ -90,7 +90,7 @@ jobs: # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@1.1.1 + - uses: rlespinasse/github-slug-action@3.1.0 - name: "Build and push front image" uses: docker/build-push-action@v1 @@ -114,7 +114,7 @@ jobs: uses: actions/checkout@v2 # Create a slugified value of the branch - - uses: rlespinasse/github-slug-action@1.1.0 + - uses: rlespinasse/github-slug-action@3.1.0 - name: Deploy uses: thecodingmachine/deeployer@master From 55ce1eee034f429433db8aed0535f8a7d7ace6f0 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 18 Nov 2020 08:40:42 +0100 Subject: [PATCH 18/18] 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 @@