Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
2.5 kB · 65 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566import { useEffect } from 'react'import { getLastInteractionTime, updateLastInteractionTime,} from '../bootstrap/state.js'import { useTerminalNotification } from '../ink/useTerminalNotification.js'import { sendNotification } from '../services/notifier.js'// The time threshold in milliseconds for considering an interaction "recent" (6 seconds)export const DEFAULT_INTERACTION_THRESHOLD_MS = 6000
function getTimeSinceLastInteraction(): number { return Date.now() - getLastInteractionTime()}
function hasRecentInteraction(threshold: number): boolean { return getTimeSinceLastInteraction() < threshold}
function shouldNotify(threshold: number): boolean { return process.env.NODE_ENV !== 'test' && !hasRecentInteraction(threshold)}
// NOTE: User interaction tracking is now done in App.tsx's processKeysInBatch// function, which calls updateLastInteractionTime() when any input is received.// This avoids having a separate stdin 'data' listener that would compete with// the main 'readable' listener and cause dropped input characters.
/** * Hook that manages desktop notifications after a timeout period. * * Shows a notification in two cases: * 1. Immediately if the app has been idle for longer than the threshold * 2. After the specified timeout if the user doesn't interact within that time * * @param message - The notification message to display * @param timeout - The timeout in milliseconds (defaults to 6000ms) */export function useNotifyAfterTimeout( message: string, notificationType: string,): void { const terminal = useTerminalNotification()
// Reset interaction time when hook is called to make sure that requests // that took a long time to complete don't pop up a notification right away. // Must be immediate because useEffect runs after Ink's render cycle has // already flushed; without it the timestamp stays stale and a premature // notification fires if the user is idle (no subsequent renders to flush). useEffect(() => { updateLastInteractionTime(true) }, [])
useEffect(() => { let hasNotified = false const timer = setInterval(() => { if (shouldNotify(DEFAULT_INTERACTION_THRESHOLD_MS) && !hasNotified) { hasNotified = true clearInterval(timer) void sendNotification({ message, notificationType }, terminal) } }, DEFAULT_INTERACTION_THRESHOLD_MS)
return () => clearInterval(timer) }, [message, notificationType, terminal])}