Allows to read and write "Player properties" from LocalStorage

This commit is contained in:
Benedicte Quimbert 2021-10-15 17:01:38 +02:00
parent ecb72d0fd1
commit 89cd292527
5 changed files with 60 additions and 3 deletions

View File

@ -28,6 +28,7 @@ import type { MessageReferenceEvent } from "./ui/TriggerActionMessageEvent";
import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent"; import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent";
import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent"; import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent";
import type { ChangeLayerEvent } from "./ChangeLayerEvent"; import type { ChangeLayerEvent } from "./ChangeLayerEvent";
import { isPlayerPropertyEvent } from "./PlayerPropertyEvent";
export interface TypedMessageEvent<T> extends MessageEvent { export interface TypedMessageEvent<T> extends MessageEvent {
data: T; data: T;
@ -59,7 +60,7 @@ export type IframeEventMap = {
registerMenu: MenuRegisterEvent; registerMenu: MenuRegisterEvent;
unregisterMenu: UnregisterMenuEvent; unregisterMenu: UnregisterMenuEvent;
setTiles: SetTilesEvent; setTiles: SetTilesEvent;
modifyEmbeddedWebsite: Partial<EmbeddedWebsite>; // Note: name should be compulsory in fact modifyEmbeddedWebsite: Partial<EmbeddedWebsite>; // Note: name should be compulsory in fact;
}; };
export interface IframeEvent<T extends keyof IframeEventMap> { export interface IframeEvent<T extends keyof IframeEventMap> {
type: T; type: T;
@ -149,6 +150,14 @@ export const iframeQueryMapTypeGuards = {
query: isCreateEmbeddedWebsiteEvent, query: isCreateEmbeddedWebsiteEvent,
answer: tg.isUndefined, answer: tg.isUndefined,
}, },
getPlayerProperty: {
query: tg.isString,
answer: isPlayerPropertyEvent,
},
setPlayerProperty: {
query: isPlayerPropertyEvent,
answer: tg.isUndefined,
},
}; };
type GuardedType<T> = T extends (x: unknown) => x is infer T ? T : never; type GuardedType<T> = T extends (x: unknown) => x is infer T ? T : never;

View File

@ -0,0 +1,13 @@
import * as tg from "generic-type-guard";
export const isPlayerPropertyEvent = new tg.IsInterface()
.withProperties({
propertyName: tg.isString,
propertyValue: tg.isUnknown,
})
.get();
/**
* A message sent from the iFrame to set player-related properties.
*/
export type PlayerPropertyEvent = tg.GuardedType<typeof isPlayerPropertyEvent>;

View File

@ -1,8 +1,9 @@
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "./IframeApiContribution";
import type { HasPlayerMovedEvent, HasPlayerMovedEventCallback } from "../Events/HasPlayerMovedEvent"; import type { HasPlayerMovedEvent, HasPlayerMovedEventCallback } from "../Events/HasPlayerMovedEvent";
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { apiCallback } from "./registeredCallbacks"; import { apiCallback } from "./registeredCallbacks";
import { isHasPlayerMovedEvent } from "../Events/HasPlayerMovedEvent"; import { isHasPlayerMovedEvent } from "../Events/HasPlayerMovedEvent";
import type { PlayerPropertyEvent } from "../Events/PlayerPropertyEvent";
const moveStream = new Subject<HasPlayerMovedEvent>(); const moveStream = new Subject<HasPlayerMovedEvent>();
@ -67,6 +68,20 @@ export class WorkadventurePlayerCommands extends IframeApiContribution<Workadven
} }
return uuid; return uuid;
} }
getPlayerProperty(name: string): Promise<PlayerPropertyEvent> {
return queryWorkadventure({
type: "getPlayerProperty",
data: name,
});
}
setPlayerProperty(property: PlayerPropertyEvent) {
queryWorkadventure({
type: "setPlayerProperty",
data: property,
}).catch((e) => console.error(e));
}
} }
export default new WorkadventurePlayerCommands(); export default new WorkadventurePlayerCommands();

View File

@ -20,8 +20,8 @@ const nonce = "nonce";
const notification = "notificationPermission"; const notification = "notificationPermission";
const code = "code"; const code = "code";
const cameraSetup = "cameraSetup"; const cameraSetup = "cameraSetup";
const cacheAPIIndex = "workavdenture-cache"; const cacheAPIIndex = "workavdenture-cache";
const userProperties = "user-properties";
class LocalUserStore { class LocalUserStore {
saveUser(localUser: LocalUser) { saveUser(localUser: LocalUser) {
@ -204,6 +204,13 @@ class LocalUserStore {
const cameraSetupValues = localStorage.getItem(cameraSetup); const cameraSetupValues = localStorage.getItem(cameraSetup);
return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined; return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined;
} }
getUserProperty(name: string): string | null {
return localStorage.getItem(userProperties + "_" + name);
}
setUserProperty(name: string, value: string): void {
localStorage.setItem(userProperties + "_" + name, value);
}
} }
export const localUserStore = new LocalUserStore(); export const localUserStore = new LocalUserStore();

View File

@ -1153,6 +1153,19 @@ ${escapedMessage}
}; };
}); });
//TODO : move Player Properties related-code
iframeListener.registerAnswerer("setPlayerProperty", (event) => {
localUserStore.setUserProperty(event.propertyName, event.propertyValue as string);
});
iframeListener.registerAnswerer("getPlayerProperty", (event) => {
return {
propertyName: event,
propertyValue: localUserStore.getUserProperty(event),
};
});
//END TODO
iframeListener.registerAnswerer("getState", async () => { iframeListener.registerAnswerer("getState", async () => {
// The sharedVariablesManager is not instantiated before the connection is established. So we need to wait // The sharedVariablesManager is not instantiated before the connection is established. So we need to wait
// for the connection to send back the answer. // for the connection to send back the answer.