added trigger message code

This commit is contained in:
jonny 2021-06-23 17:32:32 +02:00
parent 3cf0a9ee84
commit 5472d220ba
9 changed files with 267 additions and 99 deletions

View file

@ -86,4 +86,24 @@ WA.ui.registerMenuCommand("test", () => {
<div class="col"> <div class="col">
<img src="https://workadventu.re/img/docs/menu-command.png" class="figure-img img-fluid rounded" alt="" /> <img src="https://workadventu.re/img/docs/menu-command.png" class="figure-img img-fluid rounded" alt="" />
</div> </div>
### Awaiting User Confirmation (with space bar)
```typescript
triggerMessage(message: string): TriggerMessage
```
Displays a message at the bottom of the screen (that will disappear when space bar is pressed).
Example:
```javascript
const triggerMessage = WA.ui.triggerMessage("press 'space' to confirm");
setTimeout(()=>{
// later
triggerMessage.remove();
},1000)
```

View file

@ -18,6 +18,7 @@ import type { PlaySoundEvent } from "./PlaySoundEvent";
import type { MenuItemClickedEvent } from "./ui/MenuItemClickedEvent"; import type { MenuItemClickedEvent } from "./ui/MenuItemClickedEvent";
import type { MenuItemRegisterEvent } from './ui/MenuItemRegisterEvent'; import type { MenuItemRegisterEvent } from './ui/MenuItemRegisterEvent';
import type { HasPlayerMovedEvent } from "./HasPlayerMovedEvent"; import type { HasPlayerMovedEvent } from "./HasPlayerMovedEvent";
import type { MessageReferenceEvent, TriggerMessageEvent } from '../iframe/TriggerMessageEvent';
export interface TypedMessageEvent<T> extends MessageEvent { export interface TypedMessageEvent<T> extends MessageEvent {
@ -49,6 +50,9 @@ export type IframeEventMap = {
stopSound: null, stopSound: null,
getState: undefined, getState: undefined,
registerMenuCommand: MenuItemRegisterEvent registerMenuCommand: MenuItemRegisterEvent
triggerMessage: TriggerMessageEvent
removeTriggerMessage: MessageReferenceEvent
} }
export interface IframeEvent<T extends keyof IframeEventMap> { export interface IframeEvent<T extends keyof IframeEventMap> {
type: T; type: T;
@ -68,6 +72,7 @@ export interface IframeResponseEventMap {
hasPlayerMoved: HasPlayerMovedEvent hasPlayerMoved: HasPlayerMovedEvent
dataLayer: DataLayerEvent dataLayer: DataLayerEvent
menuItemClicked: MenuItemClickedEvent menuItemClicked: MenuItemClickedEvent
messageTriggered: MessageReferenceEvent
} }
export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> { export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> {
type: T; type: T;

View file

@ -0,0 +1,21 @@
import * as tg from "generic-type-guard";
export const triggerMessage = "triggerMessage"
export const removeTriggerMessage = "removeTriggerMessage"
export const isTriggerMessageEvent = new tg.IsInterface().withProperties({
message: tg.isString,
uuid: tg.isString
}).get()
export type TriggerMessageEvent = tg.GuardedType<typeof isTriggerMessageEvent>;
export const isMessageReferenceEvent =
new tg.IsInterface().withProperties({
uuid: tg.isString
}).get();
export type MessageReferenceEvent = tg.GuardedType<typeof isMessageReferenceEvent>;

View file

@ -0,0 +1,42 @@
import { Subject } from 'rxjs';
import { iframeListener } from '../../IframeListener';
import { isMessageReferenceEvent, isTriggerMessageEvent, MessageReferenceEvent, removeTriggerMessage, triggerMessage, TriggerMessageEvent } from './TriggerMessageEvent';
import * as tg from "generic-type-guard";
export function sendMessageTriggeredEvent(uuid: string) {
iframeListener.postMessage({
'type': 'messageTriggered',
'data': {
uuid,
} as MessageReferenceEvent
});
}
const _triggerMessageEvent: Subject<TriggerMessageEvent> = new Subject();
const _removeTriggerMessageEvent: Subject<MessageReferenceEvent> = new Subject();
export const triggerMessageEvent = _triggerMessageEvent.asObservable();
export const removeTriggerMessageEvent = _removeTriggerMessageEvent.asObservable();
const isTriggerMessageEventObject = new tg.IsInterface().withProperties({
type: tg.isSingletonString(triggerMessage),
data: isTriggerMessageEvent
}).get()
const isTriggerMessageRemoveEventObject = new tg.IsInterface().withProperties({
type: tg.isSingletonString(removeTriggerMessage),
data: isMessageReferenceEvent
}).get()
export const isTriggerMessageHandlerEvent = tg.isUnion(isTriggerMessageEventObject, isTriggerMessageRemoveEventObject)
export function triggerMessageEventHandler(event: tg.GuardedType<typeof isTriggerMessageHandlerEvent>) {
if (isTriggerMessageEventObject(event)) {
_triggerMessageEvent.next(event.data)
} else if (isTriggerMessageRemoveEventObject(event)) {
_removeTriggerMessageEvent.next(event.data)
}
}

View file

@ -1,14 +1,14 @@
import {Subject} from "rxjs"; import { Subject } from "rxjs";
import {ChatEvent, isChatEvent} from "./Events/ChatEvent"; import { ChatEvent, isChatEvent } from "./Events/ChatEvent";
import {HtmlUtils} from "../WebRtc/HtmlUtils"; import { HtmlUtils } from "../WebRtc/HtmlUtils";
import type {EnterLeaveEvent} from "./Events/EnterLeaveEvent"; import type { EnterLeaveEvent } from "./Events/EnterLeaveEvent";
import {isOpenPopupEvent, OpenPopupEvent} from "./Events/OpenPopupEvent"; import { isOpenPopupEvent, OpenPopupEvent } from "./Events/OpenPopupEvent";
import {isOpenTabEvent, OpenTabEvent} from "./Events/OpenTabEvent"; import { isOpenTabEvent, OpenTabEvent } from "./Events/OpenTabEvent";
import type {ButtonClickedEvent} from "./Events/ButtonClickedEvent"; import type { ButtonClickedEvent } from "./Events/ButtonClickedEvent";
import {ClosePopupEvent, isClosePopupEvent} from "./Events/ClosePopupEvent"; import { ClosePopupEvent, isClosePopupEvent } from "./Events/ClosePopupEvent";
import {scriptUtils} from "./ScriptUtils"; import { scriptUtils } from "./ScriptUtils";
import {GoToPageEvent, isGoToPageEvent} from "./Events/GoToPageEvent"; import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent";
import {isOpenCoWebsite, OpenCoWebSiteEvent} from "./Events/OpenCoWebSiteEvent"; import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent";
import { import {
IframeEvent, IframeEvent,
IframeEventMap, IframeEventMap,
@ -17,19 +17,20 @@ import {
isIframeEventWrapper, isIframeEventWrapper,
TypedMessageEvent TypedMessageEvent
} from "./Events/IframeEvent"; } from "./Events/IframeEvent";
import type {UserInputChatEvent} from "./Events/UserInputChatEvent"; import type { UserInputChatEvent } from "./Events/UserInputChatEvent";
//import { isLoadPageEvent } from './Events/LoadPageEvent'; //import { isLoadPageEvent } from './Events/LoadPageEvent';
import {isPlaySoundEvent, PlaySoundEvent} from "./Events/PlaySoundEvent"; import { isPlaySoundEvent, PlaySoundEvent } from "./Events/PlaySoundEvent";
import {isStopSoundEvent, StopSoundEvent} from "./Events/StopSoundEvent"; import { isStopSoundEvent, StopSoundEvent } from "./Events/StopSoundEvent";
import {isLoadSoundEvent, LoadSoundEvent} from "./Events/LoadSoundEvent"; import { isLoadSoundEvent, LoadSoundEvent } from "./Events/LoadSoundEvent";
import {isSetPropertyEvent, SetPropertyEvent} from "./Events/setPropertyEvent"; import { isSetPropertyEvent, SetPropertyEvent } from "./Events/setPropertyEvent";
import {isLayerEvent, LayerEvent} from "./Events/LayerEvent"; import { isLayerEvent, LayerEvent } from "./Events/LayerEvent";
import {isMenuItemRegisterEvent,} from "./Events/ui/MenuItemRegisterEvent"; import { isMenuItemRegisterEvent, } from "./Events/ui/MenuItemRegisterEvent";
import type {DataLayerEvent} from "./Events/DataLayerEvent"; import type { DataLayerEvent } from "./Events/DataLayerEvent";
import type {GameStateEvent} from "./Events/GameStateEvent"; import type { GameStateEvent } from "./Events/GameStateEvent";
import type {HasPlayerMovedEvent} from "./Events/HasPlayerMovedEvent"; import type { HasPlayerMovedEvent } from "./Events/HasPlayerMovedEvent";
import {isLoadPageEvent} from "./Events/LoadPageEvent"; import { isLoadPageEvent } from "./Events/LoadPageEvent";
import {handleMenuItemRegistrationEvent, isMenuItemRegisterIframeEvent} from "./Events/ui/MenuItemRegisterEvent"; import { handleMenuItemRegistrationEvent, isMenuItemRegisterIframeEvent } from "./Events/ui/MenuItemRegisterEvent";
import { isTriggerMessageHandlerEvent, triggerMessageEventHandler } from './Events/ui/TriggerMessageEventHandler';
/** /**
* Listens to messages from iframes and turn those messages into easy to use observables. * Listens to messages from iframes and turn those messages into easy to use observables.
@ -190,6 +191,8 @@ class IframeListener {
this._unregisterMenuCommandStream.next(data); this._unregisterMenuCommandStream.next(data);
}) })
handleMenuItemRegistrationEvent(payload.data) handleMenuItemRegistrationEvent(payload.data)
} else if (isTriggerMessageHandlerEvent(payload)) {
triggerMessageEventHandler(payload)
} }
} }
}, false); }, false);
@ -198,8 +201,8 @@ class IframeListener {
sendDataLayerEvent(dataLayerEvent: DataLayerEvent) { sendDataLayerEvent(dataLayerEvent: DataLayerEvent) {
this.postMessage({ this.postMessage({
'type' : 'dataLayer', 'type': 'dataLayer',
'data' : dataLayerEvent 'data': dataLayerEvent
}) })
} }

View file

@ -0,0 +1,51 @@
import { removeTriggerMessage, triggerMessage, TriggerMessageEvent } from '../../Events/ui/TriggerMessageEvent';
import { sendToWorkadventure } from '../IframeApiContribution';
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
export let triggerMessageInstance: TriggerMessage | undefined = undefined
export class TriggerMessage {
uuid: string
constructor(private message: string, private callback: () => void) {
this.uuid = uuidv4()
if (triggerMessageInstance) {
triggerMessageInstance.remove();
}
triggerMessageInstance = this;
this.create();
}
create(): this {
sendToWorkadventure({
type: triggerMessage,
data: {
message: this.message,
uuid: this.uuid
} as TriggerMessageEvent
})
return this
}
remove() {
sendToWorkadventure({
type: removeTriggerMessage,
data: {
uuid: this.uuid
} as TriggerMessageEvent
})
triggerMessageInstance = undefined
}
trigger() {
this.callback();
}
}

View file

@ -1,10 +1,11 @@
import { isButtonClickedEvent } from '../Events/ButtonClickedEvent'; import { isButtonClickedEvent } from '../Events/ButtonClickedEvent';
import { isMenuItemClickedEvent } from '../Events/ui/MenuItemClickedEvent'; import { isMenuItemClickedEvent } from '../Events/ui/MenuItemClickedEvent';
import type { MenuItemRegisterEvent } from '../Events/ui/MenuItemRegisterEvent'; import { isMessageReferenceEvent } from '../Events/ui/TriggerMessageEvent';
import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution'; import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution';
import { apiCallback } from "./registeredCallbacks"; import { apiCallback } from "./registeredCallbacks";
import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor"; import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor";
import { Popup } from "./Ui/Popup"; import { Popup } from "./Ui/Popup";
import { TriggerMessage, triggerMessageInstance } from './Ui/TriggerMessage';
let popupId = 0; let popupId = 0;
const popups: Map<number, Popup> = new Map<number, Popup>(); const popups: Map<number, Popup> = new Map<number, Popup>();
@ -12,41 +13,41 @@ const popupCallbacks: Map<number, Map<number, ButtonClickedCallback>> = new Map<
const menuCallbacks: Map<string, (command: string) => void> = new Map() const menuCallbacks: Map<string, (command: string) => void> = new Map()
interface ZonedPopupOptions {
zone: string
objectLayerName?: string,
popupText: string,
delay?: number
popupOptions: Array<ButtonDescriptor>
}
class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiCommands> { class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiCommands> {
callbacks = [apiCallback({ callbacks = [
type: "buttonClickedEvent", apiCallback({
typeChecker: isButtonClickedEvent, type: "buttonClickedEvent",
callback: (payloadData) => { typeChecker: isButtonClickedEvent,
const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId); callback: (payloadData) => {
const popup = popups.get(payloadData.popupId); const callback = popupCallbacks.get(payloadData.popupId)?.get(payloadData.buttonId);
if (popup === undefined) { const popup = popups.get(payloadData.popupId);
throw new Error('Could not find popup with ID "' + payloadData.popupId + '"'); if (popup === undefined) {
throw new Error('Could not find popup with ID "' + payloadData.popupId + '"');
}
if (callback) {
callback(popup);
}
} }
if (callback) { }),
callback(popup); apiCallback({
type: "menuItemClicked",
typeChecker: isMenuItemClickedEvent,
callback: event => {
const callback = menuCallbacks.get(event.menuItem);
if (callback) {
callback(event.menuItem)
}
} }
} }),
}), apiCallback({
apiCallback({ type: "messageTriggered",
type: "menuItemClicked", typeChecker: isMessageReferenceEvent,
typeChecker: isMenuItemClickedEvent, callback: event => {
callback: event => { triggerMessageInstance?.trigger();
const callback = menuCallbacks.get(event.menuItem);
if (callback) {
callback(event.menuItem)
} }
} })
})]; ];
openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup { openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup {
@ -101,6 +102,9 @@ class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventureUiComma
removeBubble(): void { removeBubble(): void {
sendToWorkadventure({ 'type': 'removeBubble', data: null }); sendToWorkadventure({ 'type': 'removeBubble', data: null });
} }
triggerMessage(message: string, callback: () => void): TriggerMessage {
return new TriggerMessage(message, callback);
}
} }
export default new WorkAdventureUiCommands(); export default new WorkAdventureUiCommands();

View file

@ -64,7 +64,8 @@ import type {
ITiledMapLayerProperty, ITiledMapLayerProperty,
ITiledMapObject, ITiledMapObject,
ITiledMapTileLayer, ITiledMapTileLayer,
ITiledTileSet } from "../Map/ITiledMap"; ITiledTileSet
} from "../Map/ITiledMap";
import { MenuScene, MenuSceneName } from '../Menu/MenuScene'; import { MenuScene, MenuSceneName } from '../Menu/MenuScene';
import { PlayerAnimationDirections } from "../Player/Animation"; import { PlayerAnimationDirections } from "../Player/Animation";
import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player"; import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player";
@ -93,7 +94,8 @@ import Tilemap = Phaser.Tilemaps.Tilemap;
import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent'; import type { HasPlayerMovedEvent } from '../../Api/Events/HasPlayerMovedEvent';
import AnimatedTiles from "phaser-animated-tiles"; import AnimatedTiles from "phaser-animated-tiles";
import {soundManager} from "./SoundManager"; import { soundManager } from "./SoundManager";
import { removeTriggerMessageEvent, sendMessageTriggeredEvent, triggerMessageEvent } from '../../Api/Events/ui/TriggerMessageEventHandler';
export interface GameSceneInitInterface { export interface GameSceneInitInterface {
initPosition: PointInterface | null, initPosition: PointInterface | null,
@ -932,11 +934,11 @@ ${escapedMessage}
scriptedBubbleSprite.destroy(); scriptedBubbleSprite.destroy();
})); }));
this.iframeSubscriptionList.push(iframeListener.showLayerStream.subscribe((layerEvent)=>{ this.iframeSubscriptionList.push(iframeListener.showLayerStream.subscribe((layerEvent) => {
this.setLayerVisibility(layerEvent.name, true); this.setLayerVisibility(layerEvent.name, true);
})); }));
this.iframeSubscriptionList.push(iframeListener.hideLayerStream.subscribe((layerEvent)=>{ this.iframeSubscriptionList.push(iframeListener.hideLayerStream.subscribe((layerEvent) => {
this.setLayerVisibility(layerEvent.name, false); this.setLayerVisibility(layerEvent.name, false);
})); }));
@ -945,7 +947,7 @@ ${escapedMessage}
})); }));
this.iframeSubscriptionList.push(iframeListener.dataLayerChangeStream.subscribe(() => { this.iframeSubscriptionList.push(iframeListener.dataLayerChangeStream.subscribe(() => {
iframeListener.sendDataLayerEvent({data: this.gameMap.getMap()}); iframeListener.sendDataLayerEvent({ data: this.gameMap.getMap() });
})) }))
this.iframeSubscriptionList.push(iframeListener.gameStateStream.subscribe(() => { this.iframeSubscriptionList.push(iframeListener.gameStateStream.subscribe(() => {
@ -959,21 +961,33 @@ ${escapedMessage}
}) })
})); }));
this.iframeSubscriptionList.push(triggerMessageEvent.subscribe(message => {
layoutManager.addActionButton(message.uuid, message.message, () => {
sendMessageTriggeredEvent(message.uuid)
layoutManager.removeActionButton(message.uuid, this.userInputManager);
}, this.userInputManager);
}))
this.iframeSubscriptionList.push(removeTriggerMessageEvent.subscribe(message => {
layoutManager.removeActionButton(message.uuid, this.userInputManager);
}))
} }
private setPropertyLayer(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void { private setPropertyLayer(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
const layer = this.gameMap.findLayer(layerName); const layer = this.gameMap.findLayer(layerName);
if (layer === undefined) { if (layer === undefined) {
console.warn('Could not find layer "' + layerName + '" when calling setProperty'); console.warn('Could not find layer "' + layerName + '" when calling setProperty');
return; return;
} }
const property = (layer.properties as ITiledMapLayerProperty[])?.find((property) => property.name === propertyName); const property = (layer.properties as ITiledMapLayerProperty[])?.find((property) => property.name === propertyName);
if (property === undefined) { if (property === undefined) {
layer.properties = []; layer.properties = [];
layer.properties.push({name : propertyName, type : typeof propertyValue, value : propertyValue}); layer.properties.push({ name: propertyName, type: typeof propertyValue, value: propertyValue });
return; return;
} }
property.value = propertyValue; property.value = propertyValue;
} }
private setLayerVisibility(layerName: string, visible: boolean): void { private setLayerVisibility(layerName: string, visible: boolean): void {
@ -1150,7 +1164,7 @@ ${escapedMessage}
} }
//todo: push that into the gameManager //todo: push that into the gameManager
private loadNextGame(exitSceneIdentifier: string) : Promise<void>{ private loadNextGame(exitSceneIdentifier: string): Promise<void> {
const { roomId, hash } = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance); const { roomId, hash } = Room.getIdFromIdentifier(exitSceneIdentifier, this.MapUrlFile, this.instance);
const room = new Room(roomId); const room = new Room(roomId);
return gameManager.loadMap(room, this.scene).catch(() => { }); return gameManager.loadMap(room, this.scene).catch(() => { });
@ -1197,7 +1211,7 @@ ${escapedMessage}
this.physics.add.collider(this.CurrentPlayer, phaserLayer, (object1: GameObject, object2: GameObject) => { this.physics.add.collider(this.CurrentPlayer, phaserLayer, (object1: GameObject, object2: GameObject) => {
//this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name) //this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name)
}); });
phaserLayer.setCollisionByProperty({collides: true}); phaserLayer.setCollisionByProperty({ collides: true });
if (DEBUG_MODE) { if (DEBUG_MODE) {
//debug code to see the collision hitbox of the object in the top layer //debug code to see the collision hitbox of the object in the top layer
phaserLayer.renderDebug(this.add.graphics(), { phaserLayer.renderDebug(this.add.graphics(), {
@ -1206,7 +1220,7 @@ ${escapedMessage}
faceColor: new Phaser.Display.Color(40, 39, 37, 255) // Colliding face edges faceColor: new Phaser.Display.Color(40, 39, 37, 255) // Colliding face edges
}); });
} }
//}); //});
} }
} }
} }

View file

@ -1,40 +1,41 @@
///<reference path="../../front/src/iframe_api.ts" />
console.log('SCRIPT LAUNCHED'); console.log('SCRIPT LAUNCHED');
//WA.sendChatMessage('Hi, my name is Poly and I repeat what you say!', 'Poly Parrot'); //WA.sendChatMessage('Hi, my name is Poly and I repeat what you say!', 'Poly Parrot');
var isFirstTimeTuto = false; var isFirstTimeTuto = false;
var textFirstPopup = 'Hey ! This is how to open start a discussion with someone ! You can be 4 max in a booble'; var textFirstPopup = 'Hey ! This is how to open start a discussion with someone ! You can be 4 max in a booble';
var textSecondPopup = 'You can also use the chat to communicate ! '; var textSecondPopup = 'You can also use the chat to communicate ! ';
var targetObjectTutoBubble ='myPopup1'; var targetObjectTutoBubble = 'myPopup1';
var targetObjectTutoChat ='myPopup2'; var targetObjectTutoChat = 'myPopup2';
var popUpExplanation = undefined; var popUpExplanation = undefined;
function launchTuto (){ function launchTuto() {
WA.ui.openPopup(targetObjectTutoBubble, textFirstPopup, [ WA.ui.openPopup(targetObjectTutoBubble, textFirstPopup, [
{ {
label: "Next", label: "Next",
className: "popUpElement", className: "popUpElement",
callback: (popup) => { callback: (popup) => {
popup.close(); popup.close();
WA.ui.openPopup(targetObjectTutoChat, textSecondPopup, [ WA.ui.openPopup(targetObjectTutoChat, textSecondPopup, [
{ {
label: "Open Chat", label: "Open Chat",
className: "popUpElement", className: "popUpElement",
callback: (popup1) => { callback: (popup1) => {
WA.chat.sendChatMessage("Hey you can talk here too ! ", 'WA Guide'); WA.chat.sendChatMessage("Hey you can talk here too ! ", 'WA Guide');
popup1.close(); popup1.close();
WA.controls.restorePlayerControls(); WA.controls.restorePlayerControls();
}
} }
}
]) ])
}
} }
]); }
WA.controls.disablePlayerControls(); ]);
WA.controls.disablePlayerControls();
} }
WA.chat.onChatMessage((message => { WA.chat.onChatMessage((message => {
console.log('CHAT MESSAGE RECEIVED BY SCRIPT'); console.log('CHAT MESSAGE RECEIVED BY SCRIPT');
WA.chat.sendChatMessage('Poly Parrot says: "'+message+'"', 'Poly Parrot'); WA.chat.sendChatMessage('Poly Parrot says: "' + message + '"', 'Poly Parrot');
})); }));
WA.room.onEnterZone('myTrigger', () => { WA.room.onEnterZone('myTrigger', () => {
@ -50,11 +51,11 @@ WA.room.onEnterZone('notExist', () => {
WA.room.onEnterZone('popupZone', () => { WA.room.onEnterZone('popupZone', () => {
WA.ui.displayBubble(); WA.ui.displayBubble();
if (!isFirstTimeTuto) { if(!isFirstTimeTuto) {
isFirstTimeTuto = true; isFirstTimeTuto = true;
launchTuto(); launchTuto();
} }
else popUpExplanation = WA.ui.openPopup(targetObjectTutoChat,'Do you want to review the explanation ? ', [ else popUpExplanation = WA.ui.openPopup(targetObjectTutoChat, 'Do you want to review the explanation ? ', [
{ {
label: "No", label: "No",
className: "popUpElementReviewexplanation", className: "popUpElementReviewexplanation",
@ -74,6 +75,13 @@ WA.room.onEnterZone('popupZone', () => {
}); });
WA.room.onLeaveZone('popupZone', () => { WA.room.onLeaveZone('popupZone', () => {
if (popUpExplanation !== undefined) popUpExplanation.close(); if(popUpExplanation !== undefined) popUpExplanation.close();
WA.ui.removeBubble(); WA.ui.removeBubble();
}) })
const message = WA.ui.triggerMessage("testMessage", () => {
WA.chat.sendChatMessage("triggered", "triggerbot");
})
setTimeout(() => {
message.remove();
}, 5000)