From 453ccb77457a3c4667476d3f420f4e9cd3870ec1 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Mon, 7 Mar 2022 15:43:00 +0100 Subject: [PATCH 01/15] Adds settings options and localUser functions --- .../Components/Menu/SettingsSubMenu.svelte | 464 ++++++++++-------- front/src/Connexion/LocalUserStore.ts | 9 + front/src/Stores/MediaStore.ts | 9 + front/src/i18n/de-DE/menu.ts | 8 + front/src/i18n/en-US/menu.ts | 8 + front/src/i18n/fr-FR/menu.ts | 8 + 6 files changed, 290 insertions(+), 216 deletions(-) diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index d5b40822..d5bcab56 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -8,243 +8,275 @@ import { displayableLocales, setCurrentLocale } from "../../i18n/locales"; import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils"; - let fullscreen: boolean = localUserStore.getFullscreen(); - let notification: boolean = localUserStore.getNotification() === "granted"; - let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); - let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); - let valueGame: number = localUserStore.getGameQualityValue(); - let valueVideo: number = localUserStore.getVideoQualityValue(); - let valueLocale: string = $locale; - let previewValueGame = valueGame; - let previewValueVideo = valueVideo; - let previewValueLocale = valueLocale; + let fullscreen: boolean = localUserStore.getFullscreen(); + let notification: boolean = localUserStore.getNotification() === "granted"; + let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); + let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); + let valueGame: number = localUserStore.getGameQualityValue(); + let valueVideo: number = localUserStore.getVideoQualityValue(); + let valueLocale: string = $locale; + let valuePrivacySettings = localUserStore.getPrivacySettings(); - function saveSetting() { - let change = false; + let previewValueGame = valueGame; + let previewValueVideo = valueVideo; + let previewValueLocale = valueLocale; + let previewPrivacySettings = valuePrivacySettings; // TODO: retreive from local storage - if (valueLocale !== previewValueLocale) { - previewValueLocale = valueLocale; - setCurrentLocale(valueLocale as Locales); - } + function saveSetting() { + let change = false; - if (valueVideo !== previewValueVideo) { - previewValueVideo = valueVideo; - videoConstraintStore.setFrameRate(valueVideo); - } - - if (valueGame !== previewValueGame) { - previewValueGame = valueGame; - localUserStore.setGameQualityValue(valueGame); - change = true; - } - - if (change) { - window.location.reload(); - } - - closeMenu(); + if (valueLocale !== previewValueLocale) { + previewValueLocale = valueLocale; + setCurrentLocale(valueLocale as Locales); } - function changeFullscreen() { - const body = HtmlUtils.querySelectorOrFail("body"); - if (body) { - if (document.fullscreenElement !== null && !fullscreen) { - document.exitFullscreen().catch((e) => console.error(e)); - } else { - body.requestFullscreen().catch((e) => console.error(e)); - } - localUserStore.setFullscreen(fullscreen); - } + if (valueVideo !== previewValueVideo) { + previewValueVideo = valueVideo; + videoConstraintStore.setFrameRate(valueVideo); } - function changeNotification() { - if (Notification.permission === "granted") { + if (valueGame !== previewValueGame) { + previewValueGame = valueGame; + localUserStore.setGameQualityValue(valueGame); + change = true; + } + + if (valuePrivacySettings !== previewPrivacySettings) { + console.log(`was: ${previewPrivacySettings} | is: ${valuePrivacySettings}`) + localUserStore.setPrivacySettings(valuePrivacySettings); + } + + if (change) { + window.location.reload(); + } + + closeMenu(); + } + + function changeFullscreen() { + const body = HtmlUtils.querySelectorOrFail("body"); + if (body) { + if (document.fullscreenElement !== null && !fullscreen) { + document.exitFullscreen().catch((e) => console.error(e)); + } else { + body.requestFullscreen().catch((e) => console.error(e)); + } + localUserStore.setFullscreen(fullscreen); + } + } + + function changeNotification() { + if (Notification.permission === "granted") { + localUserStore.setNotification(notification ? "granted" : "denied"); + } else { + Notification.requestPermission() + .then((response) => { + if (response === "granted") { localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - Notification.requestPermission() - .then((response) => { - if (response === "granted") { - localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - localUserStore.setNotification("denied"); - notification = false; - } - }) - .catch((e) => console.error(e)); - } + } else { + localUserStore.setNotification("denied"); + notification = false; + } + }) + .catch((e) => console.error(e)); } + } - function changeForceCowebsiteTrigger() { - localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); - } + function changeForceCowebsiteTrigger() { + localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); + } - function changeIgnoreFollowRequests() { - localUserStore.setIgnoreFollowRequests(ignoreFollowRequests); - } + function changeIgnoreFollowRequests() { + localUserStore.setIgnoreFollowRequests(ignoreFollowRequests); + } - function closeMenu() { - menuVisiblilityStore.set(false); - } + function closeMenu() { + menuVisiblilityStore.set(false); + } - const isMobile = isMediaBreakpointUp("md"); + const isMobile = isMediaBreakpointUp("md");
-
-

{$LL.menu.settings.gameQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.videoQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.language.title()}

-
- -
-
-
-

{$LL.menu.settings.save.warning()}

- +

{$LL.menu.settings.gameQuality.title()}

+
+ - {$LL.menu.settings.fullscreen()} - - - - -
+ + + + +
+ +
+

{$LL.menu.settings.videoQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.language.title()}

+
+ +
+
+ +
+

{$LL.menu.settings.privacySettings.title()}

+

{$LL.menu.settings.privacySettings.explaination()}

+
+ +
+
+
+

{$LL.menu.settings.save.warning()}

+ +
+
+ + + + +
diff --git a/front/src/Connexion/LocalUserStore.ts b/front/src/Connexion/LocalUserStore.ts index 24d4ab42..23e0bcb0 100644 --- a/front/src/Connexion/LocalUserStore.ts +++ b/front/src/Connexion/LocalUserStore.ts @@ -24,6 +24,7 @@ const code = "code"; const cameraSetup = "cameraSetup"; const cacheAPIIndex = "workavdenture-cache"; const userProperties = "user-properties"; +const privacySettings = "privacySettings"; class LocalUserStore { saveUser(localUser: LocalUser) { @@ -224,6 +225,14 @@ class LocalUserStore { return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined; } + setPrivacySettings(option: string) { + localStorage.setItem(privacySettings, option) + } + + getPrivacySettings() { + return localStorage.getItem(privacySettings); + } + getAllUserProperties(): Map { const result = new Map(); for (let i = 0; i < localStorage.length; i++) { diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index 9494eb7e..f1681615 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -12,6 +12,7 @@ import { privacyShutdownStore } from "./PrivacyShutdownStore"; import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError"; import { SoundMeter } from "../Phaser/Components/SoundMeter"; import { AudioContext } from "standardized-audio-context"; +import { visibilityStore } from "./VisibilityStore"; /** * A store that contains the camera state requested by the user (on or off). @@ -242,6 +243,8 @@ export const mediaStreamConstraintsStore = derived( privacyShutdownStore, cameraEnergySavingStore, isSilentStore, + visibilityStore, + //TODO: optionState ], ( [ @@ -254,6 +257,7 @@ export const mediaStreamConstraintsStore = derived( $privacyShutdownStore, $cameraEnergySavingStore, $isSilentStore, + $visibilityStore ], set ) => { @@ -308,6 +312,11 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } + // if ($visibilityStore === false && $option) { + // + // } + //TODO + // Let's make the changes only if the new value is different from the old one. if ( previousComputedVideoConstraint != currentVideoConstraint || diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index c1b7bc18..dc19e481 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,6 +57,14 @@ const menu: NonNullable = { language: { title: "Sprache", }, + privacySettings: { + title: "Datenschutzeinstellungen", //TODO: confirm & complete translation + explaination: "", + allEnabled: "", + onlyCameraEnabled: "", + onlyMicrophoneEnabled: "", + allDisabled: "" + }, save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", button: "Speichern", diff --git a/front/src/i18n/en-US/menu.ts b/front/src/i18n/en-US/menu.ts index 0883fb15..04f2f377 100644 --- a/front/src/i18n/en-US/menu.ts +++ b/front/src/i18n/en-US/menu.ts @@ -57,6 +57,14 @@ const menu: BaseTranslation = { language: { title: "Language", }, + privacySettings: { + title: "Privacy settings", + explaination: "Here you can set an option to keep your microphone/camera enabled when switching active tabs.", + allEnabled: "Camera and microphone always enabled", + onlyCameraEnabled: "Microphone disabled when the WA tab is not focused", + onlyMicrophoneEnabled: "Camera disabled when the WA tab is not focused", + allDisabled: "Both disabled when the WA tab is not focused" + }, save: { warning: "(Saving these settings will restart the game)", button: "Save", diff --git a/front/src/i18n/fr-FR/menu.ts b/front/src/i18n/fr-FR/menu.ts index f8c58990..9e32e9ba 100644 --- a/front/src/i18n/fr-FR/menu.ts +++ b/front/src/i18n/fr-FR/menu.ts @@ -57,6 +57,14 @@ const menu: NonNullable = { language: { title: "Langage", }, + privacySettings: { + title: "Paramètres de confidentialité", + explaination: "Vous pouvez définir ici si vous souhaitez conserver ou non l'activation du microphone/de la caméra au passage sur un autre onglet.", + allEnabled: "Camera et microphone toujours actifs", + onlyCameraEnabled: "Seul le microphone est activé quand l'onglet WA n'est pas sélectionné", + onlyMicrophoneEnabled: "Seule la caméra est activé quand l'onglet WA n'est pas sélectionné", + allDisabled: "Tout désactiver quand l'onglet WA n'est pas sélectionné" + }, save: { warning: "(La sauvegarde de ces paramètres redémarre le jeu)", button: "Sauvegarder", From 9442c9c9f13b45f211d33a4bec3261b826cbb51c Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Wed, 9 Mar 2022 17:46:11 +0100 Subject: [PATCH 02/15] PrivacyShutdownStore modifies constraints according to the user's setting --- .../Components/Menu/SettingsSubMenu.svelte | 3 +-- front/src/Stores/MediaStore.ts | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index d5bcab56..67a0bdc3 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -20,7 +20,7 @@ let previewValueGame = valueGame; let previewValueVideo = valueVideo; let previewValueLocale = valueLocale; - let previewPrivacySettings = valuePrivacySettings; // TODO: retreive from local storage + let previewPrivacySettings = valuePrivacySettings; function saveSetting() { let change = false; @@ -42,7 +42,6 @@ } if (valuePrivacySettings !== previewPrivacySettings) { - console.log(`was: ${previewPrivacySettings} | is: ${valuePrivacySettings}`) localUserStore.setPrivacySettings(valuePrivacySettings); } diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index f1681615..f73174c9 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -11,7 +11,6 @@ import { peerStore } from "./PeerStore"; import { privacyShutdownStore } from "./PrivacyShutdownStore"; import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError"; import { SoundMeter } from "../Phaser/Components/SoundMeter"; -import { AudioContext } from "standardized-audio-context"; import { visibilityStore } from "./VisibilityStore"; /** @@ -244,7 +243,6 @@ export const mediaStreamConstraintsStore = derived( cameraEnergySavingStore, isSilentStore, visibilityStore, - //TODO: optionState ], ( [ @@ -257,7 +255,7 @@ export const mediaStreamConstraintsStore = derived( $privacyShutdownStore, $cameraEnergySavingStore, $isSilentStore, - $visibilityStore + $visibilityStore, ], set ) => { @@ -296,7 +294,19 @@ export const mediaStreamConstraintsStore = derived( // Disable webcam for privacy reasons (the game is not visible and we were talking to no one) if ($privacyShutdownStore === true) { - currentVideoConstraint = false; + const userSetting = localUserStore.getPrivacySettings(); + switch (userSetting) { + case "cameraEnabled": + currentAudioConstraint = false; + break; + case "microphoneEnabled": + currentVideoConstraint = false; + break; + case "noneEnabled": + currentVideoConstraint = false; + currentAudioConstraint = false; + break; + } } // Disable webcam for energy reasons (the user is not moving and we are talking to no one) @@ -312,10 +322,6 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } - // if ($visibilityStore === false && $option) { - // - // } - //TODO // Let's make the changes only if the new value is different from the old one. if ( From 216f34c113a06a56499ed368762c65ae50c09525 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Mon, 21 Mar 2022 18:39:20 +0100 Subject: [PATCH 03/15] switches dropdown for checkboxes and adjusts wording --- .../Components/Menu/SettingsSubMenu.svelte | 494 +++++++++--------- front/src/Connexion/LocalUserStore.ts | 44 +- front/src/Stores/MediaStore.ts | 20 +- front/src/i18n/de-DE/menu.ts | 11 +- front/src/i18n/en-US/menu.ts | 11 +- front/src/i18n/fr-FR/menu.ts | 11 +- 6 files changed, 308 insertions(+), 283 deletions(-) diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index 67a0bdc3..40bd67cd 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -8,274 +8,274 @@ import { displayableLocales, setCurrentLocale } from "../../i18n/locales"; import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils"; - let fullscreen: boolean = localUserStore.getFullscreen(); - let notification: boolean = localUserStore.getNotification() === "granted"; - let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); - let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); - let valueGame: number = localUserStore.getGameQualityValue(); - let valueVideo: number = localUserStore.getVideoQualityValue(); - let valueLocale: string = $locale; - let valuePrivacySettings = localUserStore.getPrivacySettings(); + let fullscreen: boolean = localUserStore.getFullscreen(); + let notification: boolean = localUserStore.getNotification() === "granted"; + let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); + let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); + let valueGame: number = localUserStore.getGameQualityValue(); + let valueVideo: number = localUserStore.getVideoQualityValue(); + let valueLocale: string = $locale; + let valueCameraPrivacySettings = localUserStore.getCameraPrivacySettings(); + let valueMicrophonePrivacySettings = localUserStore.getMicrophonePrivacySettings(); - let previewValueGame = valueGame; - let previewValueVideo = valueVideo; - let previewValueLocale = valueLocale; - let previewPrivacySettings = valuePrivacySettings; + let previewValueGame = valueGame; + let previewValueVideo = valueVideo; + let previewValueLocale = valueLocale; + let previewCameraPrivacySettings = valueCameraPrivacySettings; + let previewMicrophonePrivacySettings = valueMicrophonePrivacySettings; - function saveSetting() { - let change = false; + function saveSetting() { + let change = false; - if (valueLocale !== previewValueLocale) { - previewValueLocale = valueLocale; - setCurrentLocale(valueLocale as Locales); + if (valueLocale !== previewValueLocale) { + previewValueLocale = valueLocale; + setCurrentLocale(valueLocale as Locales); + } + + if (valueVideo !== previewValueVideo) { + previewValueVideo = valueVideo; + videoConstraintStore.setFrameRate(valueVideo); + } + + if (valueGame !== previewValueGame) { + previewValueGame = valueGame; + localUserStore.setGameQualityValue(valueGame); + change = true; + } + + if (valueCameraPrivacySettings !== previewCameraPrivacySettings) { + previewCameraPrivacySettings = valueCameraPrivacySettings; + localUserStore.setCameraPrivacySettings(valueCameraPrivacySettings); + } + + if (valueMicrophonePrivacySettings !== previewMicrophonePrivacySettings) { + previewMicrophonePrivacySettings = valueMicrophonePrivacySettings; + localUserStore.setMicrophonePrivacySettings(valueMicrophonePrivacySettings); + } + + if (change) { + window.location.reload(); + } + + closeMenu(); } - if (valueVideo !== previewValueVideo) { - previewValueVideo = valueVideo; - videoConstraintStore.setFrameRate(valueVideo); + function changeFullscreen() { + const body = HtmlUtils.querySelectorOrFail("body"); + if (body) { + if (document.fullscreenElement !== null && !fullscreen) { + document.exitFullscreen().catch((e) => console.error(e)); + } else { + body.requestFullscreen().catch((e) => console.error(e)); + } + localUserStore.setFullscreen(fullscreen); + } } - if (valueGame !== previewValueGame) { - previewValueGame = valueGame; - localUserStore.setGameQualityValue(valueGame); - change = true; - } - - if (valuePrivacySettings !== previewPrivacySettings) { - localUserStore.setPrivacySettings(valuePrivacySettings); - } - - if (change) { - window.location.reload(); - } - - closeMenu(); - } - - function changeFullscreen() { - const body = HtmlUtils.querySelectorOrFail("body"); - if (body) { - if (document.fullscreenElement !== null && !fullscreen) { - document.exitFullscreen().catch((e) => console.error(e)); - } else { - body.requestFullscreen().catch((e) => console.error(e)); - } - localUserStore.setFullscreen(fullscreen); - } - } - - function changeNotification() { - if (Notification.permission === "granted") { - localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - Notification.requestPermission() - .then((response) => { - if (response === "granted") { + function changeNotification() { + if (Notification.permission === "granted") { localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - localUserStore.setNotification("denied"); - notification = false; - } - }) - .catch((e) => console.error(e)); + } else { + Notification.requestPermission() + .then((response) => { + if (response === "granted") { + localUserStore.setNotification(notification ? "granted" : "denied"); + } else { + localUserStore.setNotification("denied"); + notification = false; + } + }) + .catch((e) => console.error(e)); + } } - } - function changeForceCowebsiteTrigger() { - localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); - } + function changeForceCowebsiteTrigger() { + localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); + } - function changeIgnoreFollowRequests() { - localUserStore.setIgnoreFollowRequests(ignoreFollowRequests); - } + function changeIgnoreFollowRequests() { + localUserStore.setIgnoreFollowRequests(ignoreFollowRequests); + } - function closeMenu() { - menuVisiblilityStore.set(false); - } + function closeMenu() { + menuVisiblilityStore.set(false); + } - const isMobile = isMediaBreakpointUp("md"); + const isMobile = isMediaBreakpointUp("md");
-
-

{$LL.menu.settings.gameQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.videoQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.language.title()}

-
- -
-
+
+

{$LL.menu.settings.gameQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.videoQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.language.title()}

+
+ +
+
-
-

{$LL.menu.settings.privacySettings.title()}

-

{$LL.menu.settings.privacySettings.explaination()}

-
- -
-
-
-

{$LL.menu.settings.save.warning()}

- -
-
- - - - -
+
+

{$LL.menu.settings.privacySettings.title()}

+

{$LL.menu.settings.privacySettings.explanation()}

+ + +
+
+

{$LL.menu.settings.save.warning()}

+ +
+
+ + + + +
diff --git a/front/src/Connexion/LocalUserStore.ts b/front/src/Connexion/LocalUserStore.ts index 23e0bcb0..091d3232 100644 --- a/front/src/Connexion/LocalUserStore.ts +++ b/front/src/Connexion/LocalUserStore.ts @@ -24,12 +24,14 @@ const code = "code"; const cameraSetup = "cameraSetup"; const cacheAPIIndex = "workavdenture-cache"; const userProperties = "user-properties"; -const privacySettings = "privacySettings"; +const cameraPrivacySettings = "cameraPrivacySettings"; +const microphonePrivacySettings = "microphonePrivacySettings"; class LocalUserStore { saveUser(localUser: LocalUser) { localStorage.setItem("localUser", JSON.stringify(localUser)); } + getLocalUser(): LocalUser | null { const data = localStorage.getItem("localUser"); return data ? JSON.parse(data) : null; @@ -38,6 +40,7 @@ class LocalUserStore { setName(name: string): void { localStorage.setItem(playerNameKey, name); } + getName(): string | null { const value = localStorage.getItem(playerNameKey) || ""; return isUserNameValid(value) ? value : null; @@ -46,6 +49,7 @@ class LocalUserStore { setPlayerCharacterIndex(playerCharacterIndex: number): void { localStorage.setItem(selectedPlayerKey, "" + playerCharacterIndex); } + getPlayerCharacterIndex(): number { return parseInt(localStorage.getItem(selectedPlayerKey) || ""); } @@ -53,6 +57,7 @@ class LocalUserStore { setCustomCursorPosition(activeRow: number, selectedLayers: number[]): void { localStorage.setItem(customCursorPositionKey, JSON.stringify({ activeRow, selectedLayers })); } + getCustomCursorPosition(): { activeRow: number; selectedLayers: number[] } | null { return JSON.parse(localStorage.getItem(customCursorPositionKey) || "null"); } @@ -60,6 +65,7 @@ class LocalUserStore { setCharacterLayers(layers: string[]): void { localStorage.setItem(characterLayersKey, JSON.stringify(layers)); } + getCharacterLayers(): string[] | null { const value = JSON.parse(localStorage.getItem(characterLayersKey) || "null"); return areCharacterLayersValid(value) ? value : null; @@ -68,6 +74,7 @@ class LocalUserStore { setCompanion(companion: string | null): void { return localStorage.setItem(companionKey, JSON.stringify(companion)); } + getCompanion(): string | null { const companion = JSON.parse(localStorage.getItem(companionKey) || "null"); @@ -77,6 +84,7 @@ class LocalUserStore { return companion; } + wasCompanionSet(): boolean { return localStorage.getItem(companionKey) ? true : false; } @@ -84,6 +92,7 @@ class LocalUserStore { setGameQualityValue(value: number): void { localStorage.setItem(gameQualityKey, "" + value); } + getGameQualityValue(): number { return parseInt(localStorage.getItem(gameQualityKey) || "60"); } @@ -91,6 +100,7 @@ class LocalUserStore { setVideoQualityValue(value: number): void { localStorage.setItem(videoQualityKey, "" + value); } + getVideoQualityValue(): number { return parseInt(localStorage.getItem(videoQualityKey) || "20"); } @@ -98,6 +108,7 @@ class LocalUserStore { setAudioPlayerVolume(value: number): void { localStorage.setItem(audioPlayerVolumeKey, "" + value); } + getAudioPlayerVolume(): number { return parseFloat(localStorage.getItem(audioPlayerVolumeKey) || "1"); } @@ -105,6 +116,7 @@ class LocalUserStore { setAudioPlayerMuted(value: boolean): void { localStorage.setItem(audioPlayerMuteKey, value.toString()); } + getAudioPlayerMuted(): boolean { return localStorage.getItem(audioPlayerMuteKey) === "true"; } @@ -112,6 +124,7 @@ class LocalUserStore { setHelpCameraSettingsShown(): void { localStorage.setItem(helpCameraSettingsShown, "1"); } + getHelpCameraSettingsShown(): boolean { return localStorage.getItem(helpCameraSettingsShown) === "1"; } @@ -119,6 +132,7 @@ class LocalUserStore { setFullscreen(value: boolean): void { localStorage.setItem(fullscreenKey, value.toString()); } + getFullscreen(): boolean { return localStorage.getItem(fullscreenKey) === "true"; } @@ -126,6 +140,7 @@ class LocalUserStore { setForceCowebsiteTrigger(value: boolean): void { localStorage.setItem(forceCowebsiteTriggerKey, value.toString()); } + getForceCowebsiteTrigger(): boolean { return localStorage.getItem(forceCowebsiteTriggerKey) === "true"; } @@ -133,6 +148,7 @@ class LocalUserStore { setIgnoreFollowRequests(value: boolean): void { localStorage.setItem(ignoreFollowRequests, value.toString()); } + getIgnoreFollowRequests(): boolean { return localStorage.getItem(ignoreFollowRequests) === "true"; } @@ -149,11 +165,13 @@ class LocalUserStore { } } } + getLastRoomUrl(): string { return ( localStorage.getItem(lastRoomUrl) ?? window.location.protocol + "//" + window.location.host + START_ROOM_URL ); } + getLastRoomUrlCacheApi(): Promise { if (!("caches" in window)) { return Promise.resolve(undefined); @@ -170,6 +188,7 @@ class LocalUserStore { setAuthToken(value: string | null) { value ? localStorage.setItem(authToken, value) : localStorage.removeItem(authToken); } + getAuthToken(): string | null { return localStorage.getItem(authToken); } @@ -196,23 +215,29 @@ class LocalUserStore { } return oldValue === value; } + setState(value: string) { localStorage.setItem(state, value); } + getState(): string | null { return localStorage.getItem(state); } + generateNonce(): string { const newNonce = uuidv4(); localStorage.setItem(nonce, newNonce); return newNonce; } + getNonce(): string | null { return localStorage.getItem(nonce); } + setCode(value: string): void { localStorage.setItem(code, value); } + getCode(): string | null { return localStorage.getItem(code); } @@ -220,17 +245,26 @@ class LocalUserStore { setCameraSetup(cameraId: string) { localStorage.setItem(cameraSetup, cameraId); } + getCameraSetup(): { video: unknown; audio: unknown } | undefined { const cameraSetupValues = localStorage.getItem(cameraSetup); return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined; } - setPrivacySettings(option: string) { - localStorage.setItem(privacySettings, option) + setCameraPrivacySettings(option: boolean) { + localStorage.setItem(cameraPrivacySettings, option.toString()); } - getPrivacySettings() { - return localStorage.getItem(privacySettings); + getCameraPrivacySettings() { + return localStorage.getItem(cameraPrivacySettings) === "true"; + } + + setMicrophonePrivacySettings(option: boolean) { + localStorage.setItem(microphonePrivacySettings, option.toString()); + } + + getMicrophonePrivacySettings() { + return localStorage.getItem(microphonePrivacySettings) === "true"; } getAllUserProperties(): Map { diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index f73174c9..c662a28f 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -294,18 +294,13 @@ export const mediaStreamConstraintsStore = derived( // Disable webcam for privacy reasons (the game is not visible and we were talking to no one) if ($privacyShutdownStore === true) { - const userSetting = localUserStore.getPrivacySettings(); - switch (userSetting) { - case "cameraEnabled": - currentAudioConstraint = false; - break; - case "microphoneEnabled": - currentVideoConstraint = false; - break; - case "noneEnabled": - currentVideoConstraint = false; - currentAudioConstraint = false; - break; + const userMicrophonePrivacySetting = localUserStore.getMicrophonePrivacySettings(); + const userCameraPrivacySetting = localUserStore.getCameraPrivacySettings(); + if (!userMicrophonePrivacySetting) { + currentAudioConstraint = false; + } + if (!userCameraPrivacySetting) { + currentVideoConstraint = false; } } @@ -322,7 +317,6 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } - // Let's make the changes only if the new value is different from the old one. if ( previousComputedVideoConstraint != currentVideoConstraint || diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index dc19e481..3d785b6f 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,13 +57,12 @@ const menu: NonNullable = { language: { title: "Sprache", }, + //TODO: complete translation privacySettings: { - title: "Datenschutzeinstellungen", //TODO: confirm & complete translation - explaination: "", - allEnabled: "", - onlyCameraEnabled: "", - onlyMicrophoneEnabled: "", - allDisabled: "" + title: "", + explanation: "", + cameraToggle: "", + microphoneToggle: "", }, save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", diff --git a/front/src/i18n/en-US/menu.ts b/front/src/i18n/en-US/menu.ts index 04f2f377..6eb6de21 100644 --- a/front/src/i18n/en-US/menu.ts +++ b/front/src/i18n/en-US/menu.ts @@ -58,12 +58,11 @@ const menu: BaseTranslation = { title: "Language", }, privacySettings: { - title: "Privacy settings", - explaination: "Here you can set an option to keep your microphone/camera enabled when switching active tabs.", - allEnabled: "Camera and microphone always enabled", - onlyCameraEnabled: "Microphone disabled when the WA tab is not focused", - onlyMicrophoneEnabled: "Camera disabled when the WA tab is not focused", - allDisabled: "Both disabled when the WA tab is not focused" + title: "Away mode settings", + explanation: + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, save: { warning: "(Saving these settings will restart the game)", diff --git a/front/src/i18n/fr-FR/menu.ts b/front/src/i18n/fr-FR/menu.ts index 9e32e9ba..1515ea8f 100644 --- a/front/src/i18n/fr-FR/menu.ts +++ b/front/src/i18n/fr-FR/menu.ts @@ -58,12 +58,11 @@ const menu: NonNullable = { title: "Langage", }, privacySettings: { - title: "Paramètres de confidentialité", - explaination: "Vous pouvez définir ici si vous souhaitez conserver ou non l'activation du microphone/de la caméra au passage sur un autre onglet.", - allEnabled: "Camera et microphone toujours actifs", - onlyCameraEnabled: "Seul le microphone est activé quand l'onglet WA n'est pas sélectionné", - onlyMicrophoneEnabled: "Seule la caméra est activé quand l'onglet WA n'est pas sélectionné", - allDisabled: "Tout désactiver quand l'onglet WA n'est pas sélectionné" + title: "Paramètres du mode absent", + explanation: + "Quand l'onglet WorkAdventure n'est pas visible, vous passez en \"mode absent\". Lorsque ce mode est actif, vous pouvez décider de garder vos webcam et/ou micro désactivés tant que vous ne revenez pas sur l'onglet", + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, save: { warning: "(La sauvegarde de ces paramètres redémarre le jeu)", From a80f7ced4413ee0e6e24dc6b4462e4757af82143 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Tue, 22 Mar 2022 16:48:02 +0100 Subject: [PATCH 04/15] Adds the todo about German translation --- front/src/i18n/de-DE/menu.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index 3d785b6f..8b1faff3 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,13 +57,15 @@ const menu: NonNullable = { language: { title: "Sprache", }, - //TODO: complete translation + //TODO: German translation privacySettings: { - title: "", - explanation: "", - cameraToggle: "", - microphoneToggle: "", + title: "Away mode settings", + explanation: + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, + //END-TODO: German translation save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", button: "Speichern", From 1681373d887cfa46690f1117f2ad028b6524dbb8 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Tue, 22 Mar 2022 17:25:22 +0100 Subject: [PATCH 05/15] Adds test map --- front/src/i18n/de-DE/menu.ts | 2 +- .../AwayModeSettings/away_mode_settings.json | 97 +++++++++++++++++++ maps/tests/index.html | 8 ++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 maps/tests/AwayModeSettings/away_mode_settings.json diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index 8b1faff3..9b5fd460 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -61,7 +61,7 @@ const menu: NonNullable = { privacySettings: { title: "Away mode settings", explanation: - 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', cameraToggle: "Camera", microphoneToggle: "Microphone", }, diff --git a/maps/tests/AwayModeSettings/away_mode_settings.json b/maps/tests/AwayModeSettings/away_mode_settings.json new file mode 100644 index 00000000..62cc3c01 --- /dev/null +++ b/maps/tests/AwayModeSettings/away_mode_settings.json @@ -0,0 +1,97 @@ +{ "compressionlevel":-1, + "height":20, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":20, + "id":42, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":20, + "id":39, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":43, + "name":"Test", + "objects":[ + { + "height":225.333333333333, + "id":13, + "name":"", + "rotation":0, + "text": + { + "text":"Test: \n- Open two windows (you can use Private Mode) so that you control two Wokas.\n\n- On woka A window: go to Menu > Settings and set your away mode options\n- On woka A window: open a new tab in the browser, so that your WA tab is not visible\n\n- On woka B window: move to woka A to check that the options were applied", + "wrap":true + }, + "type":"", + "visible":true, + "width":434.773333333333, + "x":97.9466666666667, + "y":33.8366666666667 + }, + { + "height":155, + "id":16, + "name":"", + "rotation":0, + "text": + { + "color":"#00007f", + "text":"Reminder: \nThere are 4 cases to test for your away mode (WA tab hidden) settings. \nCamera and microphone stay enabled\nOnly camera stays enabled\nOnly microphone stays enabled\nBoth are disabled", + "wrap":true + }, + "type":"", + "visible":true, + "width":407.4375, + "x":96.9479166666667, + "y":322.5 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":44, + "nextobjectid":17, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"..\/Test\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":20 +} \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 26a1795f..1ba1cbb2 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -455,6 +455,14 @@ Testing zoom via mouse wheel + + + Success Failure Pending + + + Away mode settings + +
-
-

{$LL.menu.settings.gameQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.videoQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.language.title()}

-
- -
-
-
-

{$LL.menu.settings.save.warning()}

- +

{$LL.menu.settings.gameQuality.title()}

+
+ - {$LL.menu.settings.fullscreen()} - - - - - -
+ + + + +
+ +
+

{$LL.menu.settings.videoQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.language.title()}

+
+ +
+
+ +
+

{$LL.menu.settings.privacySettings.title()}

+

{$LL.menu.settings.privacySettings.explaination()}

+
+ +
+
+
+

{$LL.menu.settings.save.warning()}

+ +
+
+ + + + +
diff --git a/front/src/Connexion/LocalUserStore.ts b/front/src/Connexion/LocalUserStore.ts index 7753fd7b..fd3a5931 100644 --- a/front/src/Connexion/LocalUserStore.ts +++ b/front/src/Connexion/LocalUserStore.ts @@ -25,6 +25,7 @@ const code = "code"; const cameraSetup = "cameraSetup"; const cacheAPIIndex = "workavdenture-cache"; const userProperties = "user-properties"; +const privacySettings = "privacySettings"; class LocalUserStore { saveUser(localUser: LocalUser) { @@ -231,6 +232,14 @@ class LocalUserStore { return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined; } + setPrivacySettings(option: string) { + localStorage.setItem(privacySettings, option) + } + + getPrivacySettings() { + return localStorage.getItem(privacySettings); + } + getAllUserProperties(): Map { const result = new Map(); for (let i = 0; i < localStorage.length; i++) { diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index b86a97ce..a12469af 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -12,6 +12,7 @@ import { privacyShutdownStore } from "./PrivacyShutdownStore"; import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError"; import { SoundMeter } from "../Phaser/Components/SoundMeter"; import { AudioContext } from "standardized-audio-context"; +import { visibilityStore } from "./VisibilityStore"; /** * A store that contains the camera state requested by the user (on or off). @@ -242,6 +243,8 @@ export const mediaStreamConstraintsStore = derived( privacyShutdownStore, cameraEnergySavingStore, isSilentStore, + visibilityStore, + //TODO: optionState ], ( [ @@ -254,6 +257,7 @@ export const mediaStreamConstraintsStore = derived( $privacyShutdownStore, $cameraEnergySavingStore, $isSilentStore, + $visibilityStore ], set ) => { @@ -308,6 +312,11 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } + // if ($visibilityStore === false && $option) { + // + // } + //TODO + // Let's make the changes only if the new value is different from the old one. if ( previousComputedVideoConstraint != currentVideoConstraint || diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index c1b7bc18..dc19e481 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,6 +57,14 @@ const menu: NonNullable = { language: { title: "Sprache", }, + privacySettings: { + title: "Datenschutzeinstellungen", //TODO: confirm & complete translation + explaination: "", + allEnabled: "", + onlyCameraEnabled: "", + onlyMicrophoneEnabled: "", + allDisabled: "" + }, save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", button: "Speichern", diff --git a/front/src/i18n/en-US/menu.ts b/front/src/i18n/en-US/menu.ts index 0883fb15..04f2f377 100644 --- a/front/src/i18n/en-US/menu.ts +++ b/front/src/i18n/en-US/menu.ts @@ -57,6 +57,14 @@ const menu: BaseTranslation = { language: { title: "Language", }, + privacySettings: { + title: "Privacy settings", + explaination: "Here you can set an option to keep your microphone/camera enabled when switching active tabs.", + allEnabled: "Camera and microphone always enabled", + onlyCameraEnabled: "Microphone disabled when the WA tab is not focused", + onlyMicrophoneEnabled: "Camera disabled when the WA tab is not focused", + allDisabled: "Both disabled when the WA tab is not focused" + }, save: { warning: "(Saving these settings will restart the game)", button: "Save", diff --git a/front/src/i18n/fr-FR/menu.ts b/front/src/i18n/fr-FR/menu.ts index f8c58990..9e32e9ba 100644 --- a/front/src/i18n/fr-FR/menu.ts +++ b/front/src/i18n/fr-FR/menu.ts @@ -57,6 +57,14 @@ const menu: NonNullable = { language: { title: "Langage", }, + privacySettings: { + title: "Paramètres de confidentialité", + explaination: "Vous pouvez définir ici si vous souhaitez conserver ou non l'activation du microphone/de la caméra au passage sur un autre onglet.", + allEnabled: "Camera et microphone toujours actifs", + onlyCameraEnabled: "Seul le microphone est activé quand l'onglet WA n'est pas sélectionné", + onlyMicrophoneEnabled: "Seule la caméra est activé quand l'onglet WA n'est pas sélectionné", + allDisabled: "Tout désactiver quand l'onglet WA n'est pas sélectionné" + }, save: { warning: "(La sauvegarde de ces paramètres redémarre le jeu)", button: "Sauvegarder", From 40c0f06c8a7734b241eda0f28cf75f2f45433dc0 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Wed, 9 Mar 2022 17:46:11 +0100 Subject: [PATCH 09/15] PrivacyShutdownStore modifies constraints according to the user's setting --- .../Components/Menu/SettingsSubMenu.svelte | 28 +++++++++---------- front/src/Stores/MediaStore.ts | 22 +++++++++------ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index 69857504..67a3073e 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -9,19 +9,20 @@ import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils"; import { audioManagerVolumeStore } from "../../Stores/AudioManagerStore"; - let fullscreen: boolean = localUserStore.getFullscreen(); - let notification: boolean = localUserStore.getNotification() === "granted"; - let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); - let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); - let decreaseAudioPlayerVolumeWhileTalking: boolean = localUserStore.getDecreaseAudioPlayerVolumeWhileTalking(); - let valueGame: number = localUserStore.getGameQualityValue(); - let valueVideo: number = localUserStore.getVideoQualityValue(); - let valueLocale: string = $locale; - let valuePrivacySettings = localUserStore.getPrivacySettings(); - let previewValueGame = valueGame; - let previewValueVideo = valueVideo; - let previewValueLocale = valueLocale; - let previewPrivacySettings = valuePrivacySettings; // TODO: retreive from local storage + let fullscreen: boolean = localUserStore.getFullscreen(); + let notification: boolean = localUserStore.getNotification() === "granted"; + let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); + let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); + let decreaseAudioPlayerVolumeWhileTalking: boolean = localUserStore.getDecreaseAudioPlayerVolumeWhileTalking(); + let valueGame: number = localUserStore.getGameQualityValue(); + let valueVideo: number = localUserStore.getVideoQualityValue(); + let valueLocale: string = $locale; + let valuePrivacySettings = localUserStore.getPrivacySettings(); + + let previewValueGame = valueGame; + let previewValueVideo = valueVideo; + let previewValueLocale = valueLocale; + let previewPrivacySettings = valuePrivacySettings; function saveSetting() { let change = false; @@ -43,7 +44,6 @@ } if (valuePrivacySettings !== previewPrivacySettings) { - console.log(`was: ${previewPrivacySettings} | is: ${valuePrivacySettings}`) localUserStore.setPrivacySettings(valuePrivacySettings); } diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index a12469af..f94a3c55 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -11,7 +11,6 @@ import { peerStore } from "./PeerStore"; import { privacyShutdownStore } from "./PrivacyShutdownStore"; import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError"; import { SoundMeter } from "../Phaser/Components/SoundMeter"; -import { AudioContext } from "standardized-audio-context"; import { visibilityStore } from "./VisibilityStore"; /** @@ -244,7 +243,6 @@ export const mediaStreamConstraintsStore = derived( cameraEnergySavingStore, isSilentStore, visibilityStore, - //TODO: optionState ], ( [ @@ -257,7 +255,7 @@ export const mediaStreamConstraintsStore = derived( $privacyShutdownStore, $cameraEnergySavingStore, $isSilentStore, - $visibilityStore + $visibilityStore, ], set ) => { @@ -296,7 +294,19 @@ export const mediaStreamConstraintsStore = derived( // Disable webcam for privacy reasons (the game is not visible and we were talking to no one) if ($privacyShutdownStore === true) { - currentVideoConstraint = false; + const userSetting = localUserStore.getPrivacySettings(); + switch (userSetting) { + case "cameraEnabled": + currentAudioConstraint = false; + break; + case "microphoneEnabled": + currentVideoConstraint = false; + break; + case "noneEnabled": + currentVideoConstraint = false; + currentAudioConstraint = false; + break; + } } // Disable webcam for energy reasons (the user is not moving and we are talking to no one) @@ -312,10 +322,6 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } - // if ($visibilityStore === false && $option) { - // - // } - //TODO // Let's make the changes only if the new value is different from the old one. if ( From 4e5fb735bddf75081f7f63e33700752f20aa4953 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Mon, 21 Mar 2022 18:39:20 +0100 Subject: [PATCH 10/15] switches dropdown for checkboxes and adjusts wording --- .../Components/Menu/SettingsSubMenu.svelte | 490 +++++++++--------- front/src/Connexion/LocalUserStore.ts | 44 +- front/src/Stores/MediaStore.ts | 20 +- front/src/i18n/de-DE/menu.ts | 11 +- front/src/i18n/en-US/menu.ts | 11 +- front/src/i18n/fr-FR/menu.ts | 11 +- 6 files changed, 306 insertions(+), 281 deletions(-) diff --git a/front/src/Components/Menu/SettingsSubMenu.svelte b/front/src/Components/Menu/SettingsSubMenu.svelte index 67a3073e..6623ea44 100644 --- a/front/src/Components/Menu/SettingsSubMenu.svelte +++ b/front/src/Components/Menu/SettingsSubMenu.svelte @@ -9,84 +9,92 @@ import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils"; import { audioManagerVolumeStore } from "../../Stores/AudioManagerStore"; - let fullscreen: boolean = localUserStore.getFullscreen(); - let notification: boolean = localUserStore.getNotification() === "granted"; - let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); - let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); - let decreaseAudioPlayerVolumeWhileTalking: boolean = localUserStore.getDecreaseAudioPlayerVolumeWhileTalking(); - let valueGame: number = localUserStore.getGameQualityValue(); - let valueVideo: number = localUserStore.getVideoQualityValue(); - let valueLocale: string = $locale; - let valuePrivacySettings = localUserStore.getPrivacySettings(); + let fullscreen: boolean = localUserStore.getFullscreen(); + let notification: boolean = localUserStore.getNotification() === "granted"; + let forceCowebsiteTrigger: boolean = localUserStore.getForceCowebsiteTrigger(); + let ignoreFollowRequests: boolean = localUserStore.getIgnoreFollowRequests(); + let decreaseAudioPlayerVolumeWhileTalking: boolean = localUserStore.getDecreaseAudioPlayerVolumeWhileTalking(); + let valueGame: number = localUserStore.getGameQualityValue(); + let valueVideo: number = localUserStore.getVideoQualityValue(); + let valueLocale: string = $locale; + let valueCameraPrivacySettings = localUserStore.getCameraPrivacySettings(); + let valueMicrophonePrivacySettings = localUserStore.getMicrophonePrivacySettings(); - let previewValueGame = valueGame; - let previewValueVideo = valueVideo; - let previewValueLocale = valueLocale; - let previewPrivacySettings = valuePrivacySettings; + let previewValueGame = valueGame; + let previewValueVideo = valueVideo; + let previewValueLocale = valueLocale; + let previewCameraPrivacySettings = valueCameraPrivacySettings; + let previewMicrophonePrivacySettings = valueMicrophonePrivacySettings; - function saveSetting() { - let change = false; + function saveSetting() { + let change = false; - if (valueLocale !== previewValueLocale) { - previewValueLocale = valueLocale; - setCurrentLocale(valueLocale as Locales); - } + if (valueLocale !== previewValueLocale) { + previewValueLocale = valueLocale; + setCurrentLocale(valueLocale as Locales); + } - if (valueVideo !== previewValueVideo) { - previewValueVideo = valueVideo; - videoConstraintStore.setFrameRate(valueVideo); - } + if (valueVideo !== previewValueVideo) { + previewValueVideo = valueVideo; + videoConstraintStore.setFrameRate(valueVideo); + } - if (valueGame !== previewValueGame) { - previewValueGame = valueGame; - localUserStore.setGameQualityValue(valueGame); - change = true; - } + if (valueGame !== previewValueGame) { + previewValueGame = valueGame; + localUserStore.setGameQualityValue(valueGame); + change = true; + } - if (valuePrivacySettings !== previewPrivacySettings) { - localUserStore.setPrivacySettings(valuePrivacySettings); - } + if (valueCameraPrivacySettings !== previewCameraPrivacySettings) { + previewCameraPrivacySettings = valueCameraPrivacySettings; + localUserStore.setCameraPrivacySettings(valueCameraPrivacySettings); + } + + if (valueMicrophonePrivacySettings !== previewMicrophonePrivacySettings) { + previewMicrophonePrivacySettings = valueMicrophonePrivacySettings; + localUserStore.setMicrophonePrivacySettings(valueMicrophonePrivacySettings); + } if (change) { window.location.reload(); } audioManagerVolumeStore.setDecreaseWhileTalking(decreaseAudioPlayerVolumeWhileTalking); - closeMenu(); - } - - function changeFullscreen() { - const body = HtmlUtils.querySelectorOrFail("body"); - if (body) { - if (document.fullscreenElement !== null && !fullscreen) { - document.exitFullscreen().catch((e) => console.error(e)); - } else { - body.requestFullscreen().catch((e) => console.error(e)); - } - localUserStore.setFullscreen(fullscreen); + closeMenu(); } - } - function changeNotification() { - if (Notification.permission === "granted") { - localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - Notification.requestPermission() - .then((response) => { - if (response === "granted") { + function changeFullscreen() { + const body = HtmlUtils.querySelectorOrFail("body"); + if (body) { + if (document.fullscreenElement !== null && !fullscreen) { + document.exitFullscreen().catch((e) => console.error(e)); + } else { + body.requestFullscreen().catch((e) => console.error(e)); + } + localUserStore.setFullscreen(fullscreen); + } + } + + function changeNotification() { + if (Notification.permission === "granted") { localUserStore.setNotification(notification ? "granted" : "denied"); - } else { - localUserStore.setNotification("denied"); - notification = false; - } - }) - .catch((e) => console.error(e)); + } else { + Notification.requestPermission() + .then((response) => { + if (response === "granted") { + localUserStore.setNotification(notification ? "granted" : "denied"); + } else { + localUserStore.setNotification("denied"); + notification = false; + } + }) + .catch((e) => console.error(e)); + } } - } - function changeForceCowebsiteTrigger() { - localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); - } + function changeForceCowebsiteTrigger() { + localUserStore.setForceCowebsiteTrigger(forceCowebsiteTrigger); + } function changeIgnoreFollowRequests() { localUserStore.setIgnoreFollowRequests(ignoreFollowRequests); @@ -99,198 +107,190 @@ localUserStore.setDecreaseAudioPlayerVolumeWhileTalking(decreaseAudioPlayerVolumeWhileTalking); } - const isMobile = isMediaBreakpointUp("md"); + const isMobile = isMediaBreakpointUp("md");
-
-

{$LL.menu.settings.gameQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.videoQuality.title()}

-
- -
-
-
-

{$LL.menu.settings.language.title()}

-
- -
-
+
+

{$LL.menu.settings.gameQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.videoQuality.title()}

+
+ +
+
+
+

{$LL.menu.settings.language.title()}

+
+ +
+
-
-

{$LL.menu.settings.privacySettings.title()}

-

{$LL.menu.settings.privacySettings.explaination()}

-
- -
-
-
-

{$LL.menu.settings.save.warning()}

- -
-
- - - - -
+
+

{$LL.menu.settings.privacySettings.title()}

+

{$LL.menu.settings.privacySettings.explanation()}

+ + +
+
+

{$LL.menu.settings.save.warning()}

+ +
+
+ + + + +
diff --git a/front/src/Connexion/LocalUserStore.ts b/front/src/Connexion/LocalUserStore.ts index fd3a5931..8e0d6f07 100644 --- a/front/src/Connexion/LocalUserStore.ts +++ b/front/src/Connexion/LocalUserStore.ts @@ -25,12 +25,14 @@ const code = "code"; const cameraSetup = "cameraSetup"; const cacheAPIIndex = "workavdenture-cache"; const userProperties = "user-properties"; -const privacySettings = "privacySettings"; +const cameraPrivacySettings = "cameraPrivacySettings"; +const microphonePrivacySettings = "microphonePrivacySettings"; class LocalUserStore { saveUser(localUser: LocalUser) { localStorage.setItem("localUser", JSON.stringify(localUser)); } + getLocalUser(): LocalUser | null { const data = localStorage.getItem("localUser"); return data ? JSON.parse(data) : null; @@ -39,6 +41,7 @@ class LocalUserStore { setName(name: string): void { localStorage.setItem(playerNameKey, name); } + getName(): string | null { const value = localStorage.getItem(playerNameKey) || ""; return isUserNameValid(value) ? value : null; @@ -47,6 +50,7 @@ class LocalUserStore { setPlayerCharacterIndex(playerCharacterIndex: number): void { localStorage.setItem(selectedPlayerKey, "" + playerCharacterIndex); } + getPlayerCharacterIndex(): number { return parseInt(localStorage.getItem(selectedPlayerKey) || ""); } @@ -54,6 +58,7 @@ class LocalUserStore { setCustomCursorPosition(activeRow: number, selectedLayers: number[]): void { localStorage.setItem(customCursorPositionKey, JSON.stringify({ activeRow, selectedLayers })); } + getCustomCursorPosition(): { activeRow: number; selectedLayers: number[] } | null { return JSON.parse(localStorage.getItem(customCursorPositionKey) || "null"); } @@ -61,6 +66,7 @@ class LocalUserStore { setCharacterLayers(layers: string[]): void { localStorage.setItem(characterLayersKey, JSON.stringify(layers)); } + getCharacterLayers(): string[] | null { const value = JSON.parse(localStorage.getItem(characterLayersKey) || "null"); return areCharacterLayersValid(value) ? value : null; @@ -69,6 +75,7 @@ class LocalUserStore { setCompanion(companion: string | null): void { return localStorage.setItem(companionKey, JSON.stringify(companion)); } + getCompanion(): string | null { const companion = JSON.parse(localStorage.getItem(companionKey) || "null"); @@ -78,6 +85,7 @@ class LocalUserStore { return companion; } + wasCompanionSet(): boolean { return localStorage.getItem(companionKey) ? true : false; } @@ -85,6 +93,7 @@ class LocalUserStore { setGameQualityValue(value: number): void { localStorage.setItem(gameQualityKey, "" + value); } + getGameQualityValue(): number { return parseInt(localStorage.getItem(gameQualityKey) || "60"); } @@ -92,6 +101,7 @@ class LocalUserStore { setVideoQualityValue(value: number): void { localStorage.setItem(videoQualityKey, "" + value); } + getVideoQualityValue(): number { return parseInt(localStorage.getItem(videoQualityKey) || "20"); } @@ -99,6 +109,7 @@ class LocalUserStore { setAudioPlayerVolume(value: number): void { localStorage.setItem(audioPlayerVolumeKey, "" + value); } + getAudioPlayerVolume(): number { return parseFloat(localStorage.getItem(audioPlayerVolumeKey) || "1"); } @@ -106,6 +117,7 @@ class LocalUserStore { setAudioPlayerMuted(value: boolean): void { localStorage.setItem(audioPlayerMuteKey, value.toString()); } + getAudioPlayerMuted(): boolean { return localStorage.getItem(audioPlayerMuteKey) === "true"; } @@ -113,6 +125,7 @@ class LocalUserStore { setHelpCameraSettingsShown(): void { localStorage.setItem(helpCameraSettingsShown, "1"); } + getHelpCameraSettingsShown(): boolean { return localStorage.getItem(helpCameraSettingsShown) === "1"; } @@ -120,6 +133,7 @@ class LocalUserStore { setFullscreen(value: boolean): void { localStorage.setItem(fullscreenKey, value.toString()); } + getFullscreen(): boolean { return localStorage.getItem(fullscreenKey) === "true"; } @@ -127,6 +141,7 @@ class LocalUserStore { setForceCowebsiteTrigger(value: boolean): void { localStorage.setItem(forceCowebsiteTriggerKey, value.toString()); } + getForceCowebsiteTrigger(): boolean { return localStorage.getItem(forceCowebsiteTriggerKey) === "true"; } @@ -134,6 +149,7 @@ class LocalUserStore { setIgnoreFollowRequests(value: boolean): void { localStorage.setItem(ignoreFollowRequests, value.toString()); } + getIgnoreFollowRequests(): boolean { return localStorage.getItem(ignoreFollowRequests) === "true"; } @@ -156,11 +172,13 @@ class LocalUserStore { } } } + getLastRoomUrl(): string { return ( localStorage.getItem(lastRoomUrl) ?? window.location.protocol + "//" + window.location.host + START_ROOM_URL ); } + getLastRoomUrlCacheApi(): Promise { if (!("caches" in window)) { return Promise.resolve(undefined); @@ -177,6 +195,7 @@ class LocalUserStore { setAuthToken(value: string | null) { value ? localStorage.setItem(authToken, value) : localStorage.removeItem(authToken); } + getAuthToken(): string | null { return localStorage.getItem(authToken); } @@ -203,23 +222,29 @@ class LocalUserStore { } return oldValue === value; } + setState(value: string) { localStorage.setItem(state, value); } + getState(): string | null { return localStorage.getItem(state); } + generateNonce(): string { const newNonce = uuidv4(); localStorage.setItem(nonce, newNonce); return newNonce; } + getNonce(): string | null { return localStorage.getItem(nonce); } + setCode(value: string): void { localStorage.setItem(code, value); } + getCode(): string | null { return localStorage.getItem(code); } @@ -227,17 +252,26 @@ class LocalUserStore { setCameraSetup(cameraId: string) { localStorage.setItem(cameraSetup, cameraId); } + getCameraSetup(): { video: unknown; audio: unknown } | undefined { const cameraSetupValues = localStorage.getItem(cameraSetup); return cameraSetupValues != undefined ? JSON.parse(cameraSetupValues) : undefined; } - setPrivacySettings(option: string) { - localStorage.setItem(privacySettings, option) + setCameraPrivacySettings(option: boolean) { + localStorage.setItem(cameraPrivacySettings, option.toString()); } - getPrivacySettings() { - return localStorage.getItem(privacySettings); + getCameraPrivacySettings() { + return localStorage.getItem(cameraPrivacySettings) === "true"; + } + + setMicrophonePrivacySettings(option: boolean) { + localStorage.setItem(microphonePrivacySettings, option.toString()); + } + + getMicrophonePrivacySettings() { + return localStorage.getItem(microphonePrivacySettings) === "true"; } getAllUserProperties(): Map { diff --git a/front/src/Stores/MediaStore.ts b/front/src/Stores/MediaStore.ts index f94a3c55..557cbcd8 100644 --- a/front/src/Stores/MediaStore.ts +++ b/front/src/Stores/MediaStore.ts @@ -294,18 +294,13 @@ export const mediaStreamConstraintsStore = derived( // Disable webcam for privacy reasons (the game is not visible and we were talking to no one) if ($privacyShutdownStore === true) { - const userSetting = localUserStore.getPrivacySettings(); - switch (userSetting) { - case "cameraEnabled": - currentAudioConstraint = false; - break; - case "microphoneEnabled": - currentVideoConstraint = false; - break; - case "noneEnabled": - currentVideoConstraint = false; - currentAudioConstraint = false; - break; + const userMicrophonePrivacySetting = localUserStore.getMicrophonePrivacySettings(); + const userCameraPrivacySetting = localUserStore.getCameraPrivacySettings(); + if (!userMicrophonePrivacySetting) { + currentAudioConstraint = false; + } + if (!userCameraPrivacySetting) { + currentVideoConstraint = false; } } @@ -322,7 +317,6 @@ export const mediaStreamConstraintsStore = derived( currentAudioConstraint = false; } - // Let's make the changes only if the new value is different from the old one. if ( previousComputedVideoConstraint != currentVideoConstraint || diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index dc19e481..3d785b6f 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,13 +57,12 @@ const menu: NonNullable = { language: { title: "Sprache", }, + //TODO: complete translation privacySettings: { - title: "Datenschutzeinstellungen", //TODO: confirm & complete translation - explaination: "", - allEnabled: "", - onlyCameraEnabled: "", - onlyMicrophoneEnabled: "", - allDisabled: "" + title: "", + explanation: "", + cameraToggle: "", + microphoneToggle: "", }, save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", diff --git a/front/src/i18n/en-US/menu.ts b/front/src/i18n/en-US/menu.ts index 04f2f377..6eb6de21 100644 --- a/front/src/i18n/en-US/menu.ts +++ b/front/src/i18n/en-US/menu.ts @@ -58,12 +58,11 @@ const menu: BaseTranslation = { title: "Language", }, privacySettings: { - title: "Privacy settings", - explaination: "Here you can set an option to keep your microphone/camera enabled when switching active tabs.", - allEnabled: "Camera and microphone always enabled", - onlyCameraEnabled: "Microphone disabled when the WA tab is not focused", - onlyMicrophoneEnabled: "Camera disabled when the WA tab is not focused", - allDisabled: "Both disabled when the WA tab is not focused" + title: "Away mode settings", + explanation: + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, save: { warning: "(Saving these settings will restart the game)", diff --git a/front/src/i18n/fr-FR/menu.ts b/front/src/i18n/fr-FR/menu.ts index 9e32e9ba..1515ea8f 100644 --- a/front/src/i18n/fr-FR/menu.ts +++ b/front/src/i18n/fr-FR/menu.ts @@ -58,12 +58,11 @@ const menu: NonNullable = { title: "Langage", }, privacySettings: { - title: "Paramètres de confidentialité", - explaination: "Vous pouvez définir ici si vous souhaitez conserver ou non l'activation du microphone/de la caméra au passage sur un autre onglet.", - allEnabled: "Camera et microphone toujours actifs", - onlyCameraEnabled: "Seul le microphone est activé quand l'onglet WA n'est pas sélectionné", - onlyMicrophoneEnabled: "Seule la caméra est activé quand l'onglet WA n'est pas sélectionné", - allDisabled: "Tout désactiver quand l'onglet WA n'est pas sélectionné" + title: "Paramètres du mode absent", + explanation: + "Quand l'onglet WorkAdventure n'est pas visible, vous passez en \"mode absent\". Lorsque ce mode est actif, vous pouvez décider de garder vos webcam et/ou micro désactivés tant que vous ne revenez pas sur l'onglet", + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, save: { warning: "(La sauvegarde de ces paramètres redémarre le jeu)", From 5c6a74df4cbe479fed48590f5729634fba0edb35 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Tue, 22 Mar 2022 16:48:02 +0100 Subject: [PATCH 11/15] Adds the todo about German translation --- front/src/i18n/de-DE/menu.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index 3d785b6f..8b1faff3 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -57,13 +57,15 @@ const menu: NonNullable = { language: { title: "Sprache", }, - //TODO: complete translation + //TODO: German translation privacySettings: { - title: "", - explanation: "", - cameraToggle: "", - microphoneToggle: "", + title: "Away mode settings", + explanation: + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + cameraToggle: "Camera", + microphoneToggle: "Microphone", }, + //END-TODO: German translation save: { warning: "(Das Spiel wird nach dem Speichern neugestartet)", button: "Speichern", From 421592514193b814c852c965fef0e4d05aa51b88 Mon Sep 17 00:00:00 2001 From: Benedicte Quimbert Date: Tue, 22 Mar 2022 17:25:22 +0100 Subject: [PATCH 12/15] Adds test map --- front/src/i18n/de-DE/menu.ts | 2 +- .../AwayModeSettings/away_mode_settings.json | 97 +++++++++++++++++++ maps/tests/index.html | 8 ++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 maps/tests/AwayModeSettings/away_mode_settings.json diff --git a/front/src/i18n/de-DE/menu.ts b/front/src/i18n/de-DE/menu.ts index 8b1faff3..9b5fd460 100644 --- a/front/src/i18n/de-DE/menu.ts +++ b/front/src/i18n/de-DE/menu.ts @@ -61,7 +61,7 @@ const menu: NonNullable = { privacySettings: { title: "Away mode settings", explanation: - 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', + 'When the WorkAdventure tab is not visible, it switches to "away mode". In this mode, you can decide to automatically disable your webcam and/or microphone for as long as the tab stays hidden.', cameraToggle: "Camera", microphoneToggle: "Microphone", }, diff --git a/maps/tests/AwayModeSettings/away_mode_settings.json b/maps/tests/AwayModeSettings/away_mode_settings.json new file mode 100644 index 00000000..62cc3c01 --- /dev/null +++ b/maps/tests/AwayModeSettings/away_mode_settings.json @@ -0,0 +1,97 @@ +{ "compressionlevel":-1, + "height":20, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":20, + "id":42, + "name":"start", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":20, + "id":39, + "name":"floor", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":20, + "x":0, + "y":0 + }, + { + "draworder":"topdown", + "id":43, + "name":"Test", + "objects":[ + { + "height":225.333333333333, + "id":13, + "name":"", + "rotation":0, + "text": + { + "text":"Test: \n- Open two windows (you can use Private Mode) so that you control two Wokas.\n\n- On woka A window: go to Menu > Settings and set your away mode options\n- On woka A window: open a new tab in the browser, so that your WA tab is not visible\n\n- On woka B window: move to woka A to check that the options were applied", + "wrap":true + }, + "type":"", + "visible":true, + "width":434.773333333333, + "x":97.9466666666667, + "y":33.8366666666667 + }, + { + "height":155, + "id":16, + "name":"", + "rotation":0, + "text": + { + "color":"#00007f", + "text":"Reminder: \nThere are 4 cases to test for your away mode (WA tab hidden) settings. \nCamera and microphone stay enabled\nOnly camera stays enabled\nOnly microphone stays enabled\nBoth are disabled", + "wrap":true + }, + "type":"", + "visible":true, + "width":407.4375, + "x":96.9479166666667, + "y":322.5 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "x":0, + "y":0 + }], + "nextlayerid":44, + "nextobjectid":17, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.7.2", + "tileheight":32, + "tilesets":[ + { + "columns":11, + "firstgid":1, + "image":"..\/Test\/tileset1.png", + "imageheight":352, + "imagewidth":352, + "margin":0, + "name":"tileset1", + "spacing":0, + "tilecount":121, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "type":"map", + "version":"1.6", + "width":20 +} \ No newline at end of file diff --git a/maps/tests/index.html b/maps/tests/index.html index 3a1ef520..e625aa6d 100644 --- a/maps/tests/index.html +++ b/maps/tests/index.html @@ -463,6 +463,14 @@ Testing zoom via mouse wheel + + + Success Failure Pending + + + Away mode settings + +