diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts
index 5b1e13bf..f0c6e627 100644
--- a/back/src/Model/GameRoom.ts
+++ b/back/src/Model/GameRoom.ts
@@ -144,9 +144,8 @@ export class GameRoom {
joinRoomMessage.getUseruuid(),
joinRoomMessage.getIpaddress(),
position,
- false,
this.positionNotifier,
- joinRoomMessage.getAway(),
+ joinRoomMessage.getStatus(),
socket,
joinRoomMessage.getTagList(),
joinRoomMessage.getVisitcardurl(),
@@ -208,6 +207,9 @@ export class GameRoom {
updatePlayerDetails(user: User, playerDetailsMessage: SetPlayerDetailsMessage) {
user.updateDetails(playerDetailsMessage);
+ if (user.group !== undefined && user.silent) {
+ this.leaveGroup(user);
+ }
}
private updateUserGroup(user: User): void {
@@ -345,21 +347,6 @@ export class GameRoom {
});
}
- setSilent(user: User, silent: boolean) {
- if (user.silent === silent) {
- return;
- }
-
- user.silent = silent;
- if (silent && user.group !== undefined) {
- this.leaveGroup(user);
- }
- if (!silent) {
- // If we are back to life, let's trigger a position update to see if we can join some group.
- this.updatePosition(user, user.getPosition());
- }
- }
-
/**
* Makes a user leave a group and closes and destroy the group if the group contains only one remaining person.
*
diff --git a/back/src/Model/User.ts b/back/src/Model/User.ts
index 7a6a53f1..b103f240 100644
--- a/back/src/Model/User.ts
+++ b/back/src/Model/User.ts
@@ -5,6 +5,7 @@ import { Movable } from "../Model/Movable";
import { PositionNotifier } from "../Model/PositionNotifier";
import { ServerDuplexStream } from "grpc";
import {
+ AvailabilityStatus,
BatchMessage,
CompanionMessage,
FollowAbortMessage,
@@ -30,9 +31,8 @@ export class User implements Movable {
public readonly uuid: string,
public readonly IPAddress: string,
private position: PointInterface,
- public silent: boolean,
private positionNotifier: PositionNotifier,
- private away: boolean,
+ private status: AvailabilityStatus,
public readonly socket: UserSocket,
public readonly tags: string[],
public readonly visitCardUrl: string | null,
@@ -90,8 +90,12 @@ export class User implements Movable {
return this.outlineColor;
}
- public isAway(): boolean {
- return this.away;
+ public getStatus(): AvailabilityStatus {
+ return this.status;
+ }
+
+ public get silent(): boolean {
+ return this.status === AvailabilityStatus.SILENT || this.status === AvailabilityStatus.JITSI;
}
get following(): User | undefined {
@@ -134,9 +138,11 @@ export class User implements Movable {
}
this.voiceIndicatorShown = details.getShowvoiceindicator()?.getValue();
- const away = details.getAway();
- if (away) {
- this.away = away.getValue();
+ const status = details.getStatus();
+ let sendStatusUpdate = false;
+ if (status && status !== this.status) {
+ this.status = status;
+ sendStatusUpdate = true;
}
const playerDetails = new SetPlayerDetailsMessage();
@@ -147,8 +153,8 @@ export class User implements Movable {
if (this.voiceIndicatorShown !== undefined) {
playerDetails.setShowvoiceindicator(new BoolValue().setValue(this.voiceIndicatorShown));
}
- if (details.getAway() !== undefined) {
- playerDetails.setAway(new BoolValue().setValue(this.away));
+ if (sendStatusUpdate) {
+ playerDetails.setStatus(details.getStatus());
}
this.positionNotifier.updatePlayerDetails(this, playerDetails);
diff --git a/back/src/RoomManager.ts b/back/src/RoomManager.ts
index c07d7e76..7211facb 100644
--- a/back/src/RoomManager.ts
+++ b/back/src/RoomManager.ts
@@ -22,7 +22,6 @@ import {
SendUserMessage,
ServerToAdminClientMessage,
SetPlayerDetailsMessage,
- SilentMessage,
UserMovesMessage,
VariableMessage,
WebRtcSignalToServerMessage,
@@ -80,8 +79,6 @@ const roomManager: IRoomManagerServer = {
user,
message.getUsermovesmessage() as UserMovesMessage
);
- } else if (message.hasSilentmessage()) {
- socketManager.handleSilentMessage(room, user, message.getSilentmessage() as SilentMessage);
} else if (message.hasItemeventmessage()) {
socketManager.handleItemEvent(
room,
diff --git a/back/src/Services/SocketManager.ts b/back/src/Services/SocketManager.ts
index c186658f..8d71f4d8 100644
--- a/back/src/Services/SocketManager.ts
+++ b/back/src/Services/SocketManager.ts
@@ -5,7 +5,6 @@ import {
PointMessage,
RoomJoinedMessage,
ServerToClientMessage,
- SilentMessage,
SubMessage,
UserMovedMessage,
UserMovesMessage,
@@ -160,10 +159,6 @@ export class SocketManager {
room.updatePlayerDetails(user, playerDetailsMessage);
}
- handleSilentMessage(room: GameRoom, user: User, silentMessage: SilentMessage) {
- room.setSilent(user, silentMessage.getSilent());
- }
-
handleItemEvent(room: GameRoom, user: User, itemEventMessage: ItemEventMessage) {
const itemEvent = ProtobufUtils.toItemEvent(itemEventMessage);
@@ -328,7 +323,7 @@ export class SocketManager {
userJoinedZoneMessage.setUserid(thing.id);
userJoinedZoneMessage.setUseruuid(thing.uuid);
userJoinedZoneMessage.setName(thing.name);
- userJoinedZoneMessage.setAway(thing.isAway());
+ userJoinedZoneMessage.setStatus(thing.getStatus());
userJoinedZoneMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedZoneMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));
userJoinedZoneMessage.setFromzone(this.toProtoZone(fromZone));
@@ -656,7 +651,7 @@ export class SocketManager {
userJoinedMessage.setUserid(thing.id);
userJoinedMessage.setUseruuid(thing.uuid);
userJoinedMessage.setName(thing.name);
- userJoinedMessage.setAway(thing.isAway());
+ userJoinedMessage.setStatus(thing.getStatus());
userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));
if (thing.visitCardUrl) {
diff --git a/back/tests/PositionNotifierTest.ts b/back/tests/PositionNotifierTest.ts
index a5af48f8..70e4c0a0 100644
--- a/back/tests/PositionNotifierTest.ts
+++ b/back/tests/PositionNotifierTest.ts
@@ -6,6 +6,7 @@ import { Zone } from "../src/Model/Zone";
import { Movable } from "../src/Model/Movable";
import { PositionInterface } from "../src/Model/PositionInterface";
import { ZoneSocket } from "../src/RoomManager";
+import { AvailabilityStatus } from "../src/Messages/generated/messages_pb";
describe("PositionNotifier", () => {
it("should receive notifications when player moves", () => {
@@ -40,9 +41,8 @@ describe("PositionNotifier", () => {
moving: false,
direction: "down",
},
- false,
positionNotifier,
- false,
+ AvailabilityStatus.ONLINE,
{} as UserSocket,
[],
null,
@@ -60,9 +60,8 @@ describe("PositionNotifier", () => {
moving: false,
direction: "down",
},
- false,
positionNotifier,
- false,
+ AvailabilityStatus.ONLINE,
{} as UserSocket,
[],
null,
@@ -150,9 +149,8 @@ describe("PositionNotifier", () => {
moving: false,
direction: "down",
},
- false,
positionNotifier,
- false,
+ AvailabilityStatus.ONLINE,
{} as UserSocket,
[],
null,
@@ -170,9 +168,8 @@ describe("PositionNotifier", () => {
moving: false,
direction: "down",
},
- false,
positionNotifier,
- false,
+ AvailabilityStatus.ONLINE,
{} as UserSocket,
[],
null,
diff --git a/front/public/resources/icons/icon_status_indicator_inside.png b/front/public/resources/icons/icon_status_indicator_inside.png
new file mode 100644
index 00000000..29a2daad
Binary files /dev/null and b/front/public/resources/icons/icon_status_indicator_inside.png differ
diff --git a/front/public/resources/icons/icon_status_indicator_outline.png b/front/public/resources/icons/icon_status_indicator_outline.png
new file mode 100644
index 00000000..67f86ec5
Binary files /dev/null and b/front/public/resources/icons/icon_status_indicator_outline.png differ
diff --git a/front/src/Api/desktop/index.ts b/front/src/Api/desktop/index.ts
index 0b1ea9f9..6e38403c 100644
--- a/front/src/Api/desktop/index.ts
+++ b/front/src/Api/desktop/index.ts
@@ -1,4 +1,4 @@
-import { isSilentStore, requestedCameraState, requestedMicrophoneState } from "../../Stores/MediaStore";
+import { requestedCameraState, requestedMicrophoneState, silentStore } from "../../Stores/MediaStore";
import { get } from "svelte/store";
import { WorkAdventureDesktopApi } from "@wa-preload-app";
@@ -36,8 +36,8 @@ class DesktopApi {
}
});
- isSilentStore.subscribe((value) => {
- this.isSilent = value;
+ silentStore.subscribe((silent) => {
+ this.isSilent = silent;
});
}
}
diff --git a/front/src/Components/CameraControls.svelte b/front/src/Components/CameraControls.svelte
index b9cb7801..fad3c3c1 100644
--- a/front/src/Components/CameraControls.svelte
+++ b/front/src/Components/CameraControls.svelte
@@ -1,6 +1,6 @@
@@ -94,7 +87,7 @@
@@ -103,7 +96,7 @@
@@ -113,26 +106,26 @@
- {#if $requestedScreenSharingState && !isSilent}
+ {#if $requestedScreenSharingState && !$silentStore}
{:else}
{/if}
-
- {#if $requestedCameraState && !isSilent}
+
+ {#if $requestedCameraState && !$silentStore}
{:else}
{/if}
-
- {#if $requestedMicrophoneState && !isSilent}
+
+ {#if $requestedMicrophoneState && !$silentStore}
{:else}
diff --git a/front/src/Components/MyCamera.svelte b/front/src/Components/MyCamera.svelte
index 7f97ff22..d72a8eee 100644
--- a/front/src/Components/MyCamera.svelte
+++ b/front/src/Components/MyCamera.svelte
@@ -1,6 +1,6 @@
- {#if isSilent}
+ {#if $silentStore}
{$LL.camera.my.silentZone()}
{:else if $localStreamStore.type === "success" && $localStreamStore.stream}
diff --git a/front/src/Connexion/ConnexionModels.ts b/front/src/Connexion/ConnexionModels.ts
index 1231373f..d3909f55 100644
--- a/front/src/Connexion/ConnexionModels.ts
+++ b/front/src/Connexion/ConnexionModels.ts
@@ -1,6 +1,7 @@
import type { SignalData } from "simple-peer";
import type { RoomConnection } from "./RoomConnection";
import type { BodyResourceDescriptionInterface } from "../Phaser/Entity/PlayerTextures";
+import { AvailabilityStatus } from "../Messages/ts-proto-generated/protos/messages";
export interface PointInterface {
x: number;
@@ -14,7 +15,7 @@ export interface MessageUserPositionInterface {
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
- away: boolean;
+ status: AvailabilityStatus;
visitCardUrl: string | null;
companion: string | null;
userUuid: string;
@@ -30,7 +31,7 @@ export interface MessageUserJoined {
name: string;
characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface;
- away: boolean;
+ status: AvailabilityStatus;
visitCardUrl: string | null;
companion: string | null;
userUuid: string;
diff --git a/front/src/Connexion/RoomConnection.ts b/front/src/Connexion/RoomConnection.ts
index e385fcc7..04993226 100644
--- a/front/src/Connexion/RoomConnection.ts
+++ b/front/src/Connexion/RoomConnection.ts
@@ -41,6 +41,7 @@ import {
SetPlayerDetailsMessage as SetPlayerDetailsMessageTsProto,
PingMessage as PingMessageTsProto,
CharacterLayerMessage,
+ AvailabilityStatus,
} from "../Messages/ts-proto-generated/protos/messages";
import { Subject } from "rxjs";
import { selectCharacterSceneVisibleStore } from "../Stores/SelectCharacterStore";
@@ -520,9 +521,9 @@ export class RoomConnection implements RoomConnection {
this.socket.send(bytes);
}
- public emitPlayerAway(away: boolean): void {
+ public emitPlayerStatusChange(status: AvailabilityStatus): void {
const message = SetPlayerDetailsMessageTsProto.fromPartial({
- away,
+ status,
});
const bytes = ClientToServerMessageTsProto.encode({
message: {
@@ -614,19 +615,6 @@ export class RoomConnection implements RoomConnection {
this.socket.send(bytes);
}
- public setSilent(silent: boolean): void {
- const bytes = ClientToServerMessageTsProto.encode({
- message: {
- $case: "silentMessage",
- silentMessage: {
- silent,
- },
- },
- }).finish();
-
- this.socket.send(bytes);
- }
-
public setViewport(viewport: ViewportInterface): void {
const bytes = ClientToServerMessageTsProto.encode({
message: {
@@ -670,7 +658,7 @@ export class RoomConnection implements RoomConnection {
characterLayers,
visitCardUrl: message.visitCardUrl,
position: ProtobufClientUtils.toPointInterface(position),
- away: message.away,
+ status: message.status,
companion: companion ? companion.name : null,
userUuid: message.userUuid,
outlineColor: message.hasOutline ? message.outlineColor : undefined,
diff --git a/front/src/Phaser/Components/PlayerStatusDot.ts b/front/src/Phaser/Components/PlayerStatusDot.ts
index af893b2f..d85cce86 100644
--- a/front/src/Phaser/Components/PlayerStatusDot.ts
+++ b/front/src/Phaser/Components/PlayerStatusDot.ts
@@ -1,36 +1,41 @@
+import { AvailabilityStatus } from "../../Messages/ts-proto-generated/protos/messages";
import { Easing } from "../../types";
export class PlayerStatusDot extends Phaser.GameObjects.Container {
- private graphics: Phaser.GameObjects.Graphics;
+ private statusImage: Phaser.GameObjects.Image;
+ private statusImageOutline: Phaser.GameObjects.Image;
- private away: boolean;
+ private status: AvailabilityStatus;
- private readonly COLORS = {
- // online: 0x00ff00,
- // away: 0xffff00,
- online: 0x8cc43f,
- onlineOutline: 0x427a25,
- away: 0xf5931e,
- awayOutline: 0x875d13,
+ private readonly COLORS: Record
= {
+ [AvailabilityStatus.AWAY]: { filling: 0xf5931e, outline: 0x875d13 },
+ [AvailabilityStatus.ONLINE]: { filling: 0x8cc43f, outline: 0x427a25 },
+ [AvailabilityStatus.SILENT]: { filling: 0xe74c3c, outline: 0xc0392b },
+ [AvailabilityStatus.JITSI]: { filling: 0x8cc43f, outline: 0x427a25 },
+ [AvailabilityStatus.UNRECOGNIZED]: { filling: 0xffffff, outline: 0xffffff },
+ [AvailabilityStatus.UNCHANGED]: { filling: 0xffffff, outline: 0xffffff },
};
constructor(scene: Phaser.Scene, x: number, y: number) {
super(scene, x, y);
- this.away = false;
+ this.status = AvailabilityStatus.ONLINE;
+
+ this.statusImage = this.scene.add.image(0, 0, "iconStatusIndicatorInside");
+ this.statusImageOutline = this.scene.add.image(0, 0, "iconStatusIndicatorOutline");
+
+ this.add([this.statusImage, this.statusImageOutline]);
- this.graphics = this.scene.add.graphics();
- this.add(this.graphics);
this.redraw();
this.scene.add.existing(this);
}
- public setAway(away: boolean = true, instant: boolean = false): void {
- if (this.away === away) {
+ public setStatus(status: AvailabilityStatus, instant: boolean = false): void {
+ if (this.status === status || status === AvailabilityStatus.UNCHANGED) {
return;
}
- this.away = away;
+ this.status = status;
if (instant) {
this.redraw();
} else {
@@ -56,10 +61,8 @@ export class PlayerStatusDot extends Phaser.GameObjects.Container {
}
private redraw(): void {
- this.graphics.clear();
- this.graphics.fillStyle(this.away ? this.COLORS.away : this.COLORS.online);
- this.graphics.lineStyle(1, this.away ? this.COLORS.awayOutline : this.COLORS.onlineOutline);
- this.graphics.fillCircle(0, 0, 3);
- this.graphics.strokeCircle(0, 0, 3);
+ const colors = this.COLORS[this.status];
+ this.statusImage.setTintFill(colors.filling);
+ this.statusImageOutline.setTintFill(colors.outline);
}
}
diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts
index 681efd29..9e277838 100644
--- a/front/src/Phaser/Entity/Character.ts
+++ b/front/src/Phaser/Entity/Character.ts
@@ -9,7 +9,6 @@ import { Companion } from "../Companion/Companion";
import type { GameScene } from "../Game/GameScene";
import { DEPTH_INGAME_TEXT_INDEX } from "../Game/DepthIndexes";
import type OutlinePipelinePlugin from "phaser3-rex-plugins/plugins/outlinepipeline-plugin.js";
-import { isSilentStore } from "../../Stores/MediaStore";
import { lazyLoadPlayerCharacterTextures } from "./PlayerTexturesLoadingManager";
import { TexturesHelper } from "../Helpers/TexturesHelper";
import type { PictureStore } from "../../Stores/PictureStore";
@@ -20,6 +19,7 @@ import type CancelablePromise from "cancelable-promise";
import { TalkIcon } from "../Components/TalkIcon";
import { Deferred } from "ts-deferred";
import { PlayerStatusDot } from "../Components/PlayerStatusDot";
+import { AvailabilityStatus } from "../../Messages/ts-proto-generated/protos/messages";
const playerNameY = -25;
const interactiveRadius = 35;
@@ -236,8 +236,8 @@ export abstract class Character extends Container implements OutlineableInterfac
this.talkIcon.show(show, forceClose);
}
- public setAwayStatus(away: boolean = true, instant: boolean = false): void {
- this.statusDot.setAway(away, instant);
+ public setStatus(status: AvailabilityStatus, instant: boolean = false): void {
+ this.statusDot.setStatus(status, instant);
}
public addCompanion(name: string, texturePromise?: CancelablePromise): void {
@@ -355,13 +355,6 @@ export abstract class Character extends Container implements OutlineableInterfac
super.destroy();
}
- isSilent() {
- isSilentStore.set(true);
- }
- noSilent() {
- isSilentStore.set(false);
- }
-
playEmote(emote: string) {
this.cancelPreviousEmote();
const emoteY = -45;
diff --git a/front/src/Phaser/Game/GameMapPropertiesListener.ts b/front/src/Phaser/Game/GameMapPropertiesListener.ts
index e94c02df..363b2d1f 100644
--- a/front/src/Phaser/Game/GameMapPropertiesListener.ts
+++ b/front/src/Phaser/Game/GameMapPropertiesListener.ts
@@ -17,6 +17,7 @@ import { audioManagerFileStore, audioManagerVisibilityStore } from "../../Stores
import { iframeListener } from "../../Api/IframeListener";
import { Room } from "../../Connexion/Room";
import LL from "../../i18n/i18n-svelte";
+import { inJitsiStore, silentStore } from "../../Stores/MediaStore";
interface OpenCoWebsite {
actionId: string;
@@ -77,6 +78,7 @@ export class GameMapPropertiesListener {
coWebsiteManager.closeCoWebsite(coWebsite);
}
});
+ inJitsiStore.set(false);
} else {
const openJitsiRoomFunction = () => {
let addPrefix = true;
@@ -119,11 +121,15 @@ export class GameMapPropertiesListener {
uuid: "jitsi",
type: "message",
message: message,
- callback: () => openJitsiRoomFunction(),
+ callback: () => {
+ openJitsiRoomFunction();
+ inJitsiStore.set(true);
+ },
userInputManager: this.scene.userInputManager,
});
} else {
openJitsiRoomFunction();
+ inJitsiStore.set(true);
}
}
});
@@ -160,11 +166,9 @@ export class GameMapPropertiesListener {
this.gameMap.onPropertyChange(GameMapProperties.SILENT, (newValue) => {
if (newValue === undefined || newValue === false || newValue === "") {
- this.scene.connection?.setSilent(false);
- this.scene.CurrentPlayer.noSilent();
+ silentStore.set(false);
} else {
- this.scene.connection?.setSilent(true);
- this.scene.CurrentPlayer.isSilent();
+ silentStore.set(true);
}
});
diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts
index 85e6e614..3a94b820 100644
--- a/front/src/Phaser/Game/GameScene.ts
+++ b/front/src/Phaser/Game/GameScene.ts
@@ -91,7 +91,7 @@ import { MapStore } from "../../Stores/Utils/MapStore";
import { followUsersColorStore } from "../../Stores/FollowStore";
import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler";
import { locale } from "../../i18n/i18n-svelte";
-import { localVolumeStore } from "../../Stores/MediaStore";
+import { availabilityStatusStore, localVolumeStore } from "../../Stores/MediaStore";
import { StringUtils } from "../../Utils/StringUtils";
import { startLayerNamesStore } from "../../Stores/StartLayerNamesStore";
import { JitsiCoWebsite } from "../../WebRtc/CoWebsite/JitsiCoWebsite";
@@ -101,7 +101,6 @@ import CancelablePromise from "cancelable-promise";
import { Deferred } from "ts-deferred";
import { SuperLoaderPlugin } from "../Services/SuperLoaderPlugin";
import { PlayerDetailsUpdatedMessage } from "../../Messages/ts-proto-generated/protos/messages";
-import { privacyShutdownStore } from "../../Stores/PrivacyShutdownStore";
export interface GameSceneInitInterface {
initPosition: PointInterface | null;
reconnecting: boolean;
@@ -249,6 +248,8 @@ export class GameScene extends DirtyScene {
this.listenToIframeEvents();
this.load.image("iconTalk", "/resources/icons/icon_talking.png");
+ this.load.image("iconStatusIndicatorInside", "/resources/icons/icon_status_indicator_inside.png");
+ this.load.image("iconStatusIndicatorOutline", "/resources/icons/icon_status_indicator_outline.png");
if (touchScreenManager.supportTouchScreen) {
this.load.image(joystickBaseKey, joystickBaseImg);
@@ -679,6 +680,11 @@ export class GameScene extends DirtyScene {
this.tryChangeShowVoiceIndicatorState(this.jitsiDominantSpeaker && this.jitsiParticipantsCount > 1);
});
+ availabilityStatusStore.subscribe((status) => {
+ this.connection?.emitPlayerStatusChange(status);
+ this.CurrentPlayer.setStatus(status);
+ });
+
this.emoteUnsubscribe = emoteStore.subscribe((emote) => {
if (emote) {
this.CurrentPlayer?.playEmote(emote.url);
@@ -705,10 +711,6 @@ export class GameScene extends DirtyScene {
}
});
- this.privacyShutdownStoreUnsubscribe = privacyShutdownStore.subscribe((away) => {
- this.connection?.emitPlayerAway(away);
- });
-
Promise.all([
this.connectionAnswerPromiseDeferred.promise as Promise,
...scriptPromises,
@@ -767,7 +769,7 @@ export class GameScene extends DirtyScene {
characterLayers: message.characterLayers,
name: message.name,
position: message.position,
- away: message.away,
+ status: message.status,
visitCardUrl: message.visitCardUrl,
companion: message.companion,
userUuid: message.userUuid,
@@ -1933,8 +1935,8 @@ ${escapedMessage}
if (addPlayerData.outlineColor !== undefined) {
player.setApiOutlineColor(addPlayerData.outlineColor);
}
- if (addPlayerData.away !== undefined) {
- player.setAwayStatus(addPlayerData.away, true);
+ if (addPlayerData.status !== undefined) {
+ player.setStatus(addPlayerData.status, true);
}
this.MapPlayers.add(player);
this.MapPlayersByKey.set(player.userId, player);
@@ -2085,8 +2087,8 @@ ${escapedMessage}
if (message.details?.showVoiceIndicator !== undefined) {
character.showTalkIcon(message.details?.showVoiceIndicator);
}
- if (message.details?.away !== undefined) {
- character.setAwayStatus(message.details?.away);
+ if (message.details?.status !== undefined) {
+ character.setStatus(message.details?.status);
}
}
@@ -2130,13 +2132,10 @@ ${escapedMessage}
}
public enableMediaBehaviors() {
- const silent = this.gameMap.getCurrentProperties().get(GameMapProperties.SILENT);
- this.connection?.setSilent(!!silent);
mediaManager.showMyCamera();
}
public disableMediaBehaviors() {
- this.connection?.setSilent(true);
mediaManager.hideMyCamera();
}
diff --git a/front/src/Phaser/Game/PlayerInterface.ts b/front/src/Phaser/Game/PlayerInterface.ts
index 571bf3cb..c6ac3420 100644
--- a/front/src/Phaser/Game/PlayerInterface.ts
+++ b/front/src/Phaser/Game/PlayerInterface.ts
@@ -1,3 +1,4 @@
+import { AvailabilityStatus } from "../../Messages/ts-proto-generated/protos/messages";
import type { BodyResourceDescriptionInterface } from "../Entity/PlayerTextures";
export interface PlayerInterface {
@@ -7,7 +8,7 @@ export interface PlayerInterface {
visitCardUrl: string | null;
companion: string | null;
userUuid: string;
- away: boolean;
+ status: AvailabilityStatus;
color?: string;
outlineColor?: number;
}
diff --git a/front/src/Phaser/Game/PlayerMovement.ts b/front/src/Phaser/Game/PlayerMovement.ts
index fc14078d..80b4ddcc 100644
--- a/front/src/Phaser/Game/PlayerMovement.ts
+++ b/front/src/Phaser/Game/PlayerMovement.ts
@@ -34,7 +34,6 @@ export class PlayerMovement {
const y =
(this.endPosition.y - this.startPosition.y) * ((tick - this.startTick) / (this.endTick - this.startTick)) +
this.startPosition.y;
- //console.log('Computed position ', x, y)
return {
x,
y,
diff --git a/front/src/Phaser/Helpers/TexturesHelper.ts b/front/src/Phaser/Helpers/TexturesHelper.ts
index 6c0f1aab..4476461f 100644
--- a/front/src/Phaser/Helpers/TexturesHelper.ts
+++ b/front/src/Phaser/Helpers/TexturesHelper.ts
@@ -67,4 +67,20 @@ export class TexturesHelper {
rectangleTexture.generateTexture(textureKey, width, height);
rectangleTexture.destroy();
}
+
+ public static createCircleTexture(
+ scene: Phaser.Scene,
+ textureKey: string,
+ radius: number,
+ color: number,
+ outlineColor?: number,
+ outlineThickness?: number
+ ): void {
+ const circleTexture = scene.add.graphics().fillStyle(color, 1).fillCircle(radius, radius, radius);
+ if (outlineColor) {
+ circleTexture.lineStyle(outlineThickness ?? 1, outlineColor).strokeCircle(radius, radius, radius);
+ }
+ circleTexture.generateTexture(textureKey, radius * 2, radius * 2);
+ circleTexture.destroy();
+ }
}
diff --git a/front/src/Phaser/Player/Player.ts b/front/src/Phaser/Player/Player.ts
index cae7b496..65e423a4 100644
--- a/front/src/Phaser/Player/Player.ts
+++ b/front/src/Phaser/Player/Player.ts
@@ -28,7 +28,6 @@ export class Player extends Character {
companionTexturePromise?: CancelablePromise
) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1, true, companion, companionTexturePromise);
- this.statusDot.setVisible(false);
//the current player model should be push away by other players to prevent conflict
this.getBody().setImmovable(false);
}
diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts
index 534fa53b..dc0680dc 100644
--- a/front/src/Stores/MediaStore.ts
+++ b/front/src/Stores/MediaStore.ts
@@ -11,6 +11,7 @@ import { peerStore } from "./PeerStore";
import { privacyShutdownStore } from "./PrivacyShutdownStore";
import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError";
import { SoundMeter } from "../Phaser/Components/SoundMeter";
+import { AvailabilityStatus } from "../Messages/ts-proto-generated/protos/messages";
import deepEqual from "fast-deep-equal";
/**
@@ -179,10 +180,19 @@ function createVideoConstraintStore() {
};
}
-/**
- * A store containing if user is silent, so if he is in silent zone. This permit to show et hide camera of user
- */
-export const isSilentStore = writable(false);
+export const inJitsiStore = writable(false);
+export const silentStore = writable(false);
+
+export const availabilityStatusStore = derived(
+ [inJitsiStore, silentStore, privacyShutdownStore],
+ ([$inJitsiStore, $silentStore, $privacyShutdownStore]) => {
+ if ($inJitsiStore) return AvailabilityStatus.JITSI;
+ if ($silentStore) return AvailabilityStatus.SILENT;
+ if ($privacyShutdownStore) return AvailabilityStatus.AWAY;
+ return AvailabilityStatus.ONLINE;
+ },
+ AvailabilityStatus.ONLINE
+);
export const videoConstraintStore = createVideoConstraintStore();
@@ -241,7 +251,7 @@ export const mediaStreamConstraintsStore = derived(
audioConstraintStore,
privacyShutdownStore,
cameraEnergySavingStore,
- isSilentStore,
+ availabilityStatusStore,
],
(
[
@@ -253,7 +263,7 @@ export const mediaStreamConstraintsStore = derived(
$audioConstraintStore,
$privacyShutdownStore,
$cameraEnergySavingStore,
- $isSilentStore,
+ $availabilityStatusStore,
],
set
) => {
@@ -310,7 +320,7 @@ export const mediaStreamConstraintsStore = derived(
//currentAudioConstraint = false;
}
- if ($isSilentStore === true) {
+ if ($availabilityStatusStore === AvailabilityStatus.SILENT) {
currentVideoConstraint = false;
currentAudioConstraint = false;
}
diff --git a/front/src/Stores/PlayersStore.ts b/front/src/Stores/PlayersStore.ts
index 70c59b92..be270b5a 100644
--- a/front/src/Stores/PlayersStore.ts
+++ b/front/src/Stores/PlayersStore.ts
@@ -2,6 +2,7 @@ import { writable } from "svelte/store";
import type { PlayerInterface } from "../Phaser/Game/PlayerInterface";
import type { RoomConnection } from "../Connexion/RoomConnection";
import { getRandomColor } from "../WebRtc/ColorGenerator";
+import { AvailabilityStatus } from "../Messages/ts-proto-generated/protos/messages";
let idCount = 0;
@@ -28,7 +29,7 @@ function createPlayersStore() {
visitCardUrl: message.visitCardUrl,
companion: message.companion,
userUuid: message.userUuid,
- away: message.away,
+ status: message.status,
color: getRandomColor(),
});
return users;
@@ -58,7 +59,7 @@ function createPlayersStore() {
characterLayers: [],
visitCardUrl: null,
companion: null,
- away: false,
+ status: AvailabilityStatus.ONLINE,
userUuid: "dummy",
color: getRandomColor(),
});
diff --git a/maps/tests/index.html b/maps/tests/index.html
index be9ba2c5..370d99e6 100644
--- a/maps/tests/index.html
+++ b/maps/tests/index.html
@@ -479,6 +479,14 @@
Away mode settings
+
+
+ Success Failure Pending
+ |
+
+ Test Status Indicator
+ |
+