diff --git a/front/src/Api/Events/ButtonClickedEvent.ts b/front/src/Api/Events/ButtonClickedEvent.ts new file mode 100644 index 00000000..de807037 --- /dev/null +++ b/front/src/Api/Events/ButtonClickedEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isButtonClickedEvent = + new tg.IsInterface().withProperties({ + popupId: tg.isNumber, + buttonId: tg.isNumber, + }).get(); +/** + * A message sent from the game to the iFrame when a user enters or leaves a zone marked with the "zone" property. + */ +export type ButtonClickedEvent = tg.GuardedType; diff --git a/front/src/Api/Events/OpenPopupEvent.ts b/front/src/Api/Events/OpenPopupEvent.ts index bbfc12bf..55df8a40 100644 --- a/front/src/Api/Events/OpenPopupEvent.ts +++ b/front/src/Api/Events/OpenPopupEvent.ts @@ -6,14 +6,13 @@ const isButtonDescriptor = className: tg.isOptional(tg.isString), closeOnClick: tg.isOptional(tg.isBoolean) }).get(); -type ButtonDescriptor = tg.GuardedType; export const isOpenPopupEvent = new tg.IsInterface().withProperties({ popupId: tg.isNumber, targetObject: tg.isString, message: tg.isString, - buttons: tg.isAny //tg.isArray, + buttons: tg.isArray(isButtonDescriptor) }).get(); /** diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 1a6a0ea7..f55a70bd 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -6,6 +6,7 @@ import * as crypto from "crypto"; import {HtmlUtils} from "../WebRtc/HtmlUtils"; import {EnterLeaveEvent} from "./Events/EnterLeaveEvent"; import {isOpenPopupEvent, OpenPopupEvent} from "./Events/OpenPopupEvent"; +import {ButtonClickedEvent} from "./Events/ButtonClickedEvent"; @@ -40,13 +41,10 @@ class IframeListener { } const payload = message.data; - console.log('FOO'); if (isIframeEventWrapper(payload)) { - console.log('FOOBAR', payload); if (payload.type === 'chat' && isChatEvent(payload.data)) { this._chatStream.next(payload.data); } else if (payload.type === 'openPopup' && isOpenPopupEvent(payload.data)) { - console.log('OPENPOPUP called'); this._openPopupStream.next(payload.data); } } @@ -158,6 +156,16 @@ class IframeListener { }); } + sendButtonClickedEvent(popupId: number, buttonId: number): void { + this.postMessage({ + 'type': 'buttonClickedEvent', + 'data': { + popupId, + buttonId + } as ButtonClickedEvent + }); + } + /** * Sends the message... to all allowed iframes. */ @@ -166,6 +174,7 @@ class IframeListener { iframe.contentWindow?.postMessage(message, '*'); } } + } export const iframeListener = new IframeListener(); diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 0a953363..0a422ff8 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -273,7 +273,8 @@ export class GameScene extends ResizableScene implements CenterListener { break; } default: - throw new Error('Unsupported object type: "'+ itemType +'"'); + continue; + //throw new Error('Unsupported object type: "'+ itemType +'"'); } itemFactory.preload(this.load); @@ -747,10 +748,27 @@ export class GameScene extends ResizableScene implements CenterListener { let html = `
${escapedMessage}
`; + let id = 0; + for (const button of openPopupEvent.buttons) { + html += ``; + id++; + } const domElement = this.add.dom(150, 150).createFromHTML(html); domElement.scale = 0; domElement.setClassName('popUpElement'); + + id = 0; + for (const button of openPopupEvent.buttons) { + const button = HtmlUtils.getElementByIdOrFail(`popup-${openPopupEvent.popupId}-${id}`); + const btnId = id; + button.onclick = () => { + iframeListener.sendButtonClickedEvent(openPopupEvent.popupId, btnId); + console.log('BUTTON CLICKED', btnId); + } + id++; + } + this.tweens.add({ targets : domElement , scale : 1, diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts index c5e5e604..e72093e6 100644 --- a/front/src/iframe_api.ts +++ b/front/src/iframe_api.ts @@ -4,6 +4,7 @@ import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputCh import {Subject} from "rxjs"; import {EnterLeaveEvent, isEnterLeaveEvent} from "./Api/Events/EnterLeaveEvent"; import {OpenPopupEvent} from "./Api/Events/OpenPopupEvent"; +import {isButtonClickedEvent} from "./Api/Events/ButtonClickedEvent"; interface WorkAdventureApi { sendChatMessage(message: string, author: string): void; @@ -23,6 +24,8 @@ type ChatMessageCallback = (message: string) => void; const userInputChatStream: Subject = new Subject(); const enterStreams: Map> = new Map>(); const leaveStreams: Map> = new Map>(); +const popupCallbacks: Map void>> = new Map void>>(); + let popupId = 0; interface ButtonDescriptor { /** @@ -120,6 +123,11 @@ window.addEventListener('message', message => { enterStreams.get(payloadData.name)?.next(); } else if (payload.type === 'leaveEvent' && isEnterLeaveEvent(payloadData)) { leaveStreams.get(payloadData.name)?.next(); + } else if (payload.type === 'buttonClickedEvent' && isButtonClickedEvent(payloadData)) { + const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId); + if (callback) { + callback(); + } } }