2021-06-21 14:07:03 +02:00
import { get , writable } from "svelte/store" ;
2021-06-17 10:07:15 +02:00
import type { Box } from "../WebRtc/LayoutManager" ;
import { HtmlUtils } from "../WebRtc/HtmlUtils" ;
import { LayoutMode } from "../WebRtc/LayoutManager" ;
import { layoutModeStore } from "./LayoutStore" ;
/ * *
* Tries to find the biggest available box of remaining space ( this is a space where we can center the character )
* /
2021-06-21 14:07:03 +02:00
function findBiggestAvailableArea ( ) : Box {
2021-06-17 10:07:15 +02:00
const game = HtmlUtils . querySelectorOrFail < HTMLCanvasElement > ( '#game canvas' ) ;
if ( get ( layoutModeStore ) === 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 ) {
return {
xStart : 0 ,
yStart : lastDiv.offsetTop + lastDiv . offsetHeight ,
xEnd : game.offsetWidth ,
yEnd : game.offsetHeight
}
} else {
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
}
}
}
}
/ * *
* A store that contains the list of ( video ) peers we are connected to .
* /
2021-06-21 14:07:03 +02:00
function createBiggestAvailableAreaStore() {
2021-06-17 10:07:15 +02:00
2021-06-21 14:07:03 +02:00
const { subscribe , set } = writable < Box > ( { xStart :0 , yStart : 0 , xEnd : 1 , yEnd : 1 } ) ;
2021-06-17 10:07:15 +02:00
return {
subscribe ,
recompute : ( ) = > {
2021-06-21 14:07:03 +02:00
set ( findBiggestAvailableArea ( ) ) ;
2021-06-17 10:07:15 +02:00
}
} ;
}
2021-06-21 14:07:03 +02:00
export const biggestAvailableAreaStore = createBiggestAvailableAreaStore ( ) ;