From 827a3978e9bf62d06b11a0a659232ef74222c7ad Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 17 Mar 2026 12:11:20 +0100 Subject: [PATCH] Show toast and open source panel when rolling initiative without loaded source When a user clicks the d20 to roll initiative for a single combatant whose bestiary source isn't cached, show an informative toast and open the stat block panel so they can load the source directly. Co-Authored-By: Claude Opus 4.6 --- apps/web/src/App.tsx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index bf41c2c..ef5c039 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -117,6 +117,7 @@ export function App() { const sidePanel = useSidePanelState(); const [rollSkippedCount, setRollSkippedCount] = useState(0); + const [rollSingleSkipped, setRollSingleSkipped] = useState(false); const selectedCreature: Creature | null = sidePanel.selectedCreatureId ? (getCreature(sidePanel.selectedCreatureId) ?? null) @@ -145,9 +146,21 @@ export function App() { const handleRollInitiative = useCallback( (id: CombatantId) => { - rollInitiativeUseCase(makeStore(), id, rollDice(), getCreature); + const result = rollInitiativeUseCase( + makeStore(), + id, + rollDice(), + getCreature, + ); + if (isDomainError(result)) { + setRollSingleSkipped(true); + const combatant = encounter.combatants.find((c) => c.id === id); + if (combatant?.creatureId) { + sidePanel.showCreature(combatant.creatureId); + } + } }, - [makeStore, getCreature], + [makeStore, getCreature, encounter.combatants, sidePanel.showCreature], ); const handleRollAllInitiative = useCallback(() => { @@ -363,6 +376,14 @@ export function App() { /> )} + {!!rollSingleSkipped && ( + setRollSingleSkipped(false)} + autoDismissMs={4000} + /> + )} +