Related illustrations grid in detail view
Created by: jedmund
Summary
- Renders a masonry grid of Pixiv's related illustrations below the metadata in
IllustDetailContent, replacing the placeholder stub - Tapping a related cell pushes a nested matched-geometry detail overlay on top of the current one (
MainTabViewalready caps rendering atstack.suffix(2)) - Reuses
MasonryFeed/IllustCellverbatim, so R-18 blur, bookmark hearts, and multi-page pills render identically to the outer feeds
Implementation
Three commits:
-
Add
illustRelatedendpoint — onePixivEndpointcase wrappingGET /v2/illust/related?illust_id=<id>&filter=for_ios, response decodes to the existingPixivIllustFeedshape. -
Render related-illusts masonry — fills in
RelatedIllustsSectionwith a lazyIllustFeedViewModel(constructed inside.task(id: illust.id)so v2's horizontal pager retargets correctly). The nestedPresentedDetailusesfeedID: \"related/<illust.id>\"so composite matched-geometry IDs can't collide with outer feeds. WrapsIllustDetailContent's outerScrollViewin aScrollViewReaderand injects the proxy via\\.feedScrollProxyso the nested detail's dismiss flow can scroll the related grid back to an off-screen source cell. -
Fix nested-dismiss hero —
MainTabView.onChange(of: presenter.stack.last?.id)fired for every top change, including pops. For a nested dismiss ([A, B]→[A]), that re-ranhandleStackChange()which rewrote the coordinator'sactiveMatchedID/sourceFramefrom B's to A's before B's deferred dismiss spring, so the floating hero animated to A's cell instead of B's. Gated onstack.countgoing up.
Test plan
-
Build clean -
Open an illust from Home; scroll past metadata; see related grid with correct cell chrome -
Paginate the related grid -
Tap a related cell → nested overlay lifts from tapped cell -
Dismiss the nested overlay → hero animates back to the related cell (not the Home cell) -
Swipe-page the nested overlay through enough related illusts that the source cell scrolls off the detail; dismiss → detail scroll should bring the cell back before the reverse animation -
From the nested detail, tap a tag pill → all overlays dismiss and the tag feed pushes on the host NavigationStack -
Repeat the above from Profile → works → detail -
Open an R-18 illust with restricted content hidden → related cells blur with badge