23b46f931071492639dae9368eb258890cc46868
改了什么 - data/api/SessionsApi.kt:messages 端点加可选 q(契约 §1 行 6:q 是同一个端点上的 查询参数,不是新端点)。不传 q 时 Retrofit 整个省掉该参数,既有调用线上请求逐字不变 —— 这条用真 HTTP 服务端读原始 URI 钉住,而不是靠读代码相信。 - data/repository/MessageRepository.kt:新增 search()(走既有 apiCall/Result 风格, 倒序返回统一转成升序的 PagedMessages),以及 normalizeSearchQuery(只 trim: 不转义 % _ \、不改大小写 —— 这两件事服务端已做,两边都做必然错一边)。 空查询不发请求(契约里空 q = 未传,那会把整段历史当成搜索结果回给调用方)。 - ui/chat/SessionSearchModel.kt(新):全部纯逻辑 —— 命中片段投影(先过 domain/parse 这一处解析器再拼回纯文本,绝不把标记当富文本;标记里才有的词只显示不高亮)、 结果合并去重排序(倒序,与聊天页的升序 MessageOrder 刻意相反)、游标推进、 「这条在不在窗口里」的判定、失败文案。 - ui/chat/SessionSearchViewModel.kt(新):只属于聊天页搜索态的小 VM,带代际号, 连打两次回车时慢的那个请求回来不会顶掉新关键词的结果。 - ui/chat/SessionSearchPanel.kt(新):全屏搜索面板 —— 自动聚焦输入框(IME 搜索键与 放大镜都能提交)+ 结果列表(角色 / 时间 / 命中片段,BasicComponent 包 PreferenceCard) + 往下翻加载更早的命中 + 未搜/搜索中/空结果/失败 四态分开渲染。 - ui/chat/ChatScreen.kt:只加接线 —— 顶栏搜索入口、面板叠层、返回键先关搜索、 点结果之后的如实告知。 为什么这么做 - 搜索态独立成小 VM:ChatViewModel 正被另一个并行模块改动,而搜索不改消息窗、不发消息、 不碰 WS,没有任何理由挤进去。 - 面板叠在聊天页之上而不是替换它:底下的 LazyColumn 必须保持挂载,点一条命中要 animateScrollToItem 定位,而 LazyColumn 一旦被移出组合,滚动就落空。 - 命中不在「已加载窗口」里时不插一条临时气泡,而是如实提示(比一个假的跳转诚实): 聊天列表是升序倒过来喂给 reverseLayout 的,凭空插一条几千条之前的消息会出现在列表最底 ——也就是「刚刚发出的位置」——与它自己的时间戳矛盾,还会带偏跟随底部的判断; 而把消息真的并进窗口要改 ChatViewModel,本模块不许。 - 失败绝不渲染成「没有找到」:两者都是一张空列表,但一个该换关键词、一个该修网络或权限。 - 返回键先关搜索:新处理器注册在 ChatHomeScreen 那几条之后(优先级更高), 且搜索没开时是 disabled,抽屉 / 管理页 / 设置页的既有层级不变。 测试 706 -> 737(+31:纯逻辑 25 + 数据层 6)
Releases
5
Alpha_v0.1.0_4
Latest