🐛 fix(vscode): 刷新按钮加载态可见,图标随重拉转圈

刷新按钮此前只发消息重拉数据,看板已有列表时界面毫无变化,用户
无法判断点击是否生效。消息协议里的 issues/loading 从未被发送。

loadAndPush 现在在开跑前推 issues/loading,并在 finally 里推新增的
issues/loaded,保证成功、报错、缺 token 提前返回都能收尾;webhook
触发的自动重拉同样走这条链路。webview 据此维护 refreshing 状态,
刷新图标转圈并在期间禁用按钮。

Claude-Session: https://claude.ai/code/session_01REdhpbaNyqWASF2HWsnTFv
This commit is contained in:
cruldra committed 2026-09-13 08:22:38 +08:00
1 parent 9167b86708
commit ef0750b4ef
7 files changed
+30 -5

No files matched your search

+11 -1
View File
@@ -159,6 +159,11 @@ export interface UseIssuesResult {
profiles: ClaudeProfile[]
setIssues: (issues: Issue[]) => void
refresh: () => void
/**
* True while the host is reloading the board (手动刷新、切换范围、webhook
* 触发都算)。看板已有列表时不会退回 loading 空屏,靠它转刷新图标给反馈。
*/
refreshing: boolean
saveSettings: (values: SettingsValues) => void
/**
* Fetch the YouTrack project list for the settings dropdown using the
@@ -344,6 +349,7 @@ export function useIssues(): UseIssuesResult {
// 默认团队全部,与扩展侧 DEFAULT_KANBAN_SCOPE 一致(两个包不共享源码)。
const [scope, setScope] = useState<'mine' | 'all'>(injected?.scope ?? 'all')
const [youtrackConfigured, setYoutrackConfigured] = useState<boolean>(injected?.youtrackConfigured ?? false)
const [refreshing, setRefreshing] = useState<boolean>(false)
const [toasts, setToasts] = useState<ToastItem[]>([])
const [profiles, setProfiles] = useState<ClaudeProfile[]>([])
const [logs, setLogs] = useState<LogEntry[]>([])
@@ -700,8 +706,12 @@ export function useIssues(): UseIssuesResult {
const cleanup = onMessage((msg) => {
switch (msg.type) {
case 'issues/loading':
setRefreshing(true)
setState(prev => prev.status === 'ready' ? prev : { status: 'loading' })
break
case 'issues/loaded':
setRefreshing(false)
break
case 'issues/update':
setState({ status: 'ready', issues: msg.issues })
setScope(msg.scope)
@@ -908,5 +918,5 @@ export function useIssues(): UseIssuesResult {
return cleanup
}, [clearPrDiffSummaryRunning, markHandoffRunning])
return { state, settings, avatars, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning }
return { state, settings, avatars, globalAutoReview, youtrackConfigured, importYouTrack, toasts, profiles, setIssues, refresh, refreshing, scope, toggleScope, saveSettings, listYouTrackProjects, youtrackProjects, dismissSettings, requestEditAuth, createIssue, dismissToast, openUrl, resumeSession, resumeReviewSession, startTestSession, resumeTestSession, focusSession, openFile, implement, generatePrDiffSummary, isPrDiffSummaryRunning, openPr, openWorktree, deleteWorktree, mergeBranch, deleteIssue, closeIssue, closeSessionTab, continueBrainstorm, changeColumn, setDependency, clearDependency, updateIssueAutoReview, updateIssueProfilePath, updateIssueBrainstormProfilePath, updateIssueTestProfilePath, logs, fetchLogs, clearLogs, pendingSelectId, clearPendingSelect, commitRunning, runCommit, hasChanges, release, runRelease, cherryPick, dismissCherryPick, confirmCherryPick, envLocked, envFileCount, envLockRunning, envLockTitle, toggleEnvLock, me, handoffUsers, requestHandoffUsers, startHandoff, acceptHandoff, isHandoffRunning }
}