diff --git a/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt b/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt index 71ad4a6..166858a 100644 --- a/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt +++ b/app/src/main/kotlin/org/libremail/ui/compose/RichTextEditor.kt @@ -269,8 +269,6 @@ private fun FormattingToolbar( strikethrough = true, onClick = { onToggleStyle(RichStyle.Strikethrough) }, ) - val fontSizePt = RichTextEditing.styleAt(content, start, end, RichStyle.FontSize::class.java)?.pt - FontSizePicker(selectedPt = fontSizePt, onSelect = onFontSize) val fontColorArgb = RichTextEditing.styleAt(content, start, end, RichStyle.FontColor::class.java)?.argb FormatButton( label = "A", @@ -311,6 +309,14 @@ private fun FormattingToolbar( active = false, onClick = onLink, ) + // The font-size dropdown trails every glyph button on purpose. The toolbar overflows the + // screen width and scrolls horizontally, and the compose E2E taps the "•" bullet button + // *without* scrolling first (see ComposeScreenTest.formattingToolbar_bulletButtonMarksTheLine...), + // so its click lands on the button's on-screen center. Any control inserted *before* the block + // buttons shifts them right and can push the bullet past the viewport, making that tap miss — + // so this wider control is appended last, leaving every pre-existing button in its tested spot. + val fontSizePt = RichTextEditing.styleAt(content, start, end, RichStyle.FontSize::class.java)?.pt + FontSizePicker(selectedPt = fontSizePt, onSelect = onFontSize) } } diff --git a/app/src/test/kotlin/org/libremail/ui/compose/RichTextEditorTest.kt b/app/src/test/kotlin/org/libremail/ui/compose/RichTextEditorTest.kt index 9eccb38..7b9b986 100644 --- a/app/src/test/kotlin/org/libremail/ui/compose/RichTextEditorTest.kt +++ b/app/src/test/kotlin/org/libremail/ui/compose/RichTextEditorTest.kt @@ -19,6 +19,7 @@ import org.libremail.richtext.RichSpan import org.libremail.richtext.RichStyle import org.libremail.richtext.RichTextContent import org.libremail.richtext.RichTextEditing +import org.libremail.richtext.RichTextHtml import org.libremail.richtext.imageToken import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -240,6 +241,19 @@ class RichTextEditorTest { assertEquals("1. a\n2. b", result.annotatedString.text) } + @Test + fun `applyBlock bullet on an end-of-text caret marks the line and serializes to ul li html`() { + // The JVM-layer twin of ComposeScreenTest.formattingToolbar_bulletButtonMarksTheLineAndSendsItAsHtml: + // a bullet tap on the end-of-text caret that typing leaves must mark the whole line and serialize + // to a real list. Pinning it here catches a regression in the block-toggle/HTML flow without an + // emulator; the instrumented test additionally guards that the toolbar button stays tappable. + val value = field("Buy milk", TextRange(8)) + val bulleted = applyBlock(value, BlockMarker.BULLET, linkColor, noFont) + val content = bulleted.annotatedString.toRichContent() + assertEquals("• Buy milk", content.text) + assertEquals("