⚡ perf(vscode): 看板打开先出快照、评论只拉末页
This commit is contained in:
1 parent
904ab7491d
commit
a68caf5f6e
9 files changed
+447
-115
No files matched your search
@@ -2,8 +2,8 @@
|
||||
* Subscribes to the extension host's issue stream.
|
||||
*
|
||||
* State machine (`UseIssuesState`):
|
||||
* - loading : initial mount + any time the host pushes `issues/loading`
|
||||
* - ready : host pushed `issues/update`; carries the current list
|
||||
* - loading : 无快照的首次挂载,或 host 推 `issues/loading` 且当前还没有列表
|
||||
* - ready : host 推了 `issues/update`,或 HTML 里注入了上一屏快照
|
||||
* - error : host pushed `issues/error`; carries the user-facing message
|
||||
*
|
||||
* Settings UI is a separate overlay (`settings: SettingsOverlayState | null`)
|
||||
@@ -287,13 +287,48 @@ export interface UseIssuesResult {
|
||||
isHandoffRunning: (issueNumber: number) => boolean
|
||||
}
|
||||
|
||||
function readInjectedSnapshot(): {
|
||||
issues: Issue[]
|
||||
scope: 'mine' | 'all'
|
||||
me?: string
|
||||
globalAutoReview: boolean
|
||||
youtrackConfigured: boolean
|
||||
} | null {
|
||||
const el = document.getElementById('kanban-snapshot')
|
||||
if (!el?.textContent)
|
||||
return null
|
||||
try {
|
||||
const parsed: unknown = JSON.parse(el.textContent)
|
||||
if (!parsed || typeof parsed !== 'object')
|
||||
return null
|
||||
const obj = parsed as Record<string, unknown>
|
||||
if (!Array.isArray(obj.issues))
|
||||
return null
|
||||
if (obj.scope !== 'mine' && obj.scope !== 'all')
|
||||
return null
|
||||
return {
|
||||
issues: obj.issues as Issue[],
|
||||
scope: obj.scope,
|
||||
me: typeof obj.me === 'string' ? obj.me : undefined,
|
||||
globalAutoReview: obj.globalAutoReview === true,
|
||||
youtrackConfigured: obj.youtrackConfigured === true,
|
||||
}
|
||||
}
|
||||
catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function useIssues(): UseIssuesResult {
|
||||
const [state, setState] = useState<UseIssuesState>({ status: 'loading' })
|
||||
const injected = readInjectedSnapshot()
|
||||
const [state, setState] = useState<UseIssuesState>(
|
||||
injected ? { status: 'ready', issues: injected.issues } : { status: 'loading' },
|
||||
)
|
||||
const [settings, setSettings] = useState<SettingsOverlayState | null>(null)
|
||||
const [youtrackProjects, setYoutrackProjects] = useState<YouTrackProjectsState>({ status: 'idle', projects: [] })
|
||||
const [globalAutoReview, setGlobalAutoReview] = useState<boolean>(true)
|
||||
const [scope, setScope] = useState<'mine' | 'all'>('mine')
|
||||
const [youtrackConfigured, setYoutrackConfigured] = useState<boolean>(false)
|
||||
const [globalAutoReview, setGlobalAutoReview] = useState<boolean>(injected?.globalAutoReview ?? true)
|
||||
const [scope, setScope] = useState<'mine' | 'all'>(injected?.scope ?? 'mine')
|
||||
const [youtrackConfigured, setYoutrackConfigured] = useState<boolean>(injected?.youtrackConfigured ?? false)
|
||||
const [toasts, setToasts] = useState<ToastItem[]>([])
|
||||
const [profiles, setProfiles] = useState<ClaudeProfile[]>([])
|
||||
const [logs, setLogs] = useState<LogEntry[]>([])
|
||||
@@ -307,7 +342,7 @@ export function useIssues(): UseIssuesResult {
|
||||
const [envLockTitle, setEnvLockTitle] = useState<string>('正在检查 .env 锁定状态…')
|
||||
const prDiffSummaryRunningRef = useRef<Set<number>>(new Set())
|
||||
const [prDiffSummaryRunning, setPrDiffSummaryRunning] = useState<ReadonlySet<number>>(() => new Set())
|
||||
const [me, setMe] = useState<string | undefined>(undefined)
|
||||
const [me, setMe] = useState<string | undefined>(injected?.me)
|
||||
const [handoffUsers, setHandoffUsers] = useState<{ issueNumber: number, users: string[] } | null>(null)
|
||||
const handoffRunningRef = useRef<Set<number>>(new Set())
|
||||
const [handoffRunning, setHandoffRunning] = useState<Set<number>>(new Set())
|
||||
@@ -329,7 +364,7 @@ export function useIssues(): UseIssuesResult {
|
||||
}, [scope])
|
||||
|
||||
const refresh = useCallback((): void => {
|
||||
setState({ status: 'loading' })
|
||||
setState(prev => prev.status === 'ready' ? prev : { status: 'loading' })
|
||||
postMessage({ type: 'issues/refresh' })
|
||||
// 用户刷新时重查发布状态:远端分支可能已经动了。
|
||||
postMessage({ type: 'release/check' })
|
||||
@@ -637,7 +672,7 @@ export function useIssues(): UseIssuesResult {
|
||||
const cleanup = onMessage((msg) => {
|
||||
switch (msg.type) {
|
||||
case 'issues/loading':
|
||||
setState({ status: 'loading' })
|
||||
setState(prev => prev.status === 'ready' ? prev : { status: 'loading' })
|
||||
break
|
||||
case 'issues/update':
|
||||
setState({ status: 'ready', issues: msg.issues })
|
||||
|
||||
Reference in new issue
Block a user