fix(chat): 分享确认面板的正文预览改成三行窗口 + 内部滚动

问题:正文那一窗此前是 maxLines = 3 + 省略号,超过三行的分享正文在按「发送」之前根本读不到。
面板里再没有第二处放着这段正文(输入框只剩「用户附加的描述」,初值恒为空),截断就等于
「要发出去的那段正文看不见」——而这正是用户点「发送」时唯一要确认的东西。

改法:正文那一窗高度恒为三行、内部可滚,外层预览区那 150dp 的上限原样不动,所以面板不会被
长正文撑高(图片 / 文件芯片 / 按钮的位置都不变)。滚到底后余量交给外层 scroll,嵌套滚动本身
就有,不用额外接线。

上限为什么不是写死的 dp:Miuix 的 footnote1 只给了 13sp 的字号,lineHeight 是 Unspecified,
行高由系统字体的 ascent/descent 决定、随「大字体」设置一起缩放。写死 dp 在默认字号档上勉强
对得上,到大字号档就会矮一截、把末行的字切一半。所以改为量:从 TextLayoutResult 上取第三行的
底边当上限,量到之前先按无上限排一次(heightIn(max = Dp.Infinity) 在确认过 Compose 的
Density.roundToPx 对 Infinity 的处理后是安全的,即「没有上限」)。

SHARE_PREVIEW_TEXT_LINES 由 private 改 internal,只为让单测能把「这一窗是三行」钉成字面量
(本模块没有 Compose UI 测试的依赖,滚动行为单测够不着)。

测试:新增两条——正文远超三行时纯函数层仍原样交付**完整**正文(一个字不少、不加省略号),
以及三行上限的字面量;既有断言一条未放松。
This commit is contained in:
AskaEth committed 2026-10-06 21:11:30 +08:00
1 parent 33c320219a
commit ec89d828d1
2 files changed
+102 -16

No files matched your search

@@ -32,6 +32,13 @@ import top.yeij.cyrene.domain.share.SharedDocument
* ⚠️ 「输入框初值为空」本身是 Compose 状态(`ChatScreen` 里那格 `remember`),单测碰不到——它由
* 主人真机验收(输入框空着、预览里有正文)。这份测试能钉住的是它的**后果**:描述为空时,拼出来的
* 正文就是分享正文本身、而且只出现**一次**(见 `the caption is not a copy of the shared text`)。
*
* ## W54D 又改掉了什么
* 正文那一窗从「三行 + 省略号」改成「三行窗口 + 内部滚动」(主人拍板):面板里再没有第二处放着这段
* 正文,收成省略号就等于「按发送之前读不到要发的那段正文」。滚动是渲染层的事、单测够不着(本模块
* 没有 Compose UI 测试的依赖),所以这里钉的是它的两个前提——**正文完整地进到预览**(一个字都不少)
* 与**这一窗仍然是三行**(面板不随正文变高),见 `the whole body reaches the preview …` 与
* `the preview window stays three lines tall`。
*/
class ShareConfirmTest {
@@ -54,6 +61,33 @@ class ShareConfirmTest {
assertFalse(preview.isEmpty)
}
@Test
fun `the whole body reaches the preview even when it is longer than the window`() {
val long = (1..40).joinToString("\n") { "第 $it 行" }
// W54D 主人拍板:预览的正文那一窗恒为三行高,但**里面能滚**——三行之外不再收成省略号。这条钉
// 的是那一窗的输入:纯函数层把**完整**的正文交给渲染层(这一段一个字都不许在这里少),少了就
// 一定读不到——面板里再没有第二处放着这段正文(输入框只剩「用户附加的描述」)。
val preview = shareConfirmPreview(SharedContent(text = long))
assertEquals(long, preview.text)
assertEquals(40, preview.text.lines().size)
assertTrue(
"这一档必须真的超过三行,否则上面那条断言什么也证明不了",
preview.text.lines().size > SHARE_PREVIEW_TEXT_LINES,
)
// 发出去的那一段同样一个字不少(两边同源,见 [shareConfirmBody])。
assertEquals(long, shareConfirmBody(SharedContent(text = long), ""))
}
@Test
fun `the preview window stays three lines tall`() {
// 3 这个字面量就是这条测试的全部内容:滚动是渲染层的事、单测够不着(本模块没有 Compose UI
// 测试的依赖),能钉住的只有「这一窗是三行」这条判据本身。改大 ⇒ 面板会随长正文变高(主人
// 拍板的高度上限没了);改小 ⇒ 正文的可见窗口白缩一行。
assertEquals(3, SHARE_PREVIEW_TEXT_LINES)
}
@Test
fun `blank pieces count as nothing to show`() {
val preview = shareConfirmPreview(