Adding CoWebsiteManager + first working version of flex video

This commit is contained in:
David Négrier 2020-08-13 18:21:48 +02:00
parent 83fe024c45
commit 9f6c6e0ce1
6 changed files with 326 additions and 51 deletions

View file

@ -0,0 +1,56 @@
import {HtmlUtils} from "./HtmlUtils";
export type CoWebsiteStateChangedCallback = () => void;
export class CoWebsiteManager {
private static observers = new Array<CoWebsiteStateChangedCallback>();
public static loadCoWebsite(url: string): void {
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
cowebsiteDiv.innerHTML = '';
const iframe = document.createElement('iframe');
iframe.id = 'cowebsite-iframe';
iframe.src = url;
cowebsiteDiv.appendChild(iframe);
CoWebsiteManager.fire();
}
public static closeCoWebsite(): void {
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
cowebsiteDiv.innerHTML = '';
CoWebsiteManager.fire();
}
public static getGameSize(): {width: number, height: number} {
const iframe = document.getElementById('cowebsite-iframe');
if (iframe === null) {
return {
width: window.innerWidth,
height: window.innerHeight
}
}
if (window.innerWidth >= window.innerHeight) {
return {
width: window.innerWidth / 2,
height: window.innerHeight
}
} else {
return {
width: window.innerWidth,
height: window.innerHeight / 2
}
}
}
public static onStateChange(observer: CoWebsiteStateChangedCallback) {
CoWebsiteManager.observers.push(observer);
}
private static fire(): void {
for (const callback of CoWebsiteManager.observers) {
callback();
}
}
}

View file

@ -18,7 +18,7 @@ export enum DivImportance {
* This class is in charge of the video-conference layout.
* It receives positioning requests for videos and does its best to place them on the screen depending on the active layout mode.
*/
export class LayoutManager {
class LayoutManager {
private mode: LayoutMode = LayoutMode.Presentation;
private importantDivs: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
@ -26,7 +26,7 @@ export class LayoutManager {
public add(importance: DivImportance, userId: string, html: string): void {
const div = document.createElement('div');
div.append(html);
div.innerHTML = html;
div.id = "user-"+userId;
if (importance === DivImportance.Important) {
@ -65,6 +65,7 @@ export class LayoutManager {
* Removes the DIV matching userId.
*/
public remove(userId: string): void {
console.log('Removing video for userID '+userId+'.');
let div = this.importantDivs.get(userId);
if (div !== undefined) {
div.remove();
@ -81,7 +82,8 @@ export class LayoutManager {
return;
}
throw new Error('Could not find user ID "'+userId+'"');
console.log('Cannot remove userID '+userId+'. Already removed?');
//throw new Error('Could not find user ID "'+userId+'"');
}
private adjustVideoChatClass(): void {
@ -104,6 +106,16 @@ export class LayoutManager {
private switchLayoutMode(layoutMode: LayoutMode) {
this.mode = layoutMode;
if (layoutMode === LayoutMode.Presentation) {
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').style.display = 'block';
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section').style.display = 'block';
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode').style.display = 'none';
} else {
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').style.display = 'none';
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section').style.display = 'none';
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode').style.display = 'block';
}
for (let div of this.importantDivs.values()) {
this.positionDiv(div, DivImportance.Important);
}
@ -112,3 +124,7 @@ export class LayoutManager {
}
}
}
const layoutManager = new LayoutManager();
export { layoutManager };

View file

@ -1,3 +1,5 @@
import {DivImportance, layoutManager} from "./LayoutManager";
const videoConstraint: boolean|MediaTrackConstraints = {
width: { ideal: 1280 },
height: { ideal: 720 },
@ -73,8 +75,8 @@ export class MediaManager {
}
activeVisio(){
const webRtc = this.getElementByIdOrFail('webRtc');
webRtc.classList.add('active');
const gameOverlay = this.getElementByIdOrFail('game-overlay');
gameOverlay.classList.add('active');
}
enabledCamera() {
@ -184,10 +186,11 @@ export class MediaManager {
*/
addActiveVideo(userId : string, userName: string = ""){
this.webrtcInAudio.play();
const elementRemoteVideo = this.getElementByIdOrFail("activeCam");
//const elementRemoteVideo = this.getElementByIdOrFail("activeCam");
userName = userName.toUpperCase();
const color = this.getColorByString(userName);
elementRemoteVideo.insertAdjacentHTML('beforeend', `
/*elementRemoteVideo.insertAdjacentHTML('beforeend', `
<div id="div-${userId}" class="video-container" style="border-color: ${color};">
<div class="connecting-spinner"></div>
<div class="rtc-error" style="display: none"></div>
@ -195,7 +198,20 @@ export class MediaManager {
<img id="microphone-${userId}" src="resources/logos/microphone-close.svg">
<video id="${userId}" autoplay></video>
</div>
`);
`);*/
const html = `
<div id="div-${userId}" class="video-container">
<div class="connecting-spinner"></div>
<div class="rtc-error" style="display: none"></div>
<i style="background-color: ${color};">${userName}</i>
<img id="microphone-${userId}" src="resources/logos/microphone-close.svg">
<video id="${userId}" autoplay></video>
</div>
`;
layoutManager.add(DivImportance.Normal, userId, html);
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
}
@ -274,11 +290,12 @@ export class MediaManager {
* @param userId
*/
removeActiveVideo(userId : string){
const element = document.getElementById(`div-${userId}`);
/*const element = document.getElementById(`div-${userId}`);
if(!element){
return;
}
element.remove();
element.remove();*/
layoutManager.remove(userId);
this.remoteVideo.delete(userId);
}

View file

@ -4,16 +4,21 @@ import {DEBUG_MODE, RESOLUTION} from "./Enum/EnvironmentVariable";
import {cypressAsserter} from "./Cypress/CypressAsserter";
import {LoginScene} from "./Phaser/Login/LoginScene";
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
import {gameManager} from "./Phaser/Game/GameManager";
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
import {EnableCameraScene} from "./Phaser/Login/EnableCameraScene";
import {FourOFourScene} from "./Phaser/Reconnecting/FourOFourScene";
import {CustomizeScene} from "./Phaser/Login/CustomizeScene";
import {HtmlUtils} from "./WebRtc/HtmlUtils";
import {CoWebsiteManager} from "./WebRtc/CoWebsiteManager";
//CoWebsiteManager.loadCoWebsite('https://thecodingmachine.com');
const {width, height} = CoWebsiteManager.getGameSize();
const config: GameConfig = {
title: "WorkAdventure",
width: window.innerWidth / RESOLUTION,
height: window.innerHeight / RESOLUTION,
width: width / RESOLUTION,
height: height / RESOLUTION,
parent: "game",
scene: [LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene, CustomizeScene],
zoom: RESOLUTION,
@ -30,5 +35,12 @@ cypressAsserter.gameStarted();
const game = new Phaser.Game(config);
window.addEventListener('resize', function (event) {
game.scale.resize(window.innerWidth / RESOLUTION, window.innerHeight / RESOLUTION);
const {width, height} = CoWebsiteManager.getGameSize();
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
});
CoWebsiteManager.onStateChange(() => {
const {width, height} = CoWebsiteManager.getGameSize();
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
});