feat: 实现聊天取消功能,提升用户交互体验
- 在教练页面中添加用户取消发送或终止回复的能力 - 更新发送按钮状态,支持发送和取消状态切换 - 在流式回复中显示取消按钮,允许用户中断助手的生成 - 增强请求管理,添加请求序列号和有效性验证,防止延迟响应影响用户体验 - 优化错误处理,区分用户主动取消和网络错误,提升系统稳定性 - 更新相关文档,详细描述取消功能的实现和用户体验设计
This commit is contained in:
137
docs/cancel-chat-implementation.md
Normal file
137
docs/cancel-chat-implementation.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# 取消聊天功能实现文档
|
||||
|
||||
## 功能概述
|
||||
|
||||
为 AI 教练聊天界面添加了用户可以取消发送或终止回复的能力,参照业内最佳实践(如 ChatGPT、Claude 等)实现。
|
||||
|
||||
## 主要功能
|
||||
|
||||
### 1. 发送按钮状态切换
|
||||
- **发送状态**: 绿色背景,显示上箭头图标
|
||||
- **取消状态**: 红色背景 (#FF4444),显示停止图标
|
||||
- 根据 `isSending` 或 `isStreaming` 状态自动切换
|
||||
|
||||
### 2. 流式回复中的取消按钮
|
||||
- 在助手正在思考时显示"正在思考…"和取消按钮
|
||||
- 在助手正在输出文本时显示"停止生成"按钮
|
||||
- 取消按钮采用红色主题,与停止操作语义一致
|
||||
|
||||
### 3. 取消逻辑处理
|
||||
- 调用 `streamAbortRef.current.abort()` 中断 XMLHttpRequest
|
||||
- 清理状态:`isSending`、`isStreaming`、`pendingAssistantIdRef`
|
||||
- 移除正在生成中的助手消息
|
||||
- 提供触觉反馈(Warning 类型)
|
||||
|
||||
### 4. 错误处理优化
|
||||
- 区分用户主动取消和网络错误
|
||||
- 对于 AbortError 不进行错误提示和降级处理
|
||||
- 避免在取消操作后显示"请求失败"等错误信息
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 关键函数
|
||||
|
||||
```typescript
|
||||
function cancelCurrentRequest() {
|
||||
// 中断流式请求
|
||||
if (streamAbortRef.current) {
|
||||
streamAbortRef.current.abort();
|
||||
streamAbortRef.current = null;
|
||||
}
|
||||
|
||||
// 清理状态
|
||||
setIsSending(false);
|
||||
setIsStreaming(false);
|
||||
|
||||
// 移除正在生成的消息
|
||||
if (pendingAssistantIdRef.current) {
|
||||
setMessages(prev => prev.filter(msg => msg.id !== pendingAssistantIdRef.current));
|
||||
pendingAssistantIdRef.current = null;
|
||||
}
|
||||
|
||||
// 用户反馈
|
||||
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning);
|
||||
}
|
||||
```
|
||||
|
||||
### UI 状态管理
|
||||
|
||||
1. **发送按钮**:
|
||||
- 背景色:发送时为主题色,取消时为红色
|
||||
- 图标:发送时为上箭头,取消时为停止图标
|
||||
- 禁用状态:只在无内容且非发送状态时禁用
|
||||
|
||||
2. **流式消息气泡**:
|
||||
- 思考阶段:显示"正在思考…"和取消按钮
|
||||
- 输出阶段:在消息下方显示"停止生成"按钮
|
||||
|
||||
### 边界情况处理
|
||||
|
||||
1. **组件卸载**: 自动清理未完成的请求
|
||||
2. **新建会话**: 如果有进行中的请求,先取消再创建
|
||||
3. **切换历史会话**: 取消当前请求后再加载历史会话
|
||||
4. **多次点击**: 防止重复发送,支持随时取消
|
||||
|
||||
## 用户体验设计
|
||||
|
||||
### 视觉反馈
|
||||
- 按钮颜色变化(绿色→红色)
|
||||
- 图标变化(发送→停止)
|
||||
- 取消按钮采用一致的红色主题
|
||||
|
||||
### 交互反馈
|
||||
- 触觉反馈:取消时提供 Warning 类型震动
|
||||
- 即时响应:点击取消后立即停止生成
|
||||
- 状态清理:取消后界面回到可输入状态
|
||||
|
||||
### 语义化设计
|
||||
- "正在思考…" + "取消":在等待响应阶段
|
||||
- "停止生成":在文本输出阶段
|
||||
- 红色主题:与停止操作的通用语义保持一致
|
||||
|
||||
## 业内最佳实践对比
|
||||
|
||||
### ChatGPT
|
||||
- ✅ 发送按钮变为停止按钮
|
||||
- ✅ 红色停止图标
|
||||
- ✅ 即时响应
|
||||
|
||||
### Claude
|
||||
- ✅ 流式输出过程中显示停止按钮
|
||||
- ✅ 取消后清理当前消息
|
||||
- ✅ 明确的视觉区分
|
||||
|
||||
### 我们的实现
|
||||
- ✅ 发送/取消按钮一体化设计
|
||||
- ✅ 双重取消入口(发送按钮 + 消息内按钮)
|
||||
- ✅ 完整的状态管理和错误处理
|
||||
- ✅ 触觉反馈增强用户体验
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. **基本功能测试**:
|
||||
- 发送消息后立即点击取消
|
||||
- 在流式输出过程中点击停止
|
||||
- 连续发送多条消息并取消
|
||||
|
||||
2. **边界情况测试**:
|
||||
- 网络异常时的取消行为
|
||||
- 快速切换会话时的状态清理
|
||||
- 组件卸载时的资源清理
|
||||
|
||||
3. **用户体验测试**:
|
||||
- 按钮状态变化的流畅性
|
||||
- 触觉反馈的适当性
|
||||
- 界面响应的即时性
|
||||
|
||||
## 总结
|
||||
|
||||
本实现参照业内主流 AI 聊天应用的最佳实践,提供了完整的取消/终止功能,包括:
|
||||
|
||||
- 直观的 UI 状态切换
|
||||
- 完善的取消逻辑处理
|
||||
- 良好的用户反馈机制
|
||||
- 健壮的错误处理
|
||||
- 一致的设计语言
|
||||
|
||||
功能实现既保证了技术的正确性,也注重了用户体验的完整性。
|
||||
Reference in New Issue
Block a user