Repository navigation
Render chat markdown through MarkView.Avalonia - #834
Conversation
MarkView's link, autolink and HTML renderers are replaced so a link exists only where LinkPolicy would open it and nothing agent-authored is fetched. One TextMate extension serves every view: a per-view instance rebuilds its highlighters on each render. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PR Summary by QodoRender chat markdown with MarkView.Avalonia
AI Description
Diagram
High-Level Assessment
Files changed (10)
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3170590b6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var text = new MarkdownSelectableTextBlock { TextWrapping = TextWrapping.Wrap }; | ||
| text.Classes.Add("markdown-paragraph"); | ||
| renderer.Push(text.Inlines!); | ||
| renderer.WriteLeafRawLines(obj); |
There was a problem hiding this comment.
Keep multiline HTML out of inline collections
When an agent response or PR body contains a multiline HTML block such as <div>\ntext\n</div>, WriteLeafRawLines writes those embedded newlines into this InlineCollection. The renderer removed by this commit explicitly avoided that shape because Avalonia 12's line breaker does not finish laying out inline text containing newlines under the unconstrained StackPanel/ScrollViewer used by these views, so such content can hang the desktop UI. Render the raw block through the text block's Text property (or split it into newline-free runs/line breaks) instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
WriteLeafRawLines emits one Run per source line with a LineBreak inline between them, so no run carries a newline; the hang the old renderer worked around was a newline inside an inline's text. Pinned by Multi_line_html_and_hard_breaks_lay_out_under_an_unconstrained_parent in 9fbd932: a multi-line HTML block and a hard break inside ScrollViewer > StackPanel lay out under a 30 s timeout, and the assertion checks no run contains a newline.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
No GitHub issue and no Linear id: the work started as a spike in chat, so neither half of the reference exists.
What & why
The desktop chat rendered markdown through a hand-written Markdig-to-controls mapper that covered only the constructs agents emit and carried its own layout workarounds. This swaps it for MarkView.Avalonia behind the unchanged
MarkdownViewsurface, adds diff and code highlighting through its TextMate package, and renders user turns as markdown too. The library's defaults are wrapped rather than trusted:KcapMarkdownExtensionkeeps every link underLinkPolicy, turns a bare URL into an inline link instead of MarkView's self-navigating button, shows an image as its source text with no fetch, and shows HTML instead of dropping it.Where to look
MarkdownViewholds one staticTextMateExtension: the extension caches its highlighters per instance, and a per-view instance rebuilds them on every render. Paragraphs carry a transparent background so a click reaches the viewer's own handlers. Links are inline spans now, so they no longer take keyboard focus.Verification
Capacitor.App.Tests.Uniton this tree: 1584 passed, 0 failed, nine of them the newMarkdownViewTests(link click through the command, refused scheme and bare URL as plain text, diff colouring, theming).