Merging master into develop

This commit is contained in:
David Négrier 2021-06-29 18:39:43 +02:00
parent 33ee190b0f
commit 8f3d9277ac
14 changed files with 876 additions and 672 deletions

View File

@ -13,10 +13,6 @@ jobs:
node-version: '14.x' node-version: '14.x'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
- name: Edit tsconfig.json to add declarations
run: "sed -i 's/\"declaration\": false/\"declaration\": true/g' tsconfig.json"
working-directory: "front"
- name: Replace version number - name: Replace version number
run: 'sed -i "s#VERSION_PLACEHOLDER#${GITHUB_REF/refs\/tags\//}#g" package.json' run: 'sed -i "s#VERSION_PLACEHOLDER#${GITHUB_REF/refs\/tags\//}#g" package.json'
working-directory: "front/packages/iframe-api-typings" working-directory: "front/packages/iframe-api-typings"
@ -47,9 +43,9 @@ jobs:
working-directory: "front" working-directory: "front"
- name: "Build" - name: "Build"
run: yarn run build run: yarn run build-typings
env: env:
API_URL: "localhost:8080" PUSHER_URL: "//localhost:8080"
working-directory: "front" working-directory: "front"
# We build the front to generate the typings of iframe_api, then we copy those typings in a separate package. # We build the front to generate the typings of iframe_api, then we copy those typings in a separate package.

View File

@ -16,6 +16,18 @@
- Use `WA.room.getCurrentRoom(): Promise<Room>` to get the ID, JSON map file, url of the map of the current room and the layer where the current player started - Use `WA.room.getCurrentRoom(): Promise<Room>` to get the ID, JSON map file, url of the map of the current room and the layer where the current player started
- Use `WA.ui.registerMenuCommand(): void` to add a custom menu - Use `WA.ui.registerMenuCommand(): void` to add a custom menu
## Version 1.4.3 - 1.4.4 - 1.4.5
## Bugfixes
- Fixing the generation of @workadventure/iframe-api-typings
## Version 1.4.2
## Updates
- A script in an iframe opened by another script can use the IFrame API.
## Version 1.4.1 ## Version 1.4.1
### Bugfixes ### Bugfixes

View File

@ -9,4 +9,4 @@
- [Sound functions](api-sound.md) - [Sound functions](api-sound.md)
- [Controls functions](api-controls.md) - [Controls functions](api-controls.md)
- [List of deprecated functions](api-deprecated.md) - [List of deprecated functions](api-deprecated.md)

View File

@ -60,6 +60,7 @@
"templater": "cross-env ./templater.sh", "templater": "cross-env ./templater.sh",
"serve": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" webpack serve --open", "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": "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",
"test": "TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json", "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", "lint": "node_modules/.bin/eslint src/ . --ext .ts",
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts", "fix": "node_modules/.bin/eslint --fix src/ . --ext .ts",

View File

@ -1,11 +1,11 @@
<script lang="typescript"> <script lang="typescript">
import type { Game } from "../../Phaser/Game/Game"; import type { Game } from "../../Phaser/Game/Game";
import {CustomizeScene, CustomizeSceneName} from "../../Phaser/Login/CustomizeScene"; import {CustomizeScene, CustomizeSceneName} from "../../Phaser/Login/CustomizeScene";
import {activeRowStore} from "../../Stores/CustomCharacterStore";
export let game: Game; export let game: Game;
const customCharacterScene = game.scene.getScene(CustomizeSceneName) as CustomizeScene; const customCharacterScene = game.scene.getScene(CustomizeSceneName) as CustomizeScene;
let activeRow = customCharacterScene.activeRow;
function selectLeft() { function selectLeft() {
customCharacterScene.moveCursorHorizontally(-1); customCharacterScene.moveCursorHorizontally(-1);
@ -17,12 +17,10 @@
function selectUp() { function selectUp() {
customCharacterScene.moveCursorVertically(-1); customCharacterScene.moveCursorVertically(-1);
activeRow = customCharacterScene.activeRow;
} }
function selectDown() { function selectDown() {
customCharacterScene.moveCursorVertically(1); customCharacterScene.moveCursorVertically(1);
activeRow = customCharacterScene.activeRow;
} }
function previousScene() { function previousScene() {
@ -44,16 +42,16 @@
<button class="customCharacterSceneButton customCharacterSceneButtonRight nes-btn" on:click|preventDefault={ selectRight }> &gt; </button> <button class="customCharacterSceneButton customCharacterSceneButtonRight nes-btn" on:click|preventDefault={ selectRight }> &gt; </button>
</section> </section>
<section class="action"> <section class="action">
{#if activeRow === 0} {#if $activeRowStore === 0}
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ previousScene }>Return</button> <button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ previousScene }>Return</button>
{/if} {/if}
{#if activeRow !== 0} {#if $activeRowStore !== 0}
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ selectUp }>Back <img src="resources/objects/arrow_up_black.png" alt=""/></button> <button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ selectUp }>Back <img src="resources/objects/arrow_up_black.png" alt=""/></button>
{/if} {/if}
{#if activeRow === 5} {#if $activeRowStore === 5}
<button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ finish }>Finish</button> <button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ finish }>Finish</button>
{/if} {/if}
{#if activeRow !== 5} {#if $activeRowStore !== 5}
<button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ selectDown }>Next <img src="resources/objects/arrow_down.png" alt=""/></button> <button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ selectDown }>Next <img src="resources/objects/arrow_down.png" alt=""/></button>
{/if} {/if}
</section> </section>

View File

@ -1,90 +1,124 @@
import LoaderPlugin = Phaser.Loader.LoaderPlugin; import LoaderPlugin = Phaser.Loader.LoaderPlugin;
import type {CharacterTexture} from "../../Connexion/LocalUser"; import type { CharacterTexture } from "../../Connexion/LocalUser";
import {BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES} from "./PlayerTextures"; import { BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES } from "./PlayerTextures";
export interface FrameConfig { export interface FrameConfig {
frameWidth: number, frameWidth: number;
frameHeight: number, frameHeight: number;
} }
export const loadAllLayers = (load: LoaderPlugin): BodyResourceDescriptionInterface[][] => { export const loadAllLayers = (load: LoaderPlugin): BodyResourceDescriptionInterface[][] => {
const returnArray:BodyResourceDescriptionInterface[][] = []; const returnArray: BodyResourceDescriptionInterface[][] = [];
LAYERS.forEach(layer => { LAYERS.forEach((layer) => {
const layerArray:BodyResourceDescriptionInterface[] = []; const layerArray: BodyResourceDescriptionInterface[] = [];
Object.values(layer).forEach((textureDescriptor) => { Object.values(layer).forEach((textureDescriptor) => {
layerArray.push(textureDescriptor); layerArray.push(textureDescriptor);
load.spritesheet(textureDescriptor.name,textureDescriptor.img,{frameWidth: 32, frameHeight: 32}); load.spritesheet(textureDescriptor.name, textureDescriptor.img, { frameWidth: 32, frameHeight: 32 });
}) });
returnArray.push(layerArray) returnArray.push(layerArray);
}); });
return returnArray; return returnArray;
} };
export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptionInterface[] => { export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptionInterface[] => {
const returnArray = Object.values(PLAYER_RESOURCES); const returnArray = Object.values(PLAYER_RESOURCES);
returnArray.forEach((playerResource: BodyResourceDescriptionInterface) => { returnArray.forEach((playerResource: BodyResourceDescriptionInterface) => {
load.spritesheet(playerResource.name, playerResource.img, {frameWidth: 32, frameHeight: 32}); load.spritesheet(playerResource.name, playerResource.img, { frameWidth: 32, frameHeight: 32 });
}); });
return returnArray; return returnArray;
} };
export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise<BodyResourceDescriptionInterface> => { export const loadCustomTexture = (
const name = 'customCharacterTexture'+texture.id; loaderPlugin: LoaderPlugin,
const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level} texture: CharacterTexture
): Promise<BodyResourceDescriptionInterface> => {
const name = "customCharacterTexture" + texture.id;
const playerResourceDescriptor: BodyResourceDescriptionInterface = { name, img: texture.url, level: texture.level };
return createLoadingPromise(loaderPlugin, playerResourceDescriptor, { return createLoadingPromise(loaderPlugin, playerResourceDescriptor, {
frameWidth: 32, frameWidth: 32,
frameHeight: 32 frameHeight: 32,
}); });
} };
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => { export const lazyLoadPlayerCharacterTextures = (
const promisesList:Promise<unknown>[] = []; loadPlugin: LoaderPlugin,
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => { texturekeys: Array<string | BodyResourceDescriptionInterface>
): Promise<string[]> => {
const promisesList: Promise<unknown>[] = [];
texturekeys.forEach((textureKey: string | BodyResourceDescriptionInterface) => {
try { try {
//TODO refactor //TODO refactor
const playerResourceDescriptor = getRessourceDescriptor(textureKey); const playerResourceDescriptor = getRessourceDescriptor(textureKey);
if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor, { promisesList.push(
frameWidth: 32, createLoadingPromise(loadPlugin, playerResourceDescriptor, {
frameHeight: 32 frameWidth: 32,
})); frameHeight: 32,
})
);
} }
}catch (err){ } catch (err) {
console.error(err); console.error(err);
} }
}); });
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>; let returnPromise: Promise<Array<string | BodyResourceDescriptionInterface>>;
if (promisesList.length > 0) { if (promisesList.length > 0) {
loadPlugin.start(); loadPlugin.start();
returnPromise = Promise.all(promisesList).then(() => texturekeys); returnPromise = Promise.all(promisesList).then(() => texturekeys);
} else { } else {
returnPromise = Promise.resolve(texturekeys); returnPromise = Promise.resolve(texturekeys);
} }
return returnPromise.then((keys) => keys.map((key) => {
return typeof key !== 'string' ? key.name : key;
}))
}
export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptionInterface): BodyResourceDescriptionInterface => { //If the loading fail, we render the default model instead.
if (typeof textureKey !== 'string' && textureKey.img) { 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 => {
if (typeof textureKey !== "string" && textureKey.img) {
return textureKey; return textureKey;
} }
const textureName:string = typeof textureKey === 'string' ? textureKey : textureKey.name; const textureName: string = typeof textureKey === "string" ? textureKey : textureKey.name;
const playerResource = PLAYER_RESOURCES[textureName]; const playerResource = PLAYER_RESOURCES[textureName];
if (playerResource !== undefined) return playerResource; if (playerResource !== undefined) return playerResource;
for (let i=0; i<LAYERS.length;i++) { for (let i = 0; i < LAYERS.length; i++) {
const playerResource = LAYERS[i][textureName]; const playerResource = LAYERS[i][textureName];
if (playerResource !== undefined) return playerResource; if (playerResource !== undefined) return playerResource;
} }
throw 'Could not find a data for texture '+textureName; throw "Could not find a data for texture " + textureName;
} };
export const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface, frameConfig: FrameConfig) => { export const createLoadingPromise = (
return new Promise<BodyResourceDescriptionInterface>((res) => { loadPlugin: LoaderPlugin,
playerResourceDescriptor: BodyResourceDescriptionInterface,
frameConfig: FrameConfig
) => {
return new Promise<BodyResourceDescriptionInterface>((res, rej) => {
console.log("count", loadPlugin.listenerCount("loaderror"));
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
return res(playerResourceDescriptor); return res(playerResourceDescriptor);
} }
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig); 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);
}); });
} };

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
import {EnableCameraSceneName} from "./EnableCameraScene"; import { EnableCameraSceneName } from "./EnableCameraScene";
import Rectangle = Phaser.GameObjects.Rectangle; import Rectangle = Phaser.GameObjects.Rectangle;
import {loadAllLayers} from "../Entity/PlayerTexturesLoadingManager"; import { loadAllLayers } from "../Entity/PlayerTexturesLoadingManager";
import Sprite = Phaser.GameObjects.Sprite; import Sprite = Phaser.GameObjects.Sprite;
import {gameManager} from "../Game/GameManager"; import { gameManager } from "../Game/GameManager";
import {localUserStore} from "../../Connexion/LocalUserStore"; import { localUserStore } from "../../Connexion/LocalUserStore";
import {addLoader} from "../Components/Loader"; import { addLoader } from "../Components/Loader";
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
import {AbstractCharacterScene} from "./AbstractCharacterScene"; import { AbstractCharacterScene } from "./AbstractCharacterScene";
import {areCharacterLayersValid} from "../../Connexion/LocalUser"; import { areCharacterLayersValid } from "../../Connexion/LocalUser";
import { SelectCharacterSceneName } from "./SelectCharacterScene"; import { SelectCharacterSceneName } from "./SelectCharacterScene";
import {customCharacterSceneVisibleStore} from "../../Stores/CustomCharacterStore"; import { activeRowStore, customCharacterSceneVisibleStore } from "../../Stores/CustomCharacterStore";
import {waScaleManager} from "../Services/WaScaleManager"; import { waScaleManager } from "../Services/WaScaleManager";
import {isMobile} from "../../Enum/EnvironmentVariable"; import { isMobile } from "../../Enum/EnvironmentVariable";
import {CustomizedCharacter} from "../Entity/CustomizedCharacter"; import { CustomizedCharacter } from "../Entity/CustomizedCharacter";
import { get } from "svelte/store";
export const CustomizeSceneName = "CustomizeScene"; export const CustomizeSceneName = "CustomizeScene";
@ -21,7 +22,6 @@ export class CustomizeScene extends AbstractCharacterScene {
private selectedLayers: number[] = [0]; private selectedLayers: number[] = [0];
private containersRow: CustomizedCharacter[][] = []; private containersRow: CustomizedCharacter[][] = [];
public activeRow:number = 0;
private layers: BodyResourceDescriptionInterface[][] = []; private layers: BodyResourceDescriptionInterface[][] = [];
protected lazyloadingAttempt = true; //permit to update texture loaded after renderer protected lazyloadingAttempt = true; //permit to update texture loaded after renderer
@ -31,16 +31,19 @@ export class CustomizeScene extends AbstractCharacterScene {
constructor() { constructor() {
super({ super({
key: CustomizeSceneName key: CustomizeSceneName,
}); });
} }
preload() { preload() {
this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => { this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => {
bodyResourceDescriptions.forEach((bodyResourceDescription) => { bodyResourceDescriptions.forEach((bodyResourceDescription) => {
if(bodyResourceDescription.level == undefined || bodyResourceDescription.level < 0 || bodyResourceDescription.level > 5 ){ if (
throw 'Texture level is null'; bodyResourceDescription.level == undefined ||
bodyResourceDescription.level < 0 ||
bodyResourceDescription.level > 5
) {
throw "Texture level is null";
} }
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription); this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
}); });
@ -50,14 +53,13 @@ export class CustomizeScene extends AbstractCharacterScene {
this.layers = loadAllLayers(this.load); this.layers = loadAllLayers(this.load);
this.lazyloadingAttempt = false; this.lazyloadingAttempt = false;
//this function must stay at the end of preload function //this function must stay at the end of preload function
addLoader(this); addLoader(this);
} }
create() { create() {
customCharacterSceneVisibleStore.set(true); customCharacterSceneVisibleStore.set(true);
this.events.addListener('wake', () => { this.events.addListener("wake", () => {
waScaleManager.saveZoom(); waScaleManager.saveZoom();
waScaleManager.zoomModifier = isMobile() ? 3 : 1; waScaleManager.zoomModifier = isMobile() ? 3 : 1;
customCharacterSceneVisibleStore.set(true); customCharacterSceneVisibleStore.set(true);
@ -66,8 +68,13 @@ export class CustomizeScene extends AbstractCharacterScene {
waScaleManager.saveZoom(); waScaleManager.saveZoom();
waScaleManager.zoomModifier = isMobile() ? 3 : 1; waScaleManager.zoomModifier = isMobile() ? 3 : 1;
this.Rectangle = this.add.rectangle(this.cameras.main.worldView.x + this.cameras.main.width / 2, this.cameras.main.worldView.y + this.cameras.main.height / 3, 32, 33) this.Rectangle = this.add.rectangle(
this.Rectangle.setStrokeStyle(2, 0xFFFFFF); this.cameras.main.worldView.x + this.cameras.main.width / 2,
this.cameras.main.worldView.y + this.cameras.main.height / 3,
32,
33
);
this.Rectangle.setStrokeStyle(2, 0xffffff);
this.add.existing(this.Rectangle); this.add.existing(this.Rectangle);
this.createCustomizeLayer(0, 0, 0); this.createCustomizeLayer(0, 0, 0);
@ -78,24 +85,24 @@ export class CustomizeScene extends AbstractCharacterScene {
this.createCustomizeLayer(0, 0, 5); this.createCustomizeLayer(0, 0, 5);
this.moveLayers(); this.moveLayers();
this.input.keyboard.on('keyup-ENTER', () => { this.input.keyboard.on("keyup-ENTER", () => {
this.nextSceneToCamera(); this.nextSceneToCamera();
}); });
this.input.keyboard.on('keyup-BACKSPACE', () => { this.input.keyboard.on("keyup-BACKSPACE", () => {
this.backToPreviousScene(); this.backToPreviousScene();
}); });
// Note: the key bindings are not directly put on the moveCursorVertically or moveCursorHorizontally methods // Note: the key bindings are not directly put on the moveCursorVertically or moveCursorHorizontally methods
// because if 2 such events are fired close to one another, it makes the whole application crawl to a halt (for a reason I cannot // because if 2 such events are fired close to one another, it makes the whole application crawl to a halt (for a reason I cannot
// explain, the list of sprites managed by the update list become immense // explain, the list of sprites managed by the update list become immense
this.input.keyboard.on('keyup-RIGHT', () => this.moveHorizontally = 1); this.input.keyboard.on("keyup-RIGHT", () => (this.moveHorizontally = 1));
this.input.keyboard.on('keyup-LEFT', () => this.moveHorizontally = -1); this.input.keyboard.on("keyup-LEFT", () => (this.moveHorizontally = -1));
this.input.keyboard.on('keyup-DOWN', () => this.moveVertically = 1); this.input.keyboard.on("keyup-DOWN", () => (this.moveVertically = 1));
this.input.keyboard.on('keyup-UP', () => this.moveVertically = -1); this.input.keyboard.on("keyup-UP", () => (this.moveVertically = -1));
const customCursorPosition = localUserStore.getCustomCursorPosition(); const customCursorPosition = localUserStore.getCustomCursorPosition();
if (customCursorPosition) { if (customCursorPosition) {
this.activeRow = customCursorPosition.activeRow; activeRowStore.set(customCursorPosition.activeRow);
this.selectedLayers = customCursorPosition.selectedLayers; this.selectedLayers = customCursorPosition.selectedLayers;
this.moveLayers(); this.moveLayers();
this.updateSelectedLayer(); this.updateSelectedLayer();
@ -113,31 +120,30 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
private doMoveCursorHorizontally(index: number): void { private doMoveCursorHorizontally(index: number): void {
this.selectedLayers[this.activeRow] += index; this.selectedLayers[get(activeRowStore)] += index;
if (this.selectedLayers[this.activeRow] < 0) { if (this.selectedLayers[get(activeRowStore)] < 0) {
this.selectedLayers[this.activeRow] = 0 this.selectedLayers[get(activeRowStore)] = 0;
} else if(this.selectedLayers[this.activeRow] > this.layers[this.activeRow].length - 1) { } else if (this.selectedLayers[get(activeRowStore)] > this.layers[get(activeRowStore)].length - 1) {
this.selectedLayers[this.activeRow] = this.layers[this.activeRow].length - 1 this.selectedLayers[get(activeRowStore)] = this.layers[get(activeRowStore)].length - 1;
} }
this.moveLayers(); this.moveLayers();
this.updateSelectedLayer(); this.updateSelectedLayer();
this.saveInLocalStorage(); this.saveInLocalStorage();
} }
private doMoveCursorVertically(index:number): void { private doMoveCursorVertically(index: number): void {
activeRowStore.set(get(activeRowStore) + index);
this.activeRow += index; if (get(activeRowStore) < 0) {
if (this.activeRow < 0) { activeRowStore.set(0);
this.activeRow = 0 } else if (get(activeRowStore) > this.layers.length - 1) {
} else if (this.activeRow > this.layers.length - 1) { activeRowStore.set(this.layers.length - 1);
this.activeRow = this.layers.length - 1
} }
this.moveLayers(); this.moveLayers();
this.saveInLocalStorage(); this.saveInLocalStorage();
} }
private saveInLocalStorage() { private saveInLocalStorage() {
localUserStore.setCustomCursorPosition(this.activeRow, this.selectedLayers); localUserStore.setCustomCursorPosition(get(activeRowStore), this.selectedLayers);
} }
/** /**
@ -173,7 +179,7 @@ export class CustomizeScene extends AbstractCharacterScene {
* @param selectedItem, The number of the item select (0 for black body...) * @param selectedItem, The number of the item select (0 for black body...)
*/ */
private generateCharacter(x: number, y: number, layerNumber: number, selectedItem: number) { private generateCharacter(x: number, y: number, layerNumber: number, selectedItem: number) {
return new CustomizedCharacter(this, x, y, this.getContainerChildren(layerNumber,selectedItem)); return new CustomizedCharacter(this, x, y, this.getContainerChildren(layerNumber, selectedItem));
} }
private getContainerChildren(layerNumber: number, selectedItem: number): Array<string> { private getContainerChildren(layerNumber: number, selectedItem: number): Array<string> {
@ -188,7 +194,7 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
children.push(this.layers[j][layer].name); children.push(this.layers[j][layer].name);
} }
} }
return children; return children;
} }
@ -202,17 +208,16 @@ export class CustomizeScene extends AbstractCharacterScene {
const screenHeight = this.game.renderer.height; const screenHeight = this.game.renderer.height;
for (let i = 0; i < this.containersRow.length; i++) { for (let i = 0; i < this.containersRow.length; i++) {
for (let j = 0; j < this.containersRow[i].length; j++) { for (let j = 0; j < this.containersRow[i].length; j++) {
let selectedX = this.selectedLayers[i]; let selectedX = this.selectedLayers[i];
if (selectedX === undefined) { if (selectedX === undefined) {
selectedX = 0; selectedX = 0;
} }
this.containersRow[i][j].x = screenCenterX + (j - selectedX) * 40; this.containersRow[i][j].x = screenCenterX + (j - selectedX) * 40;
this.containersRow[i][j].y = screenCenterY + (i - this.activeRow) * 40; this.containersRow[i][j].y = screenCenterY + (i - get(activeRowStore)) * 40;
const alpha1 = Math.abs(selectedX - j)*47*2/screenWidth; const alpha1 = (Math.abs(selectedX - j) * 47 * 2) / screenWidth;
const alpha2 = Math.abs(this.activeRow - i)*49*2/screenHeight; const alpha2 = (Math.abs(get(activeRowStore) - i) * 49 * 2) / screenHeight;
this.containersRow[i][j].setAlpha((1 -alpha1)*(1 - alpha2)); this.containersRow[i][j].setAlpha((1 - alpha1) * (1 - alpha2));
} }
} }
} }
@ -228,8 +233,8 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
private updateSelectedLayer() { private updateSelectedLayer() {
for(let i = 0; i < this.containersRow.length; i++){ for (let i = 0; i < this.containersRow.length; i++) {
for(let j = 0; j < this.containersRow[i].length; j++){ for (let j = 0; j < this.containersRow[i].length; j++) {
const children = this.getContainerChildren(i, j); const children = this.getContainerChildren(i, j);
this.containersRow[i][j].updateSprites(children); this.containersRow[i][j].updateSprites(children);
} }
@ -237,8 +242,7 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
update(time: number, delta: number): void { update(time: number, delta: number): void {
if (this.lazyloadingAttempt) {
if(this.lazyloadingAttempt){
this.moveLayers(); this.moveLayers();
this.lazyloadingAttempt = false; this.lazyloadingAttempt = false;
} }
@ -253,38 +257,35 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
} }
public onResize(): void {
public onResize(): void {
this.moveLayers(); this.moveLayers();
this.Rectangle.x = this.cameras.main.worldView.x + this.cameras.main.width / 2; this.Rectangle.x = this.cameras.main.worldView.x + this.cameras.main.width / 2;
this.Rectangle.y = this.cameras.main.worldView.y + this.cameras.main.height / 3; this.Rectangle.y = this.cameras.main.worldView.y + this.cameras.main.height / 3;
}
public nextSceneToCamera(){
const layers: string[] = [];
let i = 0;
for (const layerItem of this.selectedLayers) {
if (layerItem !== undefined) {
layers.push(this.layers[i][layerItem].name);
}
i++;
}
if (!areCharacterLayersValid(layers)) {
return;
}
gameManager.setCharacterLayers(layers);
this.scene.sleep(CustomizeSceneName);
waScaleManager.restoreZoom();
this.events.removeListener('wake');
gameManager.tryResumingGame(this, EnableCameraSceneName);
customCharacterSceneVisibleStore.set(false);
} }
public backToPreviousScene(){ public nextSceneToCamera() {
const layers: string[] = [];
let i = 0;
for (const layerItem of this.selectedLayers) {
if (layerItem !== undefined) {
layers.push(this.layers[i][layerItem].name);
}
i++;
}
if (!areCharacterLayersValid(layers)) {
return;
}
gameManager.setCharacterLayers(layers);
this.scene.sleep(CustomizeSceneName);
waScaleManager.restoreZoom();
this.events.removeListener("wake");
gameManager.tryResumingGame(this, EnableCameraSceneName);
customCharacterSceneVisibleStore.set(false);
}
public backToPreviousScene() {
this.scene.sleep(CustomizeSceneName); this.scene.sleep(CustomizeSceneName);
waScaleManager.restoreZoom(); waScaleManager.restoreZoom();
this.scene.run(SelectCharacterSceneName); this.scene.run(SelectCharacterSceneName);

View File

@ -1,3 +1,5 @@
import { derived, writable, Writable } from "svelte/store"; import { derived, writable, Writable } from "svelte/store";
export const customCharacterSceneVisibleStore = writable(false); export const customCharacterSceneVisibleStore = writable(false);
export const activeRowStore = writable(0);

View File

@ -1,35 +1,37 @@
import type {Configuration} from "webpack"; import type { Configuration } from "webpack";
import type WebpackDevServer from "webpack-dev-server"; import type WebpackDevServer from "webpack-dev-server";
import path from 'path'; import path from "path";
import webpack from 'webpack'; import webpack from "webpack";
import HtmlWebpackPlugin from 'html-webpack-plugin'; import HtmlWebpackPlugin from "html-webpack-plugin";
import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import MiniCssExtractPlugin from "mini-css-extract-plugin";
import sveltePreprocess from 'svelte-preprocess'; import sveltePreprocess from "svelte-preprocess";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"; import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import NodePolyfillPlugin from 'node-polyfill-webpack-plugin'; import NodePolyfillPlugin from "node-polyfill-webpack-plugin";
import {DISPLAY_TERMS_OF_USE} from "./src/Enum/EnvironmentVariable"; import { DISPLAY_TERMS_OF_USE } from "./src/Enum/EnvironmentVariable";
const mode = process.env.NODE_ENV ?? 'development'; const mode = process.env.NODE_ENV ?? "development";
const isProduction = mode === 'production'; const buildNpmTypingsForApi = !!process.env.BUILD_TYPINGS;
const isProduction = mode === "production";
const isDevelopment = !isProduction; const isDevelopment = !isProduction;
const entries: { [key: string]: string } = {};
if (!buildNpmTypingsForApi) {
entries.main = "./src/index.ts";
}
entries.iframe_api = "./src/iframe_api.ts";
module.exports = { module.exports = {
entry: { entry: entries,
'main': './src/index.ts',
'iframe_api': './src/iframe_api.ts'
},
mode: mode, mode: mode,
devtool: isDevelopment ? 'inline-source-map' : 'source-map', devtool: isDevelopment ? "inline-source-map" : "source-map",
devServer: { devServer: {
contentBase: './dist', contentBase: "./dist",
host: '0.0.0.0', host: "0.0.0.0",
sockPort: 80, sockPort: 80,
disableHostCheck: true, disableHostCheck: true,
historyApiFallback: { historyApiFallback: {
rewrites: [ rewrites: [{ from: /^_\/.*$/, to: "/index.html" }],
{ from: /^_\/.*$/, to: '/index.html' } disableDotRule: true,
],
disableDotRule: true
}, },
}, },
module: { module: {
@ -38,22 +40,28 @@ module.exports = {
test: /\.tsx?$/, test: /\.tsx?$/,
//use: 'ts-loader', //use: 'ts-loader',
exclude: /node_modules/, exclude: /node_modules/,
loader: 'ts-loader', loader: "ts-loader",
options: { options: {
transpileOnly: true, transpileOnly: !buildNpmTypingsForApi,
compilerOptions: {
declaration: buildNpmTypingsForApi,
},
}, },
}, },
{ {
test: /\.scss$/, test: /\.scss$/,
exclude: /node_modules/, exclude: /node_modules/,
use: [ use: [
MiniCssExtractPlugin.loader, { MiniCssExtractPlugin.loader,
loader: 'css-loader', {
loader: "css-loader",
options: { options: {
//url: false, //url: false,
sourceMap: true sourceMap: true,
} },
}, 'sass-loader'], },
"sass-loader",
],
}, },
{ {
test: /\.css$/, test: /\.css$/,
@ -61,23 +69,23 @@ module.exports = {
use: [ use: [
MiniCssExtractPlugin.loader, MiniCssExtractPlugin.loader,
{ {
loader: 'css-loader', loader: "css-loader",
options: { options: {
//url: false, //url: false,
sourceMap: true sourceMap: true,
} },
} },
] ],
}, },
{ {
test: /\.(html|svelte)$/, test: /\.(html|svelte)$/,
exclude: /node_modules/, exclude: /node_modules/,
use: { use: {
loader: 'svelte-loader', loader: "svelte-loader",
options: { options: {
compilerOptions: { compilerOptions: {
// Dev mode must be enabled for HMR to work! // Dev mode must be enabled for HMR to work!
dev: isDevelopment dev: isDevelopment,
}, },
emitCss: isProduction, emitCss: isProduction,
hotReload: isDevelopment, hotReload: isDevelopment,
@ -90,18 +98,27 @@ module.exports = {
scss: true, scss: true,
sass: true, sass: true,
}), }),
onwarn: function (warning: { code: string }, handleWarning: (warning: { code: string }) => void) { onwarn: function (
warning: { code: string },
handleWarning: (warning: { code: string }) => void
) {
// See https://github.com/sveltejs/svelte/issues/4946#issuecomment-662168782 // See https://github.com/sveltejs/svelte/issues/4946#issuecomment-662168782
if (warning.code === 'a11y-no-onchange') { return } if (warning.code === "a11y-no-onchange") {
if (warning.code === 'a11y-autofocus') { return } return;
if (warning.code === 'a11y-media-has-caption') { return } }
if (warning.code === "a11y-autofocus") {
return;
}
if (warning.code === "a11y-media-has-caption") {
return;
}
// process as usual // process as usual
handleWarning(warning); handleWarning(warning);
} },
} },
} },
}, },
// Required to prevent errors from Svelte on Webpack 5+, omit on Webpack 4 // Required to prevent errors from Svelte on Webpack 5+, omit on Webpack 4
@ -109,86 +126,82 @@ module.exports = {
{ {
test: /node_modules\/svelte\/.*\.mjs$/, test: /node_modules\/svelte\/.*\.mjs$/,
resolve: { resolve: {
fullySpecified: false fullySpecified: false,
} },
}, },
{ {
test: /\.(eot|svg|png|gif|jpg)$/, test: /\.(eot|svg|png|gif|jpg)$/,
exclude: /node_modules/, exclude: /node_modules/,
type: 'asset' type: "asset",
}, },
{ {
test: /\.(woff(2)?|ttf)$/, test: /\.(woff(2)?|ttf)$/,
type: 'asset', type: "asset",
generator: { generator: {
filename: 'fonts/[name][ext]' filename: "fonts/[name][ext]",
} },
},
}
], ],
}, },
resolve: { resolve: {
alias: { alias: {
svelte: path.resolve('node_modules', 'svelte') svelte: path.resolve("node_modules", "svelte"),
}, },
extensions: [ '.tsx', '.ts', '.js', '.svelte' ], extensions: [".tsx", ".ts", ".js", ".svelte"],
mainFields: ['svelte', 'browser', 'module', 'main'] mainFields: ["svelte", "browser", "module", "main"],
}, },
output: { output: {
filename: (pathData) => { filename: (pathData) => {
// Add a content hash only for the main bundle. // Add a content hash only for the main bundle.
// We want the iframe_api.js file to keep its name as it will be referenced from outside iframes. // We want the iframe_api.js file to keep its name as it will be referenced from outside iframes.
return pathData.chunk?.name === 'main' ? 'js/[name].[contenthash].js': '[name].js'; return pathData.chunk?.name === "main" ? "js/[name].[contenthash].js" : "[name].js";
}, },
path: path.resolve(__dirname, 'dist'), path: path.resolve(__dirname, "dist"),
publicPath: '/' publicPath: "/",
}, },
plugins: [ plugins: [
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new ForkTsCheckerWebpackPlugin({ new ForkTsCheckerWebpackPlugin({
eslint: { eslint: {
files: './src/**/*.ts' files: "./src/**/*.ts",
} },
}),
new MiniCssExtractPlugin({ filename: "[name].[contenthash].css" }),
new HtmlWebpackPlugin({
template: "./dist/index.tmpl.html.tmp",
minify: {
collapseWhitespace: true,
keepClosingSlash: true,
removeComments: false,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
},
chunks: ["main"],
}), }),
new MiniCssExtractPlugin({filename: '[name].[contenthash].css'}),
new HtmlWebpackPlugin(
{
template: './dist/index.tmpl.html.tmp',
minify: {
collapseWhitespace: true,
keepClosingSlash: true,
removeComments: false,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
},
chunks: ['main']
}
),
new webpack.ProvidePlugin({ new webpack.ProvidePlugin({
Phaser: 'phaser' Phaser: "phaser",
}), }),
new NodePolyfillPlugin(), new NodePolyfillPlugin(),
new webpack.EnvironmentPlugin({ new webpack.EnvironmentPlugin({
'API_URL': null, API_URL: null,
'SKIP_RENDER_OPTIMIZATIONS': false, SKIP_RENDER_OPTIMIZATIONS: false,
'DISABLE_NOTIFICATIONS': false, DISABLE_NOTIFICATIONS: false,
'PUSHER_URL': undefined, PUSHER_URL: undefined,
'UPLOADER_URL': null, UPLOADER_URL: null,
'ADMIN_URL': null, ADMIN_URL: null,
'DEBUG_MODE': null, DEBUG_MODE: null,
'STUN_SERVER': null, STUN_SERVER: null,
'TURN_SERVER': null, TURN_SERVER: null,
'TURN_USER': null, TURN_USER: null,
'TURN_PASSWORD': null, TURN_PASSWORD: null,
'JITSI_URL': null, JITSI_URL: null,
'JITSI_PRIVATE_MODE': null, JITSI_PRIVATE_MODE: null,
'START_ROOM_URL': null, START_ROOM_URL: null,
'MAX_USERNAME_LENGTH': 8, MAX_USERNAME_LENGTH: 8,
'MAX_PER_GROUP': 4, MAX_PER_GROUP: 4,
'DISPLAY_TERMS_OF_USE': false, DISPLAY_TERMS_OF_USE: false,
}) }),
], ],
} as Configuration & WebpackDevServer.Configuration; } as Configuration & WebpackDevServer.Configuration;

View File

@ -13,5 +13,6 @@
</script> </script>
</head> </head>
<body> <body>
<p>Website opened by script.</p>
</body> </body>
</html> </html>

View File

@ -1 +1 @@
WA.nav.openCoWebSite("cowebsiteAllowApi.html", true, ""); WA.nav.openCoWebSite("cowebsiteAllowApi.html", true, "");

View File

@ -106,6 +106,14 @@
<a href="#" class="testLink" data-testmap="help_camera_setting.json" target="_blank">Test the HelpCameraSettingScene</a> <a href="#" class="testLink" data-testmap="help_camera_setting.json" target="_blank">Test the HelpCameraSettingScene</a>
</td> </td>
</tr> </tr>
<tr>
<td>
<input type="radio" name="test-cowebsite-allowAPI"> Success <input type="radio" name="test-cowebsite-allowAPI"> Failure <input type="radio" name="test-cowebsite-allowAPI" checked> Pending
</td>
<td>
<a href="#" class="testLink" data-testmap="Metadata/cowebsiteAllowApi.json" target="_blank">Test a iframe opened by a script can use Iframe API</a>
</td>
</tr>
<tr> <tr>
<td> <td>
<input type="radio" name="test-custom-menu"> Success <input type="radio" name="test-custom-menu"> Failure <input type="radio" name="test-custom-menu" checked> Pending <input type="radio" name="test-custom-menu"> Success <input type="radio" name="test-custom-menu"> Failure <input type="radio" name="test-custom-menu" checked> Pending

View File

@ -2,6 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
husky@^6.0.0: "husky@^6.0.0":
version "6.0.0" "resolved" "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz"
resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" "version" "6.0.0"