Skip to content

feat(editor): 支持一键关闭已保存标签页#415

Merged
J3n5en merged 1 commit into
J3n5en:mainfrom
hellomrbigshot:feat/close-open-files
Apr 11, 2026
Merged

feat(editor): 支持一键关闭已保存标签页#415
J3n5en merged 1 commit into
J3n5en:mainfrom
hellomrbigshot:feat/close-open-files

Conversation

@hellomrbigshot

Copy link
Copy Markdown
Contributor

在编辑区标签动作菜单与标签页右键菜单中新增「关闭已保存」入口,并补充相关中英文文案。

在编辑区标签动作菜单与标签页右键菜单中新增「关闭已保存」入口,并补充相关中英文文案。
@github-actions

github-actions Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Claude finished @hellomrbigshot's task in 2m 20s —— View job


🔍 代码审查报告

👋 欢迎查看审查结果! 本次审查已完成,以下是详细分析和建议。
💡 使用提示:点击 📁 文件链接可直接跳转到代码位置,建议按优先级处理问题。

📊 审查概览 · 一目了然

📋 审查项目 🔢 发现数量 📈 占比 🎯 处理状态
📁 审查文件 5 100% 已完成
🚨 严重问题 0 0%
⚠️ 中等问题 1 33% 🟡 本版本修复
轻微问题 2 67% 🔵 后续优化

🏆 代码质量评分

📊 综合评分: 85/100  🌟🌟🌟🌟⭐
📋 本次等级: 良好

📋 问题分布

🚨 严重: ░░░░░░░░░░  0%
⚠️ 中等: ███░░░░░░░ 33%
⚡ 轻微: ███████░░░ 67%
总体评分: ⭐⭐⭐⭐☆ (4/5)

🎯 关键发现

🏷️ 类别 🔍 发现数量 🎯 优先级 📈 趋势
🔒 安全性 0 个 ✅ 无风险
⚡ 性能 0 个 ✅ 无影响
🎨 代码质量 3 个 🔵 低 📊 平稳

🎯 问题详细分析 · 📊 点击展开查看

📊 **👆 点击此处展开详细统计和图表分析**

📈 问题趋势分析

本次审查: 🟡🔵🔵⚪⚪ (发现 3 个问题)
代码质量: ████████░░ 85%
安全评分: ██████████ 100% ✅
性能评分: ██████████ 100% ✅
🏆 质量指标 📊 当前分数 🎯 目标分数 📈 改进方向
代码质量 85/100 90+ ⬆️ 可改进
安全等级 100/100 100 ✅ 优秀
性能优化 100/100 100 ✅ 优秀

🐛 问题清单与修复指南 · 📋 点击展开查看

📋 **👆 点击此处展开详细问题列表 (共 3 个问题) · 一键复制追踪 📌**

🚀 快速开始

⚠️ 中等级别 (Major) 建议修复

🟡 #1 代码重复:closeSavedTabs 在两个面板中完全相同

🏷️ 类型: 代码重复 | ⏰ 优先级: P1 - 本版本修复 | 🎯 影响范围: 模块级

  • 🔍 问题描述closeSavedTabs 回调在 src/renderer/components/files/CurrentFilePanel.tsx:203-208src/renderer/components/files/FilePanel.tsx:416-421 中存在完全一样的实现:

    // src/renderer/components/files/CurrentFilePanel.tsx:203-208
    // src/renderer/components/files/FilePanel.tsx:416-421
    const closeSavedTabs = useCallback(async () => {
      const paths = tabs.filter((tab) => !tab.isDirty).map((tab) => tab.path);
      for (const path of paths) {
        await closeFile(path);
      }
    }, [tabs, closeFile]);
  • 🛠️ 解决方案:考虑将 closeSavedTabs 提取到 useEditor hook 中,与 closeFile 等方法放在一起,避免在每个使用方都重复实现。这样如果将来逻辑变化(比如需要增加批量关闭优化),只需修改一处。

    // in useEditor hook
    const closeSavedTabs = useCallback(async () => {
      const savedPaths = tabs.filter((tab) => !tab.isDirty).map((tab) => tab.path);
      for (const path of savedPaths) {
        await closeFile(path);
      }
    }, [tabs, closeFile]);
  • ⚠️ 潜在影响:当前不影响功能,但后续维护两份相同代码容易出现不一致。


⚡ 轻微级别 (Minor) 优化建议

🔵 #2 src/renderer/components/files/EditorArea.tsx:1331

🏷️ 类型: 代码优化 | ⏰ 优先级: P2 - 后续版本 | 🎯 影响范围: 局部

  • 🔍 问题描述tabs.some((tab) => !tab.isDirty) 在渲染周期中被计算了两次——一次在菜单按钮的可见性条件中(第 1331 行虽然没直接用,但 onCloseSaved 总是存在),一次在 MenuItemdisabled 属性中(第 1348 行)。虽然性能影响极小,但可以统一提取。

    // src/renderer/components/files/EditorArea.tsx:1348
    disabled={!onCloseSaved || !tabs.some((tab) => !tab.isDirty)}
  • 🛠️ 解决方案:可用 useMemohasSavedTabs 提前计算,在两处共享使用:

    const hasSavedTabs = useMemo(() => tabs.some((tab) => !tab.isDirty), [tabs]);
  • ⚠️ 潜在影响:当前性能影响可忽略不计,属于代码洁癖级别的优化。


🔵 #3 src/renderer/components/files/EditorTabs.tsx:242-252

🏷️ 类型: 一致性 | ⏰ 优先级: P2 - 后续版本 | 🎯 影响范围: 局部

  • 🔍 问题描述:右键菜单中 "Close Saved Tabs" 放在了 MenuSeparator 之后、"Close All Tabs" 之前。这与 EditorArea.tsx 中顶部下拉菜单的顺序一致(先 Close Saved、再 Close All),保持一致性很好。但右键菜单的分组逻辑中,"Close Saved" 和 "Close All" 之间缺少一个 MenuSeparator,而在其他分组之间都有。

    // src/renderer/components/files/EditorTabs.tsx:242-260
    <MenuSeparator />
    <MenuItem disabled={!canCloseSaved} ...>
      {t('Close Saved Tabs')}
    </MenuItem>
    <MenuItem disabled={!canCloseAll} ...>     {/* 与上面缺少分隔线 */}
      {t('Close All Tabs')}
    </MenuItem>
  • 🛠️ 解决方案:这不是bug,只是提示——当前的分组暗示 "Close Saved" 和 "Close All" 同属一个操作组,这其实是合理的。如果团队认为它们应分开,可添加分隔线;否则保持当前设计即可。

  • ⚠️ 潜在影响:纯视觉/交互层面,不影响功能。


📊 修复优先级矩阵

🎯 优先级 🚨 严重 ⚠️ 中等 ⚡ 轻微 📈 总计
🔴 P0 0 个 - - 0 个
🟡 P1 - 1 个 - 1 个
🔵 P2 - - 2 个 2 个
📊 合计 0 1 2 3 个

✅ 代码亮点

本次 PR 有几处值得肯定的设计:

  1. 完整的功能覆盖:同时在标签栏右键菜单和顶部动作菜单中提供入口,用户体验一致。
  2. 正确的 disabled 处理:当所有标签页都有未保存修改时,菜单项置灰,防止无意义操作。
  3. border-b 位置重构:将 border-bEditorTabs 上移到 EditorArea 的外层容器,使新增的菜单按钮能与标签栏共享同一底边框线,布局更干净。
  4. 完善的国际化:中英文文案都已补充到位。

🎯 合并决策建议

📋 合并评估结果

📊 评估维度 ⭐ 得分 🎯 状态 💭 说明
🔐 安全性 10/10 ✅ 通过 无安全风险,纯 UI 功能
📊 代码质量 8/10 ✅ 良好 存在少量代码重复,但逻辑清晰
⚡ 性能影响 10/10 ✅ 无影响 无额外性能开销
🛠️ 功能完整性 9/10 ✅ 完整 功能覆盖全面,交互合理
🧪 测试覆盖 5/10 ⚠️ 基本 无新增测试,但 UI 交互功能可接受

📈 综合评分: 42/50 分 · 等级: 良好


🚦 最终建议

建议合并

📝 详细理由

  • 🟢 功能实现完整,"关闭已保存"在右键菜单和顶部菜单中均可用
  • 🟢 代码逻辑正确,isDirty 过滤准确,不会误关有修改的标签页
  • 🟢 无安全风险和性能问题
  • 🟢 国际化文案完整,遵循项目规范
  • 🟢 UI 布局调整(border-b 重构)合理且不影响现有功能

🎯 具体行动建议

  1. 后续版本改进
    • closeSavedTabs 逻辑提取到 useEditor hook,消除 CurrentFilePanelFilePanel 中的重复代码
    • 考虑为 tabs.some(tab => !tab.isDirty) 使用 useMemo 缓存(非必须)

@J3n5en J3n5en merged commit 6ea1429 into J3n5en:main Apr 11, 2026
1 check passed
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.

2 participants