fix: improve animation hook robustness
- Add .catch handler to scheduleNext to prevent unhandled promise rejections from killing the scheduling loop - Replace `as unknown as Animation` cast with Cancellable interface for type-safe cleanup handles
This commit is contained in:
@@ -13,8 +13,9 @@ export function useMascotAnimation(
|
|||||||
containerRef: React.RefObject<HTMLDivElement | null>,
|
containerRef: React.RefObject<HTMLDivElement | null>,
|
||||||
state: MascotState,
|
state: MascotState,
|
||||||
): void {
|
): void {
|
||||||
|
interface Cancellable { cancel(): void }
|
||||||
const timeoutRef = useRef<number | null>(null);
|
const timeoutRef = useRef<number | null>(null);
|
||||||
const activeAnimations = useRef<Animation[]>([]);
|
const activeAnimations = useRef<Cancellable[]>([]);
|
||||||
const abortedRef = useRef(false);
|
const abortedRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -93,6 +94,11 @@ export function useMascotAnimation(
|
|||||||
if (!abortedRef.current) {
|
if (!abortedRef.current) {
|
||||||
scheduleNext(fn, minMs, maxMs);
|
scheduleNext(fn, minMs, maxMs);
|
||||||
}
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// Action failed — reschedule unless aborted
|
||||||
|
if (!abortedRef.current) {
|
||||||
|
scheduleNext(fn, minMs, maxMs);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, delay);
|
}, delay);
|
||||||
}
|
}
|
||||||
@@ -469,9 +475,7 @@ export function useMascotAnimation(
|
|||||||
// Store initial timeout so cleanup can cancel it
|
// Store initial timeout so cleanup can cancel it
|
||||||
activeAnimations.current.push({
|
activeAnimations.current.push({
|
||||||
cancel: () => clearTimeout(initialTimeout),
|
cancel: () => clearTimeout(initialTimeout),
|
||||||
finished: Promise.resolve(),
|
});
|
||||||
playState: 'running',
|
|
||||||
} as unknown as Animation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══ LONELY STATE ═══
|
// ═══ LONELY STATE ═══
|
||||||
|
|||||||
Reference in New Issue
Block a user