Draw replies as pieces of one parse, and lists an item at a time
A settled reply used to be cut into block *strings*, each parsed on its own and each a unit of the lazy list; the live reply split the same way with a whole-message parse per delta on top. Now a message is parsed once, and a Piece addresses a top-level block of that tree -- or one item of a top-level list, which was the one block still unbounded: a list of forty sources was one item composed whole in the frame it scrolled into. Units, the live reply's column and peer messages all draw from the same parse, so warm parses each message once instead of once per block, a delta costs one background parse instead of two, and a reference definition at the foot of a message resolves again because nothing is parsed apart from it. The renderer keeps parsing and providing its environment; MarkdownRoot wraps that around a piece, and a whole block still goes through its dispatch with our component table. List items are drawn here, with the renderer's own paddings so a split list looks like an unsplit one, and lists inside quotes come to the same code through the table -- the marker is drawn in one place, which is what a styled bullet would need later. Found on the way: a heading's words are a child of the heading node, and the inline builder draws nothing for a node type it does not know, so the span-link path had been drawing headings empty. LinkedHeading hands it the content child. Lint: profileable's shell attribute scoped to API 29 where it exists, and recordFrames renamed to the composable convention. What remains is the AGP 9.4.0 notice. Verified on the emulator against a fixture of every block kind (headings, nested and ordered lists with a start number, task items, a quote holding a list, a fence, a rule, a table with a linked cell, a setext heading), a forty-item list which the render report now shows as per-item units, a reply streamed live (34 deltas: 34 background reparses, one warm at settle, no crash), and the older link fixture. ktfmt, build and lint run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
a9ab9b3e5a
commit
48bb7de304
12 files changed
+457
-221
No files matched your search
@@ -334,17 +334,32 @@ first if a remote spawn ever mangles an argument.
|
||||
success. The phone's half is `uniqueItems`, which every list keyed on a
|
||||
server-chosen id goes through: a repeat there must never be able to
|
||||
close the app, whatever produced it.
|
||||
- **A reply is drawn as pieces of one parse, never as re-parsed
|
||||
substrings.** `MarkdownPieces.kt`: a `Piece` addresses a top-level block
|
||||
of the message's tree, or one item of a top-level list, and every piece
|
||||
is drawn from the same `State.Success` that `ParsedReplies` cached and
|
||||
`warm` made. That is what bounds a lazy-list item (one paragraph, one
|
||||
bullet) without parsing a message more than once, and it is why a
|
||||
forty-item list of sources is forty units rather than one. The renderer
|
||||
is still the parser and the environment: `MarkdownRoot` provides its
|
||||
locals and `MarkdownElement` dispatches a whole block through our
|
||||
component table, so paragraphs, headings and table cells are span-linked
|
||||
`LinkedText` (links as spans with one tap detector per text, not a layout
|
||||
node per link -- the cost that made a list of sources bumpy) and lists
|
||||
are ours wherever the dispatch meets one. A heading's words are its
|
||||
`ATX_CONTENT`/`SETEXT_CONTENT` child; the inline builder draws nothing
|
||||
for a node type it does not know, so hand it the child.
|
||||
- **A markdown table wraps its cells and never cuts one off.** The
|
||||
renderer's own defaults draw every cell at one line with an ellipsis,
|
||||
which on a phone loses most of a table -- and an elided cell looks
|
||||
exactly like a short one, so nothing on screen says anything was cut.
|
||||
`Markdown.kt` supplies its own header and row blocks with `maxLines =
|
||||
Int.MAX_VALUE` and `TextOverflow.Clip`, cells aligned to the top of the
|
||||
row so a two-line cell does not re-centre its neighbours. Width is the
|
||||
other half: a column narrows to 136dp and no further, and past that the
|
||||
whole table scrolls sideways rather than squeezing -- 136 because it is
|
||||
the widest floor that still fits three columns across a phone, which is
|
||||
the commonest table there is. Exercise it with the echo driver's
|
||||
`Markdown.kt` supplies its own rows (`LinkedTableRow`): as many lines as
|
||||
a cell needs, cells aligned to the top of the row so a two-line cell
|
||||
does not re-centre its neighbours, and each cell a `LinkedText`. Width is
|
||||
the other half: a column narrows to 136dp and no further, and past that
|
||||
the whole table scrolls sideways rather than squeezing -- 136 because it
|
||||
is the widest floor that still fits three columns across a phone, which
|
||||
is the commonest table there is. Exercise it with the echo driver's
|
||||
`/table N` (default six columns), which writes long cells on purpose:
|
||||
a fixture of tidy one-word values renders fine whether or not the
|
||||
truncation is fixed.
|
||||
|
||||
Reference in new issue
Block a user