Skip to content

feat(聊天面板): 添加标签重命名功能#313

Closed
Hemomoo wants to merge 1 commit intoxun082:mainfrom
Hemomoo:feat-chat-storage
Closed

feat(聊天面板): 添加标签重命名功能#313
Hemomoo wants to merge 1 commit intoxun082:mainfrom
Hemomoo:feat-chat-storage

Conversation

@Hemomoo
Copy link
Copy Markdown
Collaborator

@Hemomoo Hemomoo commented Feb 26, 2026

实现通过双击标签进入编辑模式并重命名的功能
添加相关状态管理和事件处理逻辑

PR 描述

  1. 添加标签重命名
  2. 增加标签的持久化

PR 类型

  • 🐛 Bug 修复
  • ✨ 新功能
  • 💄 UI/UX 改进
  • ♻️ 重构
  • 🚀 性能优化
  • 📝 文档更新
  • 🔄 其他

Issue 关联

Closes #

其他信息

image

实现通过双击标签进入编辑模式并重命名的功能
添加相关状态管理和事件处理逻辑
@netlify
Copy link
Copy Markdown

netlify bot commented Feb 26, 2026

Deploy Preview for ornate-blancmange-89db6b failed. Why did it fail? →

Name Link
🔨 Latest commit 5134b28
🔍 Latest deploy log https://app.netlify.com/projects/ornate-blancmange-89db6b/deploys/69a02b36587f9a00087a025c

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @Hemomoo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求引入了聊天面板标签的重命名功能,极大地提升了用户体验。用户现在可以通过简单的双击操作来编辑聊天标签的标题,并支持通过键盘快捷键或失去焦点来完成或取消编辑。此外,此更改还为聊天标签的状态管理增加了持久化能力,确保用户在关闭或刷新应用后,其自定义的聊天标签及其顺序能够被保留。

Highlights

  • 标签重命名功能: 实现了聊天面板标签的重命名功能,用户可以通过双击标签进入编辑模式。
  • 交互逻辑: 支持通过键盘(Enter 键提交,Escape 键取消)和失去焦点来完成或取消重命名操作。
  • 状态管理集成: 将标签重命名功能集成到 ChatTabBar 组件和 ChatPanel 容器组件中,并通过 chatStore 更新标签标题。
  • 状态持久化: 为聊天标签的状态添加了持久化存储,确保应用刷新后标签数据不丢失。
Changelog
  • apps/DocFlow/src/app/docs/_components/ChatPanel/chat-tab-bar.tsx
    • 引入了 useState, useRef, useEffect React Hooks。
    • ChatTabBarProps 接口中添加了 onRenameTab 属性。
    • 实现了标签编辑状态管理(editingTabId, editValue)和输入框引用。
    • 添加了 useEffect Hook,用于在编辑模式下自动聚焦并选中输入框。
    • 新增了 handleDoubleClick 事件处理函数,用于启动标签重命名。
    • 新增了 handleRenameSubmit 函数,用于提交重命名操作。
    • 新增了 handleKeyDown 函数,支持通过 Enter 键提交和 Escape 键取消重命名。
    • 修改了标签渲染逻辑,在编辑模式下显示可编辑的输入框。
    • 为标签按钮添加了 onDoubleClick 事件监听器。
  • apps/DocFlow/src/app/docs/_components/ChatPanel/index.tsx
    • 新增了 handleRenameTab 函数,用于调用 chatStoreupdateTab 方法更新标签标题。
    • handleRenameTab 函数作为属性传递给 ChatTabBar 组件。
  • apps/DocFlow/src/stores/chatStore.ts
    • zustand/middleware 导入了 persist
    • ChatState 接口中添加了 onRenameTab 方法定义。
    • useChatStore 的创建函数包装在 persist 中,实现了聊天标签状态的本地存储持久化。
    • 调整了 setIsOpentogglePanel 方法的逻辑,以确保在面板打开且没有标签时自动创建一个新标签,与持久化逻辑兼容。
    • 实现了 onRenameTab 方法,用于更新指定标签的标题。
    • 配置了持久化存储的名称为 'chat-storage'
Activity
  • 目前没有发现任何评论或审查活动。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次 PR 实现了聊天标签的重命名和状态持久化功能,整体实现良好。我发现了一些可以改进的地方:

  1. 事件处理逻辑: 在 chat-tab-bar.tsx 中,重命名输入框的事件处理存在一些问题,可能导致在特定操作下(如按 Escape 或 Enter 键)出现非预期的行为。我提供了一个建议来修复这些问题。
  2. 状态持久化: 在 chatStore.ts 中,持久化逻辑会保存所有状态,包括一些临时的状态(如 documentReference),这可能会在页面刷新后导致问题。建议明确指定需要持久化的状态。
  3. 代码冗余: chatStore.ts 中存在一个未被使用的 onRenameTab 方法,可以移除以保持代码库的整洁。

除此之外,代码实现清晰,功能完整。请查看具体的审查评论以获取详细信息和代码建议。

Comment on lines +45 to +77
const [editingTabId, setEditingTabId] = useState<string | null>(null);
const [editValue, setEditValue] = useState('');
const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
if (editingTabId && inputRef.current) {
inputRef.current.focus();
inputRef.current.select();
}
}, [editingTabId]);

const handleDoubleClick = (tabId: string, title: string) => {
setEditingTabId(tabId);
setEditValue(title);
};

const handleRenameSubmit = () => {
if (editingTabId && editValue.trim()) {
onRenameTab(editingTabId, editValue.trim());
}

setEditingTabId(null);
setEditValue('');
};

const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleRenameSubmit();
} else if (e.key === 'Escape') {
setEditingTabId(null);
setEditValue('');
}
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

当前重命名逻辑存在两个问题:

  1. Escape 键取消编辑时,会错误地保存当前输入的内容。
  2. Enter 键确认重命名时,可能会触发两次保存操作(一次来自 onKeyDown,一次来自 onBlur)。

这两个问题都源于 onBlur 事件在输入框失焦时(包括程序性失焦)总是会触发保存。建议重构事件处理逻辑,使用一个 ref 来防止重复操作和区分取消与保存操作,以确保行为的正确性。

  const [editingTabId, setEditingTabId] = useState<string | null>(null);
  const [editValue, setEditValue] = useState('');
  const inputRef = useRef<HTMLInputElement>(null);
  const isActionTaken = useRef(false);

  useEffect(() => {
    if (editingTabId && inputRef.current) {
      isActionTaken.current = false;
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [editingTabId]);

  const handleDoubleClick = (tabId: string, title: string) => {
    setEditingTabId(tabId);
    setEditValue(title);
  };

  const handleRenameSubmit = () => {
    if (isActionTaken.current) return;
    isActionTaken.current = true;

    if (editingTabId && editValue.trim()) {
      onRenameTab(editingTabId, editValue.trim());
    }

    setEditingTabId(null);
    setEditValue('');
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      handleRenameSubmit();
    } else if (e.key === 'Escape') {
      if (isActionTaken.current) return;
      isActionTaken.current = true;
      setEditingTabId(null);
      setEditValue('');
    }
  };

Comment on lines +151 to +153
{
name: 'chat-storage',
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

使用 persist 中间件时,默认会持久化整个 store 的状态。其中 documentReferencepresetMessage 似乎是临时状态,不应该在页面刷新后保留。这可能导致非预期的行为,例如在新的会话中出现旧的文档引用。

建议使用 persist 中间件的 partialize 选项来指定只持久化需要跨会话保留的状态,例如 tabs, activeTabIdisOpen

    {
      name: 'chat-storage',
      partialize: (state) => ({
        isOpen: state.isOpen,
        tabs: state.tabs,
        activeTabId: state.activeTabId,
      }),
    },

Comment on lines +142 to +145
onRenameTab: (id, newTitle) =>
set((state) => ({
tabs: state.tabs.map((t) => (t.id === id ? { ...t, title: newTitle } : t)),
})),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这个 onRenameTab 方法的实现是多余的。重命名功能已经通过 updateTab 方法在 ChatPanel/index.tsx 组件中实现。为了保持代码简洁并避免冗余,建议移除此方法。同时,也请从第 33 行的 ChatState 接口中移除其定义。

@Hemomoo Hemomoo closed this Feb 27, 2026
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