fix: delay boss lore toasts until battle animation reveals result
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m3s
CI / Lint, Build & Test (push) Successful in 1m6s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 19:18:46 -07:00
committed by Naomi Carrigan
parent 5a065998b6
commit 6e2cb45553
2 changed files with 47 additions and 4 deletions
+8 -1
View File
@@ -58,7 +58,12 @@ const BattleModal = ({
onDismiss, onDismiss,
}: BattleModalProperties): JSX.Element => { }: BattleModalProperties): JSX.Element => {
const { result, bossName } = battle; const { result, bossName } = battle;
const { enableNotifications, enableSounds, formatNumber } = useGame(); const {
enableNotifications,
enableSounds,
flushBossLoreToasts,
formatNumber,
} = useGame();
const [ phase, setPhase ] = useState<"animating" | "result">("animating"); const [ phase, setPhase ] = useState<"animating" | "result">("animating");
@@ -111,6 +116,7 @@ const BattleModal = ({
const revealTimeout = setTimeout(() => { const revealTimeout = setTimeout(() => {
setPhase("result"); setPhase("result");
flushBossLoreToasts();
if (result.won) { if (result.won) {
if (enableSounds) { if (enableSounds) {
playSound("bossVictory"); playSound("bossVictory");
@@ -132,6 +138,7 @@ const BattleModal = ({
bossStartPercent, bossStartPercent,
enableNotifications, enableNotifications,
enableSounds, enableSounds,
flushBossLoreToasts,
partyEndPercent, partyEndPercent,
result.won, result.won,
]); ]);
+38 -2
View File
@@ -455,6 +455,11 @@ interface GameContextValue {
*/ */
dismissCodexEntry: (id: string)=> void; dismissCodexEntry: (id: string)=> void;
/**
* Flush pending boss lore codex toasts — call after the battle animation reveals the result.
*/
flushBossLoreToasts: ()=> void;
/** /**
* Perform a transcendence — nuclear reset, earning echoes. * Perform a transcendence — nuclear reset, earning echoes.
*/ */
@@ -613,6 +618,7 @@ export const GameProvider = ({
Array<string> Array<string>
>([]); >([]);
const codexProcessedReference = useRef<Set<string>>(new Set()); const codexProcessedReference = useRef<Set<string>>(new Set());
const pendingBossCodexIdsReference = useRef<Array<string>>([]);
const [ unlockedStoryChapterIds, setUnlockedStoryChapterIds ] = useState< const [ unlockedStoryChapterIds, setUnlockedStoryChapterIds ] = useState<
Array<string> Array<string>
>([]); >([]);
@@ -880,12 +886,30 @@ export const GameProvider = ({
}; };
}); });
if (!isFirstRun) { if (!isFirstRun) {
const bossIds = addedIds.filter((id) => {
return id.startsWith("boss_");
});
const otherIds = addedIds.filter((id) => {
return !id.startsWith("boss_");
});
if (bossIds.length > 0) {
if (battleResult === null) {
otherIds.push(...bossIds);
} else {
pendingBossCodexIdsReference.current = [
...pendingBossCodexIdsReference.current,
...bossIds,
];
}
}
if (otherIds.length > 0) {
setUnlockedCodexEntryIds((previous) => { setUnlockedCodexEntryIds((previous) => {
return [ ...previous, ...addedIds ]; return [ ...previous, ...otherIds ];
}); });
} }
} }
}, [ state ]); }
}, [ battleResult, state ]);
// Detect newly unlocked story chapters // Detect newly unlocked story chapters
useEffect(() => { useEffect(() => {
@@ -1836,6 +1860,16 @@ export const GameProvider = ({
}); });
}, []); }, []);
const flushBossLoreToasts = useCallback(() => {
const pending = pendingBossCodexIdsReference.current;
if (pending.length > 0) {
pendingBossCodexIdsReference.current = [];
setUnlockedCodexEntryIds((previous) => {
return [ ...previous, ...pending ];
});
}
}, []);
const dismissStoryChapter = useCallback((id: string) => { const dismissStoryChapter = useCallback((id: string) => {
setUnlockedStoryChapterIds((previous) => { setUnlockedStoryChapterIds((previous) => {
return previous.filter((chapter) => { return previous.filter((chapter) => {
@@ -1935,6 +1969,7 @@ export const GameProvider = ({
equipItem, equipItem,
error, error,
failedQuestToasts, failedQuestToasts,
flushBossLoreToasts,
forceSync, forceSync,
formatNumber, formatNumber,
handleClick, handleClick,
@@ -2001,6 +2036,7 @@ export const GameProvider = ({
enableSounds, enableSounds,
equipItem, equipItem,
error, error,
flushBossLoreToasts,
forceSync, forceSync,
handleClick, handleClick,
isLoading, isLoading,