Animation de victoire uniquement à la fin de la partie
Build and Publish Docker Image / build-and-push-image (push) Successful in 1m43s
Build and Publish Docker Image / build-and-push-image (push) Successful in 1m43s
L'overlay de célébration (confettis + avatar du vainqueur) se rejouait à chaque consultation d'une partie terminée. Il n'est désormais déclenché que lorsqu'on arrive depuis la fin de partie (état de navigation justFinished), état consommé ensuite pour qu'un rechargement ne le rejoue pas. Depuis l'historique ou l'accueil, l'écran de fin s'affiche sans célébration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+17
-2
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useParams, useNavigate } from "react-router-dom";
|
import { useParams, useNavigate, useLocation } from "react-router-dom";
|
||||||
import { Trophy, Home, Share2, RotateCcw, Clock, MapPin } from "lucide-react";
|
import { Trophy, Home, Share2, RotateCcw, Clock, MapPin } from "lucide-react";
|
||||||
import * as Icons from "lucide-react";
|
import * as Icons from "lucide-react";
|
||||||
import { useLiveQuery } from "dexie-react-hooks";
|
import { useLiveQuery } from "dexie-react-hooks";
|
||||||
@@ -20,7 +20,13 @@ export default function GameOver() {
|
|||||||
const { sessionId } = useParams<{ sessionId: string }>();
|
const { sessionId } = useParams<{ sessionId: string }>();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [session, setSession] = useState<GameSession | null>(null);
|
const [session, setSession] = useState<GameSession | null>(null);
|
||||||
const [showCelebration, setShowCelebration] = useState(true);
|
// Only celebrate when arriving straight from the end of the game, never when
|
||||||
|
// browsing a finished game from the history.
|
||||||
|
const routerLocation = useLocation();
|
||||||
|
const justFinished = Boolean(
|
||||||
|
(routerLocation.state as { justFinished?: boolean } | null)?.justFinished,
|
||||||
|
);
|
||||||
|
const [showCelebration, setShowCelebration] = useState(justFinished);
|
||||||
const startNewGame = useGameStore((state) => state.startNewGame);
|
const startNewGame = useGameStore((state) => state.startNewGame);
|
||||||
|
|
||||||
const gameConfig = useGameConfig(session?.gameId);
|
const gameConfig = useGameConfig(session?.gameId);
|
||||||
@@ -47,6 +53,15 @@ export default function GameOver() {
|
|||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [sessionId]);
|
}, [sessionId]);
|
||||||
|
|
||||||
|
// Consume the flag so reloading or coming back to this screen doesn't replay
|
||||||
|
// the celebration (history.state survives a page reload).
|
||||||
|
useEffect(() => {
|
||||||
|
if (justFinished) {
|
||||||
|
navigate(routerLocation.pathname, { replace: true, state: null });
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (!session)
|
if (!session)
|
||||||
return <div className="p-4 text-center mt-10">Chargement...</div>;
|
return <div className="p-4 text-center mt-10">Chargement...</div>;
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,9 @@ export default function PlayGame() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await finishGame(winnerIds);
|
await finishGame(winnerIds);
|
||||||
navigate(`/gameover/${activeSession.id}`);
|
// `justFinished` déclenche l'animation de victoire (une seule fois) :
|
||||||
|
// en venant de l'historique, l'écran de fin s'affiche sans célébration.
|
||||||
|
navigate(`/gameover/${activeSession.id}`, { state: { justFinished: true } });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancelGame = async () => {
|
const handleCancelGame = async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user