2021-03-06 15:26:07 +01:00
|
|
|
import {ChatEvent, isChatEvent} from "./Api/Events/ChatEvent";
|
|
|
|
import {isIframeEventWrapper} from "./Api/Events/IframeEvent";
|
|
|
|
import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputChatEvent";
|
|
|
|
import {Subject} from "rxjs";
|
2021-03-08 18:57:59 +01:00
|
|
|
import {EnterLeaveEvent, isEnterLeaveEvent} from "./Api/Events/EnterLeaveEvent";
|
2021-03-09 16:21:14 +01:00
|
|
|
import {OpenPopupEvent} from "./Api/Events/OpenPopupEvent";
|
2021-03-09 18:05:07 +01:00
|
|
|
import {isButtonClickedEvent} from "./Api/Events/ButtonClickedEvent";
|
2021-05-16 14:04:45 +02:00
|
|
|
import {ClosePopupEvent, isClosePopupEvent} from "./Api/Events/ClosePopupEvent";
|
2021-03-25 17:12:53 +01:00
|
|
|
import {OpenTabEvent} from "./Api/Events/OpenTabEvent";
|
|
|
|
import {GoToPageEvent} from "./Api/Events/GoToPageEvent";
|
|
|
|
import {OpenCoWebSiteEvent} from "./Api/Events/OpenCoWebSiteEvent";
|
2021-05-16 14:52:07 +02:00
|
|
|
import {ExitUrlEvent} from "./Api/Events/ExitUrlEvent";
|
2021-03-05 16:50:54 +01:00
|
|
|
|
2021-03-04 19:00:00 +01:00
|
|
|
interface WorkAdventureApi {
|
|
|
|
sendChatMessage(message: string, author: string): void;
|
2021-03-05 16:50:54 +01:00
|
|
|
onChatMessage(callback: (message: string) => void): void;
|
2021-05-16 14:04:45 +02:00
|
|
|
closeChatMessage(): void;
|
2021-03-08 18:57:59 +01:00
|
|
|
onEnterZone(name: string, callback: () => void): void;
|
|
|
|
onLeaveZone(name: string, callback: () => void): void;
|
2021-05-16 14:04:45 +02:00
|
|
|
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], input: boolean): Popup;
|
|
|
|
openTab(url: string): void;
|
|
|
|
goToPage(url: string): void;
|
|
|
|
openCoWebSite(url: string): void;
|
2021-03-25 17:12:53 +01:00
|
|
|
closeCoWebSite(): void;
|
2021-05-16 14:04:45 +02:00
|
|
|
disablePlayerControl(): void;
|
|
|
|
restorePlayerControl(): void;
|
|
|
|
displayBubble(): void;
|
|
|
|
removeBubble(): void;
|
2021-05-16 14:52:07 +02:00
|
|
|
exitUrl(url : string): void;
|
2021-03-04 19:00:00 +01:00
|
|
|
}
|
|
|
|
|
2021-03-05 16:50:54 +01:00
|
|
|
declare global {
|
|
|
|
// eslint-disable-next-line no-var
|
|
|
|
var WA: WorkAdventureApi
|
2021-03-25 17:12:53 +01:00
|
|
|
|
2021-03-05 16:50:54 +01:00
|
|
|
}
|
2021-03-04 19:00:00 +01:00
|
|
|
|
2021-03-06 15:26:07 +01:00
|
|
|
type ChatMessageCallback = (message: string) => void;
|
2021-03-09 18:51:30 +01:00
|
|
|
type ButtonClickedCallback = (popup: Popup) => void;
|
2021-03-06 15:26:07 +01:00
|
|
|
|
|
|
|
const userInputChatStream: Subject<UserInputChatEvent> = new Subject();
|
2021-03-08 18:57:59 +01:00
|
|
|
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
|
|
|
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
2021-03-09 18:51:30 +01:00
|
|
|
const popups: Map<number, Popup> = new Map<number, Popup>();
|
|
|
|
const popupCallbacks: Map<number, Map<number, ButtonClickedCallback>> = new Map<number, Map<number, ButtonClickedCallback>>();
|
2021-03-09 18:05:07 +01:00
|
|
|
|
2021-03-09 16:21:14 +01:00
|
|
|
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"
|
|
|
|
*/
|
2021-05-16 14:04:45 +02:00
|
|
|
className?: "normal" | "primary" | "success" | "warning" | "error" | "disabled",
|
2021-03-09 16:21:14 +01:00
|
|
|
/**
|
|
|
|
* Callback called if the button is pressed
|
|
|
|
*/
|
2021-03-09 18:57:25 +01:00
|
|
|
callback: ButtonClickedCallback,
|
2021-03-09 16:21:14 +01:00
|
|
|
}
|
2021-03-06 15:26:07 +01:00
|
|
|
|
2021-03-09 18:51:30 +01:00
|
|
|
class Popup {
|
2021-05-16 14:04:45 +02:00
|
|
|
inputValue: string;
|
|
|
|
|
2021-03-09 18:51:30 +01:00
|
|
|
constructor(private id: number) {
|
2021-05-16 14:04:45 +02:00
|
|
|
this.inputValue = '';
|
2021-03-09 18:51:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Closes the popup
|
|
|
|
*/
|
|
|
|
public close(): void {
|
|
|
|
window.parent.postMessage({
|
|
|
|
'type': 'closePopup',
|
|
|
|
'data': {
|
|
|
|
'popupId': this.id,
|
2021-05-16 14:04:45 +02:00
|
|
|
'inputValue': this.inputValue,
|
2021-03-09 18:51:30 +01:00
|
|
|
} as ClosePopupEvent
|
|
|
|
}, '*');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-04 19:00:00 +01:00
|
|
|
window.WA = {
|
|
|
|
/**
|
2021-03-05 16:50:54 +01:00
|
|
|
* Send a message in the chat.
|
2021-03-04 19:00:00 +01:00
|
|
|
* Only the local user will receive this message.
|
|
|
|
*/
|
|
|
|
sendChatMessage(message: string, author: string) {
|
|
|
|
window.parent.postMessage({
|
|
|
|
'type': 'chat',
|
|
|
|
'data': {
|
|
|
|
'message': message,
|
|
|
|
'author': author
|
2021-03-05 16:50:54 +01:00
|
|
|
} as ChatEvent
|
2021-03-04 19:00:00 +01:00
|
|
|
}, '*');
|
2021-03-05 16:50:54 +01:00
|
|
|
},
|
2021-05-16 14:04:45 +02:00
|
|
|
closeChatMessage(): void {
|
2021-05-16 10:22:05 +02:00
|
|
|
window.parent.postMessage({
|
2021-05-16 14:04:45 +02:00
|
|
|
"type": 'closeChatMessage'
|
|
|
|
}, '*');
|
2021-05-16 10:22:05 +02:00
|
|
|
},
|
2021-05-16 14:04:45 +02:00
|
|
|
disablePlayerControl(): void {
|
|
|
|
window.parent.postMessage({'type': 'disablePlayerControl'}, '*');
|
2021-03-12 16:39:29 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
restorePlayerControl(): void {
|
|
|
|
window.parent.postMessage({'type': 'restorePlayerControl'}, '*');
|
2021-03-12 16:39:29 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
displayBubble(): void {
|
|
|
|
window.parent.postMessage({'type': 'displayBubble'}, '*');
|
2021-03-12 16:39:29 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
removeBubble(): void {
|
|
|
|
window.parent.postMessage({'type': 'removeBubble'}, '*');
|
2021-03-12 16:39:29 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
openTab(url: string): void {
|
2021-03-25 17:12:53 +01:00
|
|
|
window.parent.postMessage({
|
2021-05-16 14:04:45 +02:00
|
|
|
"type": 'openTab',
|
|
|
|
"data": {
|
2021-03-25 17:12:53 +01:00
|
|
|
url
|
|
|
|
} as OpenTabEvent
|
2021-05-16 14:04:45 +02:00
|
|
|
}, '*');
|
2021-03-25 17:12:53 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
goToPage(url: string): void {
|
2021-03-25 17:12:53 +01:00
|
|
|
window.parent.postMessage({
|
2021-05-16 14:04:45 +02:00
|
|
|
"type": 'goToPage',
|
|
|
|
"data": {
|
2021-03-25 17:12:53 +01:00
|
|
|
url
|
|
|
|
} as GoToPageEvent
|
2021-05-16 14:04:45 +02:00
|
|
|
}, '*');
|
2021-03-25 17:12:53 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
openCoWebSite(url: string): void {
|
2021-03-25 17:12:53 +01:00
|
|
|
window.parent.postMessage({
|
2021-05-16 14:04:45 +02:00
|
|
|
"type": 'openCoWebSite',
|
|
|
|
"data": {
|
2021-03-25 17:12:53 +01:00
|
|
|
url
|
|
|
|
} as OpenCoWebSiteEvent
|
2021-05-16 14:04:45 +02:00
|
|
|
}, '*');
|
2021-03-25 17:12:53 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
closeCoWebSite(): void {
|
2021-03-25 17:12:53 +01:00
|
|
|
window.parent.postMessage({
|
2021-05-16 14:04:45 +02:00
|
|
|
"type": 'closeCoWebSite'
|
|
|
|
}, '*');
|
2021-03-25 17:12:53 +01:00
|
|
|
},
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[], input: boolean = false): Popup {
|
2021-03-09 16:21:14 +01:00
|
|
|
popupId++;
|
2021-03-09 18:51:30 +01:00
|
|
|
const popup = new Popup(popupId);
|
|
|
|
const btnMap = new Map<number, () => void>();
|
|
|
|
popupCallbacks.set(popupId, btnMap);
|
|
|
|
let id = 0;
|
2021-05-16 14:04:45 +02:00
|
|
|
for(const button of buttons) {
|
2021-03-09 18:51:30 +01:00
|
|
|
const callback = button.callback;
|
2021-05-16 14:04:45 +02:00
|
|
|
if(callback) {
|
2021-03-09 18:51:30 +01:00
|
|
|
btnMap.set(id, () => {
|
|
|
|
callback(popup);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
id++;
|
|
|
|
}
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
if(input) {
|
|
|
|
this.disablePlayerControl();
|
|
|
|
}
|
2021-03-11 10:58:48 +01:00
|
|
|
|
2021-03-09 16:21:14 +01:00
|
|
|
window.parent.postMessage({
|
|
|
|
'type': 'openPopup',
|
|
|
|
'data': {
|
|
|
|
popupId,
|
|
|
|
targetObject,
|
|
|
|
message,
|
|
|
|
buttons: buttons.map((button) => {
|
|
|
|
return {
|
|
|
|
label: button.label,
|
2021-03-09 18:57:25 +01:00
|
|
|
className: button.className
|
2021-03-09 16:21:14 +01:00
|
|
|
};
|
2021-05-16 14:04:45 +02:00
|
|
|
}),
|
|
|
|
input: input
|
2021-03-09 16:21:14 +01:00
|
|
|
} as OpenPopupEvent
|
|
|
|
}, '*');
|
2021-03-09 18:51:30 +01:00
|
|
|
|
|
|
|
popups.set(popupId, popup)
|
|
|
|
return popup;
|
2021-03-09 16:21:14 +01:00
|
|
|
},
|
2021-03-05 16:50:54 +01:00
|
|
|
/**
|
|
|
|
* Listen to messages sent by the local user, in the chat.
|
|
|
|
*/
|
2021-03-06 15:26:07 +01:00
|
|
|
onChatMessage(callback: ChatMessageCallback): void {
|
|
|
|
userInputChatStream.subscribe((userInputChatEvent) => {
|
|
|
|
callback(userInputChatEvent.message);
|
|
|
|
});
|
2021-03-08 18:57:59 +01:00
|
|
|
},
|
|
|
|
onEnterZone(name: string, callback: () => void): void {
|
|
|
|
let subject = enterStreams.get(name);
|
2021-05-16 14:04:45 +02:00
|
|
|
if(subject === undefined) {
|
2021-03-08 18:57:59 +01:00
|
|
|
subject = new Subject<EnterLeaveEvent>();
|
|
|
|
enterStreams.set(name, subject);
|
|
|
|
}
|
|
|
|
subject.subscribe(callback);
|
|
|
|
},
|
|
|
|
onLeaveZone(name: string, callback: () => void): void {
|
|
|
|
let subject = leaveStreams.get(name);
|
2021-05-16 14:04:45 +02:00
|
|
|
if(subject === undefined) {
|
2021-03-08 18:57:59 +01:00
|
|
|
subject = new Subject<EnterLeaveEvent>();
|
|
|
|
leaveStreams.set(name, subject);
|
|
|
|
}
|
|
|
|
subject.subscribe(callback);
|
|
|
|
},
|
2021-05-16 14:52:07 +02:00
|
|
|
exitUrl(url : string) : void{
|
|
|
|
window.parent.postMessage({
|
|
|
|
"type" : 'exitUrl',
|
|
|
|
"data" : {
|
|
|
|
url
|
|
|
|
} as ExitUrlEvent
|
|
|
|
},'*');
|
|
|
|
},
|
2021-03-04 19:00:00 +01:00
|
|
|
}
|
2021-03-06 15:26:07 +01:00
|
|
|
|
|
|
|
window.addEventListener('message', message => {
|
2021-05-16 14:04:45 +02:00
|
|
|
if(message.source !== window.parent) {
|
2021-03-06 15:26:07 +01:00
|
|
|
return; // Skip message in this event listener
|
|
|
|
}
|
|
|
|
|
|
|
|
const payload = message.data;
|
2021-03-08 18:57:59 +01:00
|
|
|
|
|
|
|
console.log(payload);
|
|
|
|
|
2021-05-16 14:04:45 +02:00
|
|
|
if(isIframeEventWrapper(payload)) {
|
2021-03-08 18:57:59 +01:00
|
|
|
const payloadData = payload.data;
|
2021-05-16 14:04:45 +02:00
|
|
|
if(payload.type === 'userInputChat' && isUserInputChatEvent(payloadData)) {
|
2021-03-08 18:57:59 +01:00
|
|
|
userInputChatStream.next(payloadData);
|
2021-05-16 14:04:45 +02:00
|
|
|
} else if(payload.type === 'enterEvent' && isEnterLeaveEvent(payloadData)) {
|
2021-03-08 18:57:59 +01:00
|
|
|
enterStreams.get(payloadData.name)?.next();
|
2021-05-16 14:04:45 +02:00
|
|
|
} else if(payload.type === 'leaveEvent' && isEnterLeaveEvent(payloadData)) {
|
2021-03-08 18:57:59 +01:00
|
|
|
leaveStreams.get(payloadData.name)?.next();
|
2021-05-16 14:04:45 +02:00
|
|
|
} else if(payload.type === 'buttonClickedEvent' && isButtonClickedEvent(payloadData)) {
|
2021-03-09 18:05:07 +01:00
|
|
|
const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId);
|
2021-03-09 18:51:30 +01:00
|
|
|
const popup = popups.get(payloadData.popupId);
|
2021-05-16 14:04:45 +02:00
|
|
|
if(popup === undefined) {
|
|
|
|
throw new Error('Could not find popup with ID "' + payloadData.popupId + '"');
|
2021-03-09 18:51:30 +01:00
|
|
|
}
|
2021-05-16 14:04:45 +02:00
|
|
|
if(callback) {
|
|
|
|
popup.inputValue = payloadData.inputValue;
|
2021-03-09 18:51:30 +01:00
|
|
|
callback(popup);
|
2021-03-09 18:05:07 +01:00
|
|
|
}
|
2021-03-06 15:26:07 +01:00
|
|
|
}
|
2021-03-12 16:39:29 +01:00
|
|
|
|
2021-03-06 15:26:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// ...
|
|
|
|
});
|