init claude-code
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { 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])
|
||||
}
|
||||
Reference in New Issue
Block a user