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