Merge remote-tracking branch 'remotes/upstream/develop' into tiles-start-positions
This commit is contained in:
commit
7f61e9addd
182 changed files with 17118 additions and 4494 deletions
11
front/src/Api/iframe/Ui/MenuItem.ts
Normal file
11
front/src/Api/iframe/Ui/MenuItem.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import type { MenuItemClickedEvent } from "../../Events/ui/MenuItemClickedEvent";
|
||||
import { iframeListener } from "../../IframeListener";
|
||||
|
||||
export function sendMenuClickedEvent(menuItem: string) {
|
||||
iframeListener.postMessage({
|
||||
type: "menuItemClicked",
|
||||
data: {
|
||||
menuItem: menuItem,
|
||||
} as MenuItemClickedEvent,
|
||||
});
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
import type { ChatEvent } from '../Events/ChatEvent'
|
||||
import { isUserInputChatEvent, UserInputChatEvent } from '../Events/UserInputChatEvent'
|
||||
import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution'
|
||||
import type { ChatEvent } from "../Events/ChatEvent";
|
||||
import { isUserInputChatEvent, UserInputChatEvent } from "../Events/UserInputChatEvent";
|
||||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import {Subject} from "rxjs";
|
||||
import { Subject } from "rxjs";
|
||||
|
||||
const chatStream = new Subject<string>();
|
||||
|
||||
class WorkadventureChatCommands extends IframeApiContribution<WorkadventureChatCommands> {
|
||||
|
||||
callbacks = [apiCallback({
|
||||
callback: (event: UserInputChatEvent) => {
|
||||
chatStream.next(event.message);
|
||||
},
|
||||
type: "userInputChat",
|
||||
typeChecker: isUserInputChatEvent
|
||||
})]
|
||||
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
callback: (event: UserInputChatEvent) => {
|
||||
chatStream.next(event.message);
|
||||
},
|
||||
type: "userInputChat",
|
||||
typeChecker: isUserInputChatEvent,
|
||||
}),
|
||||
];
|
||||
|
||||
sendChatMessage(message: string, author: string) {
|
||||
sendToWorkadventure({
|
||||
type: 'chat',
|
||||
type: "chat",
|
||||
data: {
|
||||
'message': message,
|
||||
'author': author
|
||||
} as ChatEvent
|
||||
})
|
||||
message: message,
|
||||
author: author,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,4 +35,4 @@ class WorkadventureChatCommands extends IframeApiContribution<WorkadventureChatC
|
|||
}
|
||||
}
|
||||
|
||||
export default new WorkadventureChatCommands()
|
||||
export default new WorkadventureChatCommands();
|
||||
|
|
|
@ -1,56 +1,54 @@
|
|||
import type { GoToPageEvent } from '../Events/GoToPageEvent';
|
||||
import type { OpenTabEvent } from '../Events/OpenTabEvent';
|
||||
import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution';
|
||||
import type {OpenCoWebSiteEvent} from "../Events/OpenCoWebSiteEvent";
|
||||
|
||||
import type { GoToPageEvent } from "../Events/GoToPageEvent";
|
||||
import type { OpenTabEvent } from "../Events/OpenTabEvent";
|
||||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import type { OpenCoWebSiteEvent } from "../Events/OpenCoWebSiteEvent";
|
||||
import type { LoadPageEvent } from "../Events/LoadPageEvent";
|
||||
|
||||
class WorkadventureNavigationCommands extends IframeApiContribution<WorkadventureNavigationCommands> {
|
||||
callbacks = []
|
||||
|
||||
callbacks = [];
|
||||
|
||||
openTab(url: string): void {
|
||||
sendToWorkadventure({
|
||||
"type": 'openTab',
|
||||
"data": {
|
||||
url
|
||||
} as OpenTabEvent
|
||||
type: "openTab",
|
||||
data: {
|
||||
url,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
goToPage(url: string): void {
|
||||
sendToWorkadventure({
|
||||
"type": 'goToPage',
|
||||
"data": {
|
||||
url
|
||||
} as GoToPageEvent
|
||||
type: "goToPage",
|
||||
data: {
|
||||
url,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
goToRoom(url: string): void {
|
||||
sendToWorkadventure({
|
||||
"type": 'loadPage',
|
||||
"data": {
|
||||
url
|
||||
}
|
||||
type: "loadPage",
|
||||
data: {
|
||||
url,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
openCoWebSite(url: string): void {
|
||||
sendToWorkadventure({
|
||||
"type": 'openCoWebSite',
|
||||
"data": {
|
||||
url
|
||||
} as OpenCoWebSiteEvent
|
||||
type: "openCoWebSite",
|
||||
data: {
|
||||
url,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
closeCoWebSite(): void {
|
||||
sendToWorkadventure({
|
||||
"type": 'closeCoWebSite',
|
||||
data: null
|
||||
type: "closeCoWebSite",
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default new WorkadventureNavigationCommands();
|
||||
|
|
29
front/src/Api/iframe/player.ts
Normal file
29
front/src/Api/iframe/player.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import type { HasPlayerMovedEvent, HasPlayerMovedEventCallback } from "../Events/HasPlayerMovedEvent";
|
||||
import { Subject } from "rxjs";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import { isHasPlayerMovedEvent } from "../Events/HasPlayerMovedEvent";
|
||||
|
||||
const moveStream = new Subject<HasPlayerMovedEvent>();
|
||||
|
||||
class WorkadventurePlayerCommands extends IframeApiContribution<WorkadventurePlayerCommands> {
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "hasPlayerMoved",
|
||||
typeChecker: isHasPlayerMovedEvent,
|
||||
callback: (payloadData) => {
|
||||
moveStream.next(payloadData);
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
onPlayerMove(callback: HasPlayerMovedEventCallback): void {
|
||||
moveStream.subscribe(callback);
|
||||
sendToWorkadventure({
|
||||
type: "onPlayerMove",
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new WorkadventurePlayerCommands();
|
|
@ -1,10 +1,52 @@
|
|||
import { Subject } from "rxjs";
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from '../Events/EnterLeaveEvent';
|
||||
import { IframeApiContribution } from './IframeApiContribution';
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
||||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import type { LayerEvent } from "../Events/LayerEvent";
|
||||
import type { SetPropertyEvent } from "../Events/setPropertyEvent";
|
||||
import type { GameStateEvent } from "../Events/GameStateEvent";
|
||||
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
|
||||
import type { DataLayerEvent } from "../Events/DataLayerEvent";
|
||||
import { isGameStateEvent } from "../Events/GameStateEvent";
|
||||
import { isDataLayerEvent } from "../Events/DataLayerEvent";
|
||||
|
||||
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
const dataLayerResolver = new Subject<DataLayerEvent>();
|
||||
const stateResolvers = new Subject<GameStateEvent>();
|
||||
|
||||
let immutableData: GameStateEvent;
|
||||
|
||||
interface Room {
|
||||
id: string;
|
||||
mapUrl: string;
|
||||
map: ITiledMap;
|
||||
startLayer: string | null;
|
||||
}
|
||||
|
||||
interface User {
|
||||
id: string | undefined;
|
||||
nickName: string | null;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
function getGameState(): Promise<GameStateEvent> {
|
||||
if (immutableData) {
|
||||
return Promise.resolve(immutableData);
|
||||
} else {
|
||||
return new Promise<GameStateEvent>((resolver, thrower) => {
|
||||
stateResolvers.subscribe(resolver);
|
||||
sendToWorkadventure({ type: "getState", data: null });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getDataLayer(): Promise<DataLayerEvent> {
|
||||
return new Promise<DataLayerEvent>((resolver, thrower) => {
|
||||
dataLayerResolver.subscribe(resolver);
|
||||
sendToWorkadventure({ type: "getDataLayer", data: null });
|
||||
});
|
||||
}
|
||||
|
||||
class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomCommands> {
|
||||
callbacks = [
|
||||
|
@ -13,18 +55,30 @@ class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomC
|
|||
enterStreams.get(payloadData.name)?.next();
|
||||
},
|
||||
type: "enterEvent",
|
||||
typeChecker: isEnterLeaveEvent
|
||||
typeChecker: isEnterLeaveEvent,
|
||||
}),
|
||||
apiCallback({
|
||||
type: "leaveEvent",
|
||||
typeChecker: isEnterLeaveEvent,
|
||||
callback: (payloadData) => {
|
||||
leaveStreams.get(payloadData.name)?.next();
|
||||
}
|
||||
})
|
||||
|
||||
]
|
||||
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "gameState",
|
||||
typeChecker: isGameStateEvent,
|
||||
callback: (payloadData) => {
|
||||
stateResolvers.next(payloadData);
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "dataLayer",
|
||||
typeChecker: isDataLayerEvent,
|
||||
callback: (payloadData) => {
|
||||
dataLayerResolver.next(payloadData);
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
onEnterZone(name: string, callback: () => void): void {
|
||||
let subject = enterStreams.get(name);
|
||||
|
@ -33,7 +87,6 @@ class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomC
|
|||
enterStreams.set(name, subject);
|
||||
}
|
||||
subject.subscribe(callback);
|
||||
|
||||
}
|
||||
onLeaveZone(name: string, callback: () => void): void {
|
||||
let subject = leaveStreams.get(name);
|
||||
|
@ -43,8 +96,39 @@ class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomC
|
|||
}
|
||||
subject.subscribe(callback);
|
||||
}
|
||||
|
||||
showLayer(layerName: string): void {
|
||||
sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
|
||||
}
|
||||
hideLayer(layerName: string): void {
|
||||
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
|
||||
}
|
||||
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
|
||||
sendToWorkadventure({
|
||||
type: "setProperty",
|
||||
data: {
|
||||
layerName: layerName,
|
||||
propertyName: propertyName,
|
||||
propertyValue: propertyValue,
|
||||
},
|
||||
});
|
||||
}
|
||||
getCurrentRoom(): Promise<Room> {
|
||||
return getGameState().then((gameState) => {
|
||||
return getDataLayer().then((mapJson) => {
|
||||
return {
|
||||
id: gameState.roomId,
|
||||
map: mapJson.data as ITiledMap,
|
||||
mapUrl: gameState.mapUrl,
|
||||
startLayer: gameState.startLayerName,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
getCurrentUser(): Promise<User> {
|
||||
return getGameState().then((gameState) => {
|
||||
return { id: gameState.uuid, nickName: gameState.nickname, tags: gameState.tags };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default new WorkadventureRoomCommands();
|
||||
|
|
|
@ -1,40 +1,55 @@
|
|||
import { isButtonClickedEvent } from '../Events/ButtonClickedEvent';
|
||||
import type { ClosePopupEvent } from '../Events/ClosePopupEvent';
|
||||
import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution';
|
||||
import { isButtonClickedEvent } from "../Events/ButtonClickedEvent";
|
||||
import { isMenuItemClickedEvent } from "../Events/ui/MenuItemClickedEvent";
|
||||
import type { MenuItemRegisterEvent } from "../Events/ui/MenuItemRegisterEvent";
|
||||
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import {Popup} from "./Ui/Popup";
|
||||
import type {ButtonClickedCallback, ButtonDescriptor} from "./Ui/ButtonDescriptor";
|
||||
import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor";
|
||||
import { Popup } from "./Ui/Popup";
|
||||
|
||||
let popupId = 0;
|
||||
const popups: Map<number, Popup> = new Map<number, Popup>();
|
||||
const popupCallbacks: Map<number, Map<number, ButtonClickedCallback>> = new Map<number, Map<number, ButtonClickedCallback>>();
|
||||
const popupCallbacks: Map<number, Map<number, ButtonClickedCallback>> = new Map<
|
||||
number,
|
||||
Map<number, ButtonClickedCallback>
|
||||
>();
|
||||
|
||||
const menuCallbacks: Map<string, (command: string) => void> = new Map();
|
||||
|
||||
interface ZonedPopupOptions {
|
||||
zone: string
|
||||
objectLayerName?: string,
|
||||
popupText: string,
|
||||
delay?: number
|
||||
popupOptions: Array<ButtonDescriptor>
|
||||
zone: string;
|
||||
objectLayerName?: string;
|
||||
popupText: string;
|
||||
delay?: number;
|
||||
popupOptions: Array<ButtonDescriptor>;
|
||||
}
|
||||
|
||||
|
||||
class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiCommands> {
|
||||
|
||||
callbacks = [apiCallback({
|
||||
type: "buttonClickedEvent",
|
||||
typeChecker: isButtonClickedEvent,
|
||||
callback: (payloadData) => {
|
||||
const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId);
|
||||
const popup = popups.get(payloadData.popupId);
|
||||
if (popup === undefined) {
|
||||
throw new Error('Could not find popup with ID "' + payloadData.popupId + '"');
|
||||
}
|
||||
if (callback) {
|
||||
callback(popup);
|
||||
}
|
||||
}
|
||||
})];
|
||||
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "buttonClickedEvent",
|
||||
typeChecker: isButtonClickedEvent,
|
||||
callback: (payloadData) => {
|
||||
const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId);
|
||||
const popup = popups.get(payloadData.popupId);
|
||||
if (popup === undefined) {
|
||||
throw new Error('Could not find popup with ID "' + payloadData.popupId + '"');
|
||||
}
|
||||
if (callback) {
|
||||
callback(popup);
|
||||
}
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "menuItemClicked",
|
||||
typeChecker: isMenuItemClickedEvent,
|
||||
callback: (event) => {
|
||||
const callback = menuCallbacks.get(event.menuItem);
|
||||
if (callback) {
|
||||
callback(event.menuItem);
|
||||
}
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
|
||||
popupId++;
|
||||
|
@ -53,30 +68,40 @@ class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiComma
|
|||
}
|
||||
|
||||
sendToWorkadventure({
|
||||
'type': 'openPopup',
|
||||
'data': {
|
||||
type: "openPopup",
|
||||
data: {
|
||||
popupId,
|
||||
targetObject,
|
||||
message,
|
||||
buttons: buttons.map((button) => {
|
||||
return {
|
||||
label: button.label,
|
||||
className: button.className
|
||||
className: button.className,
|
||||
};
|
||||
})
|
||||
}
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
popups.set(popupId, popup)
|
||||
popups.set(popupId, popup);
|
||||
return popup;
|
||||
}
|
||||
|
||||
registerMenuCommand(commandDescriptor: string, callback: (commandDescriptor: string) => void) {
|
||||
menuCallbacks.set(commandDescriptor, callback);
|
||||
sendToWorkadventure({
|
||||
type: "registerMenuCommand",
|
||||
data: {
|
||||
menutItem: commandDescriptor,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
displayBubble(): void {
|
||||
sendToWorkadventure({ 'type': 'displayBubble', data: null });
|
||||
sendToWorkadventure({ type: "displayBubble", data: null });
|
||||
}
|
||||
|
||||
removeBubble(): void {
|
||||
sendToWorkadventure({ 'type': 'removeBubble', data: null });
|
||||
sendToWorkadventure({ type: "removeBubble", data: null });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue