Collection folder rails: reuse Home's actual row widget - #282
Merged
Merged
Conversation
Rails now render through a new BoardShelfRow, wrapping the same BoardCell (and its CardFocusRise scale/shadow/focus-ring/hover-grow chrome) Home's own board rows paint, instead of DiscoverShelfScope/SeeAllPosterGrid's Discover-stage card. Matching poster width alone (PR #277) left the card corner radius, shadow, focus ring, hover-grow and row gutter different from Home's — this makes a folder's rails an actual Home row rather than an approximation of one. BoardShelfRow owns its own focus-node pool and exposes focusFirst() so the folder screen's existing rail-to-rail DPAD ladder, All row and per-rail pagination are unchanged. The merged "All" grid and Tabs single-list view stay on SeeAllPosterGrid — they're poster walls, not rows, and were never meant to read as Home.
Merged
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The user (testing on the Shield) reported the collection folder menu still doesn't match Home's row design after PR #277. That PR made rails use
homeRailPosterWidth()for poster WIDTH, but the rails themselves still rendered throughDiscoverShelfScope/SeeAllPosterGrid— the Discover feature's own card widget (CatalogItemTile). Matching width alone left the card corner radius, shadow, focus ring, hover-grow scale/timing and row gutter all different from an actual Home row, which is painted by a completely different widget family:BoardCell(inlib/screens/search/board_cell.dart), wrappingCardFocusRisefor the focus/hover chrome, inlined directly intosearch_screen.dart's_buildRow.What
Full widget reuse — not a matched-properties fallback.
_buildRowinsearch_screen.dartis a private method on the giantSearchScreenstate (tightly coupled to_rowNodes,_hero,_boardRuntime, etc.), so it can't be called directly from another screen. But the actual per-poster widget it composes,BoardCell, has zero such coupling — it already takes plain callbacks and is reused as-is by the Canvas/Promenade board stages (stage_shelf_content.dart,canvas_board_stage.dart). It was the reusable unit all along.Added
lib/screens/search/board_shelf_row.dart—BoardShelfRow, a small standalone widget that lays out one horizontal row ofBoardCells with Home's exact row gutter (13px outer / 11px per card) and pagination threshold (900px), owning its own focus-node pool (mirroringSeeAllPosterGridState's bookkeeping) and exposingfocusFirst()for a host's DPAD ladder. It lives next toBoardCellandContinueWatchingRow(Home's other extractable row-shell widget) rather than underlib/widgets/, sinceBoardCellis itself underlib/screens/search/and the repo's layering check forbidswidgets/importing fromscreens/(tool/check_layering.dart) — this keeps the violation count unchanged (still 42, at the ceiling).CollectionFolderScreen._buildRailnow renders each rail throughBoardShelfRowinstead ofDiscoverShelfScope+SeeAllPosterGrid, preserving every rail-specific behavior: the rail-to-rail DPAD ladder (_focusRailAbove/_focusRailBelow), the "All" row, per-rail pagination (_loadMoreRail), folder switching, and PR #277's "no See-all link, whole header opens the rail" behavior. The merged "All" grid and the Tabs layout's single-list view are intentionally left onSeeAllPosterGrid— they're full poster walls (multi-column, titled), not rows, and were never meant to mimic Home.Zero changes to
search_screen.dart,continue_watching_row.dart,board_cell.dart, orcard_focus_rise.dart— Home's own rendering code is untouched, so there's no risk of Home drifting from itself.How verified
flutter test --no-pub test/board_shelf_row_test.dart— new tests: renders oneBoardCell/CardFocusRiseper item (proves the actual class, not a lookalike), SELECT opens the focused item, RIGHT walks cards and LEFT at column 0 is safely swallowed (this screen has no sidebar to hand off to, unlike the Home board), UP/DOWN call the host's exit callbacks from any card, the trailing pagination spinner appears,focusFirst()on an empty row no-ops. All 6 pass.flutter test --no-pub test/collection_folder_screen_test.dart— all 6 existing tests (from Collection folder: plain rows in Rows layout, no See all on collection rails #277) pass unchanged: layout chrome, DPAD ladder to the Retry button, Tabs' filter-bar ladder.flutter test --no-pubon Home's regression suite (home_board_controller_test.dart,home_row_id_grammar_test.dart,home_row_order_test.dart,home_row_registry_test.dart,search_board_cell_origin_test.dart,search_board_runtime_origin_test.dart,spotlight_board_compact_test.dart,spotlight_board_test.dart) — all 103 pass, confirming zero regression to Home's own rows (expected, since none of those files changed).dart analyzeon both changed/added lib files and the new test file — 0 issues.dart run tool/check_layering.dart— 42 violations, ceiling 42, unchanged (exit 0).python tool/analyze_baseline.py— my files produce no new diagnostics; the script's pre-existing failure (UNAWAITED_RETURN_IN_TRY_BLOCKin unrelated services files) is present on the base branch too and untouched by this diff.grep -rl matchesGoldenFile test), so none needed regenerating.Risks
SeeAllPosterGridhad a_maybeAutoFillsafeguard for this thatBoardShelfRowdoesn't replicate. This matches Home's own_buildRow, which has the same gap, so it's parity rather than a regression, but flagging it as a known edge case (very small catalogs only).homeRailPosterWidth's collection-rail usage before this PR either — out of scope here, not a regression.