Detail: endless swipe via source feed + dark-mode hero placeholder
Created by: jedmund
Summary
Two small follow-ups to the harness promotion that landed in #17.
-
Endless swipe in the detail. The detail's pedestal swipe-paging used to dead-end at the tail of the
itemsarray captured at push time. Now it consults the sameIllustFeedViewModelthe grid uses — splicing any illusts the VM already has beyond our snapshot, and asking the VM to paginate when the user approaches the snapshot's tail. The pedestal delegate's existingitems.indices.contains(currentIndex + 1)guard becomes true organically after each splice, so no extra UI state was needed. -
Respect OS appearance for the in-flight cell placeholder. The white rectangle shown while the hero snapshot was "lifted" from a cell looked fine in light mode but rendered as a jarring white hole in dark mode. Swapped to
Color(.systemBackground)so the hole matches the scroll-view background in both appearances.
Also exposes IllustFeedView.feedItem(from:) (was private static) so the detail VC can splice newly-paginated illusts through the same mapper the grid cells use — no drift risk between the two rendering paths.
Instrumentation
Endless-swipe ships with heroLog.notice breadcrumbs end-to-end (detail VC + IllustFeedViewModel.loadMoreIfNeeded) so future debug sessions can see which guard short-circuits, the exact URL being fetched, and how many items came back vs. were newly unique after dedupe. Filter Console with subsystem:com.attractor.pixillate category:hero to tail them.
Test plan
-
Open detail → swipe forward past the initial 30-item snapshot. Next pages load transparently; swipe never dead-ends until the source feed is actually exhausted. -
Confirm the VM logs pagination progression ( FETCH url=… OK returned=N newAfterDedupe=M total=X) as you approach each tail. -
Verify that reaching the true end of a feed (e.g. a small user's works grid) still blocks the forward swipe cleanly (no spinning). -
Switch the simulator to Dark Mode, tap a cell, observe the in-flight hero placeholder — should be near-black, not white. -
Back to Light Mode, same tap — placeholder should be white / system background.