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)
|
// 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);
|
||||||
setWinnerUserId(meta?.winner_user_id || "");
|
if (!winnerSelectionDirtyRef.current) {
|
||||||
|
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}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user