refactor(client): 四处轮询站点迁移到 use-polling,语义逐一保持
- SubagentView useSubagentLive:self-scheduling(上一请求 settle 后才排 下一次,不重叠)+ 每代 AbortSignal + signal.aborted 拦迟到写入,行为 与原 disposed 标志等价(teardown 同步置 disposed 并 abort)。 - SideChatView:立即拉取 effect 与 2s 定时拆分——输入变化(含 running 翻转)仍先拉一次转录,运行中间隔 tick 拉转录+徽章;fetchThread 自带 的逐次 abort 与卸载 abort 原样保留。 - GitLens:可见时 2s 固定静默 tick,无初始突发(mount/scope 变更的完整 刷新在别处);refresh 身份变化照旧重启间隔相位。 - ChangesTab:输入变化即拉一次(含隐藏态翻转),可见时 2.5s 固定间隔; pull 内部 pollGen 代际守卫不动。 守护 spec 全绿:subagent-live-polling + subagent-jobs-view 13/13、 sidechat-view + sidechat-transcript 29/29、git-view-worktree + changes-tab + changes-ops 13/13;断言零改动。
This commit is contained in:
@@ -18,6 +18,7 @@ import type { SidebarSessionEvent } from '../../context-types.ts'
|
||||
import type { TabComponentProps } from '../service.ts'
|
||||
import { t } from '../locales.ts'
|
||||
import { api } from '../api.ts'
|
||||
import { usePolling } from '../use-polling.ts'
|
||||
import { floatTab, type SidebarDiffRef } from '../state.ts'
|
||||
import { GitLens } from './GitLens.tsx'
|
||||
import { SessionLens } from './SessionLens.tsx'
|
||||
@@ -104,12 +105,11 @@ export function ChangesTab({ ctx, store, scope, tab, visible, onOpenFile, onOpen
|
||||
seqRef.current = 0
|
||||
setOpsError(false)
|
||||
}, [scope.sessionId])
|
||||
useEffect(() => {
|
||||
void pull()
|
||||
if (!visible) return
|
||||
const timer = window.setInterval(() => { void pull() }, 2_500)
|
||||
return () => { window.clearInterval(timer) }
|
||||
}, [visible, pull])
|
||||
// One pull on every input change — mount, scope change, and visibility
|
||||
// flip all re-pull (a hidden tab still catches up on the flip); only the
|
||||
// poll CADENCE below is gated by visibility.
|
||||
useEffect(() => { void pull() }, [visible, pull])
|
||||
usePolling(visible, pull, { intervalMs: 2_500 })
|
||||
// tick only forces the re-render; the fold reads the ref directly.
|
||||
void tick
|
||||
const ops = opsRef.current
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { GitLogEntry, GitStatusEntry, GitStatusResult, GitWorktree, SessionScope } from '../api.ts'
|
||||
import { api } from '../api.ts'
|
||||
import { usePolling } from '../use-polling.ts'
|
||||
import { baseName, isWithinWorkspace, relativeTo } from '../paths.ts'
|
||||
import { resolveSidebarPath } from '../produced-files.ts'
|
||||
import { relativeTime, t } from '../locales.ts'
|
||||
@@ -280,11 +281,11 @@ export function GitLens(props: GitLensProps) {
|
||||
const generation = refreshGeneration.current += 1
|
||||
void refreshTarget(chosenPathRef.current ?? '', { loading: true, generation })
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!visible) return
|
||||
const timer = window.setInterval(() => { void refresh(true) }, 2_000)
|
||||
return () => { window.clearInterval(timer) }
|
||||
}, [visible, refresh])
|
||||
/** The silent poll tick (the status-only fast path between worktree
|
||||
* re-lists, see refresh) — fixed 2s cadence while visible, no initial
|
||||
* burst (mount and scope changes already refresh above). */
|
||||
const pollTick = useCallback((): Promise<void> => refresh(true), [refresh])
|
||||
usePolling(visible, pollTick, { intervalMs: 2_000 })
|
||||
|
||||
/** Append the next history page (lazy: only when the user asks for more). */
|
||||
const loadMoreLog = async (): Promise<void> => {
|
||||
|
||||
Reference in New Issue
Block a user