AskaEth
14955ef6c0
feat(chat): 分享确认面板的正文预览可以展开 / 收起
问题:W54D 把正文那一窗改成「三行 + 内部滚动」之后「读不到整段正文」是解决了,但一次只看得见
三行。主人拍板「可以滚动 可以展开」——两个都要,所以这一轮补上后半。
改法(只动 ShareConfirmPanel.kt 与它的测试,ChatScreen / ChatViewModel 与接线一字未碰):
- 正文卡片里加一枚「展开 / 收起」(`Text` + `clickable`,不用 `TextButton`:按钮自带高度会把
这一行撑高一截)。它挂在「分享的文字」那一行的右端,不挂在正文末尾——展开后正文可能好几屏,
末尾那枚「收起」要滚到底才找得到。
- 收起态一个字没变:三行窗(SHARE_PREVIEW_TEXT_LINES = 3)+ 内部滚动。
- 展开态:正文那一窗撤掉自己的上限(`heightIn(max = Dp.Infinity)`,正是首帧那个状态),整段交给
外层预览区滚;外层上限由 150dp 抬到 240dp(SHARE_PREVIEW_EXPANDED_MAX_HEIGHT)。展开态**只留
这一层**滚动是刻意的:两层都设上限时手势先被内层吃掉、内层滚到底才轮到外层,两层上界还互相
牵制,最容易出的错就是「明明展开了还剩半截读不到」。
- 控件**只在正文排下来超过三行时出现**。判据是行数 > SHARE_PREVIEW_TEXT_LINES,不是
`hasVisualOverflow`:这一窗的高度不受限(`verticalScroll` 给子项的就是无上限约束),`Text` 自己
永远报「没有溢出」,拿它当判据会在最长的那种正文上漏掉控件;行数则与上限无关,首帧就可用。
- 展开态为什么是 240dp:这个上限管的是**整个预览区**,下面还压着描述输入框(最多 4 行)与两枚
按钮,面板贴着屏幕底、键盘一弹可用高度只剩半屏上下。150 → 240 在默认字号档上把正文窗从三行抬到
十行上下;再往上(例如整屏的六成)先被顶掉的会是按钮。⚠️ 这个数**没在真机上量过**,是按这笔账
取的保守值,观感由主人验收,要调只改这一个常量。
- 两条判据都做成纯函数(`sharePreviewTextOverflowsWindow` / `sharePreviewMaxHeight`),调用点只读
结论,单测钉的就是它们。
上一批留下的「首帧回流会不会看得出来」疑点,复核结论:**留着,且确认它看不见**(理由已写进
`ShareConfirmBody` 的 KDoc):① 首帧那一下撑不动任何别的东西——正文块是预览区里的最后一个元素,
可视像素只由外层那层独立的上限裁剪决定,上面图片/文件的位置一分不动;② 展开态本来就没有这一层
上限,不存在「量完再回落」;而展开 / 收起那一帧的尺寸变化是用户动作的**目的**,不是回流。真正多
出来的是控件本身(第二帧才出现,因为行数是排完才知道的),它与标签同用 `footnote2`、行高不变,
也顶不动任何东西。组合期 `rememberTextMeasurer` 那条路要外包 `BoxWithConstraints` 拿宽度、还要
自己复现字号与字体缩放,等于把排版做两遍——为一个看不见的跳动换掉结构不划算,不做。
已知取舍(如实记下,没修):转屏(Activity 重建)后展开态回到收起。它现在活在
`remember(preview.text)` 里,跨转屏要活下来只有两条路——进 `ChatUiState`(W54C 给「已取走的分享」
与描述走的就是那条路,但那是 ChatScreen / ChatViewModel 的地盘,本批红线不许碰),或
`rememberSaveable`(本仓一次都没用过的新写法,且弹层窗口带不带 saveable registry 没在真机上验过)。
两条都没走,留一条 ⚠️ 在代码里 + 留给主人定。
测试:新增 3 条(纯函数判据)——「什么时候该出现展开控件」(0/1/3 行不给、4 行起给,并接一份
40 行的真分享走一遍)、「展开态给多高」(150 / 240 两个字面量 + 展开严格更高 + 不超过收起态的
两倍)、「两句标签不同且非空」。展开与滚动本身单测够不着(本模块没有 Compose UI 测试的依赖),
如实说明;既有断言一条未放松。
验证:`./gradlew.bat assembleDebug testDebugUnitTest --tests "*ShareConfirm*"` → BUILD SUCCESSFUL
(ShareConfirmTest 15 条 = 既有 12 + 新增 3、ShareConfirmDraftTest 3 条,0 失败 / 0 错误);
全量 `./gradlew.bat testDebugUnitTest` → BUILD SUCCESSFUL,112 suite / 1361 tests / 0 失败。