Code cleanup
This commit is contained in:
parent
d533894a74
commit
d6ec0d22d3
3 changed files with 3 additions and 243 deletions
BIN
front/dist/resources/objects/layout_modes.png
vendored
BIN
front/dist/resources/objects/layout_modes.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 297 B |
|
@ -43,7 +43,7 @@ import {
|
||||||
TRIGGER_WEBSITE_PROPERTIES,
|
TRIGGER_WEBSITE_PROPERTIES,
|
||||||
WEBSITE_MESSAGE_PROPERTIES,
|
WEBSITE_MESSAGE_PROPERTIES,
|
||||||
AUDIO_VOLUME_PROPERTY,
|
AUDIO_VOLUME_PROPERTY,
|
||||||
AUDIO_LOOP_PROPERTY
|
AUDIO_LOOP_PROPERTY, Box
|
||||||
} from "../../WebRtc/LayoutManager";
|
} from "../../WebRtc/LayoutManager";
|
||||||
import {GameMap} from "./GameMap";
|
import {GameMap} from "./GameMap";
|
||||||
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||||
|
@ -176,8 +176,6 @@ export class GameScene extends DirtyScene /*implements CenterListener*/ {
|
||||||
y: -1000
|
y: -1000
|
||||||
}
|
}
|
||||||
|
|
||||||
private presentationModeSprite!: Sprite;
|
|
||||||
private chatModeSprite!: Sprite;
|
|
||||||
private gameMap!: GameMap;
|
private gameMap!: GameMap;
|
||||||
private actionableItems: Map<number, ActionableItem> = new Map<number, ActionableItem>();
|
private actionableItems: Map<number, ActionableItem> = new Map<number, ActionableItem>();
|
||||||
// The item that can be selected by pressing the space key.
|
// The item that can be selected by pressing the space key.
|
||||||
|
@ -280,7 +278,6 @@ export class GameScene extends DirtyScene /*implements CenterListener*/ {
|
||||||
this.onMapLoad(data);
|
this.onMapLoad(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.load.spritesheet('layout_modes', 'resources/objects/layout_modes.png', {frameWidth: 32, frameHeight: 32});
|
|
||||||
this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||||
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
//eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
(this.load as any).rexWebFont({
|
(this.load as any).rexWebFont({
|
||||||
|
@ -502,10 +499,6 @@ export class GameScene extends DirtyScene /*implements CenterListener*/ {
|
||||||
this.outlinedItem?.activate();
|
this.outlinedItem?.activate();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.presentationModeSprite = new PresentationModeIcon(this, 36, this.game.renderer.height - 2);
|
|
||||||
this.presentationModeSprite.on('pointerup', this.switchLayoutMode.bind(this));
|
|
||||||
this.chatModeSprite = new ChatModeIcon(this, 70, this.game.renderer.height - 2);
|
|
||||||
this.chatModeSprite.on('pointerup', this.switchLayoutMode.bind(this));
|
|
||||||
this.openChatIcon = new OpenChatIcon(this, 2, this.game.renderer.height - 2)
|
this.openChatIcon = new OpenChatIcon(this, 2, this.game.renderer.height - 2)
|
||||||
|
|
||||||
// FIXME: change this to use the UserInputManager class for input
|
// FIXME: change this to use the UserInputManager class for input
|
||||||
|
@ -518,7 +511,7 @@ export class GameScene extends DirtyScene /*implements CenterListener*/ {
|
||||||
|
|
||||||
// From now, this game scene will be notified of reposition events
|
// From now, this game scene will be notified of reposition events
|
||||||
//layoutManager.setListener(this);
|
//layoutManager.setListener(this);
|
||||||
biggestAvailableArrayStore.subscribe((box) => this.updateCameraOffset());
|
biggestAvailableArrayStore.subscribe((box) => this.updateCameraOffset(box));
|
||||||
|
|
||||||
this.triggerOnMapLayerPropertyChange();
|
this.triggerOnMapLayerPropertyChange();
|
||||||
this.listenToIframeEvents();
|
this.listenToIframeEvents();
|
||||||
|
@ -658,15 +651,11 @@ export class GameScene extends DirtyScene /*implements CenterListener*/ {
|
||||||
const self = this;
|
const self = this;
|
||||||
this.simplePeer.registerPeerConnectionListener({
|
this.simplePeer.registerPeerConnectionListener({
|
||||||
onConnect(peer) {
|
onConnect(peer) {
|
||||||
self.presentationModeSprite.setVisible(true);
|
|
||||||
self.chatModeSprite.setVisible(true);
|
|
||||||
self.openChatIcon.setVisible(true);
|
self.openChatIcon.setVisible(true);
|
||||||
audioManager.decreaseVolume();
|
audioManager.decreaseVolume();
|
||||||
},
|
},
|
||||||
onDisconnect(userId: number) {
|
onDisconnect(userId: number) {
|
||||||
if (self.simplePeer.getNbConnections() === 0) {
|
if (self.simplePeer.getNbConnections() === 0) {
|
||||||
self.presentationModeSprite.setVisible(false);
|
|
||||||
self.chatModeSprite.setVisible(false);
|
|
||||||
self.openChatIcon.setVisible(false);
|
self.openChatIcon.setVisible(false);
|
||||||
audioManager.restoreVolume();
|
audioManager.restoreVolume();
|
||||||
}
|
}
|
||||||
|
@ -1016,23 +1005,6 @@ ${escapedMessage}
|
||||||
this.MapPlayersByKey = new Map<number, RemotePlayer>();
|
this.MapPlayersByKey = new Map<number, RemotePlayer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
this.presentationModeSprite.setFrame(1);
|
|
||||||
this.chatModeSprite.setFrame(2);
|
|
||||||
} else {
|
|
||||||
layoutManager.switchLayoutMode(LayoutMode.Presentation);
|
|
||||||
this.presentationModeSprite.setFrame(0);
|
|
||||||
this.chatModeSprite.setFrame(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private initStartXAndStartY() {
|
private initStartXAndStartY() {
|
||||||
// If there is an init position passed
|
// If there is an init position passed
|
||||||
if (this.initPosition !== null) {
|
if (this.initPosition !== null) {
|
||||||
|
@ -1523,8 +1495,6 @@ ${escapedMessage}
|
||||||
|
|
||||||
}
|
}
|
||||||
private reposition(): void {
|
private reposition(): void {
|
||||||
this.presentationModeSprite.setY(this.game.renderer.height - 2);
|
|
||||||
this.chatModeSprite.setY(this.game.renderer.height - 2);
|
|
||||||
this.openChatIcon.setY(this.game.renderer.height - 2);
|
this.openChatIcon.setY(this.game.renderer.height - 2);
|
||||||
|
|
||||||
// Recompute camera offset if needed
|
// Recompute camera offset if needed
|
||||||
|
@ -1536,8 +1506,7 @@ ${escapedMessage}
|
||||||
* Updates the offset of the character compared to the center of the screen according to the layout manager
|
* Updates the offset of the character compared to the center of the screen according to the layout manager
|
||||||
* (tries to put the character in the center of the remaining space if there is a discussion going on.
|
* (tries to put the character in the center of the remaining space if there is a discussion going on.
|
||||||
*/
|
*/
|
||||||
private updateCameraOffset(): void {
|
private updateCameraOffset(array: Box): void {
|
||||||
const array = layoutManager.findBiggestAvailableArray();
|
|
||||||
const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart;
|
const xCenter = (array.xEnd - array.xStart) / 2 + array.xStart;
|
||||||
const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart;
|
const yCenter = (array.yEnd - array.yStart) / 2 + array.yStart;
|
||||||
|
|
||||||
|
|
|
@ -36,219 +36,10 @@ export const AUDIO_LOOP_PROPERTY = 'audioLoop';
|
||||||
|
|
||||||
export type Box = {xStart: number, yStart: number, xEnd: number, yEnd: number};
|
export type Box = {xStart: number, yStart: number, xEnd: number, yEnd: number};
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
class LayoutManager {
|
class LayoutManager {
|
||||||
private mode: LayoutMode = LayoutMode.Presentation;
|
|
||||||
|
|
||||||
private importantDivs: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
|
||||||
private normalDivs: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
|
||||||
private listener: CenterListener|null = null;
|
|
||||||
|
|
||||||
private actionButtonTrigger: Map<string, Function> = new Map<string, Function>();
|
private actionButtonTrigger: Map<string, Function> = new Map<string, Function>();
|
||||||
private actionButtonInformation: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
private actionButtonInformation: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
||||||
|
|
||||||
public setListener(centerListener: CenterListener|null) {
|
|
||||||
this.listener = centerListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
private positionDiv(elem: HTMLDivElement, importance: DivImportance): void {
|
|
||||||
if (this.mode === LayoutMode.VideoChat) {
|
|
||||||
const chatModeDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode');
|
|
||||||
chatModeDiv.appendChild(elem);
|
|
||||||
} else {
|
|
||||||
if (importance === DivImportance.Important) {
|
|
||||||
const mainSectionDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section');
|
|
||||||
mainSectionDiv.appendChild(elem);
|
|
||||||
} else if (importance === DivImportance.Normal) {
|
|
||||||
const sideBarDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar');
|
|
||||||
sideBarDiv.appendChild(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
this.importantDivs.delete(userId);
|
|
||||||
this.adjustVideoChatClass();
|
|
||||||
this.listener?.onCenterChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
div = this.normalDivs.get(userId);
|
|
||||||
if (div !== undefined) {
|
|
||||||
div.remove();
|
|
||||||
this.normalDivs.delete(userId);
|
|
||||||
this.adjustVideoChatClass();
|
|
||||||
this.listener?.onCenterChange();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Cannot remove userID '+userId+'. Already removed?');
|
|
||||||
//throw new Error('Could not find user ID "'+userId+'"');
|
|
||||||
}
|
|
||||||
|
|
||||||
private adjustVideoChatClass(): void {
|
|
||||||
const chatModeDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('chat-mode');
|
|
||||||
chatModeDiv.classList.remove('one-col', 'two-col', 'three-col', 'four-col');
|
|
||||||
|
|
||||||
const nbUsers = this.importantDivs.size + this.normalDivs.size;
|
|
||||||
|
|
||||||
if (nbUsers <= 1) {
|
|
||||||
chatModeDiv.classList.add('one-col');
|
|
||||||
} else if (nbUsers <= 4) {
|
|
||||||
chatModeDiv.classList.add('two-col');
|
|
||||||
} else if (nbUsers <= 9) {
|
|
||||||
chatModeDiv.classList.add('three-col');
|
|
||||||
} else {
|
|
||||||
chatModeDiv.classList.add('four-col');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public switchLayoutMode(layoutMode: LayoutMode) {
|
|
||||||
this.mode = layoutMode;
|
|
||||||
|
|
||||||
if (layoutMode === LayoutMode.Presentation) {
|
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').style.display = 'flex';
|
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-section').style.display = 'flex';
|
|
||||||
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 = 'grid';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const div of this.importantDivs.values()) {
|
|
||||||
this.positionDiv(div, DivImportance.Important);
|
|
||||||
}
|
|
||||||
for (const div of this.normalDivs.values()) {
|
|
||||||
this.positionDiv(div, DivImportance.Normal);
|
|
||||||
}
|
|
||||||
this.listener?.onCenterChange();
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLayoutMode(): LayoutMode {
|
|
||||||
return this.mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public getGameCenter(): {x: number, y: number} {
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to find the biggest available box of remaining space (this is a space where we can center the character)
|
|
||||||
*/
|
|
||||||
public findBiggestAvailableArray(): Box {
|
|
||||||
const game = HtmlUtils.querySelectorOrFail<HTMLCanvasElement>('#game canvas');
|
|
||||||
if (this.mode === LayoutMode.VideoChat) {
|
|
||||||
const children = document.querySelectorAll<HTMLDivElement>('div.chat-mode > div');
|
|
||||||
const htmlChildren = Array.from(children.values());
|
|
||||||
|
|
||||||
// No chat? Let's go full center
|
|
||||||
if (htmlChildren.length === 0) {
|
|
||||||
return {
|
|
||||||
xStart: 0,
|
|
||||||
yStart: 0,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastDiv = htmlChildren[htmlChildren.length - 1];
|
|
||||||
// Compute area between top right of the last div and bottom right of window
|
|
||||||
const area1 = (game.offsetWidth - (lastDiv.offsetLeft + lastDiv.offsetWidth))
|
|
||||||
* (game.offsetHeight - lastDiv.offsetTop);
|
|
||||||
|
|
||||||
// Compute area between bottom of last div and bottom of the screen on whole width
|
|
||||||
const area2 = game.offsetWidth
|
|
||||||
* (game.offsetHeight - (lastDiv.offsetTop + lastDiv.offsetHeight));
|
|
||||||
|
|
||||||
if (area1 < 0 && area2 < 0) {
|
|
||||||
// If screen is full, let's not attempt something foolish and simply center character in the middle.
|
|
||||||
return {
|
|
||||||
xStart: 0,
|
|
||||||
yStart: 0,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (area1 <= area2) {
|
|
||||||
console.log('lastDiv', lastDiv.offsetTop, lastDiv.offsetHeight);
|
|
||||||
return {
|
|
||||||
xStart: 0,
|
|
||||||
yStart: lastDiv.offsetTop + lastDiv.offsetHeight,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('lastDiv', lastDiv.offsetTop);
|
|
||||||
return {
|
|
||||||
xStart: lastDiv.offsetLeft + lastDiv.offsetWidth,
|
|
||||||
yStart: lastDiv.offsetTop,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Possible destinations: at the center bottom or at the right bottom.
|
|
||||||
const mainSectionChildren = Array.from(document.querySelectorAll<HTMLDivElement>('div.main-section > div').values());
|
|
||||||
const sidebarChildren = Array.from(document.querySelectorAll<HTMLDivElement>('aside.sidebar > div').values());
|
|
||||||
|
|
||||||
// No presentation? Let's center on the screen
|
|
||||||
if (mainSectionChildren.length === 0) {
|
|
||||||
return {
|
|
||||||
xStart: 0,
|
|
||||||
yStart: 0,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, we know we have at least one element in the main section.
|
|
||||||
const lastPresentationDiv = mainSectionChildren[mainSectionChildren.length-1];
|
|
||||||
|
|
||||||
const presentationArea = (game.offsetHeight - (lastPresentationDiv.offsetTop + lastPresentationDiv.offsetHeight))
|
|
||||||
* (lastPresentationDiv.offsetLeft + lastPresentationDiv.offsetWidth);
|
|
||||||
|
|
||||||
let leftSideBar: number;
|
|
||||||
let bottomSideBar: number;
|
|
||||||
if (sidebarChildren.length === 0) {
|
|
||||||
leftSideBar = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('sidebar').offsetLeft;
|
|
||||||
bottomSideBar = 0;
|
|
||||||
} else {
|
|
||||||
const lastSideBarChildren = sidebarChildren[sidebarChildren.length - 1];
|
|
||||||
leftSideBar = lastSideBarChildren.offsetLeft;
|
|
||||||
bottomSideBar = lastSideBarChildren.offsetTop + lastSideBarChildren.offsetHeight;
|
|
||||||
}
|
|
||||||
const sideBarArea = (game.offsetWidth - leftSideBar)
|
|
||||||
* (game.offsetHeight - bottomSideBar);
|
|
||||||
|
|
||||||
if (presentationArea <= sideBarArea) {
|
|
||||||
return {
|
|
||||||
xStart: leftSideBar,
|
|
||||||
yStart: bottomSideBar,
|
|
||||||
xEnd: game.offsetWidth,
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
xStart: 0,
|
|
||||||
yStart: lastPresentationDiv.offsetTop + lastPresentationDiv.offsetHeight,
|
|
||||||
xEnd: /*lastPresentationDiv.offsetLeft + lastPresentationDiv.offsetWidth*/ game.offsetWidth , // To avoid flickering when a chat start, we center on the center of the screen, not the center of the main content area
|
|
||||||
yEnd: game.offsetHeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public addActionButton(id: string, text: string, callBack: Function, userInputManager: UserInputManager){
|
public addActionButton(id: string, text: string, callBack: Function, userInputManager: UserInputManager){
|
||||||
//delete previous element
|
//delete previous element
|
||||||
this.removeActionButton(id, userInputManager);
|
this.removeActionButton(id, userInputManager);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue