Merge branch 'iframe_api' of https://github.com/thecodingmachine/workadventure into FTUEPopup

* 'iframe_api' of https://github.com/thecodingmachine/workadventure:
  Adding button clicked handling

# Conflicts:
#	front/src/Phaser/Game/GameScene.ts
This commit is contained in:
DESKTOP-FMM8UI0\CLV 2021-03-09 17:12:28 +01:00
commit 4545de8af1
5 changed files with 54 additions and 9 deletions

View File

@ -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<typeof isButtonClickedEvent>;

View File

@ -6,14 +6,13 @@ const isButtonDescriptor =
className: tg.isOptional(tg.isString), className: tg.isOptional(tg.isString),
closeOnClick: tg.isOptional(tg.isBoolean) closeOnClick: tg.isOptional(tg.isBoolean)
}).get(); }).get();
type ButtonDescriptor = tg.GuardedType<typeof isButtonDescriptor>;
export const isOpenPopupEvent = export const isOpenPopupEvent =
new tg.IsInterface().withProperties({ new tg.IsInterface().withProperties({
popupId: tg.isNumber, popupId: tg.isNumber,
targetObject: tg.isString, targetObject: tg.isString,
message: tg.isString, message: tg.isString,
buttons: tg.isAny //tg.isArray<ButtonDescriptor>, buttons: tg.isArray(isButtonDescriptor)
}).get(); }).get();
/** /**

View File

@ -6,6 +6,7 @@ import * as crypto from "crypto";
import {HtmlUtils} from "../WebRtc/HtmlUtils"; import {HtmlUtils} from "../WebRtc/HtmlUtils";
import {EnterLeaveEvent} from "./Events/EnterLeaveEvent"; import {EnterLeaveEvent} from "./Events/EnterLeaveEvent";
import {isOpenPopupEvent, OpenPopupEvent} from "./Events/OpenPopupEvent"; import {isOpenPopupEvent, OpenPopupEvent} from "./Events/OpenPopupEvent";
import {ButtonClickedEvent} from "./Events/ButtonClickedEvent";
@ -40,13 +41,10 @@ class IframeListener {
} }
const payload = message.data; const payload = message.data;
console.log('FOO');
if (isIframeEventWrapper(payload)) { if (isIframeEventWrapper(payload)) {
console.log('FOOBAR', payload);
if (payload.type === 'chat' && isChatEvent(payload.data)) { if (payload.type === 'chat' && isChatEvent(payload.data)) {
this._chatStream.next(payload.data); this._chatStream.next(payload.data);
} else if (payload.type === 'openPopup' && isOpenPopupEvent(payload.data)) { } else if (payload.type === 'openPopup' && isOpenPopupEvent(payload.data)) {
console.log('OPENPOPUP called');
this._openPopupStream.next(payload.data); 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. * Sends the message... to all allowed iframes.
*/ */
@ -166,6 +174,7 @@ class IframeListener {
iframe.contentWindow?.postMessage(message, '*'); iframe.contentWindow?.postMessage(message, '*');
} }
} }
} }
export const iframeListener = new IframeListener(); export const iframeListener = new IframeListener();

View File

@ -275,7 +275,8 @@ export class GameScene extends ResizableScene implements CenterListener {
break; break;
} }
default: default:
throw new Error('Unsupported object type: "'+ itemType +'"'); continue;
//throw new Error('Unsupported object type: "'+ itemType +'"');
} }
itemFactory.preload(this.load); itemFactory.preload(this.load);
@ -743,7 +744,6 @@ export class GameScene extends ResizableScene implements CenterListener {
if (newValue === undefined || newValue === false || newValue === '') { if (newValue === undefined || newValue === false || newValue === '') {
iframeListener.sendLeaveEvent(oldValue as string); iframeListener.sendLeaveEvent(oldValue as string);
} else { } else {
console.log("je passe dans zone");
iframeListener.sendEnterEvent(newValue as string); iframeListener.sendEnterEvent(newValue as string);
} }
}); });
@ -756,9 +756,27 @@ export class GameScene extends ResizableScene implements CenterListener {
let html = `<div class="nes-container with-title is-centered"> let html = `<div class="nes-container with-title is-centered">
${escapedMessage} ${escapedMessage}
</div>`; </div>`;
const domElement = this.add.dom(this.popUpX, this.popUpY).createFromHTML(html); let id = 0;
domElement.scale = 1; for (const button of openPopupEvent.buttons) {
html += `<button type="button" class="nes-btn is-${HtmlUtils.escapeHtml(button.className ?? '')}" id="popup-${openPopupEvent.popupId}-${id}">${HtmlUtils.escapeHtml(button.label)}</button>`;
id++;
}
const domElement = this.add.dom(150, 150).createFromHTML(html);
domElement.scale = 0;
domElement.setClassName('popUpElement'); domElement.setClassName('popUpElement');
id = 0;
for (const button of openPopupEvent.buttons) {
const button = HtmlUtils.getElementByIdOrFail<HTMLButtonElement>(`popup-${openPopupEvent.popupId}-${id}`);
const btnId = id;
button.onclick = () => {
iframeListener.sendButtonClickedEvent(openPopupEvent.popupId, btnId);
console.log('BUTTON CLICKED', btnId);
}
id++;
}
this.tweens.add({ this.tweens.add({
targets : domElement , targets : domElement ,
scale : 1, scale : 1,

View File

@ -4,6 +4,7 @@ import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputCh
import {Subject} from "rxjs"; import {Subject} from "rxjs";
import {EnterLeaveEvent, isEnterLeaveEvent} from "./Api/Events/EnterLeaveEvent"; import {EnterLeaveEvent, isEnterLeaveEvent} from "./Api/Events/EnterLeaveEvent";
import {OpenPopupEvent} from "./Api/Events/OpenPopupEvent"; import {OpenPopupEvent} from "./Api/Events/OpenPopupEvent";
import {isButtonClickedEvent} from "./Api/Events/ButtonClickedEvent";
interface WorkAdventureApi { interface WorkAdventureApi {
sendChatMessage(message: string, author: string): void; sendChatMessage(message: string, author: string): void;
@ -23,6 +24,8 @@ type ChatMessageCallback = (message: string) => void;
const userInputChatStream: Subject<UserInputChatEvent> = new Subject(); const userInputChatStream: Subject<UserInputChatEvent> = new Subject();
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>(); const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>(); const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
const popupCallbacks: Map<number, Map<number, () => void>> = new Map<number, Map<number, () => void>>();
let popupId = 0; let popupId = 0;
interface ButtonDescriptor { interface ButtonDescriptor {
/** /**
@ -120,6 +123,11 @@ window.addEventListener('message', message => {
enterStreams.get(payloadData.name)?.next(); enterStreams.get(payloadData.name)?.next();
} else if (payload.type === 'leaveEvent' && isEnterLeaveEvent(payloadData)) { } else if (payload.type === 'leaveEvent' && isEnterLeaveEvent(payloadData)) {
leaveStreams.get(payloadData.name)?.next(); leaveStreams.get(payloadData.name)?.next();
} else if (payload.type === 'buttonClickedEvent' && isButtonClickedEvent(payloadData)) {
const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId);
if (callback) {
callback();
}
} }
} }