Commit 2da95eba44
2da95eba44fa770ba7df90ba427a75bcd66872a4
parent: 368c59e3f8
Unsigned
cmc <hello@cleberg.net> · 2026-07-16 03:08 UTC
fix: render patchsets on a plain list
Collapsing patches shrank the layout loop from 3674pt/1647pt to 718pt/600pt but
did not end it. The oscillating item is section 1 item 0 — the cover letter, not
a patch — so size alone was not the cause.
The log shows the cell laid out at width 390.0 while the content reports its
preferred size at 390.333. That is inset grouped's 20pt insets landing on a
fractional width: the Text reflows to a different height than the cell was sized
for, each size triggers the other, and it never settles.
ThreadDetailView renders the same bodies through the same DiffView with the same
modifiers and does not loop. The difference is .listStyle(.plain), which this
view never set and so inherited inset grouped.
Layout: unified · split
Hutch/Views/Patchsets/PatchsetDetailView.swift
+6
| @@ -49,6 +49,12 @@ struct PatchsetDetailView: View { |
| 49 | 49 | patchesSection(patchset) |
| 50 | 50 | } |
| 51 | 51 | .themedList() |
| 52 | // Inset grouped lays cells out at a rounded width while the content |
| 53 | // measures itself at the unrounded one, so a long Text reflows to a |
| 54 | // different height than the cell was sized for and the two chase each |
| 55 | // other into a layout loop. ThreadDetailView renders the same bodies |
| 56 | // through the same DiffView on a plain list without that fight. |
| 57 | .listStyle(.plain) |
| 52 | 58 | .refreshable { await viewModel.loadPatchset() } |
| 53 | 59 | .overlay { |
| 54 | 60 | if viewModel.isUpdatingStatus { |