fix(notifications): improve agent progress notifications and permission handling (#459)
* fix(notifications): dismiss cross-window permissions, retry countdown, subtask filter
This commit is contained in:
committed by
GitHub
parent
2e08501ea5
commit
62e5c3edfe
@@ -6,6 +6,7 @@ interface WorkingPlaceholderProps {
|
||||
statusText: string | null;
|
||||
isGenericStatus?: boolean;
|
||||
isWaitingForPermission?: boolean;
|
||||
retryInfo?: { attempt?: number; next?: number } | null;
|
||||
}
|
||||
|
||||
const STATUS_DISPLAY_TIME_MS = 1200;
|
||||
@@ -15,6 +16,7 @@ export function WorkingPlaceholder({
|
||||
statusText,
|
||||
isGenericStatus,
|
||||
isWaitingForPermission,
|
||||
retryInfo,
|
||||
}: WorkingPlaceholderProps) {
|
||||
const [displayedText, setDisplayedText] = React.useState<string | null>(null);
|
||||
const [displayedPermission, setDisplayedPermission] = React.useState<boolean>(false);
|
||||
@@ -23,6 +25,35 @@ export function WorkingPlaceholder({
|
||||
const queuedStatusRef = React.useRef<{ text: string; permission: boolean } | null>(null);
|
||||
const processQueueTimerRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
|
||||
// Countdown state for retry mode
|
||||
const retryNextRef = React.useRef<number | null>(null);
|
||||
const retryStartRef = React.useRef<number | null>(null);
|
||||
const [retryCountdown, setRetryCountdown] = React.useState<number | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
const next = retryInfo?.next;
|
||||
if (!next || next <= 0) {
|
||||
retryNextRef.current = null;
|
||||
retryStartRef.current = null;
|
||||
setRetryCountdown(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a fresh countdown when next value or attempt changes
|
||||
retryNextRef.current = next;
|
||||
retryStartRef.current = Date.now();
|
||||
|
||||
const update = () => {
|
||||
const elapsed = Date.now() - (retryStartRef.current ?? Date.now());
|
||||
const remaining = Math.max(0, next - elapsed);
|
||||
setRetryCountdown(Math.ceil(remaining / 1000));
|
||||
};
|
||||
|
||||
update();
|
||||
const id = setInterval(update, 500);
|
||||
return () => clearInterval(id);
|
||||
}, [retryInfo?.next, retryInfo?.attempt]);
|
||||
|
||||
const clearTimers = React.useCallback(() => {
|
||||
if (processQueueTimerRef.current) {
|
||||
clearTimeout(processQueueTimerRef.current);
|
||||
@@ -61,6 +92,13 @@ export function WorkingPlaceholder({
|
||||
return;
|
||||
}
|
||||
|
||||
// Retry state has its own display — skip the normal queue
|
||||
if (retryInfo) {
|
||||
clearTimers();
|
||||
queuedStatusRef.current = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const incomingText = isWaitingForPermission ? 'waiting for permission' : statusText;
|
||||
const incomingPermission = Boolean(isWaitingForPermission);
|
||||
const incomingGeneric = Boolean(isGenericStatus) && !incomingPermission;
|
||||
@@ -96,6 +134,7 @@ export function WorkingPlaceholder({
|
||||
statusText,
|
||||
isGenericStatus,
|
||||
isWaitingForPermission,
|
||||
retryInfo,
|
||||
displayedText,
|
||||
displayedPermission,
|
||||
clearTimers,
|
||||
@@ -105,7 +144,33 @@ export function WorkingPlaceholder({
|
||||
|
||||
React.useEffect(() => () => clearTimers(), [clearTimers]);
|
||||
|
||||
if (!isWorking || !displayedText) {
|
||||
if (!isWorking) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Retry state: show countdown and attempt info
|
||||
if (retryInfo) {
|
||||
const attemptLabel = retryInfo.attempt && retryInfo.attempt > 1 ? ` (attempt ${retryInfo.attempt})` : '';
|
||||
const countdownLabel = retryCountdown !== null && retryCountdown > 0 ? ` in ${retryCountdown}s` : '';
|
||||
const retryText = `Retrying${countdownLabel}${attemptLabel}...`;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex h-full items-center text-muted-foreground pl-[2ch]"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
aria-label={retryText}
|
||||
>
|
||||
<span className="flex items-center gap-1.5">
|
||||
<Text variant="shine" className="typography-ui-header">
|
||||
{retryText}
|
||||
</Text>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!displayedText) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user