Fix cowebsite closing on fast opening/closing

This commit is contained in:
Alexis Faizeau 2022-02-08 11:19:29 +01:00
parent 7334d59c4f
commit f5f71f32ee
5 changed files with 97 additions and 155 deletions

View file

@ -10,13 +10,9 @@
function closeCoWebsite() {
if ($highlightedEmbedScreen?.type === "cowebsite") {
if ($highlightedEmbedScreen.embed.closable) {
coWebsiteManager.closeCoWebsite($highlightedEmbedScreen.embed).catch(() => {
console.error("Error during co-website highlighted closing");
});
coWebsiteManager.closeCoWebsite($highlightedEmbedScreen.embed);
} else {
coWebsiteManager.unloadCoWebsite($highlightedEmbedScreen.embed).catch(() => {
console.error("Error during co-website highlighted unloading");
});
coWebsiteManager.unloadCoWebsite($highlightedEmbedScreen.embed);
}
}
}

View file

@ -9,17 +9,12 @@ import { get } from "svelte/store";
import { ON_ACTION_TRIGGER_BUTTON, ON_ICON_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager";
import type { ITiledMapLayer } from "../Map/ITiledMap";
import { GameMapProperties } from "./GameMapProperties";
enum OpenCoWebsiteState {
ASLEEP,
OPENED,
MUST_BE_CLOSE,
}
import type CancelablePromise from "cancelable-promise";
interface OpenCoWebsite {
actionId: string;
coWebsite?: CoWebsite;
state: OpenCoWebsiteState;
loadPromise?: CancelablePromise;
}
export class GameMapPropertiesListener {
@ -106,34 +101,16 @@ export class GameMapPropertiesListener {
return;
}
this.coWebsitesOpenByLayer.set(layer, {
const coWebsiteOpen: OpenCoWebsite = {
actionId: actionId,
coWebsite: undefined,
state: OpenCoWebsiteState.ASLEEP,
});
};
this.coWebsitesOpenByLayer.set(layer, coWebsiteOpen);
const loadCoWebsiteFunction = (coWebsite: CoWebsite) => {
coWebsiteManager
.loadCoWebsite(coWebsite)
.then((coWebsite) => {
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
coWebsiteManager.closeCoWebsite(coWebsite).catch(() => {
console.error("Error during a co-website closing");
});
this.coWebsitesOpenByLayer.delete(layer);
this.coWebsitesActionTriggerByLayer.delete(layer);
} else {
this.coWebsitesOpenByLayer.set(layer, {
actionId,
coWebsite,
state: OpenCoWebsiteState.OPENED,
});
}
})
.catch(() => {
console.error("Error during loading a co-website: " + coWebsite.url);
});
coWebsiteOpen.loadPromise = coWebsiteManager.loadCoWebsite(coWebsite).catch(() => {
console.error("Error during loading a co-website: " + coWebsite.url);
});
layoutManagerActionStore.removeAction(actionId);
};
@ -149,6 +126,8 @@ export class GameMapPropertiesListener {
false
);
coWebsiteOpen.coWebsite = coWebsite;
loadCoWebsiteFunction(coWebsite);
};
@ -180,11 +159,7 @@ export class GameMapPropertiesListener {
false
);
const ObjectByLayer = this.coWebsitesOpenByLayer.get(layer);
if (ObjectByLayer) {
ObjectByLayer.coWebsite = coWebsite;
}
coWebsiteOpen.coWebsite = coWebsite;
}
if (!websiteTriggerProperty) {
@ -228,12 +203,12 @@ export class GameMapPropertiesListener {
return;
}
if (coWebsiteOpen.state === OpenCoWebsiteState.ASLEEP) {
coWebsiteOpen.state = OpenCoWebsiteState.MUST_BE_CLOSE;
if (coWebsiteOpen.loadPromise !== undefined) {
coWebsiteOpen.loadPromise.cancel();
}
if (coWebsiteOpen.coWebsite !== undefined) {
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite).catch((e) => console.error(e));
coWebsiteManager.closeCoWebsite(coWebsiteOpen.coWebsite);
}
this.coWebsitesOpenByLayer.delete(layer);

View file

@ -1289,22 +1289,18 @@ ${escapedMessage}
});
});
iframeListener.registerAnswerer("closeCoWebsite", async (coWebsiteId) => {
iframeListener.registerAnswerer("closeCoWebsite", (coWebsiteId) => {
const coWebsite = coWebsiteManager.getCoWebsiteById(coWebsiteId);
if (!coWebsite) {
throw new Error("Unknown co-website");
}
return coWebsiteManager.closeCoWebsite(coWebsite).catch((error) => {
throw new Error("Error on closing co-website");
});
return coWebsiteManager.closeCoWebsite(coWebsite);
});
iframeListener.registerAnswerer("closeCoWebsites", async () => {
return await coWebsiteManager.closeCoWebsites().catch((error) => {
throw new Error("Error on closing all co-websites");
});
iframeListener.registerAnswerer("closeCoWebsites", () => {
return coWebsiteManager.closeCoWebsites();
});
iframeListener.registerAnswerer("getMapData", () => {
@ -1568,7 +1564,7 @@ ${escapedMessage}
public cleanupClosingScene(): void {
// stop playing audio, close any open website, stop any open Jitsi
coWebsiteManager.closeCoWebsites().catch((e) => console.error(e));
coWebsiteManager.closeCoWebsites();
// Stop the script, if any
const scripts = this.getScriptUrls(this.mapFile);
for (const script of scripts) {
@ -2138,9 +2134,7 @@ ${escapedMessage}
public stopJitsi(): void {
const coWebsite = coWebsiteManager.searchJitsi();
if (coWebsite) {
coWebsiteManager.closeCoWebsite(coWebsite).catch((e) => {
console.error("Error during Jitsi co-website closing", e);
});
coWebsiteManager.closeCoWebsite(coWebsite);
}
}

View file

@ -9,6 +9,7 @@ import { isMediaBreakpointDown } from "../Utils/BreakpointsUtils";
import { jitsiFactory } from "./JitsiFactory";
import { gameManager } from "../Phaser/Game/GameManager";
import { LayoutMode } from "./LayoutManager";
import CancelablePromise from "cancelable-promise";
export enum iframeStates {
closed = 1,
@ -53,11 +54,7 @@ class CoWebsiteManager {
private _onResize: Subject<void> = new Subject();
public onResize = this._onResize.asObservable();
/**
* Quickly going in and out of an iframe trigger can create conflicts between the iframe states.
* So we use this promise to queue up every cowebsite state transition
*/
private currentOperationPromise: Promise<void> = Promise.resolve();
private cowebsiteDom: HTMLDivElement;
private resizing: boolean = false;
private gameOverlayDom: HTMLDivElement;
@ -148,13 +145,9 @@ class CoWebsiteManager {
}
if (coWebsite.closable) {
this.closeCoWebsite(coWebsite).catch(() => {
console.error("Error during closing a co-website by a button");
});
this.closeCoWebsite(coWebsite);
} else {
this.unloadCoWebsite(coWebsite).catch(() => {
console.error("Error during unloading a co-website by a button");
});
this.unloadCoWebsite(coWebsite);
}
});
@ -647,7 +640,7 @@ class CoWebsiteManager {
return newCoWebsite;
}
public loadCoWebsite(coWebsite: CoWebsite): Promise<CoWebsite> {
public loadCoWebsite(coWebsite: CoWebsite): CancelablePromise<CoWebsite> {
if (get(coWebsitesNotAsleep).length < 1) {
coWebsites.remove(coWebsite);
coWebsites.add(coWebsite, 0);
@ -663,7 +656,7 @@ class CoWebsiteManager {
const mainCoWebsite = this.getMainCoWebsite();
return new Promise((resolve, reject) => {
return new CancelablePromise((resolve, reject, cancel) => {
const onloadPromise = new Promise<void>((resolve) => {
coWebsite.iframe.onload = () => {
coWebsite.state.set("ready");
@ -683,8 +676,7 @@ class CoWebsiteManager {
jitsiFactory.restart();
}
this.currentOperationPromise = this.currentOperationPromise
.then(() => Promise.race([onloadPromise, onTimeoutPromise]))
const race = CancelablePromise.race([onloadPromise, onTimeoutPromise])
.then(() => {
if (mainCoWebsite && mainCoWebsite.iframe.id === coWebsite.iframe.id) {
this.openMain();
@ -701,83 +693,72 @@ class CoWebsiteManager {
this.removeCoWebsiteFromStack(coWebsite);
return reject();
});
});
}
public unloadCoWebsite(coWebsite: CoWebsite): Promise<void> {
return new Promise((resolve, reject) => {
this.removeHighlightCoWebsite(coWebsite);
coWebsite.iframe.parentNode?.removeChild(coWebsite.iframe);
coWebsite.state.set("asleep");
coWebsites.remove(coWebsite);
if (coWebsite.jitsi) {
jitsiFactory.stop();
const gameScene = gameManager.getCurrentGameScene();
gameScene.enableMediaBehaviors();
}
const mainCoWebsite = this.getMainCoWebsite();
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
coWebsites.add(coWebsite, get(coWebsites).length);
resolve();
});
}
public closeCoWebsite(coWebsite: CoWebsite): Promise<void> {
this.currentOperationPromise = this.currentOperationPromise.then(
() =>
new Promise((resolve) => {
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();
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
resolve();
})
);
return this.currentOperationPromise;
}
public closeCoWebsites(): Promise<void> {
return (this.currentOperationPromise = this.currentOperationPromise.then(() => {
get(coWebsites).forEach((coWebsite: CoWebsite) => {
this.closeCoWebsite(coWebsite).catch(() => {
console.error("Error during closing a co-website");
});
cancel(() => {
race.cancel();
this.unloadCoWebsite(coWebsite);
});
}));
return this.currentOperationPromise;
});
}
public unloadCoWebsite(coWebsite: CoWebsite): void {
this.removeHighlightCoWebsite(coWebsite);
coWebsite.iframe.parentNode?.removeChild(coWebsite.iframe);
coWebsite.state.set("asleep");
coWebsites.remove(coWebsite);
if (coWebsite.jitsi) {
jitsiFactory.stop();
const gameScene = gameManager.getCurrentGameScene();
gameScene.enableMediaBehaviors();
}
const mainCoWebsite = this.getMainCoWebsite();
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
coWebsites.add(coWebsite, get(coWebsites).length);
}
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();
if (mainCoWebsite) {
this.removeHighlightCoWebsite(mainCoWebsite);
this.goToMain(mainCoWebsite);
this.resizeAllIframes();
} else {
this.closeMain();
}
}
public closeCoWebsites(): void {
get(coWebsites).forEach((coWebsite: CoWebsite) => {
this.closeCoWebsite(coWebsite);
});
}
public getGameSize(): { width: number; height: number } {

View file

@ -145,7 +145,7 @@ class JitsiFactory {
const coWebsite = coWebsiteManager.searchJitsi();
if (coWebsite) {
await coWebsiteManager.closeCoWebsite(coWebsite);
coWebsiteManager.closeCoWebsite(coWebsite);
}
// Jitsi meet external API maintains some data in local storage
@ -214,13 +214,9 @@ class JitsiFactory {
private closeOrUnload = function (coWebsite: CoWebsite) {
if (coWebsite.closable) {
coWebsiteManager.closeCoWebsite(coWebsite).catch(() => {
console.error("Error during closing a Jitsi Meet");
});
coWebsiteManager.closeCoWebsite(coWebsite);
} else {
coWebsiteManager.unloadCoWebsite(coWebsite).catch(() => {
console.error("Error during unloading a Jitsi Meet");
});
coWebsiteManager.unloadCoWebsite(coWebsite);
}
};