extraction idea
# Conflicts: # front/src/Api/ScriptUtils.ts # front/src/iframe_api.ts
This commit is contained in:
parent
fe573893a1
commit
1a1ab30574
35
front/src/Api/iframe/chatmessage.ts
Normal file
35
front/src/Api/iframe/chatmessage.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { ChatEvent } from '../Events/ChatEvent'
|
||||
import { isUserInputChatEvent, UserInputChatEvent } from '../Events/UserInputChatEvent'
|
||||
import { registerWorkadventureCommand, registerWorkadvntureCallback, sendToWorkadventure } from "./iframe-registration"
|
||||
|
||||
let chatMessageCallback: (event: string) => void | undefined
|
||||
|
||||
class WorkadvntureChatCommands {
|
||||
|
||||
sendChatMessage(message: string, author: string) {
|
||||
sendToWorkadventure({
|
||||
type: 'chat',
|
||||
data: {
|
||||
'message': message,
|
||||
'author': author
|
||||
} as ChatEvent
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen to messages sent by the local user, in the chat.
|
||||
*/
|
||||
onChatMessage(callback: (message: string) => void) {
|
||||
chatMessageCallback = callback
|
||||
}
|
||||
}
|
||||
|
||||
export const commands = registerWorkadventureCommand(new WorkadvntureChatCommands())
|
||||
export const callbacks = registerWorkadvntureCallback([{
|
||||
callback: (event: UserInputChatEvent) => {
|
||||
chatMessageCallback?.(event.message)
|
||||
},
|
||||
type: "userInputChat",
|
||||
typeChecker: isUserInputChatEvent
|
||||
}])
|
||||
|
30
front/src/Api/iframe/iframe-registration.ts
Normal file
30
front/src/Api/iframe/iframe-registration.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { IframeEvent, IframeEventMap, IframeResponseEventMap } from '../Events/IframeEvent';
|
||||
import { registeredCallbacks, WorkAdventureApi } from "../../iframe_api"
|
||||
export function registerWorkadventureCommand<T>(commnds: T): T {
|
||||
const commandPrototype = Object.getPrototypeOf(commnds);
|
||||
const commandClassPropertyNames = Object.getOwnPropertyNames(commandPrototype).filter(name => name !== "constructor");
|
||||
for (const key of commandClassPropertyNames) {
|
||||
window.WA[key as keyof WorkAdventureApi] = commandPrototype[key] as never
|
||||
}
|
||||
return commnds
|
||||
}
|
||||
|
||||
|
||||
export function registerWorkadvntureCallback<T extends Function>(callbacks: Array<{
|
||||
type: keyof IframeResponseEventMap,
|
||||
typeChecker: Function,
|
||||
callback: T
|
||||
}>) {
|
||||
for (const callback of callbacks) {
|
||||
registeredCallbacks[callback.type] = {
|
||||
typeChecker: callback.typeChecker,
|
||||
callback: callback.callback
|
||||
}
|
||||
}
|
||||
return callbacks
|
||||
}
|
||||
|
||||
|
||||
export function sendToWorkadventure(content: IframeEvent<keyof IframeEventMap>) {
|
||||
window.parent.postMessage(content, "*")
|
||||
}
|
27
front/src/Api/iframe/zone-events.ts
Normal file
27
front/src/Api/iframe/zone-events.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from '../Events/EnterLeaveEvent'
|
||||
import { registerWorkadventureCommand, registerWorkadvntureCallback, sendToWorkadventure } from "./iframe-registration"
|
||||
|
||||
class WorkadventureZoneCommands {
|
||||
|
||||
onEnterZone(name: string, callback: () => void): void {
|
||||
|
||||
|
||||
}
|
||||
onLeaveZone(name: string, callback: () => void): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export const commands = registerWorkadventureCommand(new WorkadventureZoneCommands())
|
||||
export const callbacks = registerWorkadvntureCallback([{
|
||||
callback: (enterEvent: EnterLeaveEvent) => {
|
||||
|
||||
},
|
||||
type: "enterEvent",
|
||||
typeChecker: isEnterLeaveEvent
|
||||
},])
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { ChatEvent } from "./Api/Events/ChatEvent";
|
||||
import { isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
||||
import { IframeEvent, IframeEventMap, IframeResponseEventMap, isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
||||
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
|
||||
import { Subject } from "rxjs";
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
|
||||
@ -10,9 +10,19 @@ import type { OpenTabEvent } from "./Api/Events/OpenTabEvent";
|
||||
import type { GoToPageEvent } from "./Api/Events/GoToPageEvent";
|
||||
import type { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent";
|
||||
|
||||
interface WorkAdventureApi {
|
||||
sendChatMessage(message: string, author: string): void;
|
||||
onChatMessage(callback: (message: string) => void): void;
|
||||
const importType = Promise.all([
|
||||
import("./Api/iframe/chatmessage"),
|
||||
import("./Api/iframe/zone-events")
|
||||
])
|
||||
type UnPromise<P> = P extends Promise<infer T> ? T : P
|
||||
|
||||
type WorkadventureCommandClasses = UnPromise<typeof importType>[number]["commands"];
|
||||
type KeysOfUnion<T> = T extends T ? keyof T : never
|
||||
type ObjectWithKeyOfUnion<O, Key> = O extends O ? (Key extends keyof O ? O[Key] : never) : never
|
||||
|
||||
type WorkAdventureApiFiles = { [Key in KeysOfUnion<WorkadventureCommandClasses>]: ObjectWithKeyOfUnion<WorkadventureCommandClasses, Key> };
|
||||
|
||||
export interface WorkAdventureApi extends WorkAdventureApiFiles {
|
||||
onEnterZone(name: string, callback: () => void): void;
|
||||
onLeaveZone(name: string, callback: () => void): void;
|
||||
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup;
|
||||
@ -26,10 +36,15 @@ interface WorkAdventureApi {
|
||||
removeBubble(): void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var WA: WorkAdventureApi
|
||||
|
||||
|
||||
|
||||
declare global {
|
||||
|
||||
interface Window {
|
||||
WA: WorkAdventureApi
|
||||
}
|
||||
let WA: WorkAdventureApi
|
||||
}
|
||||
|
||||
type ChatMessageCallback = (message: string) => void;
|
||||
@ -172,14 +187,7 @@ window.WA = {
|
||||
popups.set(popupId, popup)
|
||||
return popup;
|
||||
},
|
||||
/**
|
||||
* Listen to messages sent by the local user, in the chat.
|
||||
*/
|
||||
onChatMessage(callback: ChatMessageCallback): void {
|
||||
userInputChatStream.subscribe((userInputChatEvent) => {
|
||||
callback(userInputChatEvent.message);
|
||||
});
|
||||
},
|
||||
...({} as WorkAdventureApiFiles),
|
||||
onEnterZone(name: string, callback: () => void): void {
|
||||
let subject = enterStreams.get(name);
|
||||
if (subject === undefined) {
|
||||
@ -196,6 +204,7 @@ window.WA = {
|
||||
}
|
||||
subject.subscribe(callback);
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
window.addEventListener('message', message => {
|
||||
@ -209,6 +218,12 @@ window.addEventListener('message', message => {
|
||||
|
||||
if (isIframeResponseEventWrapper(payload)) {
|
||||
const payloadData = payload.data;
|
||||
|
||||
if (registeredCallbacks[payload.type] && registeredCallbacks[payload.type]?.typeChecker(payloadData)) {
|
||||
registeredCallbacks[payload.type]?.callback(payloadData)
|
||||
return
|
||||
}
|
||||
|
||||
if (payload.type === 'userInputChat' && isUserInputChatEvent(payloadData)) {
|
||||
userInputChatStream.next(payloadData);
|
||||
} else if (payload.type === 'enterEvent' && isEnterLeaveEvent(payloadData)) {
|
||||
|
Loading…
Reference in New Issue
Block a user