From 559f522f93be48a841f28a3f83df1736b5dc5190 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 10 Sep 2026 01:42:00 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat(UI):=20Commit=20=E8=A7=86=E7=AA=97?= =?UTF-8?q?=E5=A4=B4=E9=83=A8=E4=B8=A4=E8=A1=8C=20UI=20=E4=B8=8A=E7=A7=BB?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E6=A0=8F=E2=80=94=E2=80=94Active=20Changelis?= =?UTF-8?q?t=20=E9=80=89=E6=8B=A9=E5=99=A8=E4=B8=8E=20List/Tree=20?= =?UTF-8?q?=E5=88=87=E6=8D=A2;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Active Changelist 下拉与 ⋯ 管理菜单合并为标题栏 \$(checklist) 图标(Refresh 左侧)→ setActiveChangelist QuickPick:各列表带文件计数、活动项预选,分隔线后并入 New/Rename/Delete(默认列表不可改名删除);活动列表名常驻 view.description 副标题; - 文件列表 List ⇄ Tree 段控改为标题栏 \$(list-tree)/\$(list-flat) 互斥图标(context key hyperGit.commit.tree,交互同 Graph/Branches 范式),偏好移交 host workspaceState 按仓库持久化(hyperGit.commit.dmode:),旧 webview state 偏好一次性重置为默认 flat; - Select All 复选框吸顶于文件列表容器内首行(空态随空列表隐藏),原 .cl-bar 与 files-header 两行整体移除,净省两行纵向空间; - 协议收缩:删 commit/setActive、commit/changelistMenu 消息与 CommitChangelistItem,state 增 mode 字段(host 为事实源整态下发);清理死图标 ICON_ELLIPSIS; - 新增 tests/unit/commit-titlebar.test.ts 清单护栏;CHANGELOG 与两份特性文档同步。 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 4 + docs/features/commit-view-consolidation.md | 12 +- docs/features/file-list-group-by-directory.md | 6 +- package.json | 42 +++- src/adapter/commands.ts | 43 +++- src/adapter/webview/commit-webview.ts | 195 ++++++++---------- src/adapter/webview/shared-styles.ts | 3 - src/extension.ts | 7 +- src/shared/protocol.ts | 22 +- tests/suite/extension.test.js | 2 + tests/unit/commit-titlebar.test.ts | 87 ++++++++ 11 files changed, 282 insertions(+), 141 deletions(-) create mode 100644 tests/unit/commit-titlebar.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index edb208a..b93ce96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## [Unreleased] +### Changed + +- **Commit 视图头部两行 UI 上移 VS Code 标题栏(省两行竖直空间)**:① 「Active Changelist」下拉与 `⋯` 管理菜单合并为标题栏 Refresh 图标左侧的 `$(checklist)` 图标按钮——点击弹出 QuickPick:各列表带文件计数、当前活动项预选,分隔线后并入 New / Rename / Delete Changelist… 操作(默认列表不可改名/删除);活动 changelist 名常驻视图副标题(标题「Commit」同行右侧)。② 文件列表 List ⇄ Tree 段控改为标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(交互同 Graph/Branches 切换范式),偏好移交 host `workspaceState` 按仓库持久化(`hyperGit.commit.dmode:`)——**原 webview state 中的旧 List/Tree 偏好一次性重置为默认 flat**(勾选集、目录折叠与提交草稿不受影响)。③ Select All 复选框吸顶于文件列表容器内首行(列表为空时随空态隐藏),原 `.cl-bar` 与 files-header 两行整体移除。 + ## [0.0.17] - 2026-09-09 — Log 提交详情常驻面板 · VS Code 1.136 最佳实践对齐 · 稳定性与体验修复 自 v0.0.16 以来的积累(PR #115 / #116)。核心变更:**Log 提交详情由悬停浮层改为右侧常驻面板**(三区可拖拽分割线、窄视图自适应堆叠),并全面对齐 VS Code 1.136 控件 / 交互 / API 最佳实践(修复 9 项缺陷、Webview 控件全面主题化、能力声明与设置治理);新增长时 git 操作进度反馈、入门导览与默认键位、Stash / Worktrees 批量操作、分支 / 标签名即时校验等体验增强。完整用户视角叙述见 [Release Note v0.0.17](./docs/releases/v0.0.17.md)。 diff --git a/docs/features/commit-view-consolidation.md b/docs/features/commit-view-consolidation.md index e3ec225..fab7002 100644 --- a/docs/features/commit-view-consolidation.md +++ b/docs/features/commit-view-consolidation.md @@ -8,7 +8,7 @@ |---|---| | 文件单击看 Diff | 文件行单击(勾选框除外)→ `commit/openFile` → 复用 `hyperGit.openDiff` | | 单文件右键菜单 | 文件行右键 → `commit/fileMenu` → 原生 `showQuickPick`:Open Diff / Move to Changelist… / Show History / Stage·Unstage Hunks… / Add to .gitignore / Discard Changes(复用既有命令,含 discard 确认框) | -| Changelist 管理 | 头部 `` + `⋯` 菜单行已上移,省一行竖直空间) | | Git 操作工具栏 | 标题栏(`view/title`)承接 refresh / push / pull / fetch / pushDialog / updateProject / createPatch / applyPatch;去掉与 webview 内 Commit·Commit&Push 按钮重复的两项 | | 活动栏未提交数角标 | 迁至 Commit `WebviewView.badge`(容器图标角标 = 各视图 badge 之和,总数不变) | @@ -22,16 +22,16 @@ ## 交互范围取舍 -Commit 视图文件区以**活动 Changelist** 为提交目标(勾选集即提交范围);非活动 Changelist 通过头部下拉切换查看。相较旧树「同屏并列多 changelist」少了一处低频便利,换取窄侧栏下更聚焦的提交工作流。 +Commit 视图文件区以**活动 Changelist** 为提交目标(勾选集即提交范围);非活动 Changelist 通过标题栏 `$(checklist)` 图标弹 QuickPick 切换,活动列表名常驻 `view.description` 副标题。相较旧树「同屏并列多 changelist」少了一处低频便利,换取窄侧栏下更聚焦的提交工作流。 ## 实现 - 视图与菜单:[`package.json`](../../package.json)(删 `hyperGit.changes` 视图 / viewsWelcome / 全部 `view == hyperGit.changes` 菜单;`view/title` 迁至 `view == hyperGit.commit`)。 -- 视图主体:[`adapter/webview/commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(groups/switcher/文件交互/菜单/角标/目录树)。 -- 命令:[`adapter/commands.ts`](../../src/adapter/commands.ts)(`resolveChange` + 签名重构)。 +- 视图主体:[`adapter/webview/commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(groups/文件交互/菜单/角标/目录树;changelist 切换与管理、List/Tree 切换已上移标题栏,mode 以 host 为事实源按仓库持久化)。 +- 命令:[`adapter/commands.ts`](../../src/adapter/commands.ts)(`resolveChange` + 签名重构;`setActiveChangelist` QuickPick 承载切换与管理)。 - 装配:[`extension.ts`](../../src/extension.ts)(移除 tree/changesView,角标改由 `commitView.updateBadge`)。 -- 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`CommitChangelistItem`、`commit/openFile|fileMenu|setActive|changelistMenu`)。 +- 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`commit/openFile|fileMenu`;changelist 操作消息已随标题栏上移移除)。 ## 验证 -`pnpm run check-types && pnpm run lint && pnpm run test:unit` 全绿;Extension Development Host(F5):无 CHANGES 视图;Commit 顶部可切换/管理 changelist;文件单击开 Diff、右键出菜单(含 discard 确认);标题栏 Git 动作可用;活动栏角标随未提交数增减;无 Git 仓库时降级不崩溃。 +`pnpm run check-types && pnpm run lint && pnpm run test:unit` 全绿;Extension Development Host(F5):无 CHANGES 视图;标题栏 `$(checklist)` 图标可切换/管理 changelist、副标题显示活动列表名;文件单击开 Diff、右键出菜单(含 discard 确认);标题栏 Git 动作可用;活动栏角标随未提交数增减;无 Git 仓库时降级不崩溃。 diff --git a/docs/features/file-list-group-by-directory.md b/docs/features/file-list-group-by-directory.md index 1f3793b..733f215 100644 --- a/docs/features/file-list-group-by-directory.md +++ b/docs/features/file-list-group-by-directory.md @@ -29,14 +29,14 @@ flowchart LR | 建树路径 | 条目 `path`(仓库相对) | `CommitFileChange.path`(干净新路径,重命名归位到新目录) | | 复选框 | 有:叶子勾选 + **目录三态**级联;Select All 基于全量文件 | 无(只读浏览) | | 叶子单击 | 打开 Diff(`commit/openFile`) | 打开单文件 Diff(`log/openFile`,`data-path` 保持展示串不变) | -| 偏好持久化 | `setState({mode, collapsed, checked})` | host `workspaceState`(`hyperGit.log.dmode:`)+ webview `dcollapsed` 按仓库记忆 | -| 切换控件 | webview 内 List/Tree 段控 | Graph 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(同 Branches 分组切换范式) | +| 偏好持久化 | host `workspaceState`(`hyperGit.commit.dmode:`)+ webview `setState` 按仓库记 `collapsed`/`checked` | host `workspaceState`(`hyperGit.log.dmode:`)+ webview `dcollapsed` 按仓库记忆 | +| 切换控件 | Commit 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(context key `hyperGit.commit.tree`) | Graph 标题栏 `$(list-tree)`/`$(list-flat)` 互斥图标(同 Branches 分组切换范式) | ## 实现 - 引擎:[`engine/tree/file-tree.ts`](../../src/engine/tree/file-tree.ts)(+ [`tests/unit/file-tree.test.ts`](../../tests/unit/file-tree.test.ts),15 用例)。 - 协议:[`shared/protocol.ts`](../../src/shared/protocol.ts)(`FileTreeNode`;`CommitViewState.tree`;`log/commitFiles` payload `tree`)。 -- 渲染:[`commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(List/Tree 段控、`renderFlat`/`renderTree`、`makeLeafRow`、目录三态 `updateDirStates`)、[`log-webview.ts`](../../src/adapter/webview/log-webview.ts)(`renderDetails` 分派、`renderDetailNode`;Log 侧切换控件为 Graph 标题栏 `hyperGit.log.detailTree/detailFlat` 命令图标,模式经 `log/detailMode` 定向下发免整图重拉)。 +- 渲染:[`commit-webview.ts`](../../src/adapter/webview/commit-webview.ts)(`renderFlat`/`renderTree`、`makeLeafRow`、目录三态 `updateDirStates`;切换控件为 Commit 标题栏 `hyperGit.commit.detailTree/detailFlat` 命令图标,mode 以 host 为事实源随 `state` 整态下发)、[`log-webview.ts`](../../src/adapter/webview/log-webview.ts)(`renderDetails` 分派、`renderDetailNode`;Log 侧切换控件为 Graph 标题栏 `hyperGit.log.detailTree/detailFlat` 命令图标,模式经 `log/detailMode` 定向下发免整图重拉)。 ## 验证 diff --git a/package.json b/package.json index 0238a46..40c9d7c 100644 --- a/package.json +++ b/package.json @@ -204,8 +204,9 @@ }, { "command": "hyperGit.setActiveChangelist", - "title": "Set Active Changelist", - "category": "Hyper Git" + "title": "Set Active Changelist…", + "category": "Hyper Git", + "icon": "$(checklist)" }, { "command": "hyperGit.renameChangelist", @@ -272,6 +273,18 @@ "category": "Hyper Git", "icon": "$(list-flat)" }, + { + "command": "hyperGit.commit.detailTree", + "title": "Group Changed Files by Directory", + "category": "Hyper Git", + "icon": "$(list-tree)" + }, + { + "command": "hyperGit.commit.detailFlat", + "title": "Show Changed Files as Flat List", + "category": "Hyper Git", + "icon": "$(list-flat)" + }, { "command": "hyperGit.selectRepository", "title": "Select Repository…", @@ -816,6 +829,21 @@ } ], "view/title": [ + { + "command": "hyperGit.setActiveChangelist", + "when": "view == hyperGit.commit", + "group": "navigation@0.5" + }, + { + "command": "hyperGit.commit.detailTree", + "when": "view == hyperGit.commit && !hyperGit.commit.tree", + "group": "navigation@0.75" + }, + { + "command": "hyperGit.commit.detailFlat", + "when": "view == hyperGit.commit && hyperGit.commit.tree", + "group": "navigation@0.75" + }, { "command": "hyperGit.refresh", "when": "view == hyperGit.commit", @@ -1153,7 +1181,7 @@ }, { "command": "hyperGit.setActiveChangelist", - "when": "false" + "when": "view == hyperGit.commit" }, { "command": "hyperGit.renameChangelist", @@ -1375,6 +1403,14 @@ "command": "hyperGit.log.detailFlat", "when": "view == hyperGit.log" }, + { + "command": "hyperGit.commit.detailTree", + "when": "view == hyperGit.commit" + }, + { + "command": "hyperGit.commit.detailFlat", + "when": "view == hyperGit.commit" + }, { "command": "hyperGit.acceptOurs", "when": "hyperGit.hasConflicts" diff --git a/src/adapter/commands.ts b/src/adapter/commands.ts index 4a22f2d..b18307a 100644 --- a/src/adapter/commands.ts +++ b/src/adapter/commands.ts @@ -21,7 +21,8 @@ function asId(arg: unknown): string | undefined { * 注册 Changes / Commit 相关命令(M1;原 Changes 树移除后由 Commit webview 复用)。 * * 文件级命令统一接受 `ChangeItem | 路径字符串`:webview 传路径,host 经 {@link resolveChange} - * 回落到 `service.getChanges()` 解析为 ChangeItem(单一事实源)。视图刷新由 registry/service + * 回落到 `service.getChanges()` 解析为 ChangeItem(单一事实源)。changelist 切换与管理由 + * 标题栏 $(checklist) 图标进入 setActiveChangelist QuickPick 承载。视图刷新由 registry/service * 的 onDidChange → extension.refreshAll → commitView.refresh() 驱动,命令内不再直接刷新视图。 */ export function registerChangesCommands( @@ -57,10 +58,48 @@ export function registerChangesCommands( ); subs.push( - vscode.commands.registerCommand('hyperGit.setActiveChangelist', (arg: unknown) => { + vscode.commands.registerCommand('hyperGit.setActiveChangelist', async (arg?: unknown) => { + // 带参 = 程序化切换;无参 = QuickPick(标题栏 $(checklist) 图标与命令面板共用入口)。 const id = asId(arg); if (id) { registry.setActive(id); + return; + } + const active = registry.activeChangelistId; + // 计数取 getGroups(含空列表,未显式分配项归活动列表——见 engine/changelist/grouper)。 + const groups = registry.getGroups(service.getChanges(), (c) => c.relativePath); + type SetActiveItem = + | { label: string; description: string; picked: boolean; setId: string } + | { label: string; kind: vscode.QuickPickItemKind } + | { label: string; op: 'new' | 'rename' | 'delete'; targetId?: string }; + const items: SetActiveItem[] = groups.map((g) => ({ + label: g.name, + description: `${g.items.length} file${g.items.length === 1 ? '' : 's'}`, + picked: g.id === active, // 预选当前活动项(对齐 selectRepository 的 picked 范式) + setId: g.id, + })); + // 分隔线后并入原 webview「⋯」菜单管理操作(default 不可改名/删除,镜像原 handleChangelistMenu 语义)。 + items.push({ label: 'Actions', kind: vscode.QuickPickItemKind.Separator }); + items.push({ label: '$(add) New Changelist…', op: 'new' }); + const def = active !== 'default' ? registry.getDef(active) : undefined; + if (def) { + items.push({ label: `$(edit) Rename "${def.name}"…`, op: 'rename', targetId: active }); + items.push({ label: `$(trash) Delete "${def.name}"…`, op: 'delete', targetId: active }); + } + const pick = await vscode.window.showQuickPick(items, { placeHolder: 'Select Active Changelist' }); + if (!pick) { + return; + } + if ('setId' in pick) { + registry.setActive(pick.setId); // 视图刷新经 registry.onDidChange → refreshAll 驱动 + } else if ('op' in pick) { + if (pick.op === 'new') { + await vscode.commands.executeCommand('hyperGit.newChangelist'); + } else if (pick.op === 'rename') { + await vscode.commands.executeCommand('hyperGit.renameChangelist', pick.targetId); + } else { + await vscode.commands.executeCommand('hyperGit.deleteChangelist', pick.targetId); + } } }), ); diff --git a/src/adapter/webview/commit-webview.ts b/src/adapter/webview/commit-webview.ts index 16b4c70..71883cc 100644 --- a/src/adapter/webview/commit-webview.ts +++ b/src/adapter/webview/commit-webview.ts @@ -6,35 +6,88 @@ import type { CommitRequest } from '../commit/commit-service'; import type { ChangelistRegistry } from '../changelist-registry'; import type { ChangeItem, GitRepositoryService } from '../git-repository-service'; import type { - CommitChangelistItem, CommitFileItem, CommitViewState, HostToWebviewMessage, WebviewToHostMessage, } from '../../shared/protocol'; import type { CommitService } from '../commit/commit-service'; -import { getBaseStyles, ICON_CHEVRON_DOWN, ICON_ELLIPSIS } from './shared-styles'; +import { getBaseStyles, ICON_CHEVRON_DOWN } from './shared-styles'; import { getNonce } from './nonce'; /** * Commit 提交窗口(WebviewView,自绘提交面板)。 * - * 承载活动 changelist 文件列表(平铺 / 目录树两态可切)+ 文件单击看 diff + 单文件右键操作 + - * changelist 切换与管理(由原 Changes 视图平移而来)+ 多行 Commit Message 编辑器 + - * Amend/sign-off/skip-hooks 选项 + Commit/Commit and Push 按钮 + Conventional Commits 实时校验 + - * 最近消息复用。选中态由 webview 端管理(host 不回写,避免覆盖用户操作)。 + * 承载活动 changelist 文件列表(平铺 / 目录树两态,切换上移标题栏互斥图标)+ 文件单击看 diff + + * 单文件右键操作 + 多行 Commit Message 编辑器 + Amend/sign-off/skip-hooks 选项 + + * Commit/Commit and Push 按钮 + Conventional Commits 实时校验 + 最近消息复用。 + * changelist 切换与管理(New/Rename/Delete)由标题栏 $(checklist) 图标 → setActiveChangelist + * QuickPick 承载,活动列表名常驻 view.description 副标题;Select All 吸顶于文件列表容器内首行。 + * 选中态由 webview 端管理(host 不回写,避免覆盖用户操作)。 * 注:活动栏未提交数角标已迁至隐藏的 hyperGit.changesBadge TreeView 承载(见 extension.ts)。 */ -export class CommitWebviewProvider implements vscode.WebviewViewProvider { +export class CommitWebviewProvider implements vscode.WebviewViewProvider, vscode.Disposable { public static readonly viewType = 'hyperGit.commit'; private view?: vscode.WebviewView; private currentMessage = ''; + /** 文件列表展示模式(List/Tree,标题栏图标切换):host 为事实源,随 state 整态下发。 */ + private detailMode: 'flat' | 'tree' = 'flat'; + private readonly disposables: vscode.Disposable[] = []; + + /** List/Tree 偏好按仓库持久化 key(issue #107 同 log.dmode 范式;第三视图复用时提炼共享 helper)。 */ + private static dmodeKey(root: string): string { + return `hyperGit.commit.dmode:${root}`; + } + /** context key 同步(标题栏互斥按钮显隐由 when 子句驱动)。 */ + private static setCtx(key: string, value: string | boolean): void { + void vscode.commands.executeCommand('setContext', key, value); + } constructor( private readonly service: GitRepositoryService, private readonly registry: ChangelistRegistry, private readonly commit: CommitService, - ) {} + private readonly workspaceState: vscode.Memento, + ) { + // 激活即恢复当前仓库的 List/Tree 记忆并同步 context key(标题栏控件先于视图解析渲染); + // 活跃仓库切换(issue #107):恢复该仓库的记忆值(无记忆回退 'flat'), + // 文件列表刷新由 extension 的 onDidChange → refreshAll 驱动。 + this.loadRepoScopedPrefs(); + this.disposables.push( + service.onDidChangeRepository(() => { + this.loadRepoScopedPrefs(); + }), + ); + } + + dispose(): void { + for (const d of this.disposables) { + d.dispose(); + } + this.disposables.length = 0; + } + + /** 装载当前仓库的 List/Tree 偏好(memento → 内存 + context key)。 */ + private loadRepoScopedPrefs(): void { + const root = this.service.repoRoot; + this.detailMode = + (root ? this.workspaceState.get<'flat' | 'tree'>(CommitWebviewProvider.dmodeKey(root)) : undefined) ?? 'flat'; + CommitWebviewProvider.setCtx('hyperGit.commit.tree', this.detailMode === 'tree'); + } + + /** 标题栏 List/Tree 互斥图标切换(同 Graph/Branches 范式):pushState 全同步且幂等,整态重发即达。 */ + setDetailMode(mode: 'flat' | 'tree'): void { + if (this.detailMode === mode) { + return; + } + const root = this.service.repoRoot; + if (root) { + void this.workspaceState.update(CommitWebviewProvider.dmodeKey(root), mode); + } + this.detailMode = mode; + CommitWebviewProvider.setCtx('hyperGit.commit.tree', mode === 'tree'); + this.pushState(); + } resolveWebviewView(view: vscode.WebviewView): void { this.view = view; @@ -74,12 +127,6 @@ export class CommitWebviewProvider implements vscode.WebviewViewProvider { case 'commit/fileMenu': void this.handleFileMenu(msg.payload.path); break; - case 'commit/setActive': - void vscode.commands.executeCommand('hyperGit.setActiveChangelist', msg.payload.id); - break; - case 'commit/changelistMenu': - void this.handleChangelistMenu(msg.payload.id); - break; } } @@ -93,7 +140,7 @@ export class CommitWebviewProvider implements vscode.WebviewViewProvider { if (!change) { return; } - // QuickPick label 支持 $(codicon) 内联图标(与 changelist 菜单对齐)。 + // QuickPick label 支持 $(codicon) 内联图标(与 changelist 标题栏 QuickPick 对齐)。 const actions: ReadonlyArray<{ readonly label: string; readonly command: string }> = [ { label: '$(diff) Open Diff', command: 'hyperGit.openDiff' }, { label: '$(symbol-enum) Move to Changelist…', command: 'hyperGit.moveChangelist' }, @@ -110,30 +157,6 @@ export class CommitWebviewProvider implements vscode.WebviewViewProvider { await vscode.commands.executeCommand(pick.command, change); } - /** changelist 头部 ⋯ 菜单:新建 / 重命名 / 删除(默认列表不可改名删除,复用既有命令)。 */ - private async handleChangelistMenu(id: string): Promise { - const def = this.registry.getDef(id); - const canModify = Boolean(def) && id !== 'default'; - const items: Array<{ label: string; op: 'new' | 'rename' | 'delete' }> = [ - { label: '$(add) New Changelist…', op: 'new' }, - ]; - if (canModify && def) { - items.push({ label: `$(edit) Rename "${def.name}"…`, op: 'rename' }); - items.push({ label: `$(trash) Delete "${def.name}"…`, op: 'delete' }); - } - const pick = await vscode.window.showQuickPick(items, { placeHolder: 'Changelist actions' }); - if (!pick) { - return; - } - if (pick.op === 'new') { - await vscode.commands.executeCommand('hyperGit.newChangelist'); - } else if (pick.op === 'rename') { - await vscode.commands.executeCommand('hyperGit.renameChangelist', id); - } else { - await vscode.commands.executeCommand('hyperGit.deleteChangelist', id); - } - } - private sendValidation(): void { this.post({ type: 'conventionalValidation', payload: this.commit.validateMessage(this.currentMessage) }); } @@ -169,21 +192,20 @@ export class CommitWebviewProvider implements vscode.WebviewViewProvider { const changes = this.service.getChanges(); const groups = this.registry.getGroups(changes, (c) => c.relativePath); const activeId = this.registry.activeChangelistId; - const changelists: CommitChangelistItem[] = groups.map((g) => ({ id: g.id, name: g.name, count: g.items.length })); const activeGroup = groups.find((g) => g.id === activeId) ?? groups.find((g) => g.active) ?? groups[0]; const files = (activeGroup?.items ?? []).map((c) => this.toFileItem(c)); const state: CommitViewState = { template: this.commit.getTemplate(), recentMessages: this.commit.getRecentMessages(), - activeChangelistName: this.registry.getDef(activeId)?.name ?? 'Default', - activeChangelistId: activeId, - changelists, + mode: this.detailMode, files, tree: buildFileTree(files.map((f) => f.path)), conventionalEnabled: this.commit.conventionalEnabled(), busy: false, repoRoot: this.service.repoRoot ?? '', }; + // 标题栏副标题 = 活动 changelist 名(原 webview 头部切换行上移,省一行竖直空间)。 + this.view.description = this.registry.getDef(activeId)?.name ?? 'Default'; this.post({ type: 'state', payload: state }); this.sendValidation(); } @@ -204,14 +226,9 @@ export class CommitWebviewProvider implements vscode.WebviewViewProvider { -
- Active Changelist: - - -
-