~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

The iOS app folds a description by how tall it is, not how long

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:ios/fold-by-height

What changes

A description on a pull or issue folds under Read more when it is more than 440pt tall, as drawn, rather than when its source is over 800 characters. It then shows 360pt, so folding always hides a fair amount. So a body of links with long addresses shows whole with no button, and a long list of short lines now folds, where it did not before.

Why

Characters of Markdown source say little about height: a link's address counts and never shows, and a short line takes a whole row. The text is already laid out at full height for the fold (The iOS app's folded description reads as it does opened, which this branch is on), so measuring it costs little.

How it was checked

just ios-look pull-open, in light, left to right in the picture: nine links, 1069 characters, whole with no button. A list of 40 short items, 390 characters, folded. A long description folded, then opened, reading alike.

Shortcomings

Until it is measured, the length still guesses, so that a body about to fold is not first drawn whole. A guess that is wrong can show the wrong state for an instant: I saw no flicker in pictures, which would not show one, and it was not watched on a device. Pictures load late and make a body taller, so Read more can appear a moment after the page opens. Not run with a real picture in the body.

🤖 Generated with Claude Code

folds.png

Approved

This folds a description by its measured height. fixedSize comes before onGeometryChange, so the height read is the full height and not the clipped one. body(_:html:) is only used for the thread description, so the single bodyHeight state is safe. I couldn't build or run the app, so this is from reading the diff.

One gap, in folds (ThreadView.swift:333). text.count > foldedLength returns true before any height is looked at. A body of more than 2000 characters that draws short, such as many long links, still folds. It is also drawn from prefix(2000), so the cut can land mid-link and the visible part is shorter than the real one. That is the case the pull sets out to fix, only at a larger size. Consider letting a measured height decide once there is one, and drawing the full text when the height is small. The length guess would then only apply before the first measure.

bodyHeight is never reset. If the thread reloads with a different description, the old height is used until the next layout pass. This is minor.

ios/Knotless/Views/ThreadView.swiftline 333
/// Whether folding hides enough to be worth a button. Until it's measured,
/// a guess from its length, so what's going to fold doesn't first draw whole.
private func folds(_ text: String) -> Bool {
if text.count > Self.foldedLength { return true }
review.knotless.dev

The length check wins over the measured height here. A body over 2000 characters that draws short still folds and is cut at 2000 characters of source. Consider checking bodyHeight first when it is non-zero.

Approved

This folds a description by its measured height (more than 440pt, then shows 360pt). fixedSize comes before onGeometryChange, so the height it reads is the full height, not the clipped one. I read the diff only and did not build or run the app.

My earlier note on folds is not addressed. text.count > foldedLength still returns true before any height is read. A body over 2000 characters that draws short, such as many long links, still folds, and it is drawn from prefix(2000), which can cut mid-link. This is the case the pull sets out to fix, only at a larger size. I'm not blocking on it because it's an edge case. A better shape is to let the measured height decide once it is non-zero, and to use the length only as the guess before the first measure. The text should also not be cut to 2000 characters when the height says it is short.

bodyHeight is still never reset, so a reload with a different description uses the old height until the next layout pass. This is minor.

ios/Knotless/Views/ThreadView.swiftline 333
/// Whether folding hides enough to be worth a button. Until it's measured,
/// a guess from its length, so what's going to fold doesn't first draw whole.
private func folds(_ text: String) -> Bool {
if text.count > Self.foldedLength { return true }
review.knotless.dev

This returns true on length alone, before the measured height is read. A long body of links that draws short still folds, and the 2000-character prefix can cut it mid-link. Consider checking bodyHeight first and using the length only while it is 0.

Merged as 4445536