= ({
+ {/* Result Popups Toggle */}
+
+
+
+
{isStarted ? 'WASD / Arrows / Numpad to move' : 'Bots can join & depart in Lobby'}
diff --git a/frontend/src/hooks/useGameSocket.ts b/frontend/src/hooks/useGameSocket.ts
index 37bc145..0e9117a 100644
--- a/frontend/src/hooks/useGameSocket.ts
+++ b/frontend/src/hooks/useGameSocket.ts
@@ -51,6 +51,7 @@ export function useGameSocket() {
const [activeBattle, setActiveBattle] = useState(null);
const [activeWizardChallenge, setActiveWizardChallenge] = useState(null);
const [showScoreboard, setShowScoreboard] = useState(false);
+ const [showPopups, setShowPopups] = useState(true);
const wsRef = useRef(null);
const reconnectTimeoutRef = useRef(null);
@@ -59,6 +60,20 @@ export function useGameSocket() {
activeBattleRef.current = activeBattle;
const activeWizardChallengeRef = useRef(null);
activeWizardChallengeRef.current = activeWizardChallenge;
+ const showPopupsRef = useRef(true);
+ showPopupsRef.current = showPopups;
+
+ const updateShowPopups = useCallback((val?: boolean | ((prev: boolean) => boolean)) => {
+ setShowPopups((prev) => {
+ const next = typeof val === 'function' ? val(prev) : typeof val === 'boolean' ? val : !prev;
+ showPopupsRef.current = next;
+ if (!next) {
+ setActiveBattle(null);
+ setActiveWizardChallenge(null);
+ }
+ return next;
+ });
+ }, []);
const fetchBoard = useCallback(async () => {
try {
@@ -205,7 +220,9 @@ export function useGameSocket() {
turn: data.turn ?? prev.turn,
}));
const b: BattleResult = data.battle;
- setActiveBattle(b);
+ if (showPopupsRef.current) {
+ setActiveBattle(b);
+ }
setLastEventMessage(`⚔️ 3-Bout D20 Battle: ${b.winner_party_name} defeated ${b.defeated_party_name}!`);
} else if (data.event === 'wizard_challenge_resolved') {
setBoardState((prev) => ({
@@ -215,7 +232,9 @@ export function useGameSocket() {
turn: data.turn ?? prev.turn,
}));
const c: WizardChallengeResult = data.challenge_result || data.challenge;
- setActiveWizardChallenge(c);
+ if (showPopupsRef.current) {
+ setActiveWizardChallenge(c);
+ }
const wizName = c.wizard_name || 'Gary the Wizard';
let rewardLabel = `+${c.score_change} score`;
if (c.reward_chosen === 'strength') {
@@ -413,7 +432,9 @@ export function useGameSocket() {
throw new Error(err.detail || 'Battle failed');
}
const result: BattleResult = await res.json();
- setActiveBattle(result);
+ if (showPopupsRef.current) {
+ setActiveBattle(result);
+ }
return result;
};
@@ -432,7 +453,9 @@ export function useGameSocket() {
setSelectedPlayer((curr) => (curr?.id === data.player.id ? data.player : curr));
}
if (data.battle_triggered && data.battle_result) {
- setActiveBattle(data.battle_result);
+ if (showPopupsRef.current) {
+ setActiveBattle(data.battle_result);
+ }
}
if (data.game_concluded && data.game_concluded.concluded) {
setIsAutoPlaying(false);
@@ -490,7 +513,9 @@ export function useGameSocket() {
throw new Error(err.detail || 'Failed to challenge wizard');
}
const data: WizardChallengeResult = await res.json();
- setActiveWizardChallenge(data);
+ if (showPopupsRef.current) {
+ setActiveWizardChallenge(data);
+ }
return data;
};
@@ -515,11 +540,15 @@ export function useGameSocket() {
if (data.action_taken === 'formed_party' && data.formed_party) {
setLastEventMessage(`🤝 ${data.player_name} formed party "${data.formed_party.name}" under leader ${data.formed_party.leader_name}!`);
} else if (data.action_taken === 'battled' && data.battle_result) {
- setActiveBattle(data.battle_result);
+ if (showPopupsRef.current) {
+ setActiveBattle(data.battle_result);
+ }
setLastEventMessage(`⚔️ Battle clash: ${data.battle_result.winner_party_name} defeated ${data.battle_result.defeated_party_name}!`);
} else if (data.action_taken === 'challenged_wizard' && data.wizard_challenge_result) {
const wcr = data.wizard_challenge_result;
- setActiveWizardChallenge(wcr);
+ if (showPopupsRef.current) {
+ setActiveWizardChallenge(wcr);
+ }
const wizName = wcr.wizard_name || 'Gary the Wizard';
setLastEventMessage(
wcr.player_won
@@ -529,7 +558,9 @@ export function useGameSocket() {
} else if (data.action_taken === 'slept' && data.sleep_result) {
setLastEventMessage(`💤 ${data.player_name} took a restful sleep (+${data.sleep_result.health_gained} HP -> ${data.sleep_result.new_health} HP)!`);
} else if (data.move_result?.battle_result) {
- setActiveBattle(data.move_result.battle_result);
+ if (showPopupsRef.current) {
+ setActiveBattle(data.move_result.battle_result);
+ }
}
if (data.game_concluded && data.game_concluded.concluded) {
@@ -575,6 +606,8 @@ export function useGameSocket() {
setActiveWizardChallenge,
showScoreboard,
setShowScoreboard,
+ showPopups,
+ setShowPopups: updateShowPopups,
registerPlayer,
removePlayer,
formParty,
diff --git a/version.ini b/version.ini
index db5e20d..1688f5c 100644
--- a/version.ini
+++ b/version.ini
@@ -1,2 +1,2 @@
[metadata]
-version = 1.4
+version = 1.5