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:
+16
-2
@@ -60,6 +60,7 @@ export default function App() {
|
||||
|
||||
// Winner selection (host only)
|
||||
const [winnerUserId, setWinnerUserId] = useState("");
|
||||
const winnerSelectionDirtyRef = useRef(false);
|
||||
|
||||
// Modals
|
||||
const [helpOpen, setHelpOpen] = useState(false);
|
||||
@@ -149,7 +150,9 @@ export default function App() {
|
||||
|
||||
const meta = await api(`/games/${gameId}`);
|
||||
setGameMeta(meta);
|
||||
setWinnerUserId(meta?.winner_user_id || "");
|
||||
if (!winnerSelectionDirtyRef.current) {
|
||||
setWinnerUserId(meta?.winner_user_id || "");
|
||||
}
|
||||
|
||||
const chips = meta?.started ? await api(`/games/${gameId}/chips`) : [];
|
||||
setGameChips(chips || []);
|
||||
@@ -226,6 +229,7 @@ export default function App() {
|
||||
lastWinnerIdRef.current = null;
|
||||
gameStartBaselineRef.current = false;
|
||||
lastGameStartedRef.current = false;
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
setCelebrateOpen(false);
|
||||
setCelebrateName("");
|
||||
setStartCelebrateOpen(false);
|
||||
@@ -370,6 +374,7 @@ export default function App() {
|
||||
setMembers([]);
|
||||
setGameChips([]);
|
||||
setWinnerUserId("");
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
|
||||
// reset winner celebration on logout
|
||||
winnerBaselineRef.current = false;
|
||||
@@ -478,6 +483,7 @@ export default function App() {
|
||||
setMembers([]);
|
||||
setGameChips([]);
|
||||
setWinnerUserId("");
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
setPulseId(null);
|
||||
|
||||
// auch Chip-Modal-State resetten
|
||||
@@ -535,6 +541,7 @@ export default function App() {
|
||||
setMembers([]);
|
||||
setGameChips([]);
|
||||
setWinnerUserId("");
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
setChipOpen(false);
|
||||
setChipEntry(null);
|
||||
showSnack(language === "en" ? "Game cancelled." : "Spiel abgebrochen.");
|
||||
@@ -547,6 +554,7 @@ export default function App() {
|
||||
setMembers([]);
|
||||
setGameChips([]);
|
||||
setWinnerUserId("");
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
setChipOpen(false);
|
||||
setChipEntry(null);
|
||||
setCelebrateOpen(false);
|
||||
@@ -561,9 +569,15 @@ export default function App() {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify({ winner_user_id: winnerUserId || null }),
|
||||
});
|
||||
winnerSelectionDirtyRef.current = false;
|
||||
await loadGameMeta();
|
||||
};
|
||||
|
||||
const selectWinner = (value) => {
|
||||
winnerSelectionDirtyRef.current = true;
|
||||
setWinnerUserId(value);
|
||||
};
|
||||
|
||||
// ===== Sheet actions =====
|
||||
const cycleStatus = async (entry) => {
|
||||
if (gameMeta?.winner_user_id) return;
|
||||
@@ -806,7 +820,7 @@ export default function App() {
|
||||
isHost={isHost}
|
||||
members={members}
|
||||
winnerUserId={winnerUserId}
|
||||
setWinnerUserId={setWinnerUserId}
|
||||
setWinnerUserId={selectWinner}
|
||||
onSave={saveWinner}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user