界面优化与聊天可靠性修复
2025年8月18日
大家好!👋
过去几天我一直在改进聊天界面的一些重要功能。下面是新功能和修复的问题。
🐛 重要Bug修复
创建新聊天按钮问题
最令人沮丧的bug之一是”创建新聊天”按钮无响应。用户点击后没有反应,然后多次点击,突然会创建多个新聊天。
问题原因:
scrollToBottom函数在DOM元素准备好之前就尝试访问messageListEl.value.scrollHeight- 没有加载状态保护,快速点击会触发多个API调用
- 聊天创建流程中的竞态条件
修复方案:
// 在 scrollToBottom 中添加空值检查
const scrollToBottom = (_behavior: ScrollBehavior) => {
behavior.value = _behavior
if (messageListEl.value) {
y.value = messageListEl.value.scrollHeight
}
}
// 在 ChatSessionList 中添加加载状态
const isCreatingChat = ref(false)
async function onNewChat() {
if (isCreatingChat.value) return
isCreatingChat.value = true
try {
const data = await createChatSession()
sessionList.value.unshift(data)
await router.push(`/chat/${data.id}`)
} finally {
isCreatingChat.value = false
}
}
这是一个典型的例子,说明小的时序问题如何创造出非常恼人的用户体验问题!
✨ 新功能:增强预览面板
代码工件预览系统得到了重大升级!以前用户只能在基本的侧边面板中查看代码工件。现在我们有了:
分屏视图模式
- 聊天占用剩余空间
- 预览面板固定500px宽度
- 两者同时可见,便于对照查看
全屏模式
- 预览覆盖整个视窗
- 完全隐藏标题栏以获得最大查看区域
- 带半透明背景的浮动关闭按钮
- 非常适合查看复杂的HTML演示或详细图表
智能状态管理
这比听起来要复杂。关键洞察是将”显示/隐藏预览”状态与”正常/全屏”状态分离:
// 两个独立状态而不是一个混乱的状态
const showArtifacts = ref(false)
const isFullscreen = ref(false)
// 智能关闭行为
const closeArtifacts = () => {
showArtifacts.value = false
isFullscreen.value = false // 关闭时重置全屏状态
}
// 全屏关闭只退出全屏,不关闭预览
const toggleFullscreen = () => {
isFullscreen.value = !isFullscreen.value
}
现在的用户体验流程是:
- 点击预览 → 在分屏视图中打开
- 点击全屏 → 扩展到全屏
- 在全屏中点击X → 返回分屏视图
- 在分屏视图中点击X → 完全关闭预览
🎨 动画优化
将预览图标动画从滑入效果改为淡入效果。有时最小的改变会对界面的精致感产生最大的影响。
// 之前:从右侧滑入
.artifact-btn {
opacity: 0;
transform: translateX(8px);
}
// 之后:简单淡入
.artifact-btn {
opacity: 0;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
📚 学到的经验
1. DOM时序问题无处不在
scrollToBottom bug提醒我们Vue的响应式很快,但DOM仍然需要时间更新。在访问元素属性之前,始终检查元素是否存在。
2. 状态管理的复杂性
最初,我试图让预览系统变得”智能”,有可调整大小的分割和复杂状态。但简单往往更好——两种清晰的模式(分屏/全屏)和明显的过渡对用户来说效果更好。
3. 用户测试揭示边缘情况
聊天创建bug只在特定时序条件下发生。真实用户行为(当某些东西看起来坏了时快速点击)经常揭示在正常开发测试中不会出现的问题。
💭 给开发者同行的思考
这些UI可靠性修复可能不够华丽,但对用户体验有巨大影响。一个95%时间有效的按钮对用户来说就是坏的。花时间处理边缘情况和竞态条件是区分好界面和优秀界面的关键。
另外,在构建预览/模态系统时,始终像考虑进入流程一样考虑退出流程。用户需要理解如何回到他们来自的地方!
你希望下次看到哪些功能得到改进?在issues中留下你的想法!
- 你的开发团队