Move CoWebsite to generic class

This commit is contained in:
Alexis Faizeau
2022-02-10 11:40:36 +01:00
parent f5f71f32ee
commit 7b6a3949bc
12 changed files with 508 additions and 349 deletions
+120 -217
View File
@@ -1,15 +1,13 @@
import { HtmlUtils } from "./HtmlUtils";
import { Subject } from "rxjs";
import { iframeListener } from "../Api/IframeListener";
import { waScaleManager } from "../Phaser/Services/WaScaleManager";
import { coWebsites, coWebsitesNotAsleep, mainCoWebsite } from "../Stores/CoWebsiteStore";
import { get, Writable, writable } from "svelte/store";
import { coWebsites, coWebsitesNotAsleep, jitsiCoWebsite, mainCoWebsite } from "../Stores/CoWebsiteStore";
import { get } from "svelte/store";
import { embedScreenLayout, highlightedEmbedScreen } from "../Stores/EmbedScreensStore";
import { isMediaBreakpointDown } from "../Utils/BreakpointsUtils";
import { jitsiFactory } from "./JitsiFactory";
import { gameManager } from "../Phaser/Game/GameManager";
import { LayoutMode } from "./LayoutManager";
import CancelablePromise from "cancelable-promise";
import type { CoWebsite } from "./CoWebsite/CoWesbite";
import type CancelablePromise from "cancelable-promise";
export enum iframeStates {
closed = 1,
@@ -35,20 +33,6 @@ interface TouchMoveCoordinates {
y: number;
}
export type CoWebsiteState = "asleep" | "loading" | "ready";
export type CoWebsite = {
iframe: HTMLIFrameElement;
url: URL;
state: Writable<CoWebsiteState>;
closable: boolean;
allowPolicy: string | undefined;
allowApi: boolean | undefined;
widthPercent?: number | undefined;
jitsi?: boolean;
altMessage?: string;
};
class CoWebsiteManager {
private openedMain: iframeStates = iframeStates.closed;
@@ -144,10 +128,12 @@ class CoWebsiteManager {
throw new Error("Undefined main co-website on closing");
}
if (coWebsite.closable) {
if (coWebsite.isClosable()) {
this.closeCoWebsite(coWebsite);
} else {
this.unloadCoWebsite(coWebsite);
this.unloadCoWebsite(coWebsite).catch((err) => {
console.error("Cannot unload co-website on click on close button", err);
});
}
});
@@ -234,7 +220,10 @@ class CoWebsiteManager {
return;
}
coWebsite.iframe.style.display = "none";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "none";
}
this.resizing = true;
document.addEventListener("mousemove", movecallback);
});
@@ -250,7 +239,10 @@ class CoWebsiteManager {
return;
}
coWebsite.iframe.style.display = "flex";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "flex";
}
this.resizing = false;
});
@@ -263,7 +255,10 @@ class CoWebsiteManager {
return;
}
coWebsite.iframe.style.display = "none";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "none";
}
this.resizing = true;
const touchEvent = event.touches[0];
this.previousTouchMoveCoordinates = { x: touchEvent.pageX, y: touchEvent.pageY };
@@ -282,7 +277,10 @@ class CoWebsiteManager {
return;
}
coWebsite.iframe.style.display = "flex";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "flex";
}
this.resizing = false;
});
}
@@ -306,9 +304,12 @@ class CoWebsiteManager {
public displayMain() {
const coWebsite = this.getMainCoWebsite();
if (coWebsite) {
coWebsite.iframe.style.display = "block";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "block";
}
}
this.loadMain();
this.loadMain(coWebsite?.getWidthPercent());
this.openMain();
this.fire();
}
@@ -316,7 +317,10 @@ class CoWebsiteManager {
public hideMain() {
const coWebsite = this.getMainCoWebsite();
if (coWebsite) {
coWebsite.iframe.style.display = "none";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.display = "none";
}
}
this.cowebsiteDom.classList.add("closing");
this.cowebsiteDom.classList.remove("opened");
@@ -402,7 +406,9 @@ class CoWebsiteManager {
}
public getCoWebsiteById(coWebsiteId: string): CoWebsite | undefined {
return get(coWebsites).find((coWebsite: CoWebsite) => coWebsite.iframe.id === coWebsiteId);
return get(coWebsites).find((coWebsite: CoWebsite) => {
return coWebsite.getId() === coWebsiteId;
});
}
private getCoWebsiteByPosition(position: number): CoWebsite | undefined {
@@ -422,7 +428,9 @@ class CoWebsiteManager {
}
private getPositionByCoWebsite(coWebsite: CoWebsite): number {
return get(coWebsites).findIndex((currentCoWebsite) => currentCoWebsite.iframe.id === coWebsite.iframe.id);
return get(coWebsites).findIndex((currentCoWebsite) => {
return currentCoWebsite.getId() === coWebsite.getId();
});
}
private getSlotByCowebsite(coWebsite: CoWebsite): HTMLDivElement | undefined {
@@ -436,7 +444,7 @@ class CoWebsiteManager {
if (index === 0) {
id += "main";
} else {
id += coWebsite.iframe.id;
id += coWebsite.getId();
}
const slot = HtmlUtils.getElementById<HTMLDivElement>(id);
@@ -453,60 +461,72 @@ class CoWebsiteManager {
const bounding = coWebsiteSlot.getBoundingClientRect();
coWebsite.iframe.style.top = bounding.top + "px";
coWebsite.iframe.style.left = bounding.left + "px";
coWebsite.iframe.style.width = bounding.right - bounding.left + "px";
coWebsite.iframe.style.height = bounding.bottom - bounding.top + "px";
const iframe = coWebsite.getIframe();
if (iframe) {
iframe.style.top = bounding.top + "px";
iframe.style.left = bounding.left + "px";
iframe.style.width = bounding.right - bounding.left + "px";
iframe.style.height = bounding.bottom - bounding.top + "px";
}
}
public resizeAllIframes() {
const mainCoWebsite = this.getCoWebsiteByPosition(0);
const mainIframe = mainCoWebsite?.getIframe();
const highlightEmbed = get(highlightedEmbedScreen);
get(coWebsites).forEach((coWebsite) => {
const notMain = !mainCoWebsite || (mainCoWebsite && mainCoWebsite.iframe.id !== coWebsite.iframe.id);
get(coWebsites).forEach((coWebsite: CoWebsite) => {
const iframe = coWebsite.getIframe();
if (!iframe) {
return;
}
const notMain = !mainCoWebsite || (mainCoWebsite && mainIframe && mainIframe.id !== iframe.id);
const notHighlighEmbed =
!highlightEmbed ||
(highlightEmbed &&
(highlightEmbed.type !== "cowebsite" ||
(highlightEmbed.type === "cowebsite" &&
highlightEmbed.embed.iframe.id !== coWebsite.iframe.id)));
(highlightEmbed.type === "cowebsite" && highlightEmbed.embed.getId() !== coWebsite.getId())));
if (coWebsite.iframe.classList.contains("main") && notMain) {
coWebsite.iframe.classList.remove("main");
if (iframe.classList.contains("main") && notMain) {
iframe.classList.remove("main");
}
if (coWebsite.iframe.classList.contains("highlighted") && notHighlighEmbed) {
coWebsite.iframe.classList.remove("highlighted");
coWebsite.iframe.classList.add("pixel");
coWebsite.iframe.style.top = "-1px";
coWebsite.iframe.style.left = "-1px";
if (iframe.classList.contains("highlighted") && notHighlighEmbed) {
iframe.classList.remove("highlighted");
iframe.classList.add("pixel");
iframe.style.top = "-1px";
iframe.style.left = "-1px";
}
if (notMain && notHighlighEmbed) {
coWebsite.iframe.classList.add("pixel");
coWebsite.iframe.style.top = "-1px";
coWebsite.iframe.style.left = "-1px";
iframe.classList.add("pixel");
iframe.style.top = "-1px";
iframe.style.left = "-1px";
}
this.setIframeOffset(coWebsite);
});
if (mainCoWebsite) {
mainCoWebsite.iframe.classList.add("main");
mainCoWebsite.iframe.classList.remove("pixel");
if (mainIframe) {
mainIframe.classList.add("main");
mainIframe.classList.remove("pixel");
}
if (highlightEmbed && highlightEmbed.type === "cowebsite") {
highlightEmbed.embed.iframe.classList.add("highlighted");
highlightEmbed.embed.iframe.classList.remove("pixel");
const highlightEmbedIframe = highlightEmbed.embed.getIframe();
if (highlightEmbedIframe) {
highlightEmbedIframe.classList.add("highlighted");
highlightEmbedIframe.classList.remove("pixel");
}
}
}
private removeHighlightCoWebsite(coWebsite: CoWebsite) {
const highlighted = get(highlightedEmbedScreen);
if (highlighted && highlighted.type === "cowebsite" && highlighted.embed.iframe.id === coWebsite.iframe.id) {
if (highlighted && highlighted.type === "cowebsite" && highlighted.embed.getId() === coWebsite.getId()) {
highlightedEmbedScreen.removeHighlight();
}
}
@@ -519,7 +539,9 @@ class CoWebsiteManager {
this.closeMain();
}
coWebsite.iframe.remove();
coWebsite.unload().catch((err) => {
console.error("Cannot unload cowebsite on remove from stack");
});
}
public goToMain(coWebsite: CoWebsite) {
@@ -531,8 +553,8 @@ class CoWebsiteManager {
isMediaBreakpointDown("lg") &&
get(embedScreenLayout) === LayoutMode.Presentation &&
mainCoWebsite &&
mainCoWebsite.iframe.id !== coWebsite.iframe.id &&
get(mainCoWebsite.state) !== "asleep"
mainCoWebsite.getId() !== coWebsite.getId() &&
mainCoWebsite.getState() !== "asleep"
) {
highlightedEmbedScreen.toggleHighlight({
type: "cowebsite",
@@ -544,25 +566,15 @@ class CoWebsiteManager {
}
public searchJitsi(): CoWebsite | undefined {
return get(coWebsites).find((coWebsite: CoWebsite) => coWebsite.jitsi);
return get(jitsiCoWebsite);
}
private initialiseCowebsite(coWebsite: CoWebsite, position: number | undefined) {
if (coWebsite.allowPolicy) {
coWebsite.iframe.allow = coWebsite.allowPolicy;
}
if (coWebsite.allowApi) {
iframeListener.registerIframe(coWebsite.iframe);
}
coWebsite.iframe.classList.add("pixel");
public addCoWebsiteToStore(coWebsite: CoWebsite, position: number | undefined) {
const coWebsitePosition = position === undefined ? get(coWebsites).length : position;
coWebsites.add(coWebsite, coWebsitePosition);
}
private generateUniqueId() {
public generateUniqueId() {
let id = undefined;
do {
id = "cowebsite-iframe-" + (Math.random() + 1).toString(36).substring(7);
@@ -571,80 +583,11 @@ class CoWebsiteManager {
return id;
}
public addCoWebsite(
url: string,
base: string,
allowApi?: boolean,
allowPolicy?: string,
widthPercent?: number,
position?: number,
closable?: boolean,
altMessage?: string
): CoWebsite {
const iframe = document.createElement("iframe");
const fullUrl = new URL(url, base);
iframe.src = fullUrl.toString();
iframe.id = this.generateUniqueId();
const newCoWebsite: CoWebsite = {
iframe,
url: fullUrl,
state: writable("asleep" as CoWebsiteState),
closable: closable ?? false,
allowPolicy,
allowApi,
widthPercent,
altMessage,
};
this.initialiseCowebsite(newCoWebsite, position);
return newCoWebsite;
}
public addCoWebsiteFromIframe(
iframe: HTMLIFrameElement,
allowApi?: boolean,
allowPolicy?: string,
widthPercent?: number,
position?: number,
closable?: boolean,
jitsi?: boolean
): CoWebsite {
if (get(coWebsitesNotAsleep).length < 1) {
this.loadMain(widthPercent);
}
iframe.id = this.generateUniqueId();
const newCoWebsite: CoWebsite = {
iframe,
url: new URL(iframe.src),
state: writable("ready" as CoWebsiteState),
closable: closable ?? false,
allowPolicy,
allowApi,
widthPercent,
jitsi,
};
if (position === 0) {
this.openMain();
setTimeout(() => {
this.fire();
}, animationTime);
}
this.initialiseCowebsite(newCoWebsite, position);
return newCoWebsite;
}
public loadCoWebsite(coWebsite: CoWebsite): CancelablePromise<CoWebsite> {
public loadCoWebsite(coWebsite: CoWebsite): CancelablePromise<void> {
if (get(coWebsitesNotAsleep).length < 1) {
coWebsites.remove(coWebsite);
coWebsites.add(coWebsite, 0);
this.loadMain(coWebsite.widthPercent);
this.loadMain(coWebsite.getWidthPercent());
}
// Check if the main is hide
@@ -652,96 +595,56 @@ class CoWebsiteManager {
this.displayMain();
}
coWebsite.state.set("loading");
const coWebsiteLloading = coWebsite
.load()
.then(() => {
const mainCoWebsite = this.getMainCoWebsite();
if (mainCoWebsite && mainCoWebsite.getId() === coWebsite.getId()) {
this.openMain();
const mainCoWebsite = this.getMainCoWebsite();
return new CancelablePromise((resolve, reject, cancel) => {
const onloadPromise = new Promise<void>((resolve) => {
coWebsite.iframe.onload = () => {
coWebsite.state.set("ready");
resolve();
};
setTimeout(() => {
this.fire();
}, animationTime);
}
this.resizeAllIframes();
})
.catch((err) => {
console.error("Error on co-website loading => ", err);
this.removeCoWebsiteFromStack(coWebsite);
});
const onTimeoutPromise = new Promise<void>((resolve) => {
setTimeout(() => resolve(), 2000);
});
this.cowebsiteBufferDom.appendChild(coWebsite.iframe);
if (coWebsite.jitsi) {
const gameScene = gameManager.getCurrentGameScene();
gameScene.disableMediaBehaviors();
jitsiFactory.restart();
}
const race = CancelablePromise.race([onloadPromise, onTimeoutPromise])
.then(() => {
if (mainCoWebsite && mainCoWebsite.iframe.id === coWebsite.iframe.id) {
this.openMain();
setTimeout(() => {
this.fire();
}, animationTime);
}
return resolve(coWebsite);
})
.catch((err) => {
console.error("Error on co-website loading => ", err);
this.removeCoWebsiteFromStack(coWebsite);
return reject();
});
cancel(() => {
race.cancel();
this.unloadCoWebsite(coWebsite);
});
});
return coWebsiteLloading;
}
public unloadCoWebsite(coWebsite: CoWebsite): void {
public unloadCoWebsite(coWebsite: CoWebsite): Promise<void> {
this.removeHighlightCoWebsite(coWebsite);
coWebsite.iframe.parentNode?.removeChild(coWebsite.iframe);
coWebsite.state.set("asleep");
coWebsites.remove(coWebsite);
return coWebsite
.unload()
.then(() => {
coWebsites.remove(coWebsite);
const mainCoWebsite = this.getMainCoWebsite();
if (coWebsite.jitsi) {
jitsiFactory.stop();
const gameScene = gameManager.getCurrentGameScene();
gameScene.enableMediaBehaviors();
}
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
const mainCoWebsite = this.getMainCoWebsite();
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
coWebsites.add(coWebsite, get(coWebsites).length);
coWebsites.add(coWebsite, get(coWebsites).length);
})
.catch(() => {
console.error();
});
}
public closeCoWebsite(coWebsite: CoWebsite): void {
if (coWebsite.jitsi) {
jitsiFactory.destroy();
const gameScene = gameManager.getCurrentGameScene();
gameScene.enableMediaBehaviors();
}
if (get(coWebsites).length === 1) {
this.fire();
}
if (coWebsite.allowApi) {
iframeListener.unregisterIframe(coWebsite.iframe);
}
this.removeCoWebsiteFromStack(coWebsite);
const mainCoWebsite = this.getMainCoWebsite();