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),
closeOnClick: tg.isOptional(tg.isBoolean)
}).get();
type ButtonDescriptor = tg.GuardedType<typeof isButtonDescriptor>;
export const isOpenPopupEvent =
new tg.IsInterface().withProperties({
popupId: tg.isNumber,
targetObject: tg.isString,
message: tg.isString,
buttons: tg.isAny //tg.isArray<ButtonDescriptor>,
buttons: tg.isArray(isButtonDescriptor)
}).get();
/**

View File

@ -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();

View File

@ -275,7 +275,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);
@ -743,7 +744,6 @@ export class GameScene extends ResizableScene implements CenterListener {
if (newValue === undefined || newValue === false || newValue === '') {
iframeListener.sendLeaveEvent(oldValue as string);
} else {
console.log("je passe dans zone");
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">
${escapedMessage}
</div>`;
const domElement = this.add.dom(this.popUpX, this.popUpY).createFromHTML(html);
domElement.scale = 1;
let id = 0;
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');
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({
targets : domElement ,
scale : 1,

View File

@ -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<UserInputChatEvent> = new Subject();
const enterStreams: 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;
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();
}
}
}