Prevent winner selection from being overwritten by polling updates using dirty flag

Added `winnerSelectionDirtyRef` to track when user has manually changed winner selection. Modified `loadGameMeta` to skip updating `winnerUserId` state when dirty flag is set, preventing polling from overwriting user's unsaved selection. Introduced `selectWinner` helper that sets dirty flag on manual selection and clears flag after successful save. Reset dirty flag in all state cleanup handlers (goHome, logout, le
This commit is contained in:
2026-08-02 11:38:08 +02:00
parent ea08016ea5
commit d672648a05
+15 -1
View File
@@ -60,6 +60,7 @@ export default function App() {
// Winner selection (host only) // Winner selection (host only)
const [winnerUserId, setWinnerUserId] = useState(""); const [winnerUserId, setWinnerUserId] = useState("");
const winnerSelectionDirtyRef = useRef(false);
// Modals // Modals
const [helpOpen, setHelpOpen] = useState(false); const [helpOpen, setHelpOpen] = useState(false);
@@ -149,7 +150,9 @@ export default function App() {
const meta = await api(`/games/${gameId}`); const meta = await api(`/games/${gameId}`);
setGameMeta(meta); setGameMeta(meta);
if (!winnerSelectionDirtyRef.current) {
setWinnerUserId(meta?.winner_user_id || ""); setWinnerUserId(meta?.winner_user_id || "");
}
const chips = meta?.started ? await api(`/games/${gameId}/chips`) : []; const chips = meta?.started ? await api(`/games/${gameId}/chips`) : [];
setGameChips(chips || []); setGameChips(chips || []);
@@ -226,6 +229,7 @@ export default function App() {
lastWinnerIdRef.current = null; lastWinnerIdRef.current = null;
gameStartBaselineRef.current = false; gameStartBaselineRef.current = false;
lastGameStartedRef.current = false; lastGameStartedRef.current = false;
winnerSelectionDirtyRef.current = false;
setCelebrateOpen(false); setCelebrateOpen(false);
setCelebrateName(""); setCelebrateName("");
setStartCelebrateOpen(false); setStartCelebrateOpen(false);
@@ -370,6 +374,7 @@ export default function App() {
setMembers([]); setMembers([]);
setGameChips([]); setGameChips([]);
setWinnerUserId(""); setWinnerUserId("");
winnerSelectionDirtyRef.current = false;
// reset winner celebration on logout // reset winner celebration on logout
winnerBaselineRef.current = false; winnerBaselineRef.current = false;
@@ -478,6 +483,7 @@ export default function App() {
setMembers([]); setMembers([]);
setGameChips([]); setGameChips([]);
setWinnerUserId(""); setWinnerUserId("");
winnerSelectionDirtyRef.current = false;
setPulseId(null); setPulseId(null);
// auch Chip-Modal-State resetten // auch Chip-Modal-State resetten
@@ -535,6 +541,7 @@ export default function App() {
setMembers([]); setMembers([]);
setGameChips([]); setGameChips([]);
setWinnerUserId(""); setWinnerUserId("");
winnerSelectionDirtyRef.current = false;
setChipOpen(false); setChipOpen(false);
setChipEntry(null); setChipEntry(null);
showSnack(language === "en" ? "Game cancelled." : "Spiel abgebrochen."); showSnack(language === "en" ? "Game cancelled." : "Spiel abgebrochen.");
@@ -547,6 +554,7 @@ export default function App() {
setMembers([]); setMembers([]);
setGameChips([]); setGameChips([]);
setWinnerUserId(""); setWinnerUserId("");
winnerSelectionDirtyRef.current = false;
setChipOpen(false); setChipOpen(false);
setChipEntry(null); setChipEntry(null);
setCelebrateOpen(false); setCelebrateOpen(false);
@@ -561,9 +569,15 @@ export default function App() {
method: "PATCH", method: "PATCH",
body: JSON.stringify({ winner_user_id: winnerUserId || null }), body: JSON.stringify({ winner_user_id: winnerUserId || null }),
}); });
winnerSelectionDirtyRef.current = false;
await loadGameMeta(); await loadGameMeta();
}; };
const selectWinner = (value) => {
winnerSelectionDirtyRef.current = true;
setWinnerUserId(value);
};
// ===== Sheet actions ===== // ===== Sheet actions =====
const cycleStatus = async (entry) => { const cycleStatus = async (entry) => {
if (gameMeta?.winner_user_id) return; if (gameMeta?.winner_user_id) return;
@@ -806,7 +820,7 @@ export default function App() {
isHost={isHost} isHost={isHost}
members={members} members={members}
winnerUserId={winnerUserId} winnerUserId={winnerUserId}
setWinnerUserId={setWinnerUserId} setWinnerUserId={selectWinner}
onSave={saveWinner} onSave={saveWinner}
/> />
)} )}