added typedef for subobject types
extracted popup functions # Conflicts: # front/package-lock.json # front/package.json # front/src/iframe_api.ts
This commit is contained in:
parent
1a1ab30574
commit
2de2d114a1
6 changed files with 304 additions and 139 deletions
148
front/src/Api/iframe/popup.ts
Normal file
148
front/src/Api/iframe/popup.ts
Normal file
|
@ -0,0 +1,148 @@
|
|||
import { isButtonClickedEvent } from '../Events/ButtonClickedEvent';
|
||||
import { ClosePopupEvent } from '../Events/ClosePopupEvent';
|
||||
import { apiCallback, IframeApiContribution, IframeCallbackContribution, sendToWorkadventure } from './IframeApiContribution';
|
||||
import zoneCommands from "./zone-events"
|
||||
class Popup {
|
||||
constructor(private id: number) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the popup
|
||||
*/
|
||||
public close(): void {
|
||||
window.parent.postMessage({
|
||||
'type': 'closePopup',
|
||||
'data': {
|
||||
'popupId': this.id,
|
||||
} as ClosePopupEvent
|
||||
}, '*');
|
||||
}
|
||||
}
|
||||
|
||||
type ButtonClickedCallback = (popup: Popup) => void;
|
||||
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: ButtonClickedCallback,
|
||||
}
|
||||
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>>();
|
||||
|
||||
interface ZonedPopupOptions {
|
||||
zone: string
|
||||
objectLayerName?: string,
|
||||
popupText: string,
|
||||
delay?: number
|
||||
popupOptions: Array<ButtonDescriptor>
|
||||
}
|
||||
|
||||
|
||||
class PopupApiContribution extends IframeApiContribution<PopupApiContribution> {
|
||||
|
||||
readonly subObjectIdentifier = "ui"
|
||||
|
||||
readonly addMethodsAtRoot = true
|
||||
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);
|
||||
}
|
||||
}
|
||||
})];
|
||||
|
||||
|
||||
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
|
||||
popupId++;
|
||||
const popup = new Popup(popupId);
|
||||
const btnMap = new Map<number, () => void>();
|
||||
popupCallbacks.set(popupId, btnMap);
|
||||
let id = 0;
|
||||
for (const button of buttons) {
|
||||
const callback = button.callback;
|
||||
if (callback) {
|
||||
btnMap.set(id, () => {
|
||||
callback(popup);
|
||||
});
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
||||
sendToWorkadventure({
|
||||
'type': 'openPopup',
|
||||
'data': {
|
||||
popupId,
|
||||
targetObject,
|
||||
message,
|
||||
buttons: buttons.map((button) => {
|
||||
return {
|
||||
label: button.label,
|
||||
className: button.className
|
||||
};
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
popups.set(popupId, popup)
|
||||
return popup;
|
||||
}
|
||||
|
||||
|
||||
|
||||
popupInZone(options: ZonedPopupOptions) {
|
||||
const objectLayerName = options.objectLayerName || options.zone
|
||||
|
||||
let lastOpened = 0;
|
||||
|
||||
let popup: Popup | undefined;
|
||||
zoneCommands.onEnterZone(options.zone, () => {
|
||||
if (options.delay) {
|
||||
if (lastOpened + options.delay > Date.now()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
lastOpened = Date.now();
|
||||
popup = this.openPopup(objectLayerName, options.popupText, options.popupOptions.map(option => {
|
||||
const callback = option.callback;
|
||||
const popupOptions = {
|
||||
...option,
|
||||
className: option.className || 'normal',
|
||||
callback: () => {
|
||||
if (callback && popup) {
|
||||
callback(popup);
|
||||
}
|
||||
popup?.close();
|
||||
popup = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return popupOptions;
|
||||
}));
|
||||
});
|
||||
zoneCommands.onLeaveZone(options.zone, () => {
|
||||
if (popup) {
|
||||
popup.close();
|
||||
popup = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new PopupApiContribution()
|
Loading…
Add table
Add a link
Reference in a new issue