From 0623ee0bf2ebb8cb1f4b4277aad3d1373d2050f9 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Mon, 21 Jun 2021 11:44:18 +0200 Subject: [PATCH 01/16] HOTFIX: loading errors after the preload stage should not crash the game anymore --- .../Entity/PlayerTexturesLoadingManager.ts | 22 ++++++++++++++++--- front/src/Phaser/Game/GameScene.ts | 16 +++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts index 95f00a9e..eaba79aa 100644 --- a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts +++ b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts @@ -59,9 +59,11 @@ export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, textur } else { returnPromise = Promise.resolve(texturekeys); } + + //If the loading fail, we render the default model instead. return returnPromise.then((keys) => keys.map((key) => { return typeof key !== 'string' ? key.name : key; - })) + })).catch(() => lazyLoadPlayerCharacterTextures(loadPlugin, ["color_22", "eyes_23"])); } export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptionInterface): BodyResourceDescriptionInterface => { @@ -80,11 +82,25 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio } export const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface, frameConfig: FrameConfig) => { - return new Promise((res) => { + return new Promise((res, rej) => { + console.log('count', loadPlugin.listenerCount('loaderror')); if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { return res(playerResourceDescriptor); } loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig); - loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor)); + const errorCallback = (file: {src: string}) => { + if (file.src !== playerResourceDescriptor.img) return; + console.error('failed loading player ressource: ', playerResourceDescriptor) + rej(playerResourceDescriptor); + loadPlugin.off('filecomplete-spritesheet-' + playerResourceDescriptor.name, successCallback); + loadPlugin.off('loaderror', errorCallback); + } + const successCallback = () => { + loadPlugin.off('loaderror', errorCallback); + res(playerResourceDescriptor); + } + + loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, successCallback); + loadPlugin.on('loaderror', errorCallback); }); } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 72279c61..62d66c30 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -192,6 +192,7 @@ export class GameScene extends DirtyScene implements CenterListener { private pinchManager: PinchManager|undefined; private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time. private emoteManager!: EmoteManager; + private preloading: boolean = true; constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) { super({ @@ -259,11 +260,15 @@ export class GameScene extends DirtyScene implements CenterListener { return; } - this.scene.start(ErrorSceneName, { - title: 'Network error', - subTitle: 'An error occurred while loading resource:', - message: this.originalMapUrl ?? file.src - }); + //once preloading is over, we don't want loading errors to crash the game, so we need to disable this behavior after preloading. + console.error('Error when loading: ', file); + if (this.preloading) { + this.scene.start(ErrorSceneName, { + title: 'Network error', + subTitle: 'An error occurred while loading resource:', + message: this.originalMapUrl ?? file.src + }); + } }); this.load.on('filecomplete-tilemapJSON-'+this.MapUrlFile, (key: string, type: string, data: unknown) => { this.onMapLoad(data); @@ -388,6 +393,7 @@ export class GameScene extends DirtyScene implements CenterListener { //hook create scene create(): void { + this.preloading = false; this.trackDirtyAnims(); gameManager.gameSceneIsCreated(this); From 3e29ed4376a9e469c51291a93f8d0c1599e03b84 Mon Sep 17 00:00:00 2001 From: GRL Date: Tue, 22 Jun 2021 11:48:08 +0200 Subject: [PATCH 02/16] Correction of button customize WOKA scene issue --- .../CustomCharacterScene.svelte | 12 +++---- front/src/Phaser/Login/CustomizeScene.ts | 32 +++++++++---------- front/src/Stores/CustomCharacterStore.ts | 4 ++- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte b/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte index f9e3a66b..3fff6bc0 100644 --- a/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte +++ b/front/src/Components/CustomCharacterScene/CustomCharacterScene.svelte @@ -1,11 +1,11 @@ + + + +

Website opened by script.

+ + + \ No newline at end of file diff --git a/maps/tests/Metadata/cowebsiteAllowApi.js b/maps/tests/Metadata/cowebsiteAllowApi.js new file mode 100644 index 00000000..71ba96fa --- /dev/null +++ b/maps/tests/Metadata/cowebsiteAllowApi.js @@ -0,0 +1 @@ +WA.openCoWebSite("cowebsiteAllowApi.html", true, ""); \ No newline at end of file diff --git a/maps/tests/Metadata/cowebsiteAllowApi.json b/maps/tests/Metadata/cowebsiteAllowApi.json new file mode 100644 index 00000000..55ed615f --- /dev/null +++ b/maps/tests/Metadata/cowebsiteAllowApi.json @@ -0,0 +1,98 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[33, 34, 34, 34, 34, 34, 34, 34, 34, 35, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 49, 50, 50, 50, 50, 50, 50, 50, 50, 51], + "height":10, + "id":1, + "name":"bottom", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[ + { + "height":116.5, + "id":1, + "name":"", + "rotation":0, + "text": + { + "text":"Test : \nThe iframe is opened by script.\n\nResult : \nA message is send to the chat.", + "wrap":true + }, + "type":"", + "visible":true, + "width":295.875, + "x":11.8125, + "y":188.5 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 16, 16, 16, 0, 0, 16, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 16, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":4, + "name":"mushroom", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }], + "nextlayerid":5, + "nextobjectid":2, + "orientation":"orthogonal", + "properties":[ + { + "name":"script", + "type":"string", + "value":"cowebsiteAllowApi.js" + }], + "renderorder":"right-down", + "tiledversion":"1.4.3", + "tileheight":32, + "tilesets":[ + { + "columns":8, + "firstgid":1, + "image":"tileset_dungeon.png", + "imageheight":256, + "imagewidth":256, + "margin":0, + "name":"tileset_dungeon", + "spacing":0, + "tilecount":64, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.4, + "width":10 +} \ No newline at end of file diff --git a/maps/tests/Metadata/tileset_dungeon.png b/maps/tests/Metadata/tileset_dungeon.png new file mode 100644 index 0000000000000000000000000000000000000000..fcac082c33704b31451bc8a58af5982c06586aa6 GIT binary patch literal 9696 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 Date: Mon, 28 Jun 2021 16:05:29 +0200 Subject: [PATCH 04/16] Update docs/maps/api-reference.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: David NĂ©grier --- docs/maps/api-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/maps/api-reference.md b/docs/maps/api-reference.md index 49bc9dac..e5fc2c48 100644 --- a/docs/maps/api-reference.md +++ b/docs/maps/api-reference.md @@ -194,7 +194,7 @@ openCoWebSite(url : string, allowApi: boolean = false, allowPolicy: string = "") closeCoWebSite(): void ``` -Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allow the webpage to use the "IFrame API" and execute script. `allowPolicy` grant additional access rights to the webpage. +Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allows the webpage to use the "IFrame API" and execute script (it is equivalent to putting the `openWebsiteAllowApi` property in the map). `allowPolicy` grants additional access rights to the iFrame. The `allowPolicy` parameter is turned into an [`allow` feature policy in the iFrame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow). Example: From 06920a227121597e9bef3bc033827e01ce0b0b16 Mon Sep 17 00:00:00 2001 From: GRL Date: Mon, 28 Jun 2021 16:13:38 +0200 Subject: [PATCH 05/16] Use dynamic Iframe API --- maps/tests/Metadata/cowebsiteAllowApi.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/maps/tests/Metadata/cowebsiteAllowApi.html b/maps/tests/Metadata/cowebsiteAllowApi.html index 0076b9e4..ded7193e 100644 --- a/maps/tests/Metadata/cowebsiteAllowApi.html +++ b/maps/tests/Metadata/cowebsiteAllowApi.html @@ -1,9 +1,12 @@ - From 389ca25b6a85428720d69bd2400244ee92810493 Mon Sep 17 00:00:00 2001 From: GRL Date: Mon, 28 Jun 2021 18:00:48 +0200 Subject: [PATCH 06/16] Cowebsite opened by script can use Iframe Api --- docs/maps/api-nav.md | 4 +- front/src/Api/Events/OpenCoWebSiteEvent.ts | 2 + front/src/Api/IframeListener.ts | 14 +++- front/src/Api/ScriptUtils.ts | 4 +- front/src/Api/iframe/nav.ts | 6 +- front/src/iframe_api.ts | 4 +- maps/tests/Metadata/cowebsiteAllowApi.html | 17 ++++ maps/tests/Metadata/cowebsiteAllowApi.js | 1 + maps/tests/Metadata/cowebsiteAllowApi.json | 98 ++++++++++++++++++++++ maps/tests/index.html | 8 ++ 10 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 maps/tests/Metadata/cowebsiteAllowApi.html create mode 100644 maps/tests/Metadata/cowebsiteAllowApi.js create mode 100644 maps/tests/Metadata/cowebsiteAllowApi.json diff --git a/docs/maps/api-nav.md b/docs/maps/api-nav.md index 29323632..2abc5aff 100644 --- a/docs/maps/api-nav.md +++ b/docs/maps/api-nav.md @@ -52,11 +52,11 @@ WA.nav.goToRoom("/_/global/.json#start-layer-2") ### Opening/closing a web page in an iFrame ``` -WA.nav.openCoWebSite(url: string): void +WA.nav.openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = ""): void WA.nav.closeCoWebSite(): void ``` -Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. +Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` parameter allow the iframe to use the "IFrame API" and communicate with WorkAdventure. `allowPolicy` parameter grant additional rights to the iframe. Example: diff --git a/front/src/Api/Events/OpenCoWebSiteEvent.ts b/front/src/Api/Events/OpenCoWebSiteEvent.ts index 0fbc0ce2..d2937405 100644 --- a/front/src/Api/Events/OpenCoWebSiteEvent.ts +++ b/front/src/Api/Events/OpenCoWebSiteEvent.ts @@ -5,6 +5,8 @@ import * as tg from "generic-type-guard"; export const isOpenCoWebsite = new tg.IsInterface().withProperties({ url: tg.isString, + allowApi: tg.isBoolean, + allowPolicy: tg.isString, }).get(); /** diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 0adaac85..1c2adfdb 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -135,6 +135,8 @@ class IframeListener { return; } + foundSrc = this.getBaseUrl(foundSrc, message.source); + if (isIframeEventWrapper(payload)) { if (payload.type === 'showLayer' && isLayerEvent(payload.data)) { this._showLayerStream.next(payload.data); @@ -168,7 +170,8 @@ class IframeListener { this._loadSoundStream.next(payload.data); } else if (payload.type === 'openCoWebSite' && isOpenCoWebsite(payload.data)) { - scriptUtils.openCoWebsite(payload.data.url, foundSrc); + console.log(foundSrc); + scriptUtils.openCoWebsite(payload.data.url, foundSrc, payload.data.allowApi, payload.data.allowPolicy); } else if (payload.type === 'closeCoWebSite') { @@ -281,6 +284,15 @@ class IframeListener { } + private getBaseUrl(src: string, source: MessageEventSource | null): string{ + for (const script of this.scripts) { + if (script[1].contentWindow === source) { + return script[0]; + } + } + return src; + } + private static getIFrameId(scriptUrl: string): string { return 'script' + btoa(scriptUrl); } diff --git a/front/src/Api/ScriptUtils.ts b/front/src/Api/ScriptUtils.ts index e1c94507..75a18dc0 100644 --- a/front/src/Api/ScriptUtils.ts +++ b/front/src/Api/ScriptUtils.ts @@ -11,8 +11,8 @@ class ScriptUtils { } - public openCoWebsite(url: string, base: string) { - coWebsiteManager.loadCoWebsite(url, base); + public openCoWebsite(url: string, base: string, api: boolean, policy: string) { + coWebsiteManager.loadCoWebsite(url, base, api, policy); } public closeCoWebSite(){ diff --git a/front/src/Api/iframe/nav.ts b/front/src/Api/iframe/nav.ts index 0d31c1ea..7c7d38b4 100644 --- a/front/src/Api/iframe/nav.ts +++ b/front/src/Api/iframe/nav.ts @@ -36,11 +36,13 @@ class WorkadventureNavigationCommands extends IframeApiContribution + + + + + + + \ No newline at end of file diff --git a/maps/tests/Metadata/cowebsiteAllowApi.js b/maps/tests/Metadata/cowebsiteAllowApi.js new file mode 100644 index 00000000..4dac8ed2 --- /dev/null +++ b/maps/tests/Metadata/cowebsiteAllowApi.js @@ -0,0 +1 @@ +WA.nav.openCoWebSite("cowebsiteAllowApi.html", true, ""); \ No newline at end of file diff --git a/maps/tests/Metadata/cowebsiteAllowApi.json b/maps/tests/Metadata/cowebsiteAllowApi.json new file mode 100644 index 00000000..55ed615f --- /dev/null +++ b/maps/tests/Metadata/cowebsiteAllowApi.json @@ -0,0 +1,98 @@ +{ "compressionlevel":-1, + "height":10, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":2, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "data":[33, 34, 34, 34, 34, 34, 34, 34, 34, 35, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, 49, 50, 50, 50, 50, 50, 50, 50, 50, 51], + "height":10, + "id":1, + "name":"bottom", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":3, + "name":"floorLayer", + "objects":[ + { + "height":116.5, + "id":1, + "name":"", + "rotation":0, + "text": + { + "text":"Test : \nThe iframe is opened by script.\n\nResult : \nA message is send to the chat.", + "wrap":true + }, + "type":"", + "visible":true, + "width":295.875, + "x":11.8125, + "y":188.5 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 16, 16, 16, 0, 0, 16, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 16, 16, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":10, + "id":4, + "name":"mushroom", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":10, + "x":0, + "y":0 + }], + "nextlayerid":5, + "nextobjectid":2, + "orientation":"orthogonal", + "properties":[ + { + "name":"script", + "type":"string", + "value":"cowebsiteAllowApi.js" + }], + "renderorder":"right-down", + "tiledversion":"1.4.3", + "tileheight":32, + "tilesets":[ + { + "columns":8, + "firstgid":1, + "image":"tileset_dungeon.png", + "imageheight":256, + "imagewidth":256, + "margin":0, + "name":"tileset_dungeon", + "spacing":0, + "tilecount":64, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":1.4, + "width":10 +} \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 1f5f2a0e..93e4fd58 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -162,6 +162,14 @@ Test animated tiles + + + Success Failure Pending + + + Test cowebsite opened by script is allowed to use IFrame API + + \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 9c95c281..b7e88925 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -90,6 +90,14 @@ Test the HelpCameraSettingScene + + + Success Failure Pending + + + Test a iframe opened by a script can use Iframe API + + +

Website opened by script.

- \ No newline at end of file + diff --git a/maps/tests/Metadata/cowebsiteAllowApi.js b/maps/tests/Metadata/cowebsiteAllowApi.js index 4dac8ed2..56c7b767 100644 --- a/maps/tests/Metadata/cowebsiteAllowApi.js +++ b/maps/tests/Metadata/cowebsiteAllowApi.js @@ -1 +1 @@ -WA.nav.openCoWebSite("cowebsiteAllowApi.html", true, ""); \ No newline at end of file +WA.nav.openCoWebSite("cowebsiteAllowApi.html", true, ""); diff --git a/maps/tests/index.html b/maps/tests/index.html index 93e4fd58..bf1a056f 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -106,6 +106,14 @@ Test the HelpCameraSettingScene + + + Success Failure Pending + + + Test a iframe opened by a script can use Iframe API + + Success Failure Pending diff --git a/yarn.lock b/yarn.lock index 166b84c7..b9698f61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,6 @@ # yarn lockfile v1 -husky@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" +"husky@^6.0.0": + "resolved" "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz" + "version" "6.0.0" From bfcdd31ed2a3e54175640d1be95dfdf57dc2132b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 30 Jun 2021 10:15:55 +0200 Subject: [PATCH 15/16] Fixing NPM package generation The generation was broken due to the refactoring in several classes (some of them where not properly exported). Also, trying to generate the NPM package on every build now (to detect issues). --- .github/workflows/push-to-npm.yml | 5 ++ front/package.json | 2 +- front/src/Api/iframe/chat.ts | 40 ++++++------ front/src/Api/iframe/controls.ts | 11 ++-- front/src/Api/iframe/nav.ts | 51 +++++++-------- front/src/Api/iframe/player.ts | 26 ++++---- front/src/Api/iframe/room.ts | 2 +- front/src/Api/iframe/sound.ts | 16 ++--- front/src/Api/iframe/ui.ts | 104 +++++++++++++++--------------- 9 files changed, 129 insertions(+), 128 deletions(-) diff --git a/.github/workflows/push-to-npm.yml b/.github/workflows/push-to-npm.yml index 3b90e846..fd247b11 100644 --- a/.github/workflows/push-to-npm.yml +++ b/.github/workflows/push-to-npm.yml @@ -2,6 +2,7 @@ name: Push @workadventure/iframe-api-typings to NPM on: release: types: [created] + push: jobs: build: runs-on: ubuntu-latest @@ -52,6 +53,9 @@ jobs: - name: Copy typings to package dir run: cp front/dist/src/iframe_api.d.ts front/packages/iframe-api-typings/iframe_api.d.ts + - name: Copy typings to package dir (2) + run: cp -R front/dist/src/Api front/packages/iframe-api-typings/Api + - name: Install dependencies in package run: yarn install working-directory: "front/packages/iframe-api-typings" @@ -61,3 +65,4 @@ jobs: working-directory: "front/packages/iframe-api-typings" env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + if: ${{ github.event_name == 'release' }} diff --git a/front/package.json b/front/package.json index 20c6b073..0e0439ed 100644 --- a/front/package.json +++ b/front/package.json @@ -60,7 +60,7 @@ "templater": "cross-env ./templater.sh", "serve": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" webpack serve --open", "build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production webpack", - "build-typings": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production NODE_ENV=production BUILD_TYPINGS=1 webpack", + "build-typings": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production BUILD_TYPINGS=1 webpack", "test": "TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json", "lint": "node_modules/.bin/eslint src/ . --ext .ts", "fix": "node_modules/.bin/eslint --fix src/ . --ext .ts", diff --git a/front/src/Api/iframe/chat.ts b/front/src/Api/iframe/chat.ts index 7d8e6f71..5797df5a 100644 --- a/front/src/Api/iframe/chat.ts +++ b/front/src/Api/iframe/chat.ts @@ -1,30 +1,30 @@ -import type { ChatEvent } from '../Events/ChatEvent' -import { isUserInputChatEvent, UserInputChatEvent } from '../Events/UserInputChatEvent' -import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution' +import type { ChatEvent } from "../Events/ChatEvent"; +import { isUserInputChatEvent, UserInputChatEvent } from "../Events/UserInputChatEvent"; +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; import { apiCallback } from "./registeredCallbacks"; -import {Subject} from "rxjs"; +import { Subject } from "rxjs"; const chatStream = new Subject(); -class WorkadventureChatCommands extends IframeApiContribution { - - callbacks = [apiCallback({ - callback: (event: UserInputChatEvent) => { - chatStream.next(event.message); - }, - type: "userInputChat", - typeChecker: isUserInputChatEvent - })] - +export class WorkadventureChatCommands extends IframeApiContribution { + callbacks = [ + apiCallback({ + callback: (event: UserInputChatEvent) => { + chatStream.next(event.message); + }, + type: "userInputChat", + typeChecker: isUserInputChatEvent, + }), + ]; sendChatMessage(message: string, author: string) { sendToWorkadventure({ - type: 'chat', + type: "chat", data: { - 'message': message, - 'author': author - } - }) + message: message, + author: author, + }, + }); } /** @@ -35,4 +35,4 @@ class WorkadventureChatCommands extends IframeApiContribution { - callbacks = [] +export class WorkadventureControlsCommands extends IframeApiContribution { + callbacks = []; disablePlayerControls(): void { - sendToWorkadventure({ 'type': 'disablePlayerControls', data: null }); + sendToWorkadventure({ type: "disablePlayerControls", data: null }); } restorePlayerControls(): void { - sendToWorkadventure({ 'type': 'restorePlayerControls', data: null }); + sendToWorkadventure({ type: "restorePlayerControls", data: null }); } } - export default new WorkadventureControlsCommands(); diff --git a/front/src/Api/iframe/nav.ts b/front/src/Api/iframe/nav.ts index 7c7d38b4..f051a7c0 100644 --- a/front/src/Api/iframe/nav.ts +++ b/front/src/Api/iframe/nav.ts @@ -1,59 +1,56 @@ -import type { GoToPageEvent } from '../Events/GoToPageEvent'; -import type { OpenTabEvent } from '../Events/OpenTabEvent'; -import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution'; -import type {OpenCoWebSiteEvent} from "../Events/OpenCoWebSiteEvent"; -import type {LoadPageEvent} from "../Events/LoadPageEvent"; - - -class WorkadventureNavigationCommands extends IframeApiContribution { - callbacks = [] +import type { GoToPageEvent } from "../Events/GoToPageEvent"; +import type { OpenTabEvent } from "../Events/OpenTabEvent"; +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; +import type { OpenCoWebSiteEvent } from "../Events/OpenCoWebSiteEvent"; +import type { LoadPageEvent } from "../Events/LoadPageEvent"; +export class WorkadventureNavigationCommands extends IframeApiContribution { + callbacks = []; openTab(url: string): void { sendToWorkadventure({ - "type": 'openTab', - "data": { - url - } + type: "openTab", + data: { + url, + }, }); } goToPage(url: string): void { sendToWorkadventure({ - "type": 'goToPage', - "data": { - url - } + type: "goToPage", + data: { + url, + }, }); } goToRoom(url: string): void { sendToWorkadventure({ - "type": 'loadPage', - "data": { - url - } + type: "loadPage", + data: { + url, + }, }); } openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = ""): void { sendToWorkadventure({ - "type": 'openCoWebSite', - "data": { + type: "openCoWebSite", + data: { url, allowApi, allowPolicy, - } + }, }); } closeCoWebSite(): void { sendToWorkadventure({ - "type": 'closeCoWebSite', - data: null + type: "closeCoWebSite", + data: null, }); } } - export default new WorkadventureNavigationCommands(); diff --git a/front/src/Api/iframe/player.ts b/front/src/Api/iframe/player.ts index 67c012f7..e130d3f2 100644 --- a/front/src/Api/iframe/player.ts +++ b/front/src/Api/iframe/player.ts @@ -1,29 +1,29 @@ -import {IframeApiContribution, sendToWorkadventure} from "./IframeApiContribution"; -import type {HasPlayerMovedEvent, HasPlayerMovedEventCallback} from "../Events/HasPlayerMovedEvent"; -import {Subject} from "rxjs"; -import {apiCallback} from "./registeredCallbacks"; -import {isHasPlayerMovedEvent} from "../Events/HasPlayerMovedEvent"; +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; +import type { HasPlayerMovedEvent, HasPlayerMovedEventCallback } from "../Events/HasPlayerMovedEvent"; +import { Subject } from "rxjs"; +import { apiCallback } from "./registeredCallbacks"; +import { isHasPlayerMovedEvent } from "../Events/HasPlayerMovedEvent"; const moveStream = new Subject(); -class WorkadventurePlayerCommands extends IframeApiContribution { +export class WorkadventurePlayerCommands extends IframeApiContribution { callbacks = [ apiCallback({ - type: 'hasPlayerMoved', + type: "hasPlayerMoved", typeChecker: isHasPlayerMovedEvent, callback: (payloadData) => { moveStream.next(payloadData); - } + }, }), - ] + ]; onPlayerMove(callback: HasPlayerMovedEventCallback): void { moveStream.subscribe(callback); sendToWorkadventure({ - type: 'onPlayerMove', - data: null - }) + type: "onPlayerMove", + data: null, + }); } } -export default new WorkadventurePlayerCommands(); \ No newline at end of file +export default new WorkadventurePlayerCommands(); diff --git a/front/src/Api/iframe/room.ts b/front/src/Api/iframe/room.ts index 817141f4..e6b64db1 100644 --- a/front/src/Api/iframe/room.ts +++ b/front/src/Api/iframe/room.ts @@ -48,7 +48,7 @@ function getDataLayer(): Promise { }); } -class WorkadventureRoomCommands extends IframeApiContribution { +export class WorkadventureRoomCommands extends IframeApiContribution { callbacks = [ apiCallback({ callback: (payloadData: EnterLeaveEvent) => { diff --git a/front/src/Api/iframe/sound.ts b/front/src/Api/iframe/sound.ts index 70430b46..1e5d6157 100644 --- a/front/src/Api/iframe/sound.ts +++ b/front/src/Api/iframe/sound.ts @@ -1,17 +1,15 @@ -import type { LoadSoundEvent } from '../Events/LoadSoundEvent'; -import type { PlaySoundEvent } from '../Events/PlaySoundEvent'; -import type { StopSoundEvent } from '../Events/StopSoundEvent'; -import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution'; -import {Sound} from "./Sound/Sound"; +import type { LoadSoundEvent } from "../Events/LoadSoundEvent"; +import type { PlaySoundEvent } from "../Events/PlaySoundEvent"; +import type { StopSoundEvent } from "../Events/StopSoundEvent"; +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; +import { Sound } from "./Sound/Sound"; -class WorkadventureSoundCommands extends IframeApiContribution { - callbacks = [] +export class WorkadventureSoundCommands extends IframeApiContribution { + callbacks = []; loadSound(url: string): Sound { return new Sound(url); } - } - export default new WorkadventureSoundCommands(); diff --git a/front/src/Api/iframe/ui.ts b/front/src/Api/iframe/ui.ts index c7655b84..61c7076e 100644 --- a/front/src/Api/iframe/ui.ts +++ b/front/src/Api/iframe/ui.ts @@ -1,53 +1,55 @@ -import { isButtonClickedEvent } from '../Events/ButtonClickedEvent'; -import { isMenuItemClickedEvent } from '../Events/ui/MenuItemClickedEvent'; -import type { MenuItemRegisterEvent } from '../Events/ui/MenuItemRegisterEvent'; -import { IframeApiContribution, sendToWorkadventure } from './IframeApiContribution'; +import { isButtonClickedEvent } from "../Events/ButtonClickedEvent"; +import { isMenuItemClickedEvent } from "../Events/ui/MenuItemClickedEvent"; +import type { MenuItemRegisterEvent } from "../Events/ui/MenuItemRegisterEvent"; +import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution"; import { apiCallback } from "./registeredCallbacks"; import type { ButtonClickedCallback, ButtonDescriptor } from "./Ui/ButtonDescriptor"; import { Popup } from "./Ui/Popup"; let popupId = 0; const popups: Map = new Map(); -const popupCallbacks: Map> = new Map>(); +const popupCallbacks: Map> = new Map< + number, + Map +>(); -const menuCallbacks: Map void> = new Map() +const menuCallbacks: Map void> = new Map(); interface ZonedPopupOptions { - zone: string - objectLayerName?: string, - popupText: string, - delay?: number - popupOptions: Array + zone: string; + objectLayerName?: string; + popupText: string; + delay?: number; + popupOptions: Array; } - -class WorkAdventureUiCommands extends IframeApiContribution { - - 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); - } - } - }), - apiCallback({ - type: "menuItemClicked", - typeChecker: isMenuItemClickedEvent, - callback: event => { - const callback = menuCallbacks.get(event.menuItem); - if (callback) { - callback(event.menuItem) - } - } - })]; - +export class WorkAdventureUiCommands extends IframeApiContribution { + 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); + } + }, + }), + apiCallback({ + type: "menuItemClicked", + typeChecker: isMenuItemClickedEvent, + callback: (event) => { + const callback = menuCallbacks.get(event.menuItem); + if (callback) { + callback(event.menuItem); + } + }, + }), + ]; openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup { popupId++; @@ -66,40 +68,40 @@ class WorkAdventureUiCommands extends IframeApiContribution { return { label: button.label, - className: button.className + className: button.className, }; - }) - } + }), + }, }); - popups.set(popupId, popup) + popups.set(popupId, popup); return popup; } registerMenuCommand(commandDescriptor: string, callback: (commandDescriptor: string) => void) { menuCallbacks.set(commandDescriptor, callback); sendToWorkadventure({ - 'type': 'registerMenuCommand', - 'data': { - menutItem: commandDescriptor - } + type: "registerMenuCommand", + data: { + menutItem: commandDescriptor, + }, }); } displayBubble(): void { - sendToWorkadventure({ 'type': 'displayBubble', data: null }); + sendToWorkadventure({ type: "displayBubble", data: null }); } removeBubble(): void { - sendToWorkadventure({ 'type': 'removeBubble', data: null }); + sendToWorkadventure({ type: "removeBubble", data: null }); } } From 50fcc1caaab973e7306c3fd4623b9f11be5d0a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Wed, 30 Jun 2021 10:40:53 +0200 Subject: [PATCH 16/16] Fixing signature of openCoWebSite --- front/src/iframe_api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/src/iframe_api.ts b/front/src/iframe_api.ts index 0264d0a6..9fa204b9 100644 --- a/front/src/iframe_api.ts +++ b/front/src/iframe_api.ts @@ -22,7 +22,7 @@ interface WorkAdventureApi { openPopup(targetObject: string, message: string, buttons: ButtonDescriptor[]): Popup; openTab(url : string): void; goToPage(url : string): void; - openCoWebSite(url : string, allowApi: boolean, allowPolicy: string): void; + openCoWebSite(url : string, allowApi?: boolean, allowPolicy?: string): void; closeCoWebSite(): void; disablePlayerControls(): void; restorePlayerControls(): void;