diff --git a/docs/maps/api-ui.md b/docs/maps/api-ui.md
index f15de5df..44248b53 100644
--- a/docs/maps/api-ui.md
+++ b/docs/maps/api-ui.md
@@ -65,3 +65,26 @@ WA.room.onLeaveZone('myZone', () => {
helloWorldPopup.close();
});
```
+
+### register additional menu entries
+
+adds an additional Entry to the main menu , these exist until the map is unloaded
+
+
+```typescript
+WA.ui.registerMenuCommand(menuCommand: string, callback: (menuCommand: string) => void): void
+```
+Example:
+
+
+```javascript
+
+WA.ui.registerMenuCommand("test", () => {
+ WA.chat.sendChatMessage("test clicked", "menu cmd")
+})
+
+```
+
+
+
+
\ No newline at end of file
diff --git a/docs/maps/assets/menu-command.png b/docs/maps/assets/menu-command.png
new file mode 100644
index 00000000..0caf75c9
Binary files /dev/null and b/docs/maps/assets/menu-command.png differ
diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts
index c3e2f6c9..7325f811 100644
--- a/front/src/Api/Events/IframeEvent.ts
+++ b/front/src/Api/Events/IframeEvent.ts
@@ -15,7 +15,8 @@ import type { LayerEvent } from './LayerEvent';
import type { SetPropertyEvent } from "./setPropertyEvent";
import type { LoadSoundEvent } from "./LoadSoundEvent";
import type { PlaySoundEvent } from "./PlaySoundEvent";
-import type { MenuItemClickedEvent } from "./MenuItemClickedEvent";
+import type { MenuItemClickedEvent } from "./ui/MenuItemClickedEvent";
+import type { MenuItemRegisterEvent } from './ui/MenuItemRegisterEvent';
import type { HasPlayerMovedEvent } from "./HasPlayerMovedEvent";
@@ -47,7 +48,7 @@ export type IframeEventMap = {
playSound: PlaySoundEvent
stopSound: null,
getState: undefined,
- registerMenuCommand: undefined
+ registerMenuCommand: MenuItemRegisterEvent
}
export interface IframeEvent {
type: T;
diff --git a/front/src/Api/Events/MenuItemRegisterEvent.ts b/front/src/Api/Events/MenuItemRegisterEvent.ts
deleted file mode 100644
index a25e5cc3..00000000
--- a/front/src/Api/Events/MenuItemRegisterEvent.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import * as tg from "generic-type-guard";
-
-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;
diff --git a/front/src/Api/Events/MenuItemClickedEvent.ts b/front/src/Api/Events/ui/MenuItemClickedEvent.ts
similarity index 99%
rename from front/src/Api/Events/MenuItemClickedEvent.ts
rename to front/src/Api/Events/ui/MenuItemClickedEvent.ts
index 0735eda4..fad2944f 100644
--- a/front/src/Api/Events/MenuItemClickedEvent.ts
+++ b/front/src/Api/Events/ui/MenuItemClickedEvent.ts
@@ -8,3 +8,5 @@ export const isMenuItemClickedEvent =
* A message sent from the game to the iFrame when a menu item is clicked.
*/
export type MenuItemClickedEvent = tg.GuardedType;
+
+
diff --git a/front/src/Api/Events/ui/MenuItemRegisterEvent.ts b/front/src/Api/Events/ui/MenuItemRegisterEvent.ts
new file mode 100644
index 00000000..4a56d8a0
--- /dev/null
+++ b/front/src/Api/Events/ui/MenuItemRegisterEvent.ts
@@ -0,0 +1,25 @@
+import * as tg from "generic-type-guard";
+import { Subject } from 'rxjs';
+
+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;
+
+export const isMenuItemRegisterIframeEvent =
+ new tg.IsInterface().withProperties({
+ type: tg.isSingletonString("registerMenuCommand"),
+ data: isMenuItemRegisterEvent
+ }).get();
+
+
+const _registerMenuCommandStream: Subject = new Subject();
+export const registerMenuCommandStream = _registerMenuCommandStream.asObservable();
+
+export function handleMenuItemRegistrationEvent(event: MenuItemRegisterEvent) {
+ _registerMenuCommandStream.next(event.menutItem)
+}
\ No newline at end of file
diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts
index a495d92b..c4aa29b1 100644
--- a/front/src/Api/IframeListener.ts
+++ b/front/src/Api/IframeListener.ts
@@ -24,12 +24,12 @@ import {isStopSoundEvent, StopSoundEvent} from "./Events/StopSoundEvent";
import {isLoadSoundEvent, LoadSoundEvent} from "./Events/LoadSoundEvent";
import {isSetPropertyEvent, SetPropertyEvent} from "./Events/setPropertyEvent";
import {isLayerEvent, LayerEvent} from "./Events/LayerEvent";
-import {isMenuItemRegisterEvent} from "./Events/MenuItemRegisterEvent";
+import {isMenuItemRegisterEvent,} from "./Events/ui/MenuItemRegisterEvent";
import type {DataLayerEvent} from "./Events/DataLayerEvent";
import type {GameStateEvent} from "./Events/GameStateEvent";
-import type {MenuItemClickedEvent} from "./Events/MenuItemClickedEvent";
import type {HasPlayerMovedEvent} from "./Events/HasPlayerMovedEvent";
import {isLoadPageEvent} from "./Events/LoadPageEvent";
+import {handleMenuItemRegistrationEvent, isMenuItemRegisterIframeEvent} from "./Events/ui/MenuItemRegisterEvent";
/**
* Listens to messages from iframes and turn those messages into easy to use observables.
@@ -115,21 +115,16 @@ class IframeListener {
// Note: maybe we could restrict on the domain too for additional security (in case the iframe goes to another domain).
let foundSrc: string | undefined;
- foundSrc = [...this.scripts.keys()].find(key => {
- return this.scripts.get(key)?.contentWindow == message.source
- });
-
- if (foundSrc === undefined) {
- let iframe: HTMLIFrameElement;
+ let iframe: HTMLIFrameElement;
for (iframe of this.iframes) {
if (iframe.contentWindow === message.source) {
foundSrc = iframe.src;
- break;}
+ break;
}
+ }
- if (foundSrc === undefined) {
- return;
- }
+ if (foundSrc === undefined) {
+ return;
}
const payload = message.data;
@@ -188,13 +183,13 @@ class IframeListener {
this.sendPlayerMove = true
} else if (payload.type == "getDataLayer") {
this._dataLayerChangeStream.next();
- } else if (payload.type == "registerMenuCommand" && isMenuItemRegisterEvent(payload.data)) {
+ } else if (isMenuItemRegisterIframeEvent(payload)) {
const data = payload.data.menutItem;
// @ts-ignore
this.iframeCloseCallbacks.get(iframe).push(() => {
this._unregisterMenuCommandStream.next(data);
})
- this._registerMenuCommandStream.next(payload.data.menutItem)
+ handleMenuItemRegistrationEvent(payload.data)
}
}
}, false);
@@ -295,15 +290,6 @@ class IframeListener {
this.scripts.delete(scriptUrl);
}
- sendMenuClickedEvent(menuItem: string) {
- this.postMessage({
- 'type': 'menuItemClicked',
- 'data': {
- menuItem: menuItem,
- } as MenuItemClickedEvent
- });
- }
-
sendUserInputChat(message: string) {
this.postMessage({
'type': 'userInputChat',
@@ -353,7 +339,7 @@ class IframeListener {
/**
* Sends the message... to all allowed iframes.
*/
- private postMessage(message: IframeResponseEvent) {
+ public postMessage(message: IframeResponseEvent) {
for (const iframe of this.iframes) {
iframe.contentWindow?.postMessage(message, '*');
}
diff --git a/front/src/Api/iframe/Ui/MenuItem.ts b/front/src/Api/iframe/Ui/MenuItem.ts
new file mode 100644
index 00000000..9782ea7a
--- /dev/null
+++ b/front/src/Api/iframe/Ui/MenuItem.ts
@@ -0,0 +1,11 @@
+import type { MenuItemClickedEvent } from '../../Events/ui/MenuItemClickedEvent';
+import { iframeListener } from '../../IframeListener';
+
+export function sendMenuClickedEvent(menuItem: string) {
+ iframeListener.postMessage({
+ 'type': 'menuItemClicked',
+ 'data': {
+ menuItem: menuItem,
+ } as MenuItemClickedEvent
+ });
+}
\ No newline at end of file
diff --git a/front/src/Api/iframe/ui.ts b/front/src/Api/iframe/ui.ts
index 629d3c36..8e9943b2 100644
--- a/front/src/Api/iframe/ui.ts
+++ b/front/src/Api/iframe/ui.ts
@@ -1,14 +1,17 @@
import { isButtonClickedEvent } from '../Events/ButtonClickedEvent';
-import type { ClosePopupEvent } from '../Events/ClosePopupEvent';
+import { isMenuItemClickedEvent } from '../Events/ui/MenuItemClickedEvent';
+import type { MenuItemRegisterEvent } from '../Events/ui/MenuItemRegisterEvent';
import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution';
import { apiCallback } from "./registeredCallbacks";
-import {Popup} from "./Ui/Popup";
-import type {ButtonClickedCallback, ButtonDescriptor} from "./Ui/ButtonDescriptor";
+import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor";
+import { Popup } from "./Ui/Popup";
let popupId = 0;
const popups: Map = new Map();
const popupCallbacks: Map> = new Map>();
+const menuCallbacks: Map void> = new Map()
+
interface ZonedPopupOptions {
zone: string
objectLayerName?: string,
@@ -33,6 +36,16 @@ class WorkAdventureUiCommands extends IframeApiContribution {
+ const callback = menuCallbacks.get(event.menuItem);
+ if (callback) {
+ callback(event.menuItem)
+ }
+ }
})];
@@ -71,6 +84,16 @@ class WorkAdventureUiCommands extends IframeApiContribution void) {
+ menuCallbacks.set(commandDescriptor, callback);
+ sendToWorkadventure({
+ 'type': 'registerMenuCommand',
+ 'data': {
+ menutItem: commandDescriptor
+ } as MenuItemRegisterEvent
+ });
+ }
+
displayBubble(): void {
sendToWorkadventure({ 'type': 'displayBubble', data: null });
}
diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts
index d21a125b..cc0ce1d3 100644
--- a/front/src/Phaser/Game/GameScene.ts
+++ b/front/src/Phaser/Game/GameScene.ts
@@ -1,4 +1,10 @@
-import {gameManager, HasMovedEvent} from "./GameManager";
+import { Queue } from 'queue-typescript';
+import type { Subscription } from "rxjs";
+import { ConsoleGlobalMessageManager } from "../../Administration/ConsoleGlobalMessageManager";
+import { GlobalMessageManager } from "../../Administration/GlobalMessageManager";
+import { userMessageManager } from "../../Administration/UserMessageManager";
+import { iframeListener } from "../../Api/IframeListener";
+import { connectionManager } from "../../Connexion/ConnectionManager";
import type {
GroupCreatedUpdatedMessageInterface,
MessageUserJoined,
@@ -9,94 +15,84 @@ import type {
PositionInterface,
RoomJoinedMessageInterface
} from "../../Connexion/ConnexionModels";
-import {hasMovedEventName, Player, requestEmoteEventName} from "../Player/Player";
+import { localUserStore } from "../../Connexion/LocalUserStore";
+import { Room } from "../../Connexion/Room";
+import type { RoomConnection } from "../../Connexion/RoomConnection";
+import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream";
import {
DEBUG_MODE,
JITSI_PRIVATE_MODE,
MAX_PER_GROUP,
- POSITION_DELAY,
+ POSITION_DELAY
} from "../../Enum/EnvironmentVariable";
-import type {
- ITiledMap,
- ITiledMapLayer,
- ITiledMapLayerProperty,
- ITiledMapObject,
- ITiledMapTileLayer,
- ITiledTileSet
-} from "../Map/ITiledMap";
-import type { AddPlayerInterface } from "./AddPlayerInterface";
-import { PlayerAnimationDirections } from "../Player/Animation";
-import { PlayerMovement } from "./PlayerMovement";
-import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator";
-import { RemotePlayer } from "../Entity/RemotePlayer";
-import { Queue } from 'queue-typescript';
-import { SimplePeer, UserSimplePeerInterface } from "../../WebRtc/SimplePeer";
-import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene";
-import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager";
+import { TextureError } from "../../Exception/TextureError";
+import type { UserMovedMessage } from "../../Messages/generated/messages_pb";
+import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils";
+import { peerStore } from "../../Stores/PeerStore";
+import { touchScreenManager } from "../../Touch/TouchScreenManager";
+import { urlManager } from "../../Url/UrlManager";
+import { audioManager } from "../../WebRtc/AudioManager";
+import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
+import { HtmlUtils } from "../../WebRtc/HtmlUtils";
+import { jitsiFactory } from "../../WebRtc/JitsiFactory";
import {
- CenterListener,
+ AUDIO_LOOP_PROPERTY, AUDIO_VOLUME_PROPERTY, CenterListener,
JITSI_MESSAGE_PROPERTIES,
layoutManager,
LayoutMode,
ON_ACTION_TRIGGER_BUTTON,
TRIGGER_JITSI_PROPERTIES,
TRIGGER_WEBSITE_PROPERTIES,
- WEBSITE_MESSAGE_PROPERTIES,
- AUDIO_VOLUME_PROPERTY,
- AUDIO_LOOP_PROPERTY
+ WEBSITE_MESSAGE_PROPERTIES
} from "../../WebRtc/LayoutManager";
-import { GameMap } from "./GameMap";
-import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
import { mediaManager } from "../../WebRtc/MediaManager";
-import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface";
-import type { ActionableItem } from "../Items/ActionableItem";
-import { UserInputManager } from "../UserInput/UserInputManager";
-import {soundManager} from "./SoundManager";
-import type { UserMovedMessage } from "../../Messages/generated/messages_pb";
-import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils";
-import { connectionManager } from "../../Connexion/ConnectionManager";
-import type { RoomConnection } from "../../Connexion/RoomConnection";
-import { GlobalMessageManager } from "../../Administration/GlobalMessageManager";
-import { userMessageManager } from "../../Administration/UserMessageManager";
-import { ConsoleGlobalMessageManager } from "../../Administration/ConsoleGlobalMessageManager";
-import { ResizableScene } from "../Login/ResizableScene";
-import { Room } from "../../Connexion/Room";
-import { jitsiFactory } from "../../WebRtc/JitsiFactory";
-import { urlManager } from "../../Url/UrlManager";
-import { audioManager } from "../../WebRtc/AudioManager";
-import { PresentationModeIcon } from "../Components/PresentationModeIcon";
+import { SimplePeer, UserSimplePeerInterface } from "../../WebRtc/SimplePeer";
+import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
import { ChatModeIcon } from "../Components/ChatModeIcon";
-import { OpenChatIcon, openChatIconName } from "../Components/OpenChatIcon";
-import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene";
-import { TextureError } from "../../Exception/TextureError";
import { addLoader } from "../Components/Loader";
+import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick";
+import { OpenChatIcon, openChatIconName } from "../Components/OpenChatIcon";
+import { PresentationModeIcon } from "../Components/PresentationModeIcon";
+import { TextUtils } from "../Components/TextUtils";
+import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager";
+import { RemotePlayer } from "../Entity/RemotePlayer";
+import type { ActionableItem } from "../Items/ActionableItem";
+import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface";
+import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene";
+import type {
+ ITiledMap,
+ ITiledMapLayer,
+ ITiledMapLayerProperty,
+ ITiledMapObject,
+ ITiledMapTileLayer,
+ ITiledTileSet } from "../Map/ITiledMap";
+import { MenuScene, MenuSceneName } from '../Menu/MenuScene';
+import { PlayerAnimationDirections } from "../Player/Animation";
+import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player";
import { ErrorSceneName } from "../Reconnecting/ErrorScene";
-import { localUserStore } from "../../Connexion/LocalUserStore";
-import { iframeListener } from "../../Api/IframeListener";
-import { HtmlUtils } from "../../WebRtc/HtmlUtils";
+import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene";
+import { waScaleManager } from "../Services/WaScaleManager";
+import { PinchManager } from "../UserInput/PinchManager";
+import { UserInputManager } from "../UserInput/UserInputManager";
+import type { AddPlayerInterface } from "./AddPlayerInterface";
+import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
+import { DirtyScene } from "./DirtyScene";
+import { EmoteManager } from "./EmoteManager";
+import { gameManager } from "./GameManager";
+import { GameMap } from "./GameMap";
+import { PlayerMovement } from "./PlayerMovement";
+import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator";
+import { soundManager } from "./SoundManager";
import Texture = Phaser.Textures.Texture;
import Sprite = Phaser.GameObjects.Sprite;
import CanvasTexture = Phaser.Textures.CanvasTexture;
import GameObject = Phaser.GameObjects.GameObject;
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
import DOMElement = Phaser.GameObjects.DOMElement;
-import EVENT_TYPE =Phaser.Scenes.Events
-import type {Subscription} from "rxjs";
-import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream";
-import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
+import EVENT_TYPE = Phaser.Scenes.Events
import RenderTexture = Phaser.GameObjects.RenderTexture;
import Tilemap = Phaser.Tilemaps.Tilemap;
-import { DirtyScene } from "./DirtyScene";
-import { TextUtils } from "../Components/TextUtils";
-import { touchScreenManager } from "../../Touch/TouchScreenManager";
-import { PinchManager } from "../UserInput/PinchManager";
-import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick";
-import { DEPTH_OVERLAY_INDEX } from "./DepthIndexes";
-import { waScaleManager } from "../Services/WaScaleManager";
-import { peerStore} from "../../Stores/PeerStore";
-import {EmoteManager } from "./EmoteManager";
import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
-import { MenuScene, MenuSceneName } from '../Menu/MenuScene';
import AnimatedTiles from "phaser-animated-tiles";
@@ -192,7 +188,7 @@ export class GameScene extends DirtyScene implements CenterListener {
private characterLayers!: string[];
private companion!: string | null;
private messageSubscription: Subscription | null = null;
- private popUpElements : Map = new Map();
+ private popUpElements: Map = new Map();
private originalMapUrl: string | undefined;
private pinchManager: PinchManager | undefined;
private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time.
@@ -899,37 +895,34 @@ ${escapedMessage}
this.userInputManager.disableControls();
}));
- this.iframeSubscriptionList.push(iframeListener.playSoundStream.subscribe((playSoundEvent)=>
- {
- const url = new URL(playSoundEvent.url, this.MapUrlFile);
- soundManager.playSound(this.load,this.sound,url.toString(),playSoundEvent.config);
- }))
-
- this.iframeSubscriptionList.push(iframeListener.stopSoundStream.subscribe((stopSoundEvent)=>
- {
- const url = new URL(stopSoundEvent.url, this.MapUrlFile);
- soundManager.stopSound(this.sound,url.toString());
+ this.iframeSubscriptionList.push(iframeListener.playSoundStream.subscribe((playSoundEvent) => {
+ const url = new URL(playSoundEvent.url, this.MapUrlFile);
+ soundManager.playSound(this.load, this.sound, url.toString(), playSoundEvent.config);
}))
- this.iframeSubscriptionList.push(iframeListener.loadSoundStream.subscribe((loadSoundEvent)=>
- {
+ this.iframeSubscriptionList.push(iframeListener.stopSoundStream.subscribe((stopSoundEvent) => {
+ const url = new URL(stopSoundEvent.url, this.MapUrlFile);
+ soundManager.stopSound(this.sound, url.toString());
+ }))
+
+ this.iframeSubscriptionList.push(iframeListener.loadSoundStream.subscribe((loadSoundEvent) => {
const url = new URL(loadSoundEvent.url, this.MapUrlFile);
- soundManager.loadSound(this.load,this.sound,url.toString());
+ soundManager.loadSound(this.load, this.sound, url.toString());
}))
this.iframeSubscriptionList.push(iframeListener.enablePlayerControlStream.subscribe(() => {
this.userInputManager.restoreControls();
}));
- this.iframeSubscriptionList.push(iframeListener.loadPageStream.subscribe((url:string)=>{
- this.loadNextGame(url).then(()=>{
- this.events.once(EVENT_TYPE.POST_UPDATE,()=>{
+ this.iframeSubscriptionList.push(iframeListener.loadPageStream.subscribe((url: string) => {
+ this.loadNextGame(url).then(() => {
+ this.events.once(EVENT_TYPE.POST_UPDATE, () => {
this.onMapExit(url);
})
})
}));
- let scriptedBubbleSprite : Sprite;
- this.iframeSubscriptionList.push(iframeListener.displayBubbleStream.subscribe(()=>{
- scriptedBubbleSprite = new Sprite(this,this.CurrentPlayer.x + 25,this.CurrentPlayer.y,'circleSprite-white');
+ let scriptedBubbleSprite: Sprite;
+ this.iframeSubscriptionList.push(iframeListener.displayBubbleStream.subscribe(() => {
+ scriptedBubbleSprite = new Sprite(this, this.CurrentPlayer.x + 25, this.CurrentPlayer.y, 'circleSprite-white');
scriptedBubbleSprite.setDisplayOrigin(48, 48);
this.add.existing(scriptedBubbleSprite);
}));
@@ -1000,8 +993,8 @@ ${escapedMessage}
private onMapExit(exitKey: string) {
if (this.mapTransitioning) return;
this.mapTransitioning = true;
- const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
- if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey);
+ const { roomId, hash } = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
+ if (!roomId) throw new Error('Could not find the room from its exit key: ' + exitKey);
urlManager.pushStartLayerNameToUrl(hash);
const menuScene: MenuScene = this.scene.get(MenuSceneName) as MenuScene
menuScene.reset()
@@ -1159,7 +1152,7 @@ ${escapedMessage}
private loadNextGame(exitSceneIdentifier: string) : Promise{
const { roomId, hash } = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance);
const room = new Room(roomId);
- return gameManager.loadMap(room, this.scene).catch(() => {});
+ return gameManager.loadMap(room, this.scene).catch(() => { });
}
private startUser(layer: ITiledMapTileLayer): PositionInterface {
diff --git a/front/src/Phaser/Menu/MenuScene.ts b/front/src/Phaser/Menu/MenuScene.ts
index 8a01c259..15df4e5c 100644
--- a/front/src/Phaser/Menu/MenuScene.ts
+++ b/front/src/Phaser/Menu/MenuScene.ts
@@ -14,6 +14,8 @@ import { HtmlUtils } from '../../WebRtc/HtmlUtils';
import { iframeListener } from '../../Api/IframeListener';
import { Subscription } from 'rxjs';
import { videoConstraintStore } from "../../Stores/MediaStore";
+import {registerMenuCommandStream} from "../../Api/Events/ui/MenuItemRegisterEvent";
+import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem";
export const MenuSceneName = 'MenuScene';
const gameMenuKey = 'gameMenu';
@@ -42,12 +44,12 @@ export class MenuScene extends Phaser.Scene {
private warningContainerTimeout: NodeJS.Timeout | null = null;
private subscriptions = new Subscription()
constructor() {
- super({key: MenuSceneName});
+ super({ key: MenuSceneName });
this.gameQualityValue = localUserStore.getGameQualityValue();
this.videoQualityValue = localUserStore.getVideoQualityValue();
- this.subscriptions.add(iframeListener.registerMenuCommandStream.subscribe(menuCommand => {
+ this.subscriptions.add(registerMenuCommandStream.subscribe(menuCommand => {
this.addMenuOption(menuCommand);
}))
@@ -56,7 +58,25 @@ export class MenuScene extends Phaser.Scene {
}))
}
- preload () {
+ reset() {
+ const addedMenuItems = [...this.menuElement.node.querySelectorAll(".fromApi")];
+ for (let index = addedMenuItems.length - 1; index >= 0; index--) {
+ addedMenuItems[index].remove()
+ }
+ }
+
+ public addMenuOption(menuText: string) {
+ const wrappingSection = document.createElement("section")
+ const escapedHtml = HtmlUtils.escapeHtml(menuText);
+ wrappingSection.innerHTML = ``
+ const menuItemContainer = this.menuElement.node.querySelector("#gameMenu main");
+ if (menuItemContainer) {
+ menuItemContainer.querySelector(`#${escapedHtml}.fromApi`)?.remove()
+ menuItemContainer.insertBefore(wrappingSection, menuItemContainer.querySelector("#socialLinks"))
+ }
+ }
+
+ preload() {
this.load.html(gameMenuKey, 'resources/html/gameMenu.html');
this.load.html(gameMenuIconKey, 'resources/html/gameMenuIcon.html');
this.load.html(gameSettingsMenuKey, 'resources/html/gameQualityMenu.html');
@@ -65,13 +85,6 @@ export class MenuScene extends Phaser.Scene {
this.load.html(warningContainerKey, warningContainerHtml);
}
- reset() {
- const addedMenuItems=[...this.menuElement.node.querySelectorAll(".fromApi")];
- for(let index=addedMenuItems.length-1;index>=0;index--){
- addedMenuItems[index].remove()
- }
- }
-
create() {
menuIconVisible.set(true);
this.menuElement = this.add.dom(closedSideMenuX, 30).createFromCache(gameMenuKey);
@@ -86,11 +99,11 @@ export class MenuScene extends Phaser.Scene {
this.gameShareElement = this.add.dom(middleX, -400).createFromCache(gameShare);
MenuScene.revealMenusAfterInit(this.gameShareElement, gameShare);
this.gameShareElement.addListener('click');
- this.gameShareElement.on('click', (event:MouseEvent) => {
+ this.gameShareElement.on('click', (event: MouseEvent) => {
event.preventDefault();
- if((event?.target as HTMLInputElement).id === 'gameShareFormSubmit') {
+ if ((event?.target as HTMLInputElement).id === 'gameShareFormSubmit') {
this.copyLink();
- }else if((event?.target as HTMLInputElement).id === 'gameShareFormCancel') {
+ } else if ((event?.target as HTMLInputElement).id === 'gameShareFormCancel') {
this.closeGameShare();
}
});
@@ -146,8 +159,8 @@ export class MenuScene extends Phaser.Scene {
}
//TODO bind with future metadata of card
//if (connectionManager.getConnexionType === GameConnexionTypes.anonymous){
- const adminSection = this.menuElement.getChildByID('socialLinks') as HTMLElement;
- adminSection.hidden = false;
+ const adminSection = this.menuElement.getChildByID('socialLinks') as HTMLElement;
+ adminSection.hidden = false;
//}
this.tweens.add({
targets: this.menuElement,
@@ -197,28 +210,28 @@ export class MenuScene extends Phaser.Scene {
this.settingsMenuOpened = true;
const gameQualitySelect = this.gameQualityMenuElement.getChildByID('select-game-quality') as HTMLInputElement;
- gameQualitySelect.value = ''+this.gameQualityValue;
+ gameQualitySelect.value = '' + this.gameQualityValue;
const videoQualitySelect = this.gameQualityMenuElement.getChildByID('select-video-quality') as HTMLInputElement;
- videoQualitySelect.value = ''+this.videoQualityValue;
+ videoQualitySelect.value = '' + this.videoQualityValue;
this.gameQualityMenuElement.addListener('click');
- this.gameQualityMenuElement.on('click', (event:MouseEvent) => {
+ this.gameQualityMenuElement.on('click', (event: MouseEvent) => {
event.preventDefault();
if ((event?.target as HTMLInputElement).id === 'gameQualityFormSubmit') {
const gameQualitySelect = this.gameQualityMenuElement.getChildByID('select-game-quality') as HTMLInputElement;
const videoQualitySelect = this.gameQualityMenuElement.getChildByID('select-video-quality') as HTMLInputElement;
this.saveSetting(parseInt(gameQualitySelect.value), parseInt(videoQualitySelect.value));
- } else if((event?.target as HTMLInputElement).id === 'gameQualityFormCancel') {
+ } else if ((event?.target as HTMLInputElement).id === 'gameQualityFormCancel') {
this.closeGameQualityMenu();
}
});
- let middleY = this.scale.height / 2 - 392/2;
- if(middleY < 0){
+ let middleY = this.scale.height / 2 - 392 / 2;
+ if (middleY < 0) {
middleY = 0;
}
- let middleX = this.scale.width / 2 - 457/2;
- if(middleX < 0){
+ let middleX = this.scale.width / 2 - 457 / 2;
+ if (middleX < 0) {
middleX = 0;
}
this.tweens.add({
@@ -244,7 +257,7 @@ export class MenuScene extends Phaser.Scene {
}
- private openGameShare(): void{
+ private openGameShare(): void {
if (this.gameShareOpened) {
this.closeGameShare();
return;
@@ -258,11 +271,11 @@ export class MenuScene extends Phaser.Scene {
this.gameShareOpened = true;
let middleY = this.scale.height / 2 - 85;
- if(middleY < 0){
+ if (middleY < 0) {
middleY = 0;
}
let middleX = this.scale.width / 2 - 200;
- if(middleX < 0){
+ if (middleX < 0) {
middleX = 0;
}
this.tweens.add({
@@ -274,7 +287,7 @@ export class MenuScene extends Phaser.Scene {
});
}
- private closeGameShare(): void{
+ private closeGameShare(): void {
const gameShareInfo = this.gameShareElement.getChildByID('gameShareInfo') as HTMLParagraphElement;
gameShareInfo.innerText = '';
gameShareInfo.style.display = 'none';
@@ -287,17 +300,6 @@ export class MenuScene extends Phaser.Scene {
});
}
- public addMenuOption(menuText: string) {
- const wrappingSection = document.createElement("section")
- const excapedHtml = HtmlUtils.escapeHtml(menuText);
- wrappingSection.innerHTML = ``
- const menuItemContainer = this.menuElement.node.querySelector("#gameMenu main");
- if (menuItemContainer) {
- menuItemContainer.querySelector(`#${excapedHtml}.fromApi`)?.remove()
- menuItemContainer.insertBefore(wrappingSection, menuItemContainer.querySelector("#socialLinks"))
- }
- }
-
private onMenuClick(event: MouseEvent) {
const htmlMenuItem = (event?.target as HTMLInputElement);
if (htmlMenuItem.classList.contains('not-button')) {
@@ -306,11 +308,11 @@ export class MenuScene extends Phaser.Scene {
event.preventDefault();
if (htmlMenuItem.classList.contains("fromApi")) {
- iframeListener.sendMenuClickedEvent(htmlMenuItem.id)
+ sendMenuClickedEvent(htmlMenuItem.id)
return
}
- switch (htmlMenuItem.id) {
+ switch ((event?.target as HTMLInputElement).id) {
case 'changeNameButton':
this.closeSideMenu();
gameManager.leaveGame(this, LoginSceneName, new LoginScene());
@@ -351,7 +353,7 @@ export class MenuScene extends Phaser.Scene {
gameShareInfo.style.display = 'block';
}
- private saveSetting(valueGame: number, valueVideo: number){
+ private saveSetting(valueGame: number, valueVideo: number) {
if (valueGame !== this.gameQualityValue) {
this.gameQualityValue = valueGame;
localUserStore.setGameQualityValue(valueGame);
@@ -372,7 +374,7 @@ export class MenuScene extends Phaser.Scene {
window.open(sparkHost, '_blank');
}
- private closeAll(){
+ private closeAll() {
this.closeGameQualityMenu();
this.closeGameShare();
this.gameReportElement.close();
diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts
index e36199ba..7b6b2db9 100644
--- a/front/src/iframe_api.ts
+++ b/front/src/iframe_api.ts
@@ -1,4 +1,4 @@
-import {registeredCallbacks} from "./Api/iframe/registeredCallbacks";
+import { registeredCallbacks } from "./Api/iframe/registeredCallbacks";
import {
IframeResponseEvent,
IframeResponseEventMap,
@@ -6,19 +6,16 @@ import {
TypedMessageEvent
} from "./Api/Events/IframeEvent";
import chat from "./Api/iframe/chat";
-import type {IframeCallback} from './Api/iframe/IframeApiContribution';
+import type { IframeCallback } from './Api/iframe/IframeApiContribution';
import nav from "./Api/iframe/nav";
import controls from "./Api/iframe/controls";
import ui from "./Api/iframe/ui";
import sound from "./Api/iframe/sound";
import room from "./Api/iframe/room";
-import type {ButtonDescriptor} from "./Api/iframe/Ui/ButtonDescriptor";
-import type {Popup} from "./Api/iframe/Ui/Popup";
-import type {Sound} from "./Api/iframe/Sound/Sound";
-import type {MenuItemRegisterEvent} from "./Api/Events/MenuItemRegisterEvent";
+import type { ButtonDescriptor } from "./Api/iframe/Ui/ButtonDescriptor";
+import type { Popup } from "./Api/iframe/Ui/Popup";
+import type { Sound } from "./Api/iframe/Sound/Sound";
-
-const menuCallbacks: Map void> = new Map()
const wa = {
ui,
nav,
@@ -80,7 +77,7 @@ const wa = {
/**
* @deprecated Use WA.sound.loadSound instead
*/
- loadSound(url: string) : Sound {
+ loadSound(url: string): Sound {
console.warn('Method WA.loadSound is deprecated. Please use WA.sound.loadSound instead');
return sound.loadSound(url);
},
@@ -88,7 +85,7 @@ const wa = {
/**
* @deprecated Use WA.nav.goToPage instead
*/
- goToPage(url : string) : void {
+ goToPage(url: string): void {
console.warn('Method WA.goToPage is deprecated. Please use WA.nav.goToPage instead');
nav.goToPage(url);
},
@@ -124,16 +121,6 @@ const wa = {
console.warn('Method WA.openPopup is deprecated. Please use WA.ui.openPopup instead');
return ui.openPopup(targetObject, message, buttons);
},
-
- registerMenuCommand(commandDescriptor: string, callback: (commandDescriptor: string) => void): void {
- menuCallbacks.set(commandDescriptor, callback);
- window.parent.postMessage({
- 'type': 'registerMenuCommand',
- 'data': {
- menutItem: commandDescriptor
- } as MenuItemRegisterEvent
- }, '*');
- },
/**
* @deprecated Use WA.chat.onChatMessage instead
*/
diff --git a/maps/tests/Metadata/customMenu.html b/maps/tests/Metadata/customMenu.html
index 59f579ba..a80dca08 100644
--- a/maps/tests/Metadata/customMenu.html
+++ b/maps/tests/Metadata/customMenu.html
@@ -5,11 +5,9 @@