Actions menu api (#1862)
* wip * wip * random action on click * removing actions * register single key per command use * change removeActionsMenu action name * fixed actions menu not hiding content properly: * actions menu fix * added mock Block Player action * ActionsMenu buttons styling * added displaying priority for menu actions * moved utils actionMenu features to the UI * import as a type: * more object oriented style for API * removed registered actions from RemotePlayer instance * readme update * Fixing typos / Improving wording * added instructions on AlterActionsMenu test map Co-authored-by: Hanusiak Piotr <piotr@ltmp.co> Co-authored-by: David Négrier <d.negrier@thecodingmachine.com>
This commit is contained in:
+113
-5
@@ -8,6 +8,12 @@ import { ActionMessage } from "./Ui/ActionMessage";
|
||||
import { isMessageReferenceEvent } from "../Events/ui/TriggerActionMessageEvent";
|
||||
import { Menu } from "./Ui/Menu";
|
||||
import type { RequireOnlyOne } from "../types";
|
||||
import { isRemotePlayerClickedEvent, RemotePlayerClickedEvent } from "../Events/RemotePlayerClickedEvent";
|
||||
import {
|
||||
ActionsMenuActionClickedEvent,
|
||||
isActionsMenuActionClickedEvent,
|
||||
} from "../Events/ActionsMenuActionClickedEvent";
|
||||
import { Observable, Subject } from "rxjs";
|
||||
|
||||
let popupId = 0;
|
||||
const popups: Map<number, Popup> = new Map<number, Popup>();
|
||||
@@ -42,7 +48,77 @@ export interface ActionMessageOptions {
|
||||
callback: () => void;
|
||||
}
|
||||
|
||||
export interface RemotePlayerInterface {
|
||||
addAction(key: string, callback: Function): void;
|
||||
}
|
||||
|
||||
export class RemotePlayer implements RemotePlayerInterface {
|
||||
private id: number;
|
||||
|
||||
private actions: Map<string, ActionsMenuAction> = new Map<string, ActionsMenuAction>();
|
||||
|
||||
constructor(id: number) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public addAction(key: string, callback: Function): ActionsMenuAction {
|
||||
const newAction = new ActionsMenuAction(this, key, callback);
|
||||
this.actions.set(key, newAction);
|
||||
sendToWorkadventure({
|
||||
type: "addActionsMenuKeyToRemotePlayer",
|
||||
data: { id: this.id, actionKey: key },
|
||||
});
|
||||
return newAction;
|
||||
}
|
||||
|
||||
public callAction(key: string): void {
|
||||
const action = this.actions.get(key);
|
||||
if (action) {
|
||||
action.call();
|
||||
}
|
||||
}
|
||||
|
||||
public removeAction(key: string): void {
|
||||
this.actions.delete(key);
|
||||
sendToWorkadventure({
|
||||
type: "removeActionsMenuKeyFromRemotePlayer",
|
||||
data: { id: this.id, actionKey: key },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ActionsMenuAction {
|
||||
private remotePlayer: RemotePlayer;
|
||||
private key: string;
|
||||
private callback: Function;
|
||||
|
||||
constructor(remotePlayer: RemotePlayer, key: string, callback: Function) {
|
||||
this.remotePlayer = remotePlayer;
|
||||
this.key = key;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public call(): void {
|
||||
this.callback();
|
||||
}
|
||||
|
||||
public remove(): void {
|
||||
this.remotePlayer.removeAction(this.key);
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiCommands> {
|
||||
public readonly _onRemotePlayerClicked: Subject<RemotePlayerInterface>;
|
||||
public readonly onRemotePlayerClicked: Observable<RemotePlayerInterface>;
|
||||
|
||||
private currentlyClickedRemotePlayer?: RemotePlayer;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._onRemotePlayerClicked = new Subject<RemotePlayerInterface>();
|
||||
this.onRemotePlayerClicked = this._onRemotePlayerClicked.asObservable();
|
||||
}
|
||||
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "buttonClickedEvent",
|
||||
@@ -82,9 +158,38 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
|
||||
}
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "remotePlayerClickedEvent",
|
||||
typeChecker: isRemotePlayerClickedEvent,
|
||||
callback: (payloadData: RemotePlayerClickedEvent) => {
|
||||
this.currentlyClickedRemotePlayer = new RemotePlayer(payloadData.id);
|
||||
this._onRemotePlayerClicked.next(this.currentlyClickedRemotePlayer);
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "actionsMenuActionClickedEvent",
|
||||
typeChecker: isActionsMenuActionClickedEvent,
|
||||
callback: (payloadData: ActionsMenuActionClickedEvent) => {
|
||||
this.currentlyClickedRemotePlayer?.callAction(payloadData.actionName);
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
|
||||
public addActionsMenuKeyToRemotePlayer(id: number, actionKey: string): void {
|
||||
sendToWorkadventure({
|
||||
type: "addActionsMenuKeyToRemotePlayer",
|
||||
data: { id, actionKey },
|
||||
});
|
||||
}
|
||||
|
||||
public removeActionsMenuKeyFromRemotePlayer(id: number, actionKey: string): void {
|
||||
sendToWorkadventure({
|
||||
type: "removeActionsMenuKeyFromRemotePlayer",
|
||||
data: { id, actionKey },
|
||||
});
|
||||
}
|
||||
|
||||
public openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
|
||||
popupId++;
|
||||
const popup = new Popup(popupId);
|
||||
const btnMap = new Map<number, () => void>();
|
||||
@@ -119,7 +224,10 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
|
||||
return popup;
|
||||
}
|
||||
|
||||
registerMenuCommand(commandDescriptor: string, options: MenuOptions | ((commandDescriptor: string) => void)): Menu {
|
||||
public registerMenuCommand(
|
||||
commandDescriptor: string,
|
||||
options: MenuOptions | ((commandDescriptor: string) => void)
|
||||
): Menu {
|
||||
const menu = new Menu(commandDescriptor);
|
||||
|
||||
if (typeof options === "function") {
|
||||
@@ -168,15 +276,15 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
|
||||
return menu;
|
||||
}
|
||||
|
||||
displayBubble(): void {
|
||||
public displayBubble(): void {
|
||||
sendToWorkadventure({ type: "displayBubble", data: null });
|
||||
}
|
||||
|
||||
removeBubble(): void {
|
||||
public removeBubble(): void {
|
||||
sendToWorkadventure({ type: "removeBubble", data: null });
|
||||
}
|
||||
|
||||
displayActionMessage(actionMessageOptions: ActionMessageOptions): ActionMessage {
|
||||
public displayActionMessage(actionMessageOptions: ActionMessageOptions): ActionMessage {
|
||||
const actionMessage = new ActionMessage(actionMessageOptions, () => {
|
||||
actionMessages.delete(actionMessage.uuid);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user