Show a thread's body, not HEY's preview of it - #420
Conversation
`Entry.Summary` is HEY's ~105-character preview of the body, and renderEntries printed it above whatever came next unconditionally. Beside a body that was read, that repeats the message's opening line and then cuts it off with an ellipsis; above an "(body not read: failed)" notice it passes the preview off as the message the reader could not get. The summary now stands in only where there is nothing else to show -- a bodyless entry, which is all HEY serves for one. Each arm of the switch opens with the blank line that used to separate the header from the summary, so the spacing is unchanged.
There was a problem hiding this comment.
🟡 Changes recommended
Hydrated bodies that render empty still fall through to the misleading summary preview.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Updates TUI thread rendering to show message bodies without duplicating HEY previews.
Changes:
- Shows summaries only when no body is available.
- Adds tests for hydrated, bodyless, and failed entries.
[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or rungh pr ready --undo.
Click "Ready for review" or rungh pr readyto reengage.
File summaries
| File | Description |
|---|---|
internal/tui/mail.go |
Revises thread-entry rendering. |
internal/tui/mail_test.go |
Tests body and summary display behavior. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| fmt.Fprintf(&b, "\n%s\n", v.vc.styles.entryBody.Render(markdown.Render(e.Body, sepWidth))) | ||
| case e.BodyState == string(threadload.StateOverLimit), e.BodyState == string(threadload.StateFailed): | ||
| fmt.Fprintf(&b, "\n%s\n", v.vc.styles.entryDate.Render("(body not read: "+e.BodyState+")")) | ||
| case e.Summary != "": |
There was a problem hiding this comment.
Taken, and widened to the ladder printThreadStyled already uses in internal/cmd/topic.go: the body when there is one; (empty body) for a hydrated body that rendered to nothing; the summary only for bodyless, where it is all HEY serves; (no body) for a bodyless entry with no summary either; (body not read: state) for the rest. Pushed as e803b80 with a fourth entry in TestRenderEntriesShowsTheBodyRatherThanHEYsPreviewOfIt — <div><br></div> hydrated, summary present — asserting (empty body) and no preview. not_requested cannot arise in the TUI (fetchTopic always hydrates) but falls into the last arm rather than the summary if it ever does.
The summary stands in only where HEY served no body — the same ladder printThreadStyled uses for the CLI.
Open a thread and every message showed up twice: HEY's preview of the body, then the body itself starting with the same words. And when a body couldn't be fetched, you got the preview with nothing to tell you it wasn't the message.
BEFORE
AFTER
Entry.Summaryisn't a subject line. It's HEY's ~105-character preview of the body — the same string the posting list shows — and it comes with every entry whether or not the body did.renderEntriesprinted it unconditionally, above whatever came next. That's fine in exactly one case:over_limit,failed) — the preview sits above(body not read: failed)and reads like the message, with the "missing" part being something else. This is the bad one: we were presenting a fragment as content.So the summary moved into the switch as its last arm: it stands in only when there's nothing else to show. Each arm now opens with the blank line that used to sit above the summary, so the spacing on screen is unchanged.
Not a regression — the summary-then-body print dates back to the first TUI commit (
f65055f, ininternal/tui/topic.go) and has been carried along by every move since. #259 added the(body not read: …)arm underneath it without touching the line above.Checks
make checkpasses.TestRenderEntriesShowsTheBodyRatherThanHEYsPreviewOfItcovers all three arms;TestThreadViewShowsSubjectAndSpacesTheHeadernow asserts the body under the header instead of the preview.Summary by cubic
Thread views no longer show HEY's summary preview above every entry. They now render the full body when available, show
(empty body)when a read body renders to nothing, and(body not read: ...)when it cannot be loaded, using the summary only for bodyless entries while preserving the existing spacing.Written for commit e803b80. Summary will update on new commits.