Skip to content

fix(Graph): 修复 Tooltip 两处回归——CI 键盘触发丢失 + 提交详情缺失 branches/tags/committer - #74

Merged
ThreeFish-AI merged 11 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-log-view-commit-tooltip
Jul 4, 2026
Merged

fix(Graph): 修复 Tooltip 两处回归——CI 键盘触发丢失 + 提交详情缺失 branches/tags/committer#74
ThreeFish-AI merged 11 commits into
feature/1.x.xfrom
ThreeFish-AI/fix-log-view-commit-tooltip

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

背景

承接已合并的 #69(撤回 WebviewPanel、改光标跟随 hover tooltip、合入 TS6/vitest4 依赖升级基线)。#69 合并后发现两处回归——重做浮层时遗漏了原有能力,本 PR 修复并对齐官方 Source Control Graph 的完整信息。

变更(本 PR 净增量,两处回归修复)

1. fix(Graph) — 修复 CI 状态 Tooltip 键盘触发丢失(7ded694

  • 根因:上一轮把 positionTip(rect) 统一改为无参 positionTip()(cursor-anchored),导致键盘触发路径(聚焦 CI 图标按 Enter)传入的 rect 被忽略,tooltip 锚到过时坐标 → 看似消失。
  • 修复positionTip(rect?) 双模式——有 rect(键盘,无光标)用 positionAtRect 锚图标;无 rect(鼠标 hover / ciData 刷新)用 positionAtCursor 跟随光标。兼顾「键盘可达」与「鼠标跟随」。

2. fix(Graph) — 恢复提交 Tooltip 丢失的 branches/tags/remotes 胶囊与 Committer 行(2f9c202

  • 根因:重做提交详情浮层时只保留 author/message/diffstat/hash/github,遗漏了引用胶囊分组(HEAD/Branches/Remotes/Tags)与 Committer 行——数据一直都在(chips/泳道色在 model.rows,committer 在 VM),仅渲染未写。
  • 修复
    • renderCommitTip 新增 refsHtml:从行数据取 chips 按 HEAD/Branches/Remotes/Tags 分组,实心胶囊底色跟随该行泳道色(复用 laneColor/onColor/chipIcon,与行内胶囊同款)。
    • 新增 Committer 行:提交者名 + 相对(绝对)时间,仅当与作者不同才展示(避免与头部冗余)。
    • protocol:CommitDetailVMcommitterDateRel/committerDateAbs(host 侧预格式化)。

3. 合入 feature 基线(merge commit)

验证

  • check-types / lint / 生产打包(esbuild)/ 349 单测 / vsce package 全绿(TS 6 / vitest 4 / vite 7 基线下)。
  • harness 截图核实:BRANCHES/REMOTES/TAGS 三组胶囊 + COMMITTER 行 + author/message/diffstat/hash/Open on GitHub 全部齐全;CI tooltip 键盘触发正常。

验证边界:hover tooltip 实机手感(光标跟随、键盘 Enter 触发 CI tip、refs 胶囊)需真实 VS Code F5 端到端确认。

🤖 Generated with Claude Code

…ontrol;

根因:#48「浮层定位修复」将 positionTip/positionCommitTip 横向定位改为 left=window.innerWidth+8,
误以为 webview position:fixed 可越界渲染到编辑器。实则侧边栏 WebviewView 是沙箱 iframe,坐标系
为 iframe 自身视口,该值落到右边界外被裁剪不可见。抽出共用 positionFloat(锚触发元素右侧→越界翻
左→再越界收进视口),彻底修复 CI 与提交两处浮层。

同时按需求将面向用户的「Log」视图更名为「Graph」,并对齐 VS Code 官方 Source Control GRAPH 视图
样式(不改底层数据/协议/布局算法/CI 逻辑):
- 泳道连线 <line> 直线改三次贝塞尔 <path> 平滑曲线(fromCol===toCol 自动退化直线);
- 当前 HEAD 行节点渲染为空心环+内点(双环高亮),普通行保持实心点;
- 引用胶囊改实心半透明底+同色描边+内联 SVG 图标前缀(分支/云/tag,因无 codicon 字体);
- 工具栏 seg 按钮间距/圆角/hover 态贴近官方;
- package.json 视图名与 Refresh/Filter/Clear Graph Filter 命令标题、CI 配置描述、aria-label
  统一为 Graph(viewType hyperGit.log、log/* 消息前缀、类名等内部标识符不动)。

验证:check-types/lint/生产打包通过,324 单测全绿;贝塞尔几何与 HEAD 判定纯函数 11 项自测通过;
离线 harness 浏览器截图目视对齐官方 GRAPH 视图。

🤖 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<threefish.ai@gmail.com>
Review 复核发现上一轮 chips 与官方 Source Control GRAPH 视图存在三处实质偏离,本次逐项对齐(截图逐行比对官方图确认):
- 位置:chips 从 message 左侧前缀移到右侧后缀(列序 泳道图→message→chips→author→date→CI);
- 颜色:底色改为跟随本行泳道色 laneColor(row.layout.node.colorIdx),类型靠图标区分而非颜色,
  与官方一致(同名 origin 远程分支随所在行泳道呈多色);新增 onColor() 按底色亮度自适应深/白字保可读;
- 形状:由半透明小圆角矩形(radius 3px)改为实心不透明全圆角 pill(radius 8px),保留分支/云/tag 图标前缀;
- #commit-tip 浮层内胶囊同步同款样式,与行内保持一致。

仅渲染层调整:chipsHtml/rowHtml/buildCommitTip + CSS,未触碰数据/协议/布局算法/CI 逻辑。
验证:check-types/lint/生产打包通过,324 单测全绿;DOM 结构断言(chips 在 msg 后、颜色跟泳道、
HEAD 空心环)+ Chrome headless 截图与官方图 3 逐行比对确认对齐。

🤖 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<threefish.ai@gmail.com>
需求:悬停 GRAPH 列表某 commit 时,在右侧编辑器区展示该提交详情面板(对齐官方 Source Control
Graph 的 hover 面板位置)。原实现是侧栏 iframe 内 position:fixed 浮层——受浏览器沙箱限制,DOM
浮层无法渲染到 iframe 之外的编辑器区,此路架构上封死,故改用 WebviewPanel。

实现(仅渲染/呈现层,不改数据/协议既有分支/布局算法/CI 逻辑):
- 新增 CommitDetailPanel(editor 区 WebviewPanel,ViewColumn.Beside + preserveFocus 不抢焦点):
  单例复用,悬停切换只 postMessage 换数据 + reveal,不反复 create/dispose;reqSeq 竞态守卫 +
  lastHash 去重;onDidDispose 置空、下次悬停重建。面板内容 = 头像占位+作者+相对/绝对时间、完整
  message、变更统计(N files changed/+ins/-del)、完整 hash + Open on GitHub。
- GRAPH 悬停 400ms 防抖 → 发 log/showCommitDetail;移除旧侧栏浮层 #commit-tip(CSS/DOM/JS 约
  20 处),CI 浮层 #ci-tip 保持不动;i 键改为对选中提交打开面板(保留键盘可达)。
- engine 纯函数(零 vscode,可单测):parseShortStat(shortstat 解析)、commitWebUrl(GitHub 提交
  页 URL)、format-time(相对/绝对时间,host 侧预格式化下发)。github-ci-service 暴露 public
  getGitHubRemote 复用远程解析缓存;Open on GitHub 走既有 openExternal(SSRF 白名单已放行 web 域)。
- protocol 扩展 CommitDetailVM/Stat + log/showCommitDetail + commitDetail/data、openExternal 消息。

验证:check-types/lint/生产打包通过;单测 341 全绿(新增 shortstat/commitWebUrl/format-time 17
例);panel 离线 harness 浏览器截图与官方图逐项比对对齐。注:编辑器区面板生命周期/悬停/不抢焦点
需真实 VS Code F5 端到端确认(webview 交互离线不可覆盖)。

🤖 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<threefish.ai@gmail.com>
…/fix-log-view-commit-tooltip

# Conflicts:
#	src/adapter/webview/log-webview.ts
根因:Dependabot #60 单方面把 @types/vscode 从 ~1.85.0 bump 到 ~1.125.0,未联动 engines.vscode
(自 M0 起刻意固定 ^1.85.0 的广兼容基线,从未上调)。vsce package 强制要求 @types/vscode 的
major.minor ≤ engines.vscode,1.125 > 1.85 命中校验失败,连带令基于 feature/1.x.x 的下游 PR
(含本 PR #65)Package vsix job 全部 fail。

修复(降级依赖,不动 engines):
- @types/vscode ~1.125.0 → ~1.85.0(对齐 engines.vscode ^1.85.0);同步 pnpm-lock.yaml。
- .github/dependabot.yml 为 npm 生态加 ignore: @types/vscode,防 Dependabot 再次单方面 bump
  破坏约束——该版本须与 engines 联动,属人工产品决策。

循证(Workflow 三路调研):代码未用任何 >1.85 的稳定 API(最新为 TreeView.badge,1.72 稳定),
降级不致 tsc 报错;升 engines 会不可逆抬高 Marketplace 安装门槛、收窄用户面,违背广兼容定位,不取。

验证(本地复现原失败点):check-types/lint 通过;vsce package 成功生成 vsix(原报错点解除);
单测 349 全绿。

🤖 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<threefish.ai@gmail.com>
对照官方截图逐字符核验三处真实偏差并修复(DOM 文本 ground truth,非图像识别):
- diffstat:'3 files changed +86 -1'(简写)→ '3 files changed, 86 insertions(+), 1 deletion(-)'
  (完整文字、逗号分隔,绿/红着色覆盖数字+insertions(+)/deletions(-) 整段);
- 时间:'7 hr ago · 2026/7/4 09:41'(缩写/数字日期/带秒)→ '7 hours ago (2026年7月4日 09:12)'
  (相对时间全拼 hours/minutes/days、括号包裹本地化绝对时间、去掉秒);
- 作者区:邮箱从作者名旁尖括号移到第二行(与时间同色同行)。

formatRelative/formatAbsolute 同步改全拼/去秒并更新单测;check-types/lint/349 单测/vsce package 通过。

🤖 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<threefish.ai@gmail.com>
撤回上一轮的 WebviewPanel(Beside) 方案(在编辑器区开 tab,与官方 hover tooltip 相悖),按方案 A 实现:

- 提交详情浮层重回 webview 内(#commit-tip),但定位改为 cursor-anchored:mousemove 跟踪光标,
  浮层锚在光标处、边沿自动翻转(右→左、下→上)、钳制视口。这是 sidebar webview iframe 限制下
  最接近官方观感的做法(GitLens/Git Graph 同款限制,无法溢出到编辑器区像素)。
- 交互:400ms 防抖请求 → host 组装富数据 → 回包渲染(无空闪);hover bridge(移到浮层不消失,
  方便点 Open on GitHub);mouseout/scroll/Escape 隐藏;i 键键盘可达(锚选中行 rect,无光标)。
- 富布局:头像+作者+邮箱·相对(绝对)时间/subject+body/diffstat(绿红 tabular-nums)/hash+Open on GitHub,
  对齐前几轮已校准的官方字符级文案。
- 统一所有 tooltip:CI 浮层也用 positionAtCursor(替换原 rect 锚),共享 editorHoverWidget 语义
  令牌/阴影/圆角,视觉语言一致。

实现:buildCommitDetail 移入 LogWebviewProvider 私有方法(复用 engine 纯函数 parseShortStat/
commitWebUrl/formatRelative/formatAbsolute);删除 commit-detail-panel.ts;protocol 新增
log/commitDetail(host→webview)。

验证:check-types/lint/生产打包/349 单测通过;harness 截图 DOM 核实浮层锚在光标右下、富布局完整。

🤖 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<threefish.ai@gmail.com>
… tsconfig 迁移);

冲突解决(3 处均取 HEAD——hover tooltip 是用户最新决定方向,feature 上 #65 squash 带的是已撤回的 WebviewPanel 版本):
- log-webview.ts:保留 HEAD 光标跟随 hover tooltip + log/commitDetail 回包;丢弃 feature 的 WebviewPanel 方案。
- format-time.ts / log-format-time.test.ts:保留 HEAD 全拼(minutes/hours)+ 去秒;丢弃 feature 的缩写(min/hr)+ 带秒。
- commit-detail-panel.ts:HEAD 已删(撤回 WebviewPanel),feature 重新引入→再次删除。

feature 净并入:package.json/pnpm-lock.yaml(vitest 4 / vite 7 / typescript-eslint 8.62.1 / TS 6.0.3)、
tsconfig.json(#67 模块解析迁移)。

验证:TS 6 / vitest 4 / vite 7 新基线下 check-types/lint/生产打包/349 单测/vsce package 全通过。
回归根因:上一轮把 positionTip(rect) 统一改成无参 positionTip()(cursor-anchored),导致键盘触发
路径(聚焦 CI 图标按 Enter)传入的 rect 被忽略,tooltip 锚到过时光标坐标(甚至 0,0)→ 看似消失。

修复:positionTip(rect?) 双模式——有 rect(键盘,无光标)用 positionAtRect 锚图标 rect;
无 rect(鼠标 hover / ciData 刷新,光标已知)用 positionAtCursor 跟随光标。兼顾「键盘可达」与
「鼠标 hover 跟随光标」两个诉求。

验证:check-types/lint/生产打包/349 单测通过。

🤖 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<threefish.ai@gmail.com>
回归根因:上一轮 b6877cc 重做提交详情浮层时,只保留了 author/message/diffstat/hash/github,
遗漏了引用胶囊分组(HEAD/Branches/Remotes/Tags)与 Committer(提交者+提交时间)行——数据一直都在
(chips/泳道色在 webview model.rows,committer 在 VM),仅渲染未写。

修复(数据齐备,纯补渲染):
- renderCommitTip 新增 refsHtml:从 model.rows 取该行 chips,按 HEAD/Branches/Remotes/Tags 分组,
  实心胶囊底色跟随该行泳道色(复用 laneColor/onColor/chipIcon,与行内胶囊同款)。
- 新增 Committer 行:提交者名 + 相对(绝对)时间,仅当与作者不同才显示(避免与头部冗余)。
- protocol:CommitDetailVM 增 committerDateRel/committerDateAbs(host 侧 formatRelative/Absolute 预格式化)。
- 配套 CSS:.ct-refs-wrap/.ct-sec/.ct-k/.ct-v/.ct-refs/.ct-dim。

验证:check-types/lint/生产打包/349 单测通过;harness 截图确认 Branches/Remotes/Tags 胶囊 +
Committer 行 + 原有 author/message/diffstat/hash/github 全部齐全。

🤖 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<threefish.ai@gmail.com>
…/fix-log-view-commit-tooltip

# Conflicts:
#	src/adapter/webview/log-webview.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant