From b3d4230354501e5960489d70836d832ddfe6cdc4 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 26 Nov 2021 17:25:32 +0100 Subject: [PATCH 01/11] saving players avatar textures to the texturesManager --- front/src/Phaser/Entity/Character.ts | 16 ++++++++++-- front/src/Phaser/Game/GameScene.ts | 39 +++++++++++++++++++--------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 1211a52d..06ecf1fb 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -64,6 +64,7 @@ export abstract class Character extends Container { this.addTextures(textures, frame); this.invisible = false; this.playAnimation(direction, moving); + this.emit('textures-loaded'); }) .catch(() => { return lazyLoadPlayerCharacterTextures(scene.load, ["color_22", "eyes_23"]).then((textures) => { @@ -117,8 +118,15 @@ export abstract class Character extends Container { } } - private getOutlinePlugin(): OutlinePipelinePlugin | undefined { - return this.scene.plugins.get("rexOutlinePipeline") as unknown as OutlinePipelinePlugin | undefined; + public saveCharacterToTexture(saveAs: string): void { + const bounds = this.getBounds(); + const rt = this.scene.make.renderTexture({ x: 300, y: 300, width: bounds.width, height: bounds.height}, true); + for (const sprite of this.sprites.values()) { + rt.draw(sprite, sprite.displayWidth * 0.5, sprite.displayHeight * 0.5); + } + // P.H. NOTE: Change of avatar will update saved texture. We can then send it again to the backend + rt.saveTexture(saveAs); + rt.destroy(); } public addCompanion(name: string, texturePromise?: Promise): void { @@ -154,6 +162,10 @@ export abstract class Character extends Container { } } + private getOutlinePlugin(): OutlinePipelinePlugin | undefined { + return this.scene.plugins.get("rexOutlinePipeline") as unknown as OutlinePipelinePlugin | undefined; + } + private getPlayerAnimations(name: string): AnimationData[] { return [ { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index d9bb8186..9c8a2d2c 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1,7 +1,4 @@ import type { Subscription } from "rxjs"; -import { userMessageManager } from "../../Administration/UserMessageManager"; -import { iframeListener } from "../../Api/IframeListener"; -import { connectionManager } from "../../Connexion/ConnectionManager"; import type { GroupCreatedUpdatedMessageInterface, MessageUserJoined, @@ -12,14 +9,23 @@ import type { PositionInterface, RoomJoinedMessageInterface, } from "../../Connexion/ConnexionModels"; -import { DEBUG_MODE, JITSI_PRIVATE_MODE, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; +import type { UserMovedMessage } from "../../Messages/generated/messages_pb"; +import type { RoomConnection } from "../../Connexion/RoomConnection"; +import type { ActionableItem } from "../Items/ActionableItem"; +import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface"; +import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap"; +import type { AddPlayerInterface } from "./AddPlayerInterface"; +import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; +import type { Character } from '../Entity/Character'; +import { userMessageManager } from "../../Administration/UserMessageManager"; +import { iframeListener } from "../../Api/IframeListener"; +import { connectionManager } from "../../Connexion/ConnectionManager"; +import { DEBUG_MODE, JITSI_PRIVATE_MODE, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; import { Queue } from "queue-typescript"; import { Box, ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager"; import { CoWebsite, coWebsiteManager } from "../../WebRtc/CoWebsiteManager"; -import type { UserMovedMessage } from "../../Messages/generated/messages_pb"; import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils"; -import type { RoomConnection } from "../../Connexion/RoomConnection"; import { Room } from "../../Connexion/Room"; import { jitsiFactory } from "../../WebRtc/JitsiFactory"; import { urlManager } from "../../Url/UrlManager"; @@ -31,16 +37,12 @@ import { SimplePeer } from "../../WebRtc/SimplePeer"; import { Loader } from "../Components/Loader"; import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager"; import { RemotePlayer } from "../Entity/RemotePlayer"; -import type { ActionableItem } from "../Items/ActionableItem"; -import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface"; import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene"; -import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap"; import { PlayerAnimationDirections } from "../Player/Animation"; import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player"; import { ErrorSceneName } from "../Reconnecting/ErrorScene"; import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene"; import { UserInputManager } from "../UserInput/UserInputManager"; -import type { AddPlayerInterface } from "./AddPlayerInterface"; import { gameManager } from "./GameManager"; import { GameMap } from "./GameMap"; import { PlayerMovement } from "./PlayerMovement"; @@ -61,7 +63,6 @@ import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } import { waScaleManager } from "../Services/WaScaleManager"; import { EmoteManager } from "./EmoteManager"; import EVENT_TYPE = Phaser.Scenes.Events; -import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; import AnimatedTiles from "phaser-animated-tiles"; import { StartPositionCalculator } from "./StartPositionCalculator"; @@ -89,7 +90,6 @@ import { get } from "svelte/store"; import { contactPageStore } from "../../Stores/MenuStore"; import { GameMapProperties } from "./GameMapProperties"; import SpriteSheetFile = Phaser.Loader.FileTypes.SpriteSheetFile; - export interface GameSceneInitInterface { initPosition: PointInterface | null; reconnecting: boolean; @@ -1498,6 +1498,9 @@ ${escapedMessage} this.companion, this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); + this.CurrentPlayer.once('textures-loaded', () => { + this.savePlayerAvatarPicture(this.CurrentPlayer, 'hero-avatar'); + }); this.CurrentPlayer.on("pointerdown", (pointer: Phaser.Input.Pointer) => { if (pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) { return; //we don't want the menu to open when pinching on a touch screen. @@ -1525,6 +1528,12 @@ ${escapedMessage} this.createCollisionWithPlayer(); } + private savePlayerAvatarPicture(character: Character, key: string): void { + character.saveCharacterToTexture(key); + console.log(key); + this.add.image(200, 200, key); + } + pushPlayerPosition(event: HasPlayerMovedEvent) { if (this.lastMoveEventSent === event) { return; @@ -1626,9 +1635,11 @@ ${escapedMessage} break; case "AddPlayerEvent": this.doAddPlayer(event.event); + console.log('ADD PLAYER'); break; case "RemovePlayerEvent": this.doRemovePlayer(event.userId); + console.log('REMOVE PLAYER'); break; case "UserMovedEvent": this.doUpdatePlayerPosition(event.event); @@ -1668,6 +1679,7 @@ ${escapedMessage} */ private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void { const currentPlayerId = this.connection?.getUserId(); + console.log(currentPlayerId); this.removeAllRemotePlayers(); // load map usersPosition.forEach((userPosition: MessageUserPositionInterface) => { @@ -1712,6 +1724,9 @@ ${escapedMessage} addPlayerData.companion, addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined ); + player.once('textures-loaded', () => { + this.savePlayerAvatarPicture(player, `${addPlayerData.userId}-player-avatar`); + }); this.MapPlayers.add(player); this.MapPlayersByKey.set(player.userId, player); player.updatePosition(addPlayerData.position); From 0967563edaa3a1ec29e324ba8cb71d459be92687 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 26 Nov 2021 22:16:01 +0100 Subject: [PATCH 02/11] avatar as a menu button --- front/src/Components/Menu/MenuIcon.svelte | 14 +++++++++- front/src/Phaser/Entity/Character.ts | 16 +++++++---- front/src/Phaser/Game/GameScene.ts | 19 +++++++------ front/src/Stores/UserWokaPictureStore.ts | 34 +++++++++++++++++++++++ 4 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 front/src/Stores/UserWokaPictureStore.ts diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index 4b37238f..b54fd542 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -3,7 +3,9 @@ import logoTalk from "../images/logo-message-pixel.png" import {menuVisiblilityStore} from "../../Stores/MenuStore"; import {chatVisibilityStore} from "../../Stores/ChatStore"; + import {userWokaPictureStore} from "../../Stores/UserWokaPictureStore"; import {get} from "svelte/store"; + import {onDestroy} from "svelte"; function showMenu(){ menuVisiblilityStore.set(!get(menuVisiblilityStore)) @@ -11,12 +13,22 @@ function showChat(){ chatVisibilityStore.set(true); } + + let heroWokaPictureSrc = logoWA; + + const unsubscribeFromUserWokaPictureStore = userWokaPictureStore.subscribe(playersAvatars => { + heroWokaPictureSrc = playersAvatars.get(-1) ?? logoWA; + }); + + onDestroy(unsubscribeFromUserWokaPictureStore); + +
- open menu + open menu open menu
diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 06ecf1fb..5113a7a7 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -118,15 +118,21 @@ export abstract class Character extends Container { } } - public saveCharacterToTexture(saveAs: string): void { + public async getSnapshot(): Promise { const bounds = this.getBounds(); - const rt = this.scene.make.renderTexture({ x: 300, y: 300, width: bounds.width, height: bounds.height}, true); + const rt = this.scene.make.renderTexture({}, false); for (const sprite of this.sprites.values()) { rt.draw(sprite, sprite.displayWidth * 0.5, sprite.displayHeight * 0.5); } - // P.H. NOTE: Change of avatar will update saved texture. We can then send it again to the backend - rt.saveTexture(saveAs); - rt.destroy(); + // TODO: Any way for this to fail? What fallback? + return new Promise((resolve) => { + rt.snapshot((url) => { + resolve(url as HTMLImageElement); // P.H. NOTE: Exclude Color type + // rt.destroy(); + }, + 'image/png', + 1); + }) } public addCompanion(name: string, texturePromise?: Promise): void { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 9c8a2d2c..b5027cc4 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -67,11 +67,13 @@ import EVENT_TYPE = Phaser.Scenes.Events; import AnimatedTiles from "phaser-animated-tiles"; import { StartPositionCalculator } from "./StartPositionCalculator"; import { soundManager } from "./SoundManager"; + import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore"; import { videoFocusStore } from "../../Stores/VideoFocusStore"; import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; import { SharedVariablesManager } from "./SharedVariablesManager"; import { playersStore } from "../../Stores/PlayersStore"; +import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import { chatVisibilityStore } from "../../Stores/ChatStore"; import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; import { @@ -79,6 +81,7 @@ import { audioManagerVisibilityStore, audioManagerVolumeStore, } from "../../Stores/AudioManagerStore"; + import { PropertyUtils } from "../Map/PropertyUtils"; import Tileset = Phaser.Tilemaps.Tileset; import { userIsAdminStore } from "../../Stores/GameStore"; @@ -665,6 +668,7 @@ export class GameScene extends DirtyScene { this.connection = onConnect.connection; playersStore.connectToRoomConnection(this.connection); + userWokaPictureStore.connectToRoomConnection(this.connection); userIsAdminStore.set(this.connection.hasTag("admin")); @@ -1499,7 +1503,8 @@ ${escapedMessage} this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); this.CurrentPlayer.once('textures-loaded', () => { - this.savePlayerAvatarPicture(this.CurrentPlayer, 'hero-avatar'); + // TODO: How to be sure we always get hero id? + this.savePlayerWokaPicture(this.CurrentPlayer, -1); }); this.CurrentPlayer.on("pointerdown", (pointer: Phaser.Input.Pointer) => { if (pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) { @@ -1528,10 +1533,9 @@ ${escapedMessage} this.createCollisionWithPlayer(); } - private savePlayerAvatarPicture(character: Character, key: string): void { - character.saveCharacterToTexture(key); - console.log(key); - this.add.image(200, 200, key); + private async savePlayerWokaPicture(character: Character, userId: number): Promise { + const htmlImageElement = await character.getSnapshot(); + userWokaPictureStore.setWokaPicture(userId, htmlImageElement.src); } pushPlayerPosition(event: HasPlayerMovedEvent) { @@ -1635,11 +1639,9 @@ ${escapedMessage} break; case "AddPlayerEvent": this.doAddPlayer(event.event); - console.log('ADD PLAYER'); break; case "RemovePlayerEvent": this.doRemovePlayer(event.userId); - console.log('REMOVE PLAYER'); break; case "UserMovedEvent": this.doUpdatePlayerPosition(event.event); @@ -1679,7 +1681,6 @@ ${escapedMessage} */ private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void { const currentPlayerId = this.connection?.getUserId(); - console.log(currentPlayerId); this.removeAllRemotePlayers(); // load map usersPosition.forEach((userPosition: MessageUserPositionInterface) => { @@ -1725,7 +1726,7 @@ ${escapedMessage} addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined ); player.once('textures-loaded', () => { - this.savePlayerAvatarPicture(player, `${addPlayerData.userId}-player-avatar`); + this.savePlayerWokaPicture(player, addPlayerData.userId); }); this.MapPlayers.add(player); this.MapPlayersByKey.set(player.userId, player); diff --git a/front/src/Stores/UserWokaPictureStore.ts b/front/src/Stores/UserWokaPictureStore.ts new file mode 100644 index 00000000..de3f759a --- /dev/null +++ b/front/src/Stores/UserWokaPictureStore.ts @@ -0,0 +1,34 @@ +import { writable } from "svelte/store"; +import type { RoomConnection } from "../Connexion/RoomConnection"; + +/** + * A store that contains the players avatars pictures + */ +function createUserWokaPictureStore() { + let players = new Map(); + + const { subscribe, update } = writable(players); + + return { + subscribe, + connectToRoomConnection: (roomConnection: RoomConnection) => { + roomConnection.onUserLeft((userId) => { + update((users) => { + users.delete(userId); + return users; + }); + }); + }, + setWokaPicture(userId: number, url: string) { + update((users) => { + users.set(userId, url); + return users; + }); + }, + getWokaPictureById(userId: number): string | undefined { + return players.get(userId); + }, + }; +} + +export const userWokaPictureStore = createUserWokaPictureStore(); From d521e052b449f62a93385e5a27fceb99ebca86e9 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 26 Nov 2021 23:30:21 +0100 Subject: [PATCH 03/11] working woka picture if no camera view is provided --- .../src/Components/Video/VideoMediaBox.svelte | 53 ++++++++++++++----- front/src/Stores/UserWokaPictureStore.ts | 3 +- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/front/src/Components/Video/VideoMediaBox.svelte b/front/src/Components/Video/VideoMediaBox.svelte index cc7fb424..46554128 100644 --- a/front/src/Components/Video/VideoMediaBox.svelte +++ b/front/src/Components/Video/VideoMediaBox.svelte @@ -1,12 +1,14 @@
- {#if $statusStore === 'connecting'} -
+ {#if $statusStore === "connecting"} +
{/if} - {#if $statusStore === 'error'} -
+ {#if $statusStore === "error"} +
{/if} {#if !$constraintStore || $constraintStore.video === false} - {name} + + {#if !userWokaPictureSrc} + {name} + {:else} + player avatar + {/if} + {/if} {#if $constraintStore && $constraintStore.audio === false} - Muted + Muted {/if} - +
+ \ No newline at end of file diff --git a/front/src/Stores/UserWokaPictureStore.ts b/front/src/Stores/UserWokaPictureStore.ts index de3f759a..6ce7ba7d 100644 --- a/front/src/Stores/UserWokaPictureStore.ts +++ b/front/src/Stores/UserWokaPictureStore.ts @@ -5,12 +5,13 @@ import type { RoomConnection } from "../Connexion/RoomConnection"; * A store that contains the players avatars pictures */ function createUserWokaPictureStore() { - let players = new Map(); + const players = new Map(); const { subscribe, update } = writable(players); return { subscribe, + // P.H. NOTE: Not clearing the store after reconnecting to the room - is this a problem? connectToRoomConnection: (roomConnection: RoomConnection) => { roomConnection.onUserLeft((userId) => { update((users) => { From fb188578daf9e9e43952fa46d0365d9f8bd40374 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Fri, 26 Nov 2021 23:49:49 +0100 Subject: [PATCH 04/11] images are blurred no more --- front/src/Components/Menu/MenuIcon.svelte | 3 ++- front/src/Components/Video/VideoMediaBox.svelte | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index b54fd542..f8986968 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -42,7 +42,8 @@ pointer-events: auto; width: 60px; padding-top: 0; - margin: 3px + margin: 3px; + image-rendering: pixelated; } } .menuIcon img:hover{ diff --git a/front/src/Components/Video/VideoMediaBox.svelte b/front/src/Components/Video/VideoMediaBox.svelte index 46554128..0156f101 100644 --- a/front/src/Components/Video/VideoMediaBox.svelte +++ b/front/src/Components/Video/VideoMediaBox.svelte @@ -67,5 +67,6 @@ top: calc(50% - 45px); width: 90px; height: 90px; + image-rendering: pixelated; } \ No newline at end of file From e43b7a255a78f16811f0b5cb1884048c81ed87da Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Sun, 28 Nov 2021 17:05:12 +0100 Subject: [PATCH 05/11] little cleanup, added reject for Character snapshot --- front/src/Phaser/Entity/Character.ts | 20 ++-- front/src/Phaser/Game/GameScene.ts | 133 +++++++++++------------ front/src/Stores/UserWokaPictureStore.ts | 1 - 3 files changed, 76 insertions(+), 78 deletions(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 5113a7a7..8557b01e 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -119,19 +119,21 @@ export abstract class Character extends Container { } public async getSnapshot(): Promise { - const bounds = this.getBounds(); const rt = this.scene.make.renderTexture({}, false); for (const sprite of this.sprites.values()) { rt.draw(sprite, sprite.displayWidth * 0.5, sprite.displayHeight * 0.5); } - // TODO: Any way for this to fail? What fallback? - return new Promise((resolve) => { - rt.snapshot((url) => { - resolve(url as HTMLImageElement); // P.H. NOTE: Exclude Color type - // rt.destroy(); - }, - 'image/png', - 1); + return new Promise((resolve, reject) => { + try { + rt.snapshot((url) => { + resolve(url as HTMLImageElement); + rt.destroy(); + }, + 'image/png', + 1); + } catch (error) { + reject(error); + } }) } diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index b5027cc4..8cee117c 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -1,4 +1,54 @@ import type { Subscription } from "rxjs"; +import AnimatedTiles from "phaser-animated-tiles"; +import { Queue } from "queue-typescript"; +import { get } from "svelte/store"; + +import { userMessageManager } from "../../Administration/UserMessageManager"; +import { connectionManager } from "../../Connexion/ConnectionManager"; +import { CoWebsite, coWebsiteManager } from "../../WebRtc/CoWebsiteManager"; +import { urlManager } from "../../Url/UrlManager"; +import { mediaManager } from "../../WebRtc/MediaManager"; +import { UserInputManager } from "../UserInput/UserInputManager"; +import { gameManager } from "./GameManager"; +import { touchScreenManager } from "../../Touch/TouchScreenManager"; +import { PinchManager } from "../UserInput/PinchManager"; +import { waScaleManager } from "../Services/WaScaleManager"; +import { EmoteManager } from "./EmoteManager"; +import { soundManager } from "./SoundManager"; +import { SharedVariablesManager } from "./SharedVariablesManager"; +import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager"; + +import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager"; +import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; +import { Box, ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager"; +import { iframeListener } from "../../Api/IframeListener"; +import { DEBUG_MODE, JITSI_PRIVATE_MODE, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; +import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils"; +import { Room } from "../../Connexion/Room"; +import { jitsiFactory } from "../../WebRtc/JitsiFactory"; +import { TextureError } from "../../Exception/TextureError"; +import { localUserStore } from "../../Connexion/LocalUserStore"; +import { HtmlUtils } from "../../WebRtc/HtmlUtils"; +import { SimplePeer } from "../../WebRtc/SimplePeer"; +import { Loader } from "../Components/Loader"; +import { RemotePlayer } from "../Entity/RemotePlayer"; +import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene"; +import { PlayerAnimationDirections } from "../Player/Animation"; +import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player"; +import { ErrorSceneName } from "../Reconnecting/ErrorScene"; +import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene"; +import { GameMap } from "./GameMap"; +import { PlayerMovement } from "./PlayerMovement"; +import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator"; +import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream"; +import { DirtyScene } from "./DirtyScene"; +import { TextUtils } from "../Components/TextUtils"; +import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; +import { StartPositionCalculator } from "./StartPositionCalculator"; +import { PropertyUtils } from "../Map/PropertyUtils"; +import { GameMapPropertiesListener } from "./GameMapPropertiesListener"; +import { analyticsClient } from "../../Administration/AnalyticsClient"; +import { GameMapProperties } from "./GameMapProperties"; import type { GroupCreatedUpdatedMessageInterface, MessageUserJoined, @@ -18,81 +68,28 @@ import type { AddPlayerInterface } from "./AddPlayerInterface"; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; import type { Character } from '../Entity/Character'; -import { userMessageManager } from "../../Administration/UserMessageManager"; -import { iframeListener } from "../../Api/IframeListener"; -import { connectionManager } from "../../Connexion/ConnectionManager"; -import { DEBUG_MODE, JITSI_PRIVATE_MODE, MAX_PER_GROUP, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; -import { Queue } from "queue-typescript"; -import { Box, ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager"; -import { CoWebsite, coWebsiteManager } from "../../WebRtc/CoWebsiteManager"; -import { ProtobufClientUtils } from "../../Network/ProtobufClientUtils"; -import { Room } from "../../Connexion/Room"; -import { jitsiFactory } from "../../WebRtc/JitsiFactory"; -import { urlManager } from "../../Url/UrlManager"; -import { TextureError } from "../../Exception/TextureError"; -import { localUserStore } from "../../Connexion/LocalUserStore"; -import { HtmlUtils } from "../../WebRtc/HtmlUtils"; -import { mediaManager } from "../../WebRtc/MediaManager"; -import { SimplePeer } from "../../WebRtc/SimplePeer"; -import { Loader } from "../Components/Loader"; -import { lazyLoadPlayerCharacterTextures, loadCustomTexture } from "../Entity/PlayerTexturesLoadingManager"; -import { RemotePlayer } from "../Entity/RemotePlayer"; -import { SelectCharacterScene, SelectCharacterSceneName } from "../Login/SelectCharacterScene"; -import { PlayerAnimationDirections } from "../Player/Animation"; -import { hasMovedEventName, Player, requestEmoteEventName } from "../Player/Player"; -import { ErrorSceneName } from "../Reconnecting/ErrorScene"; -import { ReconnectingSceneName } from "../Reconnecting/ReconnectingScene"; -import { UserInputManager } from "../UserInput/UserInputManager"; -import { gameManager } from "./GameManager"; -import { GameMap } from "./GameMap"; -import { PlayerMovement } from "./PlayerMovement"; -import { PlayersPositionInterpolator } from "./PlayersPositionInterpolator"; +import { peerStore } from "../../Stores/PeerStore"; +import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; +import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; +import { playersStore } from "../../Stores/PlayersStore"; +import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; +import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; +import { userIsAdminStore } from "../../Stores/GameStore"; +import { contactPageStore } from "../../Stores/MenuStore"; +import { + audioManagerFileStore, + audioManagerVisibilityStore, +} from "../../Stores/AudioManagerStore"; + +import EVENT_TYPE = Phaser.Scenes.Events; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; import CanvasTexture = Phaser.Textures.CanvasTexture; import GameObject = Phaser.GameObjects.GameObject; -import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR; import DOMElement = Phaser.GameObjects.DOMElement; -import { worldFullMessageStream } from "../../Connexion/WorldFullMessageStream"; -import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; -import { DirtyScene } from "./DirtyScene"; -import { TextUtils } from "../Components/TextUtils"; -import { touchScreenManager } from "../../Touch/TouchScreenManager"; -import { PinchManager } from "../UserInput/PinchManager"; -import { joystickBaseImg, joystickBaseKey, joystickThumbImg, joystickThumbKey } from "../Components/MobileJoystick"; -import { waScaleManager } from "../Services/WaScaleManager"; -import { EmoteManager } from "./EmoteManager"; -import EVENT_TYPE = Phaser.Scenes.Events; - -import AnimatedTiles from "phaser-animated-tiles"; -import { StartPositionCalculator } from "./StartPositionCalculator"; -import { soundManager } from "./SoundManager"; - -import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore"; -import { videoFocusStore } from "../../Stores/VideoFocusStore"; -import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; -import { SharedVariablesManager } from "./SharedVariablesManager"; -import { playersStore } from "../../Stores/PlayersStore"; -import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; -import { chatVisibilityStore } from "../../Stores/ChatStore"; -import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; -import { - audioManagerFileStore, - audioManagerVisibilityStore, - audioManagerVolumeStore, -} from "../../Stores/AudioManagerStore"; - -import { PropertyUtils } from "../Map/PropertyUtils"; import Tileset = Phaser.Tilemaps.Tileset; -import { userIsAdminStore } from "../../Stores/GameStore"; -import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; -import { EmbeddedWebsiteManager } from "./EmbeddedWebsiteManager"; -import { GameMapPropertiesListener } from "./GameMapPropertiesListener"; -import { analyticsClient } from "../../Administration/AnalyticsClient"; -import { get } from "svelte/store"; -import { contactPageStore } from "../../Stores/MenuStore"; -import { GameMapProperties } from "./GameMapProperties"; import SpriteSheetFile = Phaser.Loader.FileTypes.SpriteSheetFile; +import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR; export interface GameSceneInitInterface { initPosition: PointInterface | null; reconnecting: boolean; diff --git a/front/src/Stores/UserWokaPictureStore.ts b/front/src/Stores/UserWokaPictureStore.ts index 6ce7ba7d..30863e44 100644 --- a/front/src/Stores/UserWokaPictureStore.ts +++ b/front/src/Stores/UserWokaPictureStore.ts @@ -11,7 +11,6 @@ function createUserWokaPictureStore() { return { subscribe, - // P.H. NOTE: Not clearing the store after reconnecting to the room - is this a problem? connectToRoomConnection: (roomConnection: RoomConnection) => { roomConnection.onUserLeft((userId) => { update((users) => { From 0a0d7e401738bb9c626386579fdbbbf3077d37b5 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Mon, 29 Nov 2021 20:39:09 +0100 Subject: [PATCH 06/11] use Prettier to fix style issues --- front/src/Phaser/Entity/Character.ts | 18 ++++++++++-------- front/src/Phaser/Game/GameScene.ts | 11 ++++------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 8557b01e..01122975 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -64,7 +64,7 @@ export abstract class Character extends Container { this.addTextures(textures, frame); this.invisible = false; this.playAnimation(direction, moving); - this.emit('textures-loaded'); + this.emit("textures-loaded"); }) .catch(() => { return lazyLoadPlayerCharacterTextures(scene.load, ["color_22", "eyes_23"]).then((textures) => { @@ -125,16 +125,18 @@ export abstract class Character extends Container { } return new Promise((resolve, reject) => { try { - rt.snapshot((url) => { - resolve(url as HTMLImageElement); - rt.destroy(); - }, - 'image/png', - 1); + rt.snapshot( + (url) => { + resolve(url as HTMLImageElement); + rt.destroy(); + }, + "image/png", + 1 + ); } catch (error) { reject(error); } - }) + }); } public addCompanion(name: string, texturePromise?: Promise): void { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8cee117c..01b8544c 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -66,7 +66,7 @@ import type { ItemFactoryInterface } from "../Items/ItemFactoryInterface"; import type { ITiledMap, ITiledMapLayer, ITiledMapProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap"; import type { AddPlayerInterface } from "./AddPlayerInterface"; import type { HasPlayerMovedEvent } from "../../Api/Events/HasPlayerMovedEvent"; -import type { Character } from '../Entity/Character'; +import type { Character } from "../Entity/Character"; import { peerStore } from "../../Stores/PeerStore"; import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; @@ -76,10 +76,7 @@ import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; import { userIsAdminStore } from "../../Stores/GameStore"; import { contactPageStore } from "../../Stores/MenuStore"; -import { - audioManagerFileStore, - audioManagerVisibilityStore, -} from "../../Stores/AudioManagerStore"; +import { audioManagerFileStore, audioManagerVisibilityStore } from "../../Stores/AudioManagerStore"; import EVENT_TYPE = Phaser.Scenes.Events; import Texture = Phaser.Textures.Texture; @@ -1499,7 +1496,7 @@ ${escapedMessage} this.companion, this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); - this.CurrentPlayer.once('textures-loaded', () => { + this.CurrentPlayer.once("textures-loaded", () => { // TODO: How to be sure we always get hero id? this.savePlayerWokaPicture(this.CurrentPlayer, -1); }); @@ -1722,7 +1719,7 @@ ${escapedMessage} addPlayerData.companion, addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined ); - player.once('textures-loaded', () => { + player.once("textures-loaded", () => { this.savePlayerWokaPicture(player, addPlayerData.userId); }); this.MapPlayers.add(player); From 407879528e91299e0c4a05a40017cac5aa3b8e13 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Tue, 30 Nov 2021 19:10:35 +0100 Subject: [PATCH 07/11] Changed the way WOKA's are stored --- front/src/Components/Menu/MenuIcon.svelte | 20 ++++------- .../src/Components/Video/VideoMediaBox.svelte | 29 ++++----------- front/src/Components/Woka/Woka.svelte | 31 ++++++++++++++++ front/src/Phaser/Entity/Character.ts | 1 - front/src/Phaser/Game/GameScene.ts | 17 ++++++--- front/src/Stores/UserWokaPictureStore.ts | 36 +++---------------- 6 files changed, 61 insertions(+), 73 deletions(-) create mode 100644 front/src/Components/Woka/Woka.svelte diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index f8986968..87d71476 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -1,11 +1,9 @@
- open menu +
open menu
@@ -49,6 +37,10 @@ .menuIcon img:hover{ transform: scale(1.2); } + + .menuIcon .woka:hover{ + transform: scale(1.2); + } @media only screen and (max-width: 800px), only screen and (max-height: 800px) { .menuIcon { margin: 3px; diff --git a/front/src/Components/Video/VideoMediaBox.svelte b/front/src/Components/Video/VideoMediaBox.svelte index 0156f101..3f64b0c1 100644 --- a/front/src/Components/Video/VideoMediaBox.svelte +++ b/front/src/Components/Video/VideoMediaBox.svelte @@ -6,9 +6,9 @@ import blockSignImg from "./images/blockSign.svg"; import { videoFocusStore } from "../../Stores/VideoFocusStore"; import { showReportScreenStore } from "../../Stores/ShowReportScreenStore"; - import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import { getColorByString, srcObject } from "./utils"; - import { onDestroy } from "svelte"; + + import Woka from '../Woka/Woka.svelte'; export let peer: VideoPeer; let streamStore = peer.streamStore; @@ -16,18 +16,9 @@ let statusStore = peer.statusStore; let constraintStore = peer.constraintsStore; - let userWokaPictureSrc: string | undefined = undefined; - - const unsubscribeFromUserWokaPictureStore = userWokaPictureStore.subscribe((playersAvatars) => { - userWokaPictureSrc = playersAvatars.get(peer.userId); - console.log(userWokaPictureSrc); - }); - function openReport(peer: VideoPeer): void { showReportScreenStore.set({ userId: peer.userId, userName: peer.userName }); } - - onDestroy(unsubscribeFromUserWokaPictureStore);
@@ -39,11 +30,7 @@ {/if} {#if !$constraintStore || $constraintStore.video === false} - {#if !userWokaPictureSrc} - {name} - {:else} - player avatar - {/if} + {/if} {#if $constraintStore && $constraintStore.audio === false} @@ -61,12 +48,10 @@
\ No newline at end of file diff --git a/front/src/Components/Woka/Woka.svelte b/front/src/Components/Woka/Woka.svelte new file mode 100644 index 00000000..badf48bf --- /dev/null +++ b/front/src/Components/Woka/Woka.svelte @@ -0,0 +1,31 @@ + + +woka + + \ No newline at end of file diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 01122975..1f7b80ed 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -8,7 +8,6 @@ import { TextureError } from "../../Exception/TextureError"; import { Companion } from "../Companion/Companion"; import type { GameScene } from "../Game/GameScene"; import { DEPTH_INGAME_TEXT_INDEX } from "../Game/DepthIndexes"; -import { waScaleManager } from "../Services/WaScaleManager"; import type OutlinePipelinePlugin from "phaser3-rex-plugins/plugins/outlinepipeline-plugin.js"; import { isSilentStore } from "../../Stores/MediaStore"; import { lazyLoadPlayerCharacterTextures } from "./PlayerTexturesLoadingManager"; diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 01b8544c..95604c2c 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -72,11 +72,11 @@ import { peerStore } from "../../Stores/PeerStore"; import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore"; import { playersStore } from "../../Stores/PlayersStore"; -import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; import { userIsAdminStore } from "../../Stores/GameStore"; import { contactPageStore } from "../../Stores/MenuStore"; import { audioManagerFileStore, audioManagerVisibilityStore } from "../../Stores/AudioManagerStore"; +import { UserWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import EVENT_TYPE = Phaser.Scenes.Events; import Texture = Phaser.Textures.Texture; @@ -201,6 +201,7 @@ export class GameScene extends DirtyScene { private objectsByType = new Map(); private embeddedWebsiteManager!: EmbeddedWebsiteManager; private loader: Loader; + private userWokaPictureStores: Map = new Map(); constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) { super({ @@ -333,6 +334,15 @@ export class GameScene extends DirtyScene { this.loader.addLoader(); } + public getUserWokaPictureStore(userId: number) { + let store = this.userWokaPictureStores.get(userId); + if (!store) { + store = new UserWokaPictureStore(); + this.userWokaPictureStores.set(userId, store); + } + return store; + } + // FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving. // eslint-disable-next-line @typescript-eslint/no-explicit-any private async onMapLoad(data: any): Promise { @@ -662,8 +672,6 @@ export class GameScene extends DirtyScene { this.connection = onConnect.connection; playersStore.connectToRoomConnection(this.connection); - userWokaPictureStore.connectToRoomConnection(this.connection); - userIsAdminStore.set(this.connection.hasTag("admin")); this.connection.onUserJoins((message: MessageUserJoined) => { @@ -1497,7 +1505,6 @@ ${escapedMessage} this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); this.CurrentPlayer.once("textures-loaded", () => { - // TODO: How to be sure we always get hero id? this.savePlayerWokaPicture(this.CurrentPlayer, -1); }); this.CurrentPlayer.on("pointerdown", (pointer: Phaser.Input.Pointer) => { @@ -1529,7 +1536,7 @@ ${escapedMessage} private async savePlayerWokaPicture(character: Character, userId: number): Promise { const htmlImageElement = await character.getSnapshot(); - userWokaPictureStore.setWokaPicture(userId, htmlImageElement.src); + this.getUserWokaPictureStore(userId).picture.set(htmlImageElement); } pushPlayerPosition(event: HasPlayerMovedEvent) { diff --git a/front/src/Stores/UserWokaPictureStore.ts b/front/src/Stores/UserWokaPictureStore.ts index 30863e44..8f5cb64f 100644 --- a/front/src/Stores/UserWokaPictureStore.ts +++ b/front/src/Stores/UserWokaPictureStore.ts @@ -1,34 +1,8 @@ -import { writable } from "svelte/store"; -import type { RoomConnection } from "../Connexion/RoomConnection"; +import { writable, Writable } from "svelte/store"; /** - * A store that contains the players avatars pictures + * A store that contains the player avatar picture */ -function createUserWokaPictureStore() { - const players = new Map(); - - const { subscribe, update } = writable(players); - - return { - subscribe, - connectToRoomConnection: (roomConnection: RoomConnection) => { - roomConnection.onUserLeft((userId) => { - update((users) => { - users.delete(userId); - return users; - }); - }); - }, - setWokaPicture(userId: number, url: string) { - update((users) => { - users.set(userId, url); - return users; - }); - }, - getWokaPictureById(userId: number): string | undefined { - return players.get(userId); - }, - }; -} - -export const userWokaPictureStore = createUserWokaPictureStore(); +export class UserWokaPictureStore { + constructor(public picture: Writable = writable(undefined)) {} +} \ No newline at end of file From bf618f1c9d703a705e5aeb29648be14bb21302a4 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 1 Dec 2021 10:26:09 +0100 Subject: [PATCH 08/11] fixed Woka picture positioning --- front/src/Components/Menu/MenuIcon.svelte | 10 +++++++++- front/src/Components/Video/VideoMediaBox.svelte | 11 +---------- front/src/Components/Woka/Woka.svelte | 5 ++++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index 87d71476..760f2e44 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -16,7 +16,9 @@
-
+
+ +
open menu
@@ -33,6 +35,12 @@ margin: 3px; image-rendering: pixelated; } + .woka { + pointer-events: auto; + width: 60px; + padding-top: 0; + margin: 3px; + } } .menuIcon img:hover{ transform: scale(1.2); diff --git a/front/src/Components/Video/VideoMediaBox.svelte b/front/src/Components/Video/VideoMediaBox.svelte index 3f64b0c1..331be702 100644 --- a/front/src/Components/Video/VideoMediaBox.svelte +++ b/front/src/Components/Video/VideoMediaBox.svelte @@ -45,13 +45,4 @@ {#if $constraintStore && $constraintStore.audio !== false} {/if} -
- - \ No newline at end of file +
\ No newline at end of file diff --git a/front/src/Components/Woka/Woka.svelte b/front/src/Components/Woka/Woka.svelte index badf48bf..8138cd14 100644 --- a/front/src/Components/Woka/Woka.svelte +++ b/front/src/Components/Woka/Woka.svelte @@ -25,7 +25,10 @@ import { onDestroy } from 'svelte'; pointer-events: auto; width: 60px; height: 60px; - margin: 3px; + left: calc(50% - 30px); + top: calc(50% - 30px); + margin: 0; + padding: 0; image-rendering: pixelated; } \ No newline at end of file From 9de13faff2fa4864f189a9d812e08ee5e33dc807 Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 1 Dec 2021 10:45:01 +0100 Subject: [PATCH 09/11] fixed bug with woka picture snapshot taking current frame and not front --- front/src/Phaser/Entity/Character.ts | 1 + front/src/Phaser/Game/GameScene.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 1f7b80ed..bf85ed59 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -120,6 +120,7 @@ export abstract class Character extends Container { public async getSnapshot(): Promise { const rt = this.scene.make.renderTexture({}, false); for (const sprite of this.sprites.values()) { + sprite.setFrame(1); rt.draw(sprite, sprite.displayWidth * 0.5, sprite.displayHeight * 0.5); } return new Promise((resolve, reject) => { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 95604c2c..62414767 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -201,7 +201,7 @@ export class GameScene extends DirtyScene { private objectsByType = new Map(); private embeddedWebsiteManager!: EmbeddedWebsiteManager; private loader: Loader; - private userWokaPictureStores: Map = new Map(); + private userWokaPictureStores: Map = new Map(); constructor(private room: Room, MapUrlFile: string, customKey?: string | undefined) { super({ From 3f7511e682bb0f0ee55b4b9b0ee6330e76355b0e Mon Sep 17 00:00:00 2001 From: Hanusiak Piotr Date: Wed, 1 Dec 2021 11:14:54 +0100 Subject: [PATCH 10/11] fallback if avatar could not be loaded --- front/src/Components/Menu/MenuIcon.svelte | 4 +++- front/src/Components/Video/VideoMediaBox.svelte | 2 +- front/src/Components/Woka/Woka.svelte | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index 760f2e44..e72f0f08 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -1,10 +1,12 @@ -woka +