Refactoring displayActionMessage signature. Now accepting an options object. This should allow for more options in the future.

This commit is contained in:
David Négrier 2021-08-05 12:02:00 +02:00
parent 87e4367455
commit bc1c6a4986
7 changed files with 84 additions and 36 deletions

View file

@ -93,7 +93,11 @@ WA.ui.registerMenuCommand("test", () => {
### Awaiting User Confirmation (with space bar)
```
WA.ui.displayActionMessage(message: string, callback: () => void): ActionMessage
WA.ui.displayActionMessage({
message: string,
callback: () => void,
type?: "message"|"warning",
}): ActionMessage
```
Displays a message at the bottom of the screen (that will disappear when space bar is pressed).
@ -105,8 +109,11 @@ Displays a message at the bottom of the screen (that will disappear when space b
Example:
```javascript
const triggerMessage = WA.ui.displayActionMessage("press 'space' to confirm", () => {
WA.chat.sendChatMessage("confirmed", "trigger message logic")
const triggerMessage = WA.ui.displayActionMessage({
message: "press 'space' to confirm",
callback: () => {
WA.chat.sendChatMessage("confirmed", "trigger message logic")
}
});
setTimeout(() => {

View file

@ -1,12 +1,17 @@
import * as tg from 'generic-type-guard';
import * as tg from "generic-type-guard";
export const triggerActionMessage = 'triggerActionMessage';
export const removeActionMessage = 'removeActionMessage';
export const triggerActionMessage = "triggerActionMessage";
export const removeActionMessage = "removeActionMessage";
export const isActionMessageType = tg.isSingletonStringUnion("message", "warning");
export type ActionMessageType = tg.GuardedType<typeof isActionMessageType>;
export const isTriggerActionMessageEvent = new tg.IsInterface()
.withProperties({
message: tg.isString,
uuid: tg.isString,
type: isActionMessageType,
})
.get();

View file

@ -417,6 +417,15 @@ class IframeListener {
});
}
sendActionMessageTriggered(uuid: string): void {
this.postMessage({
type: "messageTriggered",
data: {
uuid,
},
});
}
/**
* Sends the message... to all allowed iframes.
*/

View file

@ -1,10 +1,12 @@
import {
ActionMessageType,
MessageReferenceEvent,
removeActionMessage,
triggerActionMessage,
TriggerActionMessageEvent,
} from "../../Events/ui/TriggerActionMessageEvent";
import { queryWorkadventure } from "../IframeApiContribution";
import type { ActionMessageOptions } from "../ui";
function uuidv4() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0,
@ -13,29 +15,29 @@ function uuidv4() {
});
}
export let triggerMessageInstance: ActionMessage | undefined = undefined;
export class ActionMessage {
uuid: string;
public readonly uuid: string;
private readonly type: ActionMessageType;
private readonly message: string;
private readonly callback: () => void;
constructor(private message: string, private callback: () => void) {
constructor(actionMessageOptions: ActionMessageOptions, private onRemove: () => void) {
this.uuid = uuidv4();
if (triggerMessageInstance) {
triggerMessageInstance.remove();
}
triggerMessageInstance = this;
this.message = actionMessageOptions.message;
this.type = actionMessageOptions.type ?? "message";
this.callback = actionMessageOptions.callback;
this.create();
}
async create() {
private async create() {
await queryWorkadventure({
type: triggerActionMessage,
data: {
message: this.message,
type: this.type,
uuid: this.uuid,
} as TriggerActionMessageEvent,
});
this.callback();
}
async remove() {
@ -45,6 +47,10 @@ export class ActionMessage {
uuid: this.uuid,
} as MessageReferenceEvent,
});
triggerMessageInstance = undefined;
this.onRemove();
}
triggerCallback() {
this.callback();
}
}

View file

@ -5,6 +5,7 @@ import { apiCallback } from "./registeredCallbacks";
import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor";
import { Popup } from "./Ui/Popup";
import { ActionMessage } from "./Ui/ActionMessage";
import { isMessageReferenceEvent } from "../Events/ui/TriggerActionMessageEvent";
let popupId = 0;
const popups: Map<number, Popup> = new Map<number, Popup>();
@ -14,6 +15,7 @@ const popupCallbacks: Map<number, Map<number, ButtonClickedCallback>> = new Map<
>();
const menuCallbacks: Map<string, (command: string) => void> = new Map();
const actionMessages = new Map<string, ActionMessage>();
interface ZonedPopupOptions {
zone: string;
@ -23,6 +25,12 @@ interface ZonedPopupOptions {
popupOptions: Array<ButtonDescriptor>;
}
export interface ActionMessageOptions {
message: string;
type?: "message" | "warning";
callback: () => void;
}
export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiCommands> {
callbacks = [
apiCallback({
@ -49,6 +57,16 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
}
},
}),
apiCallback({
type: "messageTriggered",
typeChecker: isMessageReferenceEvent,
callback: (event) => {
const actionMessage = actionMessages.get(event.uuid);
if (actionMessage) {
actionMessage.triggerCallback();
}
},
}),
];
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
@ -104,8 +122,12 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
sendToWorkadventure({ type: "removeBubble", data: null });
}
displayActionMessage(message: string, callback: () => void): ActionMessage {
return new ActionMessage(message, callback);
displayActionMessage(actionMessageOptions: ActionMessageOptions): ActionMessage {
const actionMessage = new ActionMessage(actionMessageOptions, () => {
actionMessages.delete(actionMessage.uuid);
});
actionMessages.set(actionMessage.uuid, actionMessage);
return actionMessage;
}
}

View file

@ -1150,21 +1150,17 @@ ${escapedMessage}
});
});
iframeListener.registerAnswerer(
"triggerActionMessage",
(message) =>
new Promise((resolver) => {
layoutManagerActionStore.addAction({
uuid: message.uuid,
type: "message",
message: message.message,
callback: () => {
layoutManagerActionStore.removeAction(message.uuid);
resolver();
},
userInputManager: this.userInputManager,
});
})
iframeListener.registerAnswerer("triggerActionMessage", (message) =>
layoutManagerActionStore.addAction({
uuid: message.uuid,
type: "message",
message: message.message,
callback: () => {
layoutManagerActionStore.removeAction(message.uuid);
iframeListener.sendActionMessageTriggered(message.uuid);
},
userInputManager: this.userInputManager,
})
);
iframeListener.registerAnswerer("removeActionMessage", (message) => {

View file

@ -2,8 +2,11 @@ WA.onInit().then(() => {
let message;
WA.room.onEnterZone("carpet", () => {
message = WA.ui.displayActionMessage("This is a test message. Press space to display a chat message. Walk out to hide the message.", () => {
WA.chat.sendChatMessage("Hello world!", "The bot");
message = WA.ui.displayActionMessage({
message: "This is a test message. Press space to display a chat message. Walk out to hide the message.",
callback: () => {
WA.chat.sendChatMessage("Hello world!", "The bot");
}
});
});