generated from nhcarrigan/template
fix: force sync before boss fight and surface challenge errors to UI
Closes #50
This commit is contained in:
@@ -235,6 +235,7 @@ const BossPanel = (): JSX.Element => {
|
||||
toggleAutoBoss,
|
||||
autoBossLastResult,
|
||||
autoBossError,
|
||||
bossError,
|
||||
} = useGame();
|
||||
const [ challengingBossId, setChallengingBossId ] = useState<string | null>(
|
||||
null,
|
||||
@@ -362,6 +363,13 @@ const BossPanel = (): JSX.Element => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{bossError === null
|
||||
? null
|
||||
: <p className="auto-boss-error">
|
||||
{"⚠️ "}
|
||||
{bossError}
|
||||
</p>
|
||||
}
|
||||
{autoBossError === null
|
||||
? null
|
||||
: <p className="auto-boss-error">
|
||||
|
||||
@@ -557,6 +557,12 @@ interface GameContextValue {
|
||||
* when no error). Cleared automatically when the player re-enables auto-boss.
|
||||
*/
|
||||
autoBossError: string | null;
|
||||
|
||||
/**
|
||||
* Error message from the most recent manual boss challenge (null when no
|
||||
* error). Cleared automatically when a new challenge is initiated.
|
||||
*/
|
||||
bossError: string | null;
|
||||
}
|
||||
|
||||
export interface BattleResult {
|
||||
@@ -606,6 +612,7 @@ export const GameProvider = ({
|
||||
at: number;
|
||||
} | null>(null);
|
||||
const [ autoBossError, setAutoBossError ] = useState<string | null>(null);
|
||||
const [ bossError, setBossError ] = useState<string | null>(null);
|
||||
const syncErrorTimerReference = useRef<ReturnType<typeof setTimeout> | null>(
|
||||
null,
|
||||
);
|
||||
@@ -1867,6 +1874,14 @@ export const GameProvider = ({
|
||||
return;
|
||||
}
|
||||
|
||||
setBossError(null);
|
||||
|
||||
/*
|
||||
* Flush any pending state (e.g. newly equipped items) to the server before
|
||||
* the fight so the server-side calculation uses the player's live stats.
|
||||
*/
|
||||
await forceSync();
|
||||
|
||||
try {
|
||||
const result = await challengeBossApi({ bossId });
|
||||
setState((previous) => {
|
||||
@@ -1878,9 +1893,13 @@ export const GameProvider = ({
|
||||
setBattleResult({ bossName: boss.name, result: result });
|
||||
} catch (error_: unknown) {
|
||||
logError("challenge_boss", error_);
|
||||
// Silently ignore — server errors shouldn't crash the UI
|
||||
setBossError(
|
||||
error_ instanceof Error
|
||||
? error_.message
|
||||
: "Failed to challenge boss",
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
}, [ forceSync ]);
|
||||
|
||||
const dismissOfflineGold = useCallback(() => {
|
||||
setOfflineGold(0);
|
||||
@@ -2023,6 +2042,7 @@ export const GameProvider = ({
|
||||
autoBossError,
|
||||
autoBossLastResult,
|
||||
battleResult,
|
||||
bossError,
|
||||
buyAdventurer,
|
||||
buyEchoUpgrade,
|
||||
buyEquipment,
|
||||
@@ -2091,6 +2111,7 @@ export const GameProvider = ({
|
||||
autoBossError,
|
||||
autoBossLastResult,
|
||||
battleResult,
|
||||
bossError,
|
||||
completedQuestToasts,
|
||||
failedQuestToasts,
|
||||
formatNumber,
|
||||
|
||||
Reference in New Issue
Block a user