Skip to content

feat(android): inline markdown rendering for messages (beta blocker 1/5)#594

Merged
Detair merged 1 commit into
mainfrom
feature/android-markdown
Jun 12, 2026
Merged

feat(android): inline markdown rendering for messages (beta blocker 1/5)#594
Detair merged 1 commit into
mainfrom
feature/android-markdown

Conversation

@Detair

@Detair Detair commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

First of the five Android-beta daily-driver blockers (roadmap.md Android milestone) — messages were rendered as plain text; they now render inline markdown.

  • MarkdownParser.kt — pure, dependency-free inline parser → styled spans for **bold**, *italic*, ~~strike~~, `code`, ||spoiler||. Matches the desktop's inline subset. Robustness: unmatched delimiters stay literal (a stray * never eats the rest of a message); literal content inside code/spoiler isn't re-parsed.
  • Deliberate scope call: _ is not an italic delimiter. Intraword underscores (snake_case, __init__) are far more common in a dev/gaming chat than _italic_ and would produce false italics — *italic* covers the need. (GFM-style word-boundary _ can come later.)
  • MessageContent.kt — renders the spans to a Compose AnnotatedString; spoilers are background-filled + transparent until the message is tapped (click-to-reveal, matching desktop). Wired into MessageItem.

Tests

13 JUnit tests for the parser (each style, bold+italic nesting, literal code/spoiler content, unmatched/empty delimiters, ** beats *, underscores stay literal). The parser needs no Android runtime; CI's Android Build + testDebugUnitTest jobs validate compilation and tests (Android can't be built on the dev machine, same as vc-client).

Part of the Android Beta milestone — 4 blockers remain (attachment display, unread indicators, DM UI, reaction picker).

🤖 Generated with Claude Code

First of the five Android-beta daily-driver blockers from the milestone
in roadmap.md: messages rendered as plain text.

- domain/markdown/MarkdownParser.kt: pure, dependency-free inline parser
  → styled spans for **bold**, *italic*, ~~strike~~, `code`, ||spoiler||.
  Matches the desktop's inline subset. Unmatched delimiters stay literal
  (a stray * never eats the message). `_` is deliberately NOT an italic
  delimiter — intraword underscores (snake_case, __init__) are far more
  common in a dev/gaming chat than _italic_ and would false-positive.
- ui/channel/MessageContent.kt: renders the spans to a Compose
  AnnotatedString; spoilers are background-filled + transparent until the
  message is tapped (click-to-reveal, matching desktop).
- MessageItem wired to MessageContent.

13 JUnit tests for the parser (styles, nesting bold+italic, literal code/
spoiler content, unmatched/empty delimiters, ** beats *, underscores
literal). No Android runtime needed for the parser tests; CI's Android
Build + testDebugUnitTest validate compilation and tests (can't build
Android locally).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Detair Detair merged commit 024a78a into main Jun 12, 2026
18 checks passed
@Detair Detair deleted the feature/android-markdown branch June 12, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant