Compare commits
3 Commits
3e7edcb1b7
...
4a43083178
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a43083178 | |||
| efcbf9e972 | |||
| f11ed67452 |
Binary file not shown.
@@ -3,9 +3,11 @@ import type { ReactNode } from "react";
|
||||
import {
|
||||
Captions,
|
||||
Gauge,
|
||||
LogOut,
|
||||
Hand,
|
||||
Laptop,
|
||||
Music2,
|
||||
RotateCcw,
|
||||
Server,
|
||||
Volume2,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
@@ -14,25 +16,19 @@ import {
|
||||
GRAPHICS_PRESETS,
|
||||
type GraphicsPreset,
|
||||
} from "@/data/world/graphicsConfig";
|
||||
import { useDebugStore } from "@/hooks/debug/useDebugStore";
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import { useSettingsStore } from "@/managers/stores/useSettingsStore";
|
||||
import { useWorldSettingsStore } from "@/managers/stores/useWorldSettingsStore";
|
||||
import type { HandTrackingSource } from "@/types/handTracking/handTracking";
|
||||
import type { SubtitleLanguage } from "@/types/settings/settings";
|
||||
import { isDebugEnabled } from "@/utils/debug/isDebugEnabled";
|
||||
import { hasSiteBeenVisitedToday } from "@/utils/cookies/siteVisitCookie";
|
||||
import { Debug } from "@/utils/debug/Debug";
|
||||
|
||||
function formatPercent(value: number): string {
|
||||
return `${Math.round(value * 100)}%`;
|
||||
}
|
||||
|
||||
function clearCookies(): void {
|
||||
document.cookie.split(";").forEach((cookie) => {
|
||||
const cookieName = cookie.split("=")[0]?.trim();
|
||||
if (!cookieName) return;
|
||||
|
||||
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
|
||||
});
|
||||
}
|
||||
|
||||
interface VolumeSliderProps {
|
||||
id: string;
|
||||
label: string;
|
||||
@@ -74,6 +70,26 @@ function formatChunkDistance(distance: number): string {
|
||||
return `${distance}m`;
|
||||
}
|
||||
|
||||
const HAND_TRACKING_OPTIONS = [
|
||||
{
|
||||
description: "Calcul local",
|
||||
icon: <Laptop size={14} aria-hidden="true" />,
|
||||
label: "Sur cet ordi",
|
||||
source: "browser",
|
||||
},
|
||||
{
|
||||
description: "Soulage l'ordi",
|
||||
icon: <Server size={14} aria-hidden="true" />,
|
||||
label: "Mode assisté",
|
||||
source: "backend",
|
||||
},
|
||||
] as const satisfies readonly {
|
||||
description: string;
|
||||
icon: ReactNode;
|
||||
label: string;
|
||||
source: HandTrackingSource;
|
||||
}[];
|
||||
|
||||
interface GraphicsPresetButtonProps {
|
||||
active: boolean;
|
||||
preset: GraphicsPreset;
|
||||
@@ -108,6 +124,9 @@ function GraphicsPresetButton({
|
||||
|
||||
export function GameSettingsMenu(): React.JSX.Element | null {
|
||||
const resetGame = useGameStore((state) => state.resetGame);
|
||||
const handTrackingSource = useDebugStore((debug) =>
|
||||
debug.getHandTrackingSource(),
|
||||
);
|
||||
const graphicsPreset = useWorldSettingsStore(
|
||||
(state) => state.graphics.preset,
|
||||
);
|
||||
@@ -148,17 +167,15 @@ export function GameSettingsMenu(): React.JSX.Element | null {
|
||||
|
||||
if (!isSettingsMenuOpen) return null;
|
||||
|
||||
const handleQuit = (): void => {
|
||||
clearCookies();
|
||||
window.location.assign("/");
|
||||
};
|
||||
|
||||
const handleRestart = (): void => {
|
||||
resetGame();
|
||||
window.location.reload();
|
||||
setSettingsMenuOpen(false);
|
||||
window.location.assign(hasSiteBeenVisitedToday() ? "/" : "/site");
|
||||
};
|
||||
|
||||
const showDebugRestart = isDebugEnabled();
|
||||
const handleHandTrackingSourceChange = (source: HandTrackingSource): void => {
|
||||
Debug.getInstance().setHandTrackingSource(source);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="game-settings-menu" role="dialog" aria-modal="true">
|
||||
@@ -185,7 +202,7 @@ export function GameSettingsMenu(): React.JSX.Element | null {
|
||||
>
|
||||
<div className="game-settings-menu__section-title">
|
||||
<Gauge size={16} aria-hidden="true" />
|
||||
<h3 id="graphics-settings-heading">Performance</h3>
|
||||
<h3 id="graphics-settings-heading">Graphisme</h3>
|
||||
</div>
|
||||
<div
|
||||
className="game-settings-menu__choice-group game-settings-menu__choice-group--presets"
|
||||
@@ -269,9 +286,38 @@ export function GameSettingsMenu(): React.JSX.Element | null {
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
className="game-settings-menu__section game-settings-menu__section--right"
|
||||
aria-labelledby="hand-tracking-settings-heading"
|
||||
>
|
||||
<div className="game-settings-menu__section-title">
|
||||
<Hand size={16} aria-hidden="true" />
|
||||
<h3 id="hand-tracking-settings-heading">Détection des mains</h3>
|
||||
</div>
|
||||
<div
|
||||
className="game-settings-menu__choice-group game-settings-menu__choice-group--hand-tracking"
|
||||
aria-label="Mode de détection des mains"
|
||||
>
|
||||
{HAND_TRACKING_OPTIONS.map((option) => (
|
||||
<button
|
||||
key={option.source}
|
||||
type="button"
|
||||
className={
|
||||
handTrackingSource === option.source ? "active" : undefined
|
||||
}
|
||||
onClick={() => handleHandTrackingSourceChange(option.source)}
|
||||
aria-pressed={handTrackingSource === option.source}
|
||||
>
|
||||
{option.icon}
|
||||
<span>{option.label}</span>
|
||||
<small>{option.description}</small>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{showDebugRestart ? (
|
||||
<button
|
||||
className="game-settings-menu__restart"
|
||||
type="button"
|
||||
@@ -280,16 +326,6 @@ export function GameSettingsMenu(): React.JSX.Element | null {
|
||||
<RotateCcw size={14} aria-hidden="true" />
|
||||
Recommencer
|
||||
</button>
|
||||
) : null}
|
||||
|
||||
<button
|
||||
className="game-settings-menu__quit"
|
||||
type="button"
|
||||
onClick={handleQuit}
|
||||
>
|
||||
<LogOut size={14} aria-hidden="true" />
|
||||
Quitter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
+30
-21
@@ -1220,8 +1220,8 @@ canvas {
|
||||
place-items: center;
|
||||
padding: clamp(18px, 4vw, 42px);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(4, 10, 18, 0.64), rgba(2, 6, 12, 0.86)),
|
||||
rgba(0, 0, 0, 0.72);
|
||||
linear-gradient(180deg, rgba(4, 10, 18, 0.72), rgba(2, 6, 12, 0.9)),
|
||||
rgba(0, 0, 0, 0.82);
|
||||
color: #ffffff;
|
||||
pointer-events: auto;
|
||||
backdrop-filter: blur(14px);
|
||||
@@ -1236,8 +1236,8 @@ canvas {
|
||||
border: 1px solid rgba(125, 211, 252, 0.38);
|
||||
border-radius: 8px;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(8, 20, 34, 0.94), rgba(3, 8, 14, 0.96)),
|
||||
rgba(4, 8, 12, 0.96);
|
||||
linear-gradient(180deg, rgba(8, 20, 34, 0.98), rgba(3, 8, 14, 0.99)),
|
||||
rgba(4, 8, 12, 0.99);
|
||||
box-shadow:
|
||||
0 28px 90px rgba(0, 0, 0, 0.58),
|
||||
inset 0 0 0 1px rgba(255, 255, 255, 0.05),
|
||||
@@ -1327,13 +1327,17 @@ canvas {
|
||||
padding: 14px;
|
||||
border: 1px solid rgba(125, 211, 252, 0.2);
|
||||
border-radius: 8px;
|
||||
background: rgba(5, 14, 24, 0.64);
|
||||
background: rgba(5, 14, 24, 0.78);
|
||||
}
|
||||
|
||||
.game-settings-menu__section--wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.game-settings-menu__section--right {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.game-settings-menu__section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1408,8 +1412,7 @@ canvas {
|
||||
}
|
||||
|
||||
.game-settings-menu__choice-group button,
|
||||
.game-settings-menu__restart,
|
||||
.game-settings-menu__quit {
|
||||
.game-settings-menu__restart {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -1419,7 +1422,7 @@ canvas {
|
||||
padding: 11px 12px;
|
||||
border: 1px solid rgba(125, 211, 252, 0.2);
|
||||
border-radius: 8px;
|
||||
background: rgba(6, 18, 30, 0.72);
|
||||
background: rgba(6, 18, 30, 0.84);
|
||||
color: #edfaff;
|
||||
cursor: pointer;
|
||||
font-size: 0.88rem;
|
||||
@@ -1451,12 +1454,21 @@ canvas {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.game-settings-menu__choice-group--hand-tracking button {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
justify-content: start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.game-settings-menu__choice-group--hand-tracking button small {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.game-settings-menu__choice-group button:hover,
|
||||
.game-settings-menu__choice-group button:focus-visible,
|
||||
.game-settings-menu__restart:hover,
|
||||
.game-settings-menu__restart:focus-visible,
|
||||
.game-settings-menu__quit:hover,
|
||||
.game-settings-menu__quit:focus-visible {
|
||||
.game-settings-menu__restart:focus-visible {
|
||||
border-color: rgba(255, 255, 255, 0.64);
|
||||
background: rgba(125, 211, 252, 0.16);
|
||||
color: #ffffff;
|
||||
@@ -1464,8 +1476,7 @@ canvas {
|
||||
}
|
||||
|
||||
.game-settings-menu__choice-group button:active,
|
||||
.game-settings-menu__restart:active,
|
||||
.game-settings-menu__quit:active {
|
||||
.game-settings-menu__restart:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
@@ -1488,14 +1499,8 @@ canvas {
|
||||
|
||||
.game-settings-menu__restart {
|
||||
margin-top: 12px;
|
||||
border-color: rgba(96, 165, 250, 0.35);
|
||||
color: #bfdbfe;
|
||||
}
|
||||
|
||||
.game-settings-menu__quit {
|
||||
margin-top: 8px;
|
||||
border-color: rgba(248, 113, 113, 0.35);
|
||||
color: #fecaca;
|
||||
border-color: rgba(125, 211, 252, 0.35);
|
||||
color: #dff7ff;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
@@ -1512,6 +1517,10 @@ canvas {
|
||||
.game-settings-menu__choice-group--presets {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.game-settings-menu__section--right {
|
||||
grid-column: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug overlay panels */
|
||||
|
||||
@@ -244,6 +244,11 @@ export class Debug {
|
||||
return this.controls.handTrackingSource;
|
||||
}
|
||||
|
||||
setHandTrackingSource(value: HandTrackingSource): void {
|
||||
this.controls.handTrackingSource = value;
|
||||
this.emit();
|
||||
}
|
||||
|
||||
getFogEnabled(): boolean {
|
||||
return this.controls.fogEnabled;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user