import {ChatEvent, isChatEvent} from "./Api/Events/ChatEvent"; import {isIframeEventWrapper} from "./Api/Events/IframeEvent"; import {isUserInputChatEvent, UserInputChatEvent} from "./Api/Events/UserInputChatEvent"; import {Subject} from "rxjs"; import {EnterLeaveEvent, isEnterLeaveEvent} from "./Api/Events/EnterLeaveEvent"; import {OpenPopupEvent} from "./Api/Events/OpenPopupEvent"; interface WorkAdventureApi { sendChatMessage(message: string, author: string): void; onChatMessage(callback: (message: string) => void): void; onEnterZone(name: string, callback: () => void): void; onLeaveZone(name: string, callback: () => void): void; openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): number; } declare global { // eslint-disable-next-line no-var var WA: WorkAdventureApi } type ChatMessageCallback = (message: string) => void; const userInputChatStream: Subject = new Subject(); const enterStreams: Map> = new Map>(); const leaveStreams: Map> = new Map>(); 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 = { /** * Send a message in the chat. * Only the local user will receive this message. */ sendChatMessage(message: string, author: string) { window.parent.postMessage({ 'type': 'chat', 'data': { 'message': message, 'author': author } 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. */ onChatMessage(callback: ChatMessageCallback): void { userInputChatStream.subscribe((userInputChatEvent) => { callback(userInputChatEvent.message); }); }, onEnterZone(name: string, callback: () => void): void { let subject = enterStreams.get(name); if (subject === undefined) { subject = new Subject(); enterStreams.set(name, subject); } subject.subscribe(callback); }, onLeaveZone(name: string, callback: () => void): void { let subject = leaveStreams.get(name); if (subject === undefined) { subject = new Subject(); leaveStreams.set(name, subject); } subject.subscribe(callback); }, } window.addEventListener('message', message => { if (message.source !== window.parent) { return; // Skip message in this event listener } const payload = message.data; console.log(payload); if (isIframeEventWrapper(payload)) { const payloadData = payload.data; if (payload.type === 'userInputChat' && isUserInputChatEvent(payloadData)) { userInputChatStream.next(payloadData); } else if (payload.type === 'enterEvent' && isEnterLeaveEvent(payloadData)) { enterStreams.get(payloadData.name)?.next(); } else if (payload.type === 'leaveEvent' && isEnterLeaveEvent(payloadData)) { leaveStreams.get(payloadData.name)?.next(); } } // ... });