Merge pull request #1828 from thecodingmachine/stabilize-cowebsite

Restore trigger message action on co-websites
This commit is contained in:
David Négrier 2022-02-07 17:58:44 +01:00 committed by GitHub
commit 41183e8bc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 216 additions and 58 deletions

View file

@ -5,6 +5,7 @@ export const isOpenCoWebsiteEvent = new tg.IsInterface()
url: tg.isString,
allowApi: tg.isOptional(tg.isBoolean),
allowPolicy: tg.isOptional(tg.isString),
widthPercent: tg.isOptional(tg.isNumber),
position: tg.isOptional(tg.isNumber),
closable: tg.isOptional(tg.isBoolean),
lazy: tg.isOptional(tg.isBoolean),

View file

@ -45,6 +45,7 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
url: string,
allowApi?: boolean,
allowPolicy?: string,
widthPercent?: number,
position?: number,
closable?: boolean,
lazy?: boolean
@ -55,6 +56,7 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
url,
allowApi,
allowPolicy,
widthPercent,
position,
closable,
lazy,

View file

@ -5,6 +5,7 @@
import { coWebsitesNotAsleep, mainCoWebsite } from "../../Stores/CoWebsiteStore";
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
import { iframeStates } from "../../WebRtc/CoWebsiteManager";
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
export let index: number;
@ -35,8 +36,12 @@
if ($mainCoWebsite.iframe.id === coWebsite.iframe.id) {
const coWebsites = $coWebsitesNotAsleep;
const newMain = $highlightedEmbedScreen ?? coWebsites.length > 1 ? coWebsites[1] : undefined;
if (newMain) {
if (newMain && newMain.iframe.id !== $mainCoWebsite.iframe.id) {
coWebsiteManager.goToMain(newMain);
} else if (coWebsiteManager.getMainState() === iframeStates.closed) {
coWebsiteManager.displayMain();
} else {
coWebsiteManager.hideMain();
}
} else {
highlightedEmbedScreen.toggleHighlight({

View file

@ -20,6 +20,7 @@ export enum GameMapProperties {
OPEN_WEBSITE = "openWebsite",
OPEN_WEBSITE_ALLOW_API = "openWebsiteAllowApi",
OPEN_WEBSITE_POLICY = "openWebsitePolicy",
OPEN_WEBSITE_WIDTH = "openWebsiteWidth",
OPEN_WEBSITE_POSITION = "openWebsitePosition",
OPEN_WEBSITE_TRIGGER = "openWebsiteTrigger",
OPEN_WEBSITE_TRIGGER_MESSAGE = "openWebsiteTriggerMessage",

View file

@ -6,10 +6,9 @@ import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
import { localUserStore } from "../../Connexion/LocalUserStore";
import { get } from "svelte/store";
import { ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager";
import { ON_ACTION_TRIGGER_BUTTON, ON_ICON_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager";
import type { ITiledMapLayer } from "../Map/ITiledMap";
import { GameMapProperties } from "./GameMapProperties";
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
enum OpenCoWebsiteState {
ASLEEP,
@ -18,12 +17,14 @@ enum OpenCoWebsiteState {
}
interface OpenCoWebsite {
coWebsite: CoWebsite;
actionId: string;
coWebsite?: CoWebsite;
state: OpenCoWebsiteState;
}
export class GameMapPropertiesListener {
private coWebsitesOpenByLayer = new Map<ITiledMapLayer, OpenCoWebsite>();
private coWebsitesActionTriggerByLayer = new Map<ITiledMapLayer, string>();
constructor(private scene: GameScene, private gameMap: GameMap) {}
@ -64,6 +65,7 @@ export class GameMapPropertiesListener {
let openWebsiteProperty: string | undefined;
let allowApiProperty: boolean | undefined;
let websitePolicyProperty: string | undefined;
let websiteWidthProperty: number | undefined;
let websitePositionProperty: number | undefined;
let websiteTriggerProperty: string | undefined;
let websiteTriggerMessageProperty: string | undefined;
@ -79,6 +81,9 @@ export class GameMapPropertiesListener {
case GameMapProperties.OPEN_WEBSITE_POLICY:
websitePolicyProperty = property.value as string | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_WIDTH:
websiteWidthProperty = property.value as number | undefined;
break;
case GameMapProperties.OPEN_WEBSITE_POSITION:
websitePositionProperty = property.value as number | undefined;
break;
@ -95,27 +100,19 @@ export class GameMapPropertiesListener {
return;
}
const actionUuid = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
const actionId = "openWebsite-" + (Math.random() + 1).toString(36).substring(7);
if (this.coWebsitesOpenByLayer.has(layer)) {
return;
}
const coWebsite = coWebsiteManager.addCoWebsite(
openWebsiteProperty,
this.scene.MapUrlFile,
allowApiProperty,
websitePolicyProperty,
websitePositionProperty,
false
);
this.coWebsitesOpenByLayer.set(layer, {
coWebsite: coWebsite,
actionId: actionId,
coWebsite: undefined,
state: OpenCoWebsiteState.ASLEEP,
});
const openWebsiteFunction = () => {
const loadCoWebsiteFunction = (coWebsite: CoWebsite) => {
coWebsiteManager
.loadCoWebsite(coWebsite)
.then((coWebsite) => {
@ -125,8 +122,10 @@ export class GameMapPropertiesListener {
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,
});
@ -136,14 +135,60 @@ export class GameMapPropertiesListener {
console.error("Error during loading a co-website: " + coWebsite.url);
});
layoutManagerActionStore.removeAction(actionUuid);
layoutManagerActionStore.removeAction(actionId);
};
const openCoWebsiteFunction = () => {
const coWebsite = coWebsiteManager.addCoWebsite(
openWebsiteProperty ?? "",
this.scene.MapUrlFile,
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
websitePositionProperty,
false
);
loadCoWebsiteFunction(coWebsite);
};
if (
!localUserStore.getForceCowebsiteTrigger() &&
websiteTriggerProperty !== ON_ACTION_TRIGGER_BUTTON
localUserStore.getForceCowebsiteTrigger() ||
websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON
) {
openWebsiteFunction();
if (!websiteTriggerMessageProperty) {
websiteTriggerMessageProperty = "Press SPACE or touch here to open web site";
}
this.coWebsitesActionTriggerByLayer.set(layer, actionId);
layoutManagerActionStore.addAction({
uuid: actionId,
type: "message",
message: websiteTriggerMessageProperty,
callback: () => openCoWebsiteFunction(),
userInputManager: this.scene.userInputManager,
});
} else if (!websiteTriggerProperty || websiteTriggerProperty === ON_ICON_TRIGGER_BUTTON) {
const coWebsite = coWebsiteManager.addCoWebsite(
openWebsiteProperty,
this.scene.MapUrlFile,
allowApiProperty,
websitePolicyProperty,
websiteWidthProperty,
websitePositionProperty,
false
);
const ObjectByLayer = this.coWebsitesOpenByLayer.get(layer);
if (ObjectByLayer) {
ObjectByLayer.coWebsite = coWebsite;
}
}
if (!websiteTriggerProperty) {
openCoWebsiteFunction();
}
});
};
@ -192,6 +237,28 @@ export class GameMapPropertiesListener {
}
this.coWebsitesOpenByLayer.delete(layer);
if (!websiteTriggerProperty) {
return;
}
const actionStore = get(layoutManagerActionStore);
const actionTriggerUuid = this.coWebsitesActionTriggerByLayer.get(layer);
if (!actionTriggerUuid) {
return;
}
const action =
actionStore && actionStore.length > 0
? actionStore.find((action) => action.uuid === actionTriggerUuid)
: undefined;
if (action) {
layoutManagerActionStore.removeAction(actionTriggerUuid);
}
this.coWebsitesActionTriggerByLayer.delete(layer);
});
};

View file

@ -1265,6 +1265,7 @@ ${escapedMessage}
iframeListener.getBaseUrlFromSource(source),
openCoWebsite.allowApi,
openCoWebsite.allowPolicy,
openCoWebsite.widthPercent,
openCoWebsite.position,
openCoWebsite.closable ?? true
);

View file

@ -10,7 +10,7 @@ import { jitsiFactory } from "./JitsiFactory";
import { gameManager } from "../Phaser/Game/GameManager";
import { LayoutMode } from "./LayoutManager";
enum iframeStates {
export enum iframeStates {
closed = 1,
loading, // loading an iframe can be slow, so we show some placeholder until it is ready
opened,
@ -21,7 +21,7 @@ const gameOverlayDomId = "game-overlay";
const cowebsiteBufferDomId = "cowebsite-buffer"; // the id of the container who contains cowebsite iframes.
const cowebsiteAsideHolderDomId = "cowebsite-aside-holder";
const cowebsiteLoaderDomId = "cowebsite-loader";
export const cowebsiteCloseButtonId = "cowebsite-close";
const cowebsiteCloseButtonId = "cowebsite-close";
const cowebsiteFullScreenButtonId = "cowebsite-fullscreen";
const cowebsiteOpenFullScreenImageId = "cowebsite-fullscreen-open";
const cowebsiteCloseFullScreenImageId = "cowebsite-fullscreen-close";
@ -43,6 +43,7 @@ export type CoWebsite = {
closable: boolean;
allowPolicy: string | undefined;
allowApi: boolean | undefined;
widthPercent?: number | undefined;
jitsi?: boolean;
altMessage?: string;
};
@ -74,6 +75,10 @@ class CoWebsiteManager {
this.resizeAllIframes();
});
public getMainState() {
return this.openedMain;
}
get width(): number {
return this.cowebsiteDom.clientWidth;
}
@ -82,8 +87,13 @@ class CoWebsiteManager {
this.cowebsiteDom.style.width = width + "px";
}
set widthPercent(width: number) {
this.cowebsiteDom.style.width = width + "%";
get maxWidth(): number {
let maxWidth = 75 * window.innerWidth;
if (maxWidth !== 0) {
maxWidth = Math.round(maxWidth / 100);
}
return maxWidth;
}
get height(): number {
@ -94,6 +104,15 @@ class CoWebsiteManager {
this.cowebsiteDom.style.height = height + "px";
}
get maxHeight(): number {
let maxHeight = 60 * window.innerHeight;
if (maxHeight !== 0) {
maxHeight = Math.round(maxHeight / 100);
}
return maxHeight;
}
get verticalMode(): boolean {
return window.innerWidth < window.innerHeight;
}
@ -191,29 +210,21 @@ class CoWebsiteManager {
if (this.verticalMode) {
const tempValue = this.height + y;
let maxHeight = 60 * window.innerHeight;
if (maxHeight !== 0) {
maxHeight = Math.round(maxHeight / 100);
}
if (tempValue < this.cowebsiteAsideHolderDom.offsetHeight) {
this.height = this.cowebsiteAsideHolderDom.offsetHeight;
} else if (tempValue > maxHeight) {
this.height = maxHeight;
} else if (tempValue > this.maxHeight) {
this.height = this.maxHeight;
} else {
this.height = tempValue;
}
} else {
const tempValue = this.width - x;
let maxWidth = 75 * window.innerWidth;
if (maxWidth !== 0) {
maxWidth = Math.round(maxWidth / 100);
}
if (tempValue < this.cowebsiteAsideHolderDom.offsetWidth) {
this.width = this.cowebsiteAsideHolderDom.offsetWidth;
} else if (tempValue > maxWidth) {
this.width = maxWidth;
} else if (tempValue > this.maxWidth) {
this.width = this.maxWidth;
} else {
this.width = tempValue;
}
@ -299,6 +310,27 @@ class CoWebsiteManager {
});
}
public displayMain() {
const coWebsite = this.getMainCoWebsite();
if (coWebsite) {
coWebsite.iframe.style.display = "block";
}
this.loadMain();
this.openMain();
this.fire();
}
public hideMain() {
const coWebsite = this.getMainCoWebsite();
if (coWebsite) {
coWebsite.iframe.style.display = "none";
}
this.cowebsiteDom.classList.add("closing");
this.cowebsiteDom.classList.remove("opened");
this.openedMain = iframeStates.closed;
this.fire();
}
private closeMain(): void {
this.toggleFullScreenIcon(true);
this.cowebsiteDom.classList.add("closing");
@ -308,7 +340,7 @@ class CoWebsiteManager {
this.fire();
}
private loadMain(): void {
private loadMain(openingWidth?: number): void {
this.loaderAnimationInterval.interval = setInterval(() => {
if (!this.loaderAnimationInterval.trails) {
this.loaderAnimationInterval.trails = [0, 1, 2];
@ -337,6 +369,25 @@ class CoWebsiteManager {
trail === 3 ? 0 : trail + 1
);
}, 200);
if (!this.verticalMode && openingWidth) {
let newWidth = 50;
if (openingWidth > 100) {
newWidth = 100;
} else if (openingWidth > 1) {
newWidth = openingWidth;
}
newWidth = Math.round((newWidth * this.maxWidth) / 100);
if (newWidth < this.cowebsiteAsideHolderDom.offsetWidth) {
newWidth = this.cowebsiteAsideHolderDom.offsetWidth;
}
this.width = newWidth;
}
this.cowebsiteDom.classList.add("opened");
this.openedMain = iframeStates.loading;
}
@ -346,7 +397,6 @@ class CoWebsiteManager {
this.resizeAllIframes();
});
this.openedMain = iframeStates.opened;
this.resetStyleMain();
}
public resetStyleMain() {
@ -533,6 +583,7 @@ class CoWebsiteManager {
base: string,
allowApi?: boolean,
allowPolicy?: string,
widthPercent?: number,
position?: number,
closable?: boolean,
altMessage?: string
@ -549,6 +600,7 @@ class CoWebsiteManager {
closable: closable ?? false,
allowPolicy,
allowApi,
widthPercent,
altMessage,
};
@ -561,14 +613,11 @@ class CoWebsiteManager {
iframe: HTMLIFrameElement,
allowApi?: boolean,
allowPolicy?: string,
widthPercent?: number,
position?: number,
closable?: boolean,
jitsi?: boolean
): CoWebsite {
if (get(coWebsitesNotAsleep).length < 1) {
this.loadMain();
}
iframe.id = this.generateUniqueId();
const newCoWebsite: CoWebsite = {
@ -578,9 +627,16 @@ class CoWebsiteManager {
closable: closable ?? false,
allowPolicy,
allowApi,
widthPercent,
jitsi,
};
if (get(coWebsitesNotAsleep).length < 1) {
coWebsites.remove(newCoWebsite);
coWebsites.add(newCoWebsite, 0);
this.loadMain(widthPercent);
}
if (position === 0) {
this.openMain();
setTimeout(() => {
@ -597,7 +653,12 @@ class CoWebsiteManager {
if (get(coWebsitesNotAsleep).length < 1) {
coWebsites.remove(coWebsite);
coWebsites.add(coWebsite, 0);
this.loadMain();
this.loadMain(coWebsite.widthPercent);
}
// Check if the main is hide
if (this.getMainCoWebsite() && this.openedMain === iframeStates.closed) {
this.displayMain();
}
coWebsite.state.set("loading");

View file

@ -179,7 +179,15 @@ class JitsiFactory {
const doResolve = (): void => {
const iframe = coWebsiteManager.getCoWebsiteBuffer().querySelector<HTMLIFrameElement>('[id*="jitsi" i]');
if (iframe && this.jitsiApi) {
const coWebsite = coWebsiteManager.addCoWebsiteFromIframe(iframe, false, undefined, 0, false, true);
const coWebsite = coWebsiteManager.addCoWebsiteFromIframe(
iframe,
false,
undefined,
undefined,
0,
false,
true
);
this.jitsiApi.addListener("videoConferenceLeft", () => {
this.closeOrUnload(coWebsite);

View file

@ -13,5 +13,6 @@ export enum DivImportance {
}
export const ON_ACTION_TRIGGER_BUTTON = "onaction";
export const ON_ICON_TRIGGER_BUTTON = "onicon";
export type Box = { xStart: number; yStart: number; xEnd: number; yEnd: number };