Merge pull request #51 from pennyteenycat/feature/chatUpdate

add timer
This commit is contained in:
pennyteenycat 2025-09-07 23:22:19 +02:00 committed by GitHub
commit 2eaf4ad75b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -113,6 +113,11 @@ export const useChatSocket = (
emit("fetch_balance", { chatId });
}, [emit, chatId]);
// Auto top-up: silent flow (no UI prompt)
const autoTopUpInProgressRef = useRef(false);
// Timer for delayed unlock after error
const autoTopUpUnlockTimerRef = useRef<NodeJS.Timeout | null>(null);
// Auto top-up: use existing single checkout flow
const { handleSingleCheckout, isLoading: isAutoTopUpLoading } =
useSingleCheckout({
@ -120,15 +125,18 @@ export const useChatSocket = (
onError: () => {
// eslint-disable-next-line no-console
console.error("Auto top-up payment failed");
// Release in-flight lock on error so a future event can retry
autoTopUpInProgressRef.current = false;
// Throttle retries: keep the lock for 30 seconds after an error
if (autoTopUpUnlockTimerRef.current) {
clearTimeout(autoTopUpUnlockTimerRef.current);
}
autoTopUpUnlockTimerRef.current = setTimeout(() => {
autoTopUpInProgressRef.current = false;
autoTopUpUnlockTimerRef.current = null;
}, 30_000);
},
returnUrl: typeof window !== "undefined" ? window.location.href : "",
});
// Auto top-up: silent flow (no UI prompt)
const autoTopUpInProgressRef = useRef(false);
const balancePollId = useRef<NodeJS.Timeout | null>(null);
// Avoid immediate leave_chat right after join in React 18 StrictMode (dev) double-invoke
// We debounce leave so that a quick remount cancels it, but real navigation (or chat switch) proceeds.
@ -203,12 +211,20 @@ export const useChatSocket = (
// If auto top-up was in-flight, release the lock only after balance became positive
if (autoTopUpInProgressRef.current && b?.data?.balance > 0) {
autoTopUpInProgressRef.current = false;
if (autoTopUpUnlockTimerRef.current) {
clearTimeout(autoTopUpUnlockTimerRef.current);
autoTopUpUnlockTimerRef.current = null;
}
}
});
useSocketEvent("balance_updated", b => {
setBalance(prev => (prev ? { ...prev, balance: b.data.balance } : null));
if (autoTopUpInProgressRef.current && b?.data?.balance > 0) {
autoTopUpInProgressRef.current = false;
if (autoTopUpUnlockTimerRef.current) {
clearTimeout(autoTopUpUnlockTimerRef.current);
autoTopUpUnlockTimerRef.current = null;
}
}
});
useSocketEvent("session_started", s => setSession(s.data));
@ -310,6 +326,16 @@ export const useChatSocket = (
};
}, [session, endSession]);
// Cleanup pending unlock timer on unmount
useEffect(() => {
return () => {
if (autoTopUpUnlockTimerRef.current) {
clearTimeout(autoTopUpUnlockTimerRef.current);
autoTopUpUnlockTimerRef.current = null;
}
};
}, []);
const isAvailableChatting =
!!balance?.balance && !!session && !isSessionExpired;