krz/hutch

an ios client for sourcehut

clone: git clone https://gitbay.org/krz/hutch.git

1d2769fc7a347939275e9130ee174d61d96ea401

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-07-16T03:08:53Z

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.
 Hutch/Views/Patchsets/PatchsetDetailView.swift | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Hutch/Views/Patchsets/PatchsetDetailView.swift b/Hutch/Views/Patchsets/PatchsetDetailView.swift
index f904424..f560326 100644
--- a/Hutch/Views/Patchsets/PatchsetDetailView.swift
+++ b/Hutch/Views/Patchsets/PatchsetDetailView.swift
@@ -49,6 +49,12 @@ struct PatchsetDetailView: View {
                 patchesSection(patchset)
             }
             .themedList()
+            // Inset grouped lays cells out at a rounded width while the content
+            // measures itself at the unrounded one, so a long Text reflows to a
+            // different height than the cell was sized for and the two chase each
+            // other into a layout loop. ThreadDetailView renders the same bodies
+            // through the same DiffView on a plain list without that fight.
+            .listStyle(.plain)
             .refreshable { await viewModel.loadPatchset() }
             .overlay {
                 if viewModel.isUpdatingStatus {