Adding support for custom logos

The admin can now set custom logos for the login scene and for the loading screen.
This commit is contained in:
David Négrier 2022-03-15 15:50:25 +01:00
parent 79db6c8f3b
commit 53b184e82b
6 changed files with 48 additions and 13 deletions

View File

@ -13,6 +13,8 @@
let name = gameManager.getPlayerName() || ""; let name = gameManager.getPlayerName() || "";
let startValidating = false; let startValidating = false;
let logo = gameManager.currentStartedRoom.loginSceneLogo ?? logoImg;
function submit() { function submit() {
startValidating = true; startValidating = true;
@ -25,7 +27,7 @@
<form class="loginScene" on:submit|preventDefault={submit}> <form class="loginScene" on:submit|preventDefault={submit}>
<section class="text-center"> <section class="text-center">
<img src={logoImg} alt="WorkAdventure logo" /> <img src={logo} alt="" />
</section> </section>
<section class="text-center"> <section class="text-center">
<h2>{$LL.login.input.name.placeholder()}</h2> <h2>{$LL.login.input.name.placeholder()}</h2>

View File

@ -31,6 +31,8 @@ export class Room {
private _group: string | null = null; private _group: string | null = null;
private _expireOn: Date | undefined; private _expireOn: Date | undefined;
private _canReport: boolean = false; private _canReport: boolean = false;
private _loadingLogo: string | undefined;
private _loginSceneLogo: string | undefined;
private constructor(private roomUrl: URL) { private constructor(private roomUrl: URL) {
this.id = roomUrl.pathname; this.id = roomUrl.pathname;
@ -126,6 +128,8 @@ export class Room {
this._expireOn = new Date(data.expireOn); this._expireOn = new Date(data.expireOn);
} }
this._canReport = data.canReport ?? false; this._canReport = data.canReport ?? false;
this._loadingLogo = data.loadingLogo ?? undefined;
this._loginSceneLogo = data.loginSceneLogo ?? undefined;
return new MapDetail(data.mapUrl); return new MapDetail(data.mapUrl);
} else { } else {
throw new Error("Data received by the /map endpoint of the Pusher is not in a valid format."); throw new Error("Data received by the /map endpoint of the Pusher is not in a valid format.");
@ -233,4 +237,12 @@ export class Room {
get canReport(): boolean { get canReport(): boolean {
return this._canReport; return this._canReport;
} }
get loadingLogo(): string | undefined {
return this._loadingLogo;
}
get loginSceneLogo(): string | undefined {
return this._loginSceneLogo;
}
} }

View File

@ -1,9 +1,8 @@
import ImageFrameConfig = Phaser.Types.Loader.FileTypes.ImageFrameConfig; import ImageFrameConfig = Phaser.Types.Loader.FileTypes.ImageFrameConfig;
import { DirtyScene } from "../Game/DirtyScene"; import { DirtyScene } from "../Game/DirtyScene";
import { gameManager } from "../Game/GameManager";
const LogoNameIndex: string = "logoLoading";
const TextName: string = "Loading..."; const TextName: string = "Loading...";
const LogoResource: string = "static/images/logo.png";
const LogoFrame: ImageFrameConfig = { frameWidth: 310, frameHeight: 60 }; const LogoFrame: ImageFrameConfig = { frameWidth: 310, frameHeight: 60 };
const loadingBarHeight: number = 16; const loadingBarHeight: number = 16;
@ -15,6 +14,7 @@ export class Loader {
private progressAmount: number = 0; private progressAmount: number = 0;
private logo: Phaser.GameObjects.Image | undefined; private logo: Phaser.GameObjects.Image | undefined;
private loadingText: Phaser.GameObjects.Text | null = null; private loadingText: Phaser.GameObjects.Text | null = null;
private logoNameIndex!: string;
public constructor(private scene: Phaser.Scene) {} public constructor(private scene: Phaser.Scene) {}
@ -24,15 +24,18 @@ export class Loader {
return; return;
} }
const logoResource = gameManager.currentStartedRoom.loadingLogo ?? "static/images/logo.png";
this.logoNameIndex = "logoLoading" + logoResource;
const loadingBarWidth: number = Math.floor(this.scene.game.renderer.width / 3); const loadingBarWidth: number = Math.floor(this.scene.game.renderer.width / 3);
const promiseLoadLogoTexture = new Promise<Phaser.GameObjects.Image>((res) => { const promiseLoadLogoTexture = new Promise<Phaser.GameObjects.Image>((res) => {
if (this.scene.load.textureManager.exists(LogoNameIndex)) { if (this.scene.load.textureManager.exists(this.logoNameIndex)) {
return res( return res(
(this.logo = this.scene.add.image( (this.logo = this.scene.add.image(
this.scene.game.renderer.width / 2, this.scene.game.renderer.width / 2,
this.scene.game.renderer.height / 2 - 150, this.scene.game.renderer.height / 2 - 150,
LogoNameIndex this.logoNameIndex
)) ))
); );
} else { } else {
@ -43,8 +46,8 @@ export class Loader {
TextName TextName
); );
} }
this.scene.load.spritesheet(LogoNameIndex, LogoResource, LogoFrame); this.scene.load.spritesheet(this.logoNameIndex, logoResource, LogoFrame);
this.scene.load.once(`filecomplete-spritesheet-${LogoNameIndex}`, () => { this.scene.load.once(`filecomplete-spritesheet-${this.logoNameIndex}`, () => {
if (this.loadingText) { if (this.loadingText) {
this.loadingText.destroy(); this.loadingText.destroy();
} }
@ -52,7 +55,7 @@ export class Loader {
(this.logo = this.scene.add.image( (this.logo = this.scene.add.image(
this.scene.game.renderer.width / 2, this.scene.game.renderer.width / 2,
this.scene.game.renderer.height / 2 - 150, this.scene.game.renderer.height / 2 - 150,
LogoNameIndex this.logoNameIndex
)) ))
); );
}); });
@ -86,8 +89,8 @@ export class Loader {
} }
public removeLoader(): void { public removeLoader(): void {
if (this.scene.load.textureManager.exists(LogoNameIndex)) { if (this.scene.load.textureManager.exists(this.logoNameIndex)) {
this.scene.load.textureManager.remove(LogoNameIndex); this.scene.load.textureManager.remove(this.logoNameIndex);
} }
} }

View File

@ -22,6 +22,10 @@ export const isMapDetailsData = new tg.IsInterface()
expireOn: tg.isString, expireOn: tg.isString,
// Whether the "report" feature is enabled or not on this room // Whether the "report" feature is enabled or not on this room
canReport: tg.isBoolean, canReport: tg.isBoolean,
// The URL of the logo image on the loading screen
loadingLogo: tg.isNullable(tg.isString),
// The URL of the logo image on "LoginScene"
loginSceneLogo: tg.isNullable(tg.isString),
}) })
.get(); .get();

View File

@ -88,6 +88,14 @@ export class MapController extends BaseHttpController {
* type: boolean|undefined * type: boolean|undefined
* description: Whether the "report" feature is enabled or not on this room * description: Whether the "report" feature is enabled or not on this room
* example: true * example: true
* loadingLogo:
* type: string
* description: The URL of the image to be used on the loading page
* example: https://example.com/logo.png
* loginSceneLogo:
* type: string
* description: The URL of the image to be used on the LoginScene
* example: https://example.com/logo_login.png
* *
*/ */
this.app.get("/map", (req, res) => { this.app.get("/map", (req, res) => {

View File

@ -1,7 +1,7 @@
import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable"; import { ADMIN_API_TOKEN, ADMIN_API_URL, ADMIN_URL, OPID_PROFILE_SCREEN_PROVIDER } from "../Enum/EnvironmentVariable";
import Axios, { AxiosResponse } from "axios"; import Axios, { AxiosResponse } from "axios";
import { MapDetailsData } from "../Messages/JsonMessages/MapDetailsData"; import { isMapDetailsData, MapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
import { RoomRedirect } from "../Messages/JsonMessages/RoomRedirect"; import { isRoomRedirect, RoomRedirect } from "../Messages/JsonMessages/RoomRedirect";
import { AdminApiData, isAdminApiData } from "../Messages/JsonMessages/AdminApiData"; import { AdminApiData, isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
import * as tg from "generic-type-guard"; import * as tg from "generic-type-guard";
import { isNumber } from "generic-type-guard"; import { isNumber } from "generic-type-guard";
@ -46,10 +46,16 @@ class AdminApi {
userId, userId,
}; };
const res = await Axios.get(ADMIN_API_URL + "/api/map", { const res = await Axios.get<unknown, AxiosResponse<unknown>>(ADMIN_API_URL + "/api/map", {
headers: { Authorization: `${ADMIN_API_TOKEN}` }, headers: { Authorization: `${ADMIN_API_TOKEN}` },
params, params,
}); });
if (!isMapDetailsData(res.data) && !isRoomRedirect(res.data)) {
throw new Error(
"Invalid answer received from the admin for the /api/map endpoint. Received: " +
JSON.stringify(res.data)
);
}
return res.data; return res.data;
} }