feat(chat): 支持多选消息复制为纯文本 - #937
Conversation
AAswordman
left a comment
There was a problem hiding this comment.
Reviewed the current draft. The selected-message builder preserves chat-list order, excludes hidden placeholders and non-chat senders, and reuses the existing plain-text/LaTeX conversion path. No code blocker found in this pass. This remains a draft with no Candidate checks, so mark it Ready for review and wait for the merge-candidate checks before merge consideration.
2eccc11 to
794364c
Compare
Thanks for the review. I’ve marked the PR as Ready and rebased it onto the latest main. I also fixed an edge case where single-line user messages without a trailing newline were omitted by the native Markdown parser. The updated branch passes 7 JVM tests and 7 instrumentation tests on an Android 16 device, together with manual multi-select copy verification. The Candidate checks are currently awaiting repository approval to run. |
|
Ready for review. Validation for this PR is green: the targeted JVM tests pass (7/7), the Android instrumentation tests pass (7/7) on an Android 16 device, manual multi-select copy verification passes for both user and assistant messages, the full Debug APK build succeeds, the repository Python checks pass (45/45), and the WebChat typecheck passes. The full |
AAswordman
left a comment
There was a problem hiding this comment.
Request changes on the latest head.\n\nP1: The PR description says the click handler captures a message snapshot before background conversion, but messagesToCopy is only a list of references returned by chatHistory::getOrNull. ChatMessage.content is mutable and is updated while an AI response streams. LaunchedEffect(currentChatId, messageOrder) keys only on timestamps, so a content-only streaming update neither cancels this job nor refreshes the captured list. The background conversion can therefore copy a different, partially updated message than the user selected at click time.\n\nCapture immutable content at click time, for example by copying each selected message's content into an immutable value object or a ChatMessage.copy(content = message.content) snapshot, and add a regression test that mutates the source message after capture but before conversion.\n\nThe single-line Markdown parser fix and its instrumentation coverage look appropriate. Candidate checks still need to run on the current merge candidate after this issue is fixed.
AAswordman
left a comment
There was a problem hiding this comment.
按功能和界面位置复核后通过。复制按钮放在多选工具栏的加入记忆与分享操作之间,位置清晰;选中消息后启用,未选中时禁用;窄屏工具栏支持横向滚动,按钮仍可访问。复制结果按聊天原始顺序合并,并复用现有 Markdown/LaTeX 纯文本转换。\n\n消息内容快照在流式更新期间可能变化属于小概率非阻断问题,不影响本次功能合入判断。当前仍需等待/运行 Candidate checks 后再合并。
变更说明 / Description
为聊天多选模式增加“复制文本”操作,使用户可以一次复制连续或不连续的多条消息。
背景与动机 / Context and motivation
当前聊天多选工具栏支持加入记忆、分享和删除,但无法复制选中的消息文本。用户只能退出多选模式后逐条复制。
改动范围 / Changes
本次仅实现纯文本复制,不包含 Markdown 源码复制、发送者标签和格式配置选项。
兼容性与风险 / Compatibility and risks
不修改数据格式、公开 API 或配置。主要风险集中在 Compose 工具栏布局、异步复制状态和不同 Markdown 内容的复制结果。复制转换在后台调度器执行,并且只在点击时读取一次选中消息快照。
关联 Issue / Related issue
Closes #895
验证方式 / Verification
上游基线说明 / Upstream baseline note
完整
:app:testDebugUnitTest在本分支运行 1029 项,其中 1027 项通过,2 项失败:MemoryAnalysisProtocolTest.parseAnalysisResult_acceptsObjectProtocolWithoutMainEventMemoryAnalysisProtocolTest.parseAnalysisResult_rejectsMissingRequiredOperationField这两项可在完全未包含本 PR 修改的
upstream/main独立工作树中复现,并与已合并 #941 的 Candidate checks 结果一致(1026 tests completed, 2 failed)。本 PR 未修改 memory 实现或对应测试,因此属于 base branch 已有失败,不是 #937 引入的回归。证据 / Evidence
upstream/main和 feat(memory): rebuild chat memories by window #941 CI 中交叉复现。检查清单 / Checklist
Candidate checks覆盖改动范围,并会处理本 PR 引入的技术失败项