Implementation of openPopup script method (WIP)
This commit is contained in:
parent
ed2ce68f37
commit
1e002f93ed
22
front/src/Api/Events/OpenPopupEvent.ts
Normal file
22
front/src/Api/Events/OpenPopupEvent.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import * as tg from "generic-type-guard";
|
||||||
|
|
||||||
|
const isButtonDescriptor =
|
||||||
|
new tg.IsInterface().withProperties({
|
||||||
|
label: tg.isString,
|
||||||
|
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>,
|
||||||
|
}).get();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message sent from the iFrame to the game to add a message in the chat.
|
||||||
|
*/
|
||||||
|
export type OpenPopupEvent = tg.GuardedType<typeof isOpenPopupEvent>;
|
@ -5,6 +5,7 @@ import {UserInputChatEvent} from "./Events/UserInputChatEvent";
|
|||||||
import * as crypto from "crypto";
|
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";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -16,6 +17,9 @@ class IframeListener {
|
|||||||
private readonly _chatStream: Subject<ChatEvent> = new Subject();
|
private readonly _chatStream: Subject<ChatEvent> = new Subject();
|
||||||
public readonly chatStream = this._chatStream.asObservable();
|
public readonly chatStream = this._chatStream.asObservable();
|
||||||
|
|
||||||
|
private readonly _openPopupStream: Subject<OpenPopupEvent> = new Subject();
|
||||||
|
public readonly openPopupStream = this._openPopupStream.asObservable();
|
||||||
|
|
||||||
private readonly iframes = new Set<HTMLIFrameElement>();
|
private readonly iframes = new Set<HTMLIFrameElement>();
|
||||||
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
||||||
|
|
||||||
@ -36,9 +40,14 @@ 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)) {
|
||||||
|
console.log('OPENPOPUP called');
|
||||||
|
this._openPopupStream.next(payload.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ import {localUserStore} from "../../Connexion/LocalUserStore";
|
|||||||
import {iframeListener} from "../../Api/IframeListener";
|
import {iframeListener} from "../../Api/IframeListener";
|
||||||
import DOMElement = Phaser.GameObjects.DOMElement;
|
import DOMElement = Phaser.GameObjects.DOMElement;
|
||||||
import Tween = Phaser.Tweens.Tween;
|
import Tween = Phaser.Tweens.Tween;
|
||||||
|
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||||
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface|null,
|
initPosition: PointInterface|null,
|
||||||
@ -165,8 +166,8 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
private openChatIcon!: OpenChatIcon;
|
private openChatIcon!: OpenChatIcon;
|
||||||
private playerName!: string;
|
private playerName!: string;
|
||||||
private characterLayers!: string[];
|
private characterLayers!: string[];
|
||||||
|
private popUpElements : Map<number, DOMElement> = new Map<number, Phaser.GameObjects.DOMElement>();
|
||||||
|
|
||||||
private popUpElement : DOMElement| undefined;
|
|
||||||
constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) {
|
constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) {
|
||||||
super({
|
super({
|
||||||
key: customKey ?? room.id
|
key: customKey ?? room.id
|
||||||
@ -442,6 +443,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
// From now, this game scene will be notified of reposition events
|
// From now, this game scene will be notified of reposition events
|
||||||
layoutManager.setListener(this);
|
layoutManager.setListener(this);
|
||||||
this.triggerOnMapLayerPropertyChange();
|
this.triggerOnMapLayerPropertyChange();
|
||||||
|
this.listenToIframeEvents();
|
||||||
|
|
||||||
const camera = this.cameras.main;
|
const camera = this.cameras.main;
|
||||||
|
|
||||||
@ -655,33 +657,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => {
|
this.gameMap.onPropertyChange('exitSceneUrl', (newValue, oldValue) => {
|
||||||
if (newValue) this.onMapExit(newValue as string);
|
if (newValue) this.onMapExit(newValue as string);
|
||||||
});
|
});
|
||||||
this.gameMap.onPropertyChange('inGameConsoleMessage', (newValue, oldValue, allProps) => {
|
|
||||||
if (newValue !== undefined) {
|
|
||||||
this.popUpElement?.destroy();
|
|
||||||
this.popUpElement = this.add.dom(2100, 150).createFromHTML(newValue as string);
|
|
||||||
this.popUpElement.scale = 0;
|
|
||||||
this.tweens.add({
|
|
||||||
targets : this.popUpElement ,
|
|
||||||
scale : 1,
|
|
||||||
ease : "EaseOut",
|
|
||||||
duration : 400,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.popUpElement.setClassName("popUpElement");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this.tweens.add({
|
|
||||||
targets : this.popUpElement ,
|
|
||||||
scale : 0,
|
|
||||||
ease : "EaseOut",
|
|
||||||
duration : 400,
|
|
||||||
onComplete : () => {
|
|
||||||
this.popUpElement?.destroy();
|
|
||||||
this.popUpElement = undefined;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.gameMap.onPropertyChange('exitUrl', (newValue, oldValue) => {
|
this.gameMap.onPropertyChange('exitUrl', (newValue, oldValue) => {
|
||||||
if (newValue) this.onMapExit(newValue as string);
|
if (newValue) this.onMapExit(newValue as string);
|
||||||
});
|
});
|
||||||
@ -765,6 +740,56 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private listenToIframeEvents(): void {
|
||||||
|
iframeListener.openPopupStream.subscribe((openPopupEvent) => {
|
||||||
|
const escapedMessage = HtmlUtils.escapeHtml(openPopupEvent.message);
|
||||||
|
|
||||||
|
let html = `<div class="nes-container with-title is-centered">
|
||||||
|
${escapedMessage}
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const domElement = this.add.dom(150, 150).createFromHTML(html);
|
||||||
|
domElement.scale = 0;
|
||||||
|
domElement.setClassName('popUpElement');
|
||||||
|
this.tweens.add({
|
||||||
|
targets : domElement ,
|
||||||
|
scale : 1,
|
||||||
|
ease : "EaseOut",
|
||||||
|
duration : 400,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.popUpElements.set(openPopupEvent.popupId, domElement);
|
||||||
|
});
|
||||||
|
/*this.gameMap.onPropertyChange('inGameConsoleMessage', (newValue, oldValue, allProps) => {
|
||||||
|
if (newValue !== undefined) {
|
||||||
|
this.popUpElement?.destroy();
|
||||||
|
this.popUpElement = this.add.dom(2100, 150).createFromHTML(newValue as string);
|
||||||
|
this.popUpElement.scale = 0;
|
||||||
|
this.tweens.add({
|
||||||
|
targets : this.popUpElement ,
|
||||||
|
scale : 1,
|
||||||
|
ease : "EaseOut",
|
||||||
|
duration : 400,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.popUpElement.setClassName("popUpElement");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.tweens.add({
|
||||||
|
targets : this.popUpElement ,
|
||||||
|
scale : 0,
|
||||||
|
ease : "EaseOut",
|
||||||
|
duration : 400,
|
||||||
|
onComplete : () => {
|
||||||
|
this.popUpElement?.destroy();
|
||||||
|
this.popUpElement = undefined;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private onMapExit(exitKey: string) {
|
private onMapExit(exitKey: string) {
|
||||||
const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
|
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);
|
if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey);
|
||||||
|
@ -24,7 +24,7 @@ export class HtmlUtils {
|
|||||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static escapeHtml(html: string): string {
|
public static escapeHtml(html: string): string {
|
||||||
const text = document.createTextNode(html);
|
const text = document.createTextNode(html);
|
||||||
const p = document.createElement('p');
|
const p = document.createElement('p');
|
||||||
p.appendChild(text);
|
p.appendChild(text);
|
||||||
|
@ -3,12 +3,14 @@ import {isIframeEventWrapper} from "./Api/Events/IframeEvent";
|
|||||||
import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputChatEvent";
|
import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputChatEvent";
|
||||||
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";
|
||||||
|
|
||||||
interface WorkAdventureApi {
|
interface WorkAdventureApi {
|
||||||
sendChatMessage(message: string, author: string): void;
|
sendChatMessage(message: string, author: string): void;
|
||||||
onChatMessage(callback: (message: string) => void): void;
|
onChatMessage(callback: (message: string) => void): void;
|
||||||
onEnterZone(name: string, callback: () => void): void;
|
onEnterZone(name: string, callback: () => void): void;
|
||||||
onLeaveZone(name: string, callback: () => void): void;
|
onLeaveZone(name: string, callback: () => void): void;
|
||||||
|
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
@ -21,6 +23,25 @@ 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>>();
|
||||||
|
let popupId = 0;
|
||||||
|
interface ButtonDescriptor {
|
||||||
|
/**
|
||||||
|
* The label of the button
|
||||||
|
*/
|
||||||
|
label: string,
|
||||||
|
/**
|
||||||
|
* The type of the button. Can be one of "normal", "primary", "success", "warning", "error", "disabled"
|
||||||
|
*/
|
||||||
|
className?: "normal"|"primary"|"success"|"warning"|"error"|"disabled",
|
||||||
|
/**
|
||||||
|
* Callback called if the button is pressed
|
||||||
|
*/
|
||||||
|
callback?: () => void,
|
||||||
|
/**
|
||||||
|
* If set to true, the popup is closed when the button is clicked
|
||||||
|
*/
|
||||||
|
closeOnClick?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
window.WA = {
|
window.WA = {
|
||||||
@ -37,6 +58,25 @@ window.WA = {
|
|||||||
} as ChatEvent
|
} as ChatEvent
|
||||||
}, '*');
|
}, '*');
|
||||||
},
|
},
|
||||||
|
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): number {
|
||||||
|
popupId++;
|
||||||
|
window.parent.postMessage({
|
||||||
|
'type': 'openPopup',
|
||||||
|
'data': {
|
||||||
|
popupId,
|
||||||
|
targetObject,
|
||||||
|
message,
|
||||||
|
buttons: buttons.map((button) => {
|
||||||
|
return {
|
||||||
|
label: button.label,
|
||||||
|
className: button.className,
|
||||||
|
closeOnClick: button.closeOnClick
|
||||||
|
};
|
||||||
|
})
|
||||||
|
} as OpenPopupEvent
|
||||||
|
}, '*');
|
||||||
|
return popupId;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Listen to messages sent by the local user, in the chat.
|
* Listen to messages sent by the local user, in the chat.
|
||||||
*/
|
*/
|
||||||
|
@ -18,3 +18,26 @@ WA.onLeaveZone('myTrigger', () => {
|
|||||||
WA.onEnterZone('notExist', () => {
|
WA.onEnterZone('notExist', () => {
|
||||||
WA.sendChatMessage("YOU SHOULD NEVER SEE THIS", 'Poly Parrot');
|
WA.sendChatMessage("YOU SHOULD NEVER SEE THIS", 'Poly Parrot');
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let popupId;
|
||||||
|
|
||||||
|
WA.onEnterZone('popupZone', () => {
|
||||||
|
popupId = WA.openPopup('foobar', 'This is a test message. Hi!', [
|
||||||
|
{
|
||||||
|
label: "Close",
|
||||||
|
className: "normal",
|
||||||
|
closeOnClick: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Next",
|
||||||
|
className: "success",
|
||||||
|
callback: () => {
|
||||||
|
console.log('BUTTON CLICKED')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
/*WA.onLeaveZone('popupZone', () => {
|
||||||
|
WA.sendChatMessage("Thanks!", 'Poly Parrot');
|
||||||
|
})*/
|
||||||
|
@ -39,6 +39,24 @@
|
|||||||
"x":0,
|
"x":0,
|
||||||
"y":0
|
"y":0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":7,
|
||||||
|
"name":"popupZone",
|
||||||
|
"opacity":1,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"zone",
|
||||||
|
"type":"string",
|
||||||
|
"value":"popupZone"
|
||||||
|
}],
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
"height":10,
|
"height":10,
|
||||||
@ -55,15 +73,26 @@
|
|||||||
"draworder":"topdown",
|
"draworder":"topdown",
|
||||||
"id":3,
|
"id":3,
|
||||||
"name":"floorLayer",
|
"name":"floorLayer",
|
||||||
"objects":[],
|
"objects":[
|
||||||
|
{
|
||||||
|
"height":120.377012261239,
|
||||||
|
"id":1,
|
||||||
|
"name":"myPopup",
|
||||||
|
"rotation":0,
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":162.815914588373,
|
||||||
|
"x":77.4042872633247,
|
||||||
|
"y":61.1226958044874
|
||||||
|
}],
|
||||||
"opacity":1,
|
"opacity":1,
|
||||||
"type":"objectgroup",
|
"type":"objectgroup",
|
||||||
"visible":true,
|
"visible":true,
|
||||||
"x":0,
|
"x":0,
|
||||||
"y":0
|
"y":0
|
||||||
}],
|
}],
|
||||||
"nextlayerid":7,
|
"nextlayerid":8,
|
||||||
"nextobjectid":1,
|
"nextobjectid":2,
|
||||||
"orientation":"orthogonal",
|
"orientation":"orthogonal",
|
||||||
"properties":[
|
"properties":[
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user