Create send data discussion
This commit is contained in:
parent
f344adc48b
commit
1945c24704
77
front/dist/resources/style/style.css
vendored
77
front/dist/resources/style/style.css
vendored
@ -689,16 +689,17 @@ div.modal-report-user{
|
|||||||
/*MESSAGE*/
|
/*MESSAGE*/
|
||||||
.discussion{
|
.discussion{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: -300px;
|
left: -300px;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: #000000;
|
background-color: #333333;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
transition: all 0.5s ease;
|
||||||
}
|
}
|
||||||
.discussion.active{
|
.discussion.active{
|
||||||
right: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
.discussion .toggle-btn{
|
.discussion .active-btn{
|
||||||
display: none;
|
display: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@ -706,22 +707,36 @@ div.modal-report-user{
|
|||||||
background-color: #2d2d2dba;
|
background-color: #2d2d2dba;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(50% - 25px);
|
top: calc(50% - 25px);
|
||||||
margin-left: -125px;
|
margin-left: 315px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
border: none;
|
border: none;
|
||||||
transition: all 0.5s ease;
|
transition: all 0.5s ease;
|
||||||
}
|
}
|
||||||
.discussion .toggle-btn.active{
|
.discussion .active-btn.active{
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
.discussion .toggle-btn:hover {
|
.discussion .active-btn:hover {
|
||||||
transform: scale(1.1) rotateY(3.142rad);
|
transform: scale(1.1) rotateY(3.142rad);
|
||||||
}
|
}
|
||||||
.discussion .toggle-btn img{
|
.discussion .active-btn img{
|
||||||
width: 26px;
|
width: 26px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
margin: 13px 5px;
|
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{
|
.discussion p{
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
@ -793,13 +808,22 @@ div.modal-report-user{
|
|||||||
|
|
||||||
.discussion .messages{
|
.discussion .messages{
|
||||||
position: absolute;
|
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{
|
.discussion .messages .message{
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
float: right;
|
float: right;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discussion .messages .message.me{
|
.discussion .messages .message.me{
|
||||||
@ -811,3 +835,38 @@ div.modal-report-user{
|
|||||||
font-size: 12px;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import {cypressAsserter} from "../../Cypress/CypressAsserter";
|
|||||||
import {SelectCharacterSceneName} from "./SelectCharacterScene";
|
import {SelectCharacterSceneName} from "./SelectCharacterScene";
|
||||||
import {ResizableScene} from "./ResizableScene";
|
import {ResizableScene} from "./ResizableScene";
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
import {Discussion} from "../../WebRtc/Discussion";
|
|
||||||
|
|
||||||
//todo: put this constants in a dedicated file
|
//todo: put this constants in a dedicated file
|
||||||
export const LoginSceneName = "LoginScene";
|
export const LoginSceneName = "LoginScene";
|
||||||
@ -75,13 +74,6 @@ export class LoginScene extends ResizableScene {
|
|||||||
});
|
});
|
||||||
|
|
||||||
cypressAsserter.initFinished();
|
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 {
|
update(time: number, delta: number): void {
|
||||||
|
@ -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<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
|
||||||
|
|
||||||
private activeDiscussion: boolean = false;
|
|
||||||
|
|
||||||
constructor(name: string) {
|
|
||||||
this.mainContainer = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('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 = `<img src="resources/logos/discussion.svg"/>`;
|
|
||||||
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 = `<span style="font-weight: bold">${name}</span>
|
|
||||||
<span style="color:#bac2cc;display:inline-block;font-size:12px;">
|
|
||||||
${date.getHours()}:${date.getMinutes()}
|
|
||||||
</span>`;
|
|
||||||
divMessage.appendChild(pMessage);
|
|
||||||
|
|
||||||
const userMessage = document.createElement('p');
|
|
||||||
userMessage.innerText = message;
|
|
||||||
divMessage.appendChild(userMessage);
|
|
||||||
|
|
||||||
this.divMessages?.appendChild(divMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
169
front/src/WebRtc/DiscussionManager.ts
Normal file
169
front/src/WebRtc/DiscussionManager.ts
Normal file
@ -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<number|string, HTMLDivElement> = new Map<number|string, HTMLDivElement>();
|
||||||
|
|
||||||
|
private activeDiscussion: boolean = false;
|
||||||
|
|
||||||
|
private sendMessageCallBack : Set<SendMessageCallback> = new Set<SendMessageCallback>();
|
||||||
|
|
||||||
|
constructor(name: string) {
|
||||||
|
this.mainContainer = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('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 = `<img src="resources/logos/close.svg"/>`;
|
||||||
|
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 = `<img src="resources/logos/discussion.svg"/>`;
|
||||||
|
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 = "<h2>Local messages</h2>"
|
||||||
|
|
||||||
|
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 = `<span style="font-weight: bold">${name}</span>
|
||||||
|
<span style="color:#bac2cc;display:inline-block;font-size:12px;">
|
||||||
|
${date.getHours()}:${date.getMinutes()}
|
||||||
|
</span>`;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import {DivImportance, layoutManager} from "./LayoutManager";
|
import {DivImportance, layoutManager} from "./LayoutManager";
|
||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
|
import {DiscussionManager, SendMessageCallback} from "./DiscussionManager";
|
||||||
declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
|
||||||
const videoConstraint: boolean|MediaTrackConstraints = {
|
const videoConstraint: boolean|MediaTrackConstraints = {
|
||||||
@ -38,6 +39,8 @@ export class MediaManager {
|
|||||||
private cinemaBtn: HTMLDivElement;
|
private cinemaBtn: HTMLDivElement;
|
||||||
private monitorBtn: HTMLDivElement;
|
private monitorBtn: HTMLDivElement;
|
||||||
|
|
||||||
|
private discussionManager: DiscussionManager;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
this.myCamVideo = HtmlUtils.getElementByIdOrFail<HTMLVideoElement>('myCamVideo');
|
this.myCamVideo = HtmlUtils.getElementByIdOrFail<HTMLVideoElement>('myCamVideo');
|
||||||
@ -89,6 +92,8 @@ export class MediaManager {
|
|||||||
this.disableScreenSharing();
|
this.disableScreenSharing();
|
||||||
//update tracking
|
//update tracking
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.discussionManager = new DiscussionManager('test');
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void {
|
public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void {
|
||||||
@ -363,6 +368,9 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail<HTMLVideoElement>(userId));
|
this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail<HTMLVideoElement>(userId));
|
||||||
|
|
||||||
|
//permit to create participant in discussion part
|
||||||
|
this.addNewParticipant(userId, userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
||||||
@ -437,6 +445,9 @@ export class MediaManager {
|
|||||||
removeActiveVideo(userId: string){
|
removeActiveVideo(userId: string){
|
||||||
layoutManager.remove(userId);
|
layoutManager.remove(userId);
|
||||||
this.remoteVideo.delete(userId);
|
this.remoteVideo.delete(userId);
|
||||||
|
|
||||||
|
//permit to remove user in discussion part
|
||||||
|
this.removeParticipant(userId);
|
||||||
}
|
}
|
||||||
removeActiveScreenSharingVideo(userId: string) {
|
removeActiveScreenSharingVideo(userId: string) {
|
||||||
this.removeActiveVideo(`screen-sharing-${userId}`)
|
this.removeActiveVideo(`screen-sharing-${userId}`)
|
||||||
@ -556,7 +567,21 @@ export class MediaManager {
|
|||||||
mainContainer.appendChild(divReport);
|
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();
|
export const mediaManager = new MediaManager();
|
||||||
|
@ -2,6 +2,7 @@ import * as SimplePeerNamespace from "simple-peer";
|
|||||||
import {mediaManager} from "./MediaManager";
|
import {mediaManager} from "./MediaManager";
|
||||||
import {TURN_SERVER, TURN_USER, TURN_PASSWORD} from "../Enum/EnvironmentVariable";
|
import {TURN_SERVER, TURN_USER, TURN_PASSWORD} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
|
import {MESSAGE_TYPE_CONSTRAINT} from "./VideoPeer";
|
||||||
|
|
||||||
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
||||||
|
|
||||||
@ -148,6 +149,6 @@ export class ScreenSharingPeer extends Peer {
|
|||||||
|
|
||||||
public stopPushingScreenSharingToRemoteUser(stream: MediaStream) {
|
public stopPushingScreenSharingToRemoteUser(stream: MediaStream) {
|
||||||
this.removeStream(stream);
|
this.removeStream(stream);
|
||||||
this.write(new Buffer(JSON.stringify({streamEnded: true})));
|
this.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, streamEnded: true})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
UpdatedLocalStreamCallback
|
UpdatedLocalStreamCallback
|
||||||
} from "./MediaManager";
|
} from "./MediaManager";
|
||||||
import {ScreenSharingPeer} from "./ScreenSharingPeer";
|
import {ScreenSharingPeer} from "./ScreenSharingPeer";
|
||||||
import {VideoPeer} from "./VideoPeer";
|
import {MESSAGE_TYPE_CONSTRAINT, MESSAGE_TYPE_MESSAGE, VideoPeer} from "./VideoPeer";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
|
|
||||||
export interface UserSimplePeerInterface{
|
export interface UserSimplePeerInterface{
|
||||||
@ -145,6 +145,12 @@ export class SimplePeer {
|
|||||||
mediaManager.addActiveVideo("" + user.userId, reportCallback, name);
|
mediaManager.addActiveVideo("" + user.userId, reportCallback, name);
|
||||||
|
|
||||||
const peer = new VideoPeer(user.userId, user.initiator ? user.initiator : false, this.Connection);
|
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;
|
peer.toClose = false;
|
||||||
// When a connection is established to a video stream, and if a screen sharing is taking place,
|
// 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!
|
// 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);
|
throw new Error('While adding media, cannot find user with ID ' + userId);
|
||||||
}
|
}
|
||||||
const localStream: MediaStream | null = mediaManager.localStream;
|
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){
|
if(!localStream){
|
||||||
return;
|
return;
|
||||||
|
@ -5,6 +5,8 @@ import {RoomConnection} from "../Connexion/RoomConnection";
|
|||||||
|
|
||||||
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
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.
|
* A peer connection used to transmit video / audio signals between 2 peers.
|
||||||
*/
|
*/
|
||||||
@ -78,8 +80,11 @@ export class VideoPeer extends Peer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.on('data', (chunk: Buffer) => {
|
this.on('data', (chunk: Buffer) => {
|
||||||
const constraint = JSON.parse(chunk.toString('utf8'));
|
const message = JSON.parse(chunk.toString('utf8'));
|
||||||
console.log("data", constraint);
|
console.log("data", message);
|
||||||
|
|
||||||
|
if(message.type === MESSAGE_TYPE_CONSTRAINT) {
|
||||||
|
const constraint = message;
|
||||||
if (constraint.audio) {
|
if (constraint.audio) {
|
||||||
mediaManager.enabledMicrophoneByUserId(this.userId);
|
mediaManager.enabledMicrophoneByUserId(this.userId);
|
||||||
} else {
|
} else {
|
||||||
@ -92,6 +97,11 @@ export class VideoPeer extends Peer {
|
|||||||
this.stream(undefined);
|
this.stream(undefined);
|
||||||
mediaManager.disabledVideoByUserId(this.userId);
|
mediaManager.disabledVideoByUserId(this.userId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.type === 'message') {
|
||||||
|
mediaManager.addNewMessage(message.name, message.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.once('finish', () => {
|
this.once('finish', () => {
|
||||||
@ -163,7 +173,7 @@ export class VideoPeer extends Peer {
|
|||||||
private pushVideoToRemoteUser() {
|
private pushVideoToRemoteUser() {
|
||||||
try {
|
try {
|
||||||
const localStream: MediaStream | null = mediaManager.localStream;
|
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){
|
if(!localStream){
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user