Refine agent list attention handling
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
Platform,
|
||||
BackHandler,
|
||||
} from "react-native";
|
||||
import { useFocusEffect } from "@react-navigation/native";
|
||||
import { useFocusEffect, useIsFocused } from "@react-navigation/native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import ReanimatedAnimated from "react-native-reanimated";
|
||||
@@ -55,7 +55,7 @@ import {
|
||||
} from "@/utils/agent-snapshots";
|
||||
import { mergePendingCreateImages } from "@/utils/pending-create-images";
|
||||
import { useKeyboardShiftStyle } from "@/hooks/use-keyboard-shift-style";
|
||||
import { shouldClearAgentAttention } from "@/utils/agent-attention";
|
||||
import { useAgentAttentionClear } from "@/hooks/use-agent-attention-clear";
|
||||
import type { DaemonClient } from "@server/client/daemon-client";
|
||||
import { useExplorerOpenGesture } from "@/hooks/use-explorer-open-gesture";
|
||||
import type { ExplorerCheckoutContext } from "@/stores/panel-store";
|
||||
@@ -431,9 +431,7 @@ function AgentScreenContent({
|
||||
const hasSession = useSessionStore(
|
||||
(state) => Boolean(state.sessions[serverId])
|
||||
);
|
||||
const focusedAgentId = useSessionStore(
|
||||
(state) => state.sessions[serverId]?.focusedAgentId ?? null
|
||||
);
|
||||
const isScreenFocused = useIsFocused();
|
||||
const { ensureAgentIsInitialized } = useAgentInitialization({
|
||||
serverId,
|
||||
client: hasSession ? client : null,
|
||||
@@ -447,8 +445,6 @@ function AgentScreenContent({
|
||||
routeKey: string;
|
||||
reason: "initial-entry" | "resume";
|
||||
} | null>(null);
|
||||
const attentionClientRef = useRef(client);
|
||||
const attentionConnectedRef = useRef(isConnected);
|
||||
const setFocusedAgentId = useCallback(
|
||||
(agentId: string | null) => {
|
||||
useSessionStore.getState().setFocusedAgentId(serverId, agentId);
|
||||
@@ -456,10 +452,14 @@ function AgentScreenContent({
|
||||
[serverId]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
attentionClientRef.current = client;
|
||||
attentionConnectedRef.current = isConnected;
|
||||
}, [client, isConnected]);
|
||||
const attentionController = useAgentAttentionClear({
|
||||
agentId: resolvedAgentId,
|
||||
client,
|
||||
isConnected,
|
||||
requiresAttention: agent?.requiresAttention,
|
||||
attentionReason: agent?.attentionReason,
|
||||
isScreenFocused,
|
||||
});
|
||||
|
||||
const { style: animatedKeyboardStyle } = useKeyboardShiftStyle({
|
||||
mode: "translate",
|
||||
@@ -534,33 +534,20 @@ function AgentScreenContent({
|
||||
isArchivingAgent({ serverId, agentId: resolvedAgentId })
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!resolvedAgentId) {
|
||||
setFocusedAgentId(null);
|
||||
return;
|
||||
}
|
||||
|
||||
setFocusedAgentId(resolvedAgentId);
|
||||
return () => {
|
||||
const latestClient = attentionClientRef.current;
|
||||
const latestAgent = useSessionStore
|
||||
.getState()
|
||||
.sessions[serverId]
|
||||
?.agents.get(resolvedAgentId);
|
||||
if (
|
||||
latestClient &&
|
||||
shouldClearAgentAttention({
|
||||
agentId: resolvedAgentId,
|
||||
isConnected: attentionConnectedRef.current,
|
||||
requiresAttention: latestAgent?.requiresAttention,
|
||||
attentionReason: latestAgent?.attentionReason,
|
||||
})
|
||||
) {
|
||||
latestClient.clearAgentAttention(resolvedAgentId);
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
if (!resolvedAgentId) {
|
||||
setFocusedAgentId(null);
|
||||
return;
|
||||
}
|
||||
setFocusedAgentId(null);
|
||||
};
|
||||
}, [resolvedAgentId, serverId, setFocusedAgentId]);
|
||||
|
||||
setFocusedAgentId(resolvedAgentId);
|
||||
return () => {
|
||||
attentionController.clearOnAgentBlur();
|
||||
setFocusedAgentId(null);
|
||||
};
|
||||
}, [attentionController, resolvedAgentId, setFocusedAgentId])
|
||||
);
|
||||
|
||||
const isInitializing = resolvedAgentId ? isInitializingFromMap !== false : false;
|
||||
const isHistorySyncing = useMemo(() => {
|
||||
@@ -956,6 +943,8 @@ function AgentScreenContent({
|
||||
serverId={serverId}
|
||||
autoFocus
|
||||
isSubmitLoading={showPendingCreateSubmitLoading}
|
||||
onAttentionInputFocus={attentionController.clearOnInputFocus}
|
||||
onAttentionPromptSend={attentionController.clearOnPromptSend}
|
||||
onAddImages={handleAddImagesCallback}
|
||||
onComposerHeightChange={() =>
|
||||
streamViewRef.current?.prepareForViewportChange()
|
||||
|
||||
@@ -10,6 +10,7 @@ import { buildHostRootRoute } from "@/utils/host-routes";
|
||||
export function AgentsScreen({ serverId }: { serverId: string }) {
|
||||
const { agents, isRevalidating, refreshAll } = useAllAgentsList({
|
||||
serverId,
|
||||
includeArchived: true,
|
||||
});
|
||||
|
||||
// Track user-initiated refresh to avoid showing spinner on background revalidation
|
||||
@@ -43,7 +44,7 @@ export function AgentsScreen({ serverId }: { serverId: string }) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<BackHeader
|
||||
title="All agents"
|
||||
title="Sessions"
|
||||
onBack={() => router.replace(buildHostRootRoute(serverId) as any)}
|
||||
/>
|
||||
<AgentList
|
||||
|
||||
@@ -195,7 +195,7 @@ export function WorkspaceDesktopTabsRow({
|
||||
maxWidth: resolvedTabWidth,
|
||||
},
|
||||
isActive && styles.tabActive,
|
||||
(hovered || pressed || isCloseHovered) && styles.tabHovered,
|
||||
!isActive && (hovered || pressed || isCloseHovered) && styles.tabHovered,
|
||||
]}
|
||||
onHoverIn={() => {
|
||||
setHoveredTabKey(tab.key);
|
||||
@@ -273,11 +273,19 @@ export function WorkspaceDesktopTabsRow({
|
||||
(hovered || pressed) && styles.tabCloseButtonActive,
|
||||
]}
|
||||
>
|
||||
{isClosingTab ? (
|
||||
<ActivityIndicator size={12} color={theme.colors.foregroundMuted} />
|
||||
) : (
|
||||
<X size={12} color={theme.colors.foregroundMuted} />
|
||||
)}
|
||||
{({ hovered, pressed }) =>
|
||||
isClosingTab ? (
|
||||
<ActivityIndicator
|
||||
size={12}
|
||||
color={hovered || pressed ? theme.colors.foreground : theme.colors.foregroundMuted}
|
||||
/>
|
||||
) : (
|
||||
<X
|
||||
size={12}
|
||||
color={hovered || pressed ? theme.colors.foreground : theme.colors.foregroundMuted}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Pressable>
|
||||
) : null}
|
||||
</ContextMenuTrigger>
|
||||
@@ -459,7 +467,7 @@ const styles = StyleSheet.create((theme) => ({
|
||||
flexShrink: 0,
|
||||
},
|
||||
tabActive: {
|
||||
backgroundColor: theme.colors.surface2,
|
||||
backgroundColor: theme.colors.surface3,
|
||||
},
|
||||
tabHovered: {
|
||||
backgroundColor: theme.colors.surface2,
|
||||
|
||||
Reference in New Issue
Block a user