Add iframe submenu by scripting API

Delete menu by scripting API
This commit is contained in:
GRL 2021-08-24 17:35:06 +02:00
parent 49eb28dacf
commit f3c4d344b3
11 changed files with 251 additions and 328 deletions

View file

@ -15,7 +15,6 @@ import type { SetPropertyEvent } from "./setPropertyEvent";
import type { LoadSoundEvent } from "./LoadSoundEvent";
import type { PlaySoundEvent } from "./PlaySoundEvent";
import type { MenuItemClickedEvent } from "./ui/MenuItemClickedEvent";
import type { MenuItemRegisterEvent } from "./ui/MenuItemRegisterEvent";
import type { HasPlayerMovedEvent } from "./HasPlayerMovedEvent";
import type { SetTilesEvent } from "./SetTilesEvent";
import type { SetVariableEvent } from "./SetVariableEvent";
@ -33,6 +32,7 @@ import type {
TriggerActionMessageEvent,
} from "./ui/TriggerActionMessageEvent";
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
import type { MenuIframeRegisterEvent, MenuItemRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
export interface TypedMessageEvent<T> extends MessageEvent {
data: T;
@ -64,6 +64,8 @@ export type IframeEventMap = {
getState: undefined;
loadTileset: LoadTilesetEvent;
registerMenuCommand: MenuItemRegisterEvent;
registerMenuIframe: MenuIframeRegisterEvent;
unregisterMenu: UnregisterMenuEvent;
setTiles: SetTilesEvent;
modifyEmbeddedWebsite: Partial<EmbeddedWebsite>; // Note: name should be compulsory in fact
};

View file

@ -1,5 +1,5 @@
import * as tg from "generic-type-guard";
import { isMenuItemRegisterEvent } from "./ui/MenuItemRegisterEvent";
import { isMenuItemRegisterEvent } from "./ui/MenuRegisterEvent";
export const isSetVariableEvent = new tg.IsInterface()
.withProperties({

View file

@ -1,27 +0,0 @@
import * as tg from "generic-type-guard";
import { Subject } from "rxjs";
import { subMenusStore } from "../../../Stores/MenuStore";
export const isMenuItemRegisterEvent = new tg.IsInterface()
.withProperties({
menutItem: tg.isString,
})
.get();
/**
* A message sent from the iFrame to the game to add a new menu item.
*/
export type MenuItemRegisterEvent = tg.GuardedType<typeof isMenuItemRegisterEvent>;
export const isMenuItemRegisterIframeEvent = new tg.IsInterface()
.withProperties({
type: tg.isSingletonString("registerMenuCommand"),
data: isMenuItemRegisterEvent,
})
.get();
const _registerMenuCommandStream: Subject<string> = new Subject();
export const registerMenuCommandStream = _registerMenuCommandStream.asObservable();
export function handleMenuItemRegistrationEvent(event: MenuItemRegisterEvent) {
subMenusStore.addMenu(event.menutItem);
}

View file

@ -0,0 +1,42 @@
import * as tg from "generic-type-guard";
/**
* A message sent from a script to the game to add a new button in the menu.
*/
export const isMenuItemRegisterEvent = new tg.IsInterface()
.withProperties({
menuItem: tg.isString,
})
.get();
export type MenuItemRegisterEvent = tg.GuardedType<typeof isMenuItemRegisterEvent>;
export const isMenuItemRegisterIframeEvent = new tg.IsInterface()
.withProperties({
type: tg.isSingletonString("registerMenuCommand"),
data: isMenuItemRegisterEvent,
})
.get();
/**
* A message sent from a script to the game to add an iframe submenu in the menu.
*/
export const isMenuIframeEvent = new tg.IsInterface()
.withProperties({
name: tg.isString,
url: tg.isString,
})
.get();
export type MenuIframeRegisterEvent = tg.GuardedType<typeof isMenuIframeEvent>;
/**
* A message sent from a script to the game to remove a custom menu from the menu
*/
export const isUnregisterMenuEvent = new tg.IsInterface()
.withProperties({
name: tg.isString,
})
.get();
export type UnregisterMenuEvent = tg.GuardedType<typeof isUnregisterMenuEvent>;

View file

@ -29,12 +29,12 @@ import { isSetPropertyEvent, SetPropertyEvent } from "./Events/setPropertyEvent"
import { isLayerEvent, LayerEvent } from "./Events/LayerEvent";
import type { HasPlayerMovedEvent } from "./Events/HasPlayerMovedEvent";
import { isLoadPageEvent } from "./Events/LoadPageEvent";
import { handleMenuItemRegistrationEvent, isMenuItemRegisterIframeEvent } from "./Events/ui/MenuItemRegisterEvent";
import { isMenuItemRegisterIframeEvent, isMenuIframeEvent, isUnregisterMenuEvent } from "./Events/ui/MenuRegisterEvent";
import { SetTilesEvent, isSetTilesEvent } from "./Events/SetTilesEvent";
import type { SetVariableEvent } from "./Events/SetVariableEvent";
import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent";
import { EmbeddedWebsite } from "./iframe/Room/EmbeddedWebsite";
import { subMenusStore } from "../Stores/MenuStore";
import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore";
type AnswererCallback<T extends keyof IframeQueryMap> = (
query: IframeQueryMap[T]["query"],
@ -256,16 +256,25 @@ class IframeListener {
} else if (payload.type == "onPlayerMove") {
this.sendPlayerMove = true;
} else if (isMenuItemRegisterIframeEvent(payload)) {
const data = payload.data.menutItem;
const data = payload.data.menuItem;
// @ts-ignore
this.iframeCloseCallbacks.get(iframe).push(() => {
subMenusStore.removeMenu(data);
handleMenuUnregisterEvent(data);
});
handleMenuItemRegistrationEvent(payload.data);
handleMenuRegistrationEvent(payload.data.menuItem);
} else if (payload.type == "setTiles" && isSetTilesEvent(payload.data)) {
this._setTilesStream.next(payload.data);
} else if (payload.type == "modifyEmbeddedWebsite" && isEmbeddedWebsiteEvent(payload.data)) {
this._modifyEmbeddedWebsiteStream.next(payload.data);
} else if (payload.type == "registerMenuIframe" && isMenuIframeEvent(payload.data)) {
const data = payload.data.name;
// @ts-ignore
this.iframeCloseCallbacks.get(iframe).push(() => {
handleMenuUnregisterEvent(data);
});
handleMenuRegistrationEvent(payload.data.name, payload.data.url, foundSrc);
} else if (payload.type == "unregisterMenu" && isUnregisterMenuEvent(payload.data)) {
handleMenuUnregisterEvent(payload.data.name);
}
}
},

View file

@ -109,11 +109,33 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
sendToWorkadventure({
type: "registerMenuCommand",
data: {
menutItem: commandDescriptor,
menuItem: commandDescriptor,
},
});
}
registerMenuIframe(menuName: string, iframeUrl: string) {
sendToWorkadventure({
type: "registerMenuIframe",
data: {
name: menuName,
url: iframeUrl,
},
});
}
unregisterMenu(menuName: string) {
sendToWorkadventure({
type: "unregisterMenu",
data: {
name: menuName,
},
});
if (menuCallbacks.get(menuName)) {
menuCallbacks.delete(menuName);
}
}
displayBubble(): void {
sendToWorkadventure({ type: "displayBubble", data: null });
}