Skip to content

Crabwalking 2.0 - The Return of Horizontal Navigation, Now With Friends! - #1060

Merged
RadicalMuffinMan merged 7 commits into
Moonfin-Client:mainfrom
mattsigal:crabwalking-v2
Aug 6, 2026
Merged

Crabwalking 2.0 - The Return of Horizontal Navigation, Now With Friends!#1060
RadicalMuffinMan merged 7 commits into
Moonfin-Client:mainfrom
mattsigal:crabwalking-v2

Conversation

@mattsigal

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

This PR rebases #398 and improves upon it in a variety of ways. The major addition is a new Group By button that allows users to select: None, Decade, Genre, Parental Rating, Studio) for Movies and TV Show libraries! If Group By is triggered from a default vertical view, the categories are placed as tabs above the media cards. If Group By is triggered from crab-mode, they instead get a Home rows-style horizontal scrolling interface. Both views are compatible with all sorts, filters, and display sizes.

Related Issues

Link related issues or tickets separated by commas.

Type of Change

  • Bug fix
  • New feature
  • Refactor
  • Performance improvement
  • UI/UX update
  • Documentation update
  • Build/CI change
  • Other (describe):

Changes Made

List the key changes included in this PR.

  • Added Group By options (None, Decade, Genre, Parental Rating, Studio) to Movies and TV Show libraries (library_browse_screen.dart, library_browse_view_model.dart).
  • Added new localization keys (groupByTitle, groupByDecade, groupByParentalRating, groupByStudio) to app_en.arb and generated l10n bindings (app_localizations.dart).
  • Removed redundant "Rating" item from the Sort & Filter dialog (library_browse_screen.dart) since it makes more sense as a Group By filter than a sort option.
  • Sorted Parental Ratings by content severity (G -> PG -> PG-13 -> R -> NC-17 -> Unrated) and Decades/Genres in logical order (library_browse_view_model.dart).
  • Implemented stateful horizontal category row controllers (_GroupedCategoryRow) with 1st-position scroll offset math matching the Home Screen experience (library_browse_screen.dart).
  • Fixed header focus traversal, category title visibility in viewport, focus indicator ring clipping, and 1-row vertical stretching (library_browse_screen.dart).
  • Restored responsive multi-row poster scaling across Small, Medium, Large, and Extra Large poster sizes in horizontal grid mode (library_browse_screen.dart). This allows a 3-row view for Small, 2-row for Medium, and 1-row for Large/Extra-Large.

Platform

  • Android
  • iOS
  • tvOS
  • Web
  • macOS
  • Windows
  • Linux
  • All / Shared code

Testing

Describe how this change was tested.

  • Tested on emulator / simulator
  • Tested on physical device
  • Manual testing completed
  • Not tested (explain why):

Test Steps

  1. Navigate to Movies or TV Shows library.
  2. Open Settings dialog and test switching Group By options (Decade, Genre, Parental Rating, Studio). Verify localized titles and severity-sorted Parental Ratings.
  3. In Horizontal view, navigate D-pad Left/Right through a category row and verify the focused item stays pinned in 1st position.
  4. Test switching Poster Size (Small, Medium, Large, Extra Large) and verify responsive row counts and poster size scaling.

Screenshots (if applicable)

Include screenshots or recordings for UI changes.

VERTICAL SCROLL (DEFAULT)

GROUP BY MENU

Shield_Screenshot_2026-08-05_16-50-29

BY DECADE

Shield_Screenshot_2026-08-05_16-51-08

BY GENRE

Shield_Screenshot_2026-08-05_16-52-39

BY PARENTAL RATING

Shield_Screenshot_2026-08-05_17-01-43

CRAB MODE ACTIVATED

BY GENRE

Shield_Screenshot_2026-08-05_17-19-03

POSTER SIZE DEMONSTRATION

Shield_Screenshot_2026-08-05_17-39-47 Shield_Screenshot_2026-08-05_17-39-56 Shield_Screenshot_2026-08-05_17-40-04 Shield_Screenshot_2026-08-05_17-40-14

Checklist

  • Code builds successfully
  • Code follows project style and conventions
  • No unnecessary commented-out code
  • No new warnings introduced

…lay settings

- Add LibraryScrollDirection enum (vertical/horizontal) to preference_constants.dart
- Add libraryScrollDirection() per-library preference factory to user_preferences.dart (key: library_scroll_dir_<libraryId>, default: vertical)
- Wire _scrollDirection field, getter, constructor init, and setScrollDirection() into LibraryBrowseViewModel
- Add 'Scroll Direction' section as first option in the library Display Settings cog, above Image Type, with Vertical/Horizontal radio tiles matching existing style
- Split _buildGrid() into _buildVerticalGrid() (existing behavior) and _buildHorizontalGrid() (new Axis.horizontal CustomScrollView with auto row count calculated from available height)
- Add scrollDirection, scrollDirectionVertical, scrollDirectionHorizontal l10n keys to app_en.arb; auto-generated all locale stubs
…el, chevrons, padding

- Fix Moonfin-Client#1 (card sizing): use _cardWidth() as target cell HEIGHT instead of image width
  so poster-size preference scales correctly for all aspect ratios (Poster/Thumb/Banner)
- Fix Moonfin-Client#2 (scroll wheel): wrap horizontal CustomScrollView in Listener that redirects
  vertical PointerScrollEvent.scrollDelta.dy to horizontal scroll offset
- Fix Moonfin-Client#3 (chevrons): overlay left/right _HorizontalScrollChevron buttons on desktop
  (non-TV) matching home-screen row pattern; fade out when at scroll boundary
- Fix Moonfin-Client#4 (leading padding): ClampingScrollPhysics() prevents rubber-banding past
  offset 0 so SliverPadding leading gap is preserved on scroll-back
- Add missing package:flutter/gestures.dart import for PointerScrollEvent
…evron style

- Poster sizing: use _cardWidth()/ar as target image height so cards match
  vertical-mode dimensions exactly; fix childAspectRatio to height/width
  (correct formula for horizontal SliverGrid where cross=height, main=width)
- Gray overlay: remove Stack/Positioned/Opacity chevron overlay from inside
  _buildHorizontalGrid() which was causing the translucent gray tint
- Chevrons: move to _buildBody() as a simple right-aligned Row with
  Icons.chevron_left/chevron_right + VisualDensity.compact, matching the
  home-screen _buildTitledRow pattern exactly; shown only when horizontal
  mode is active on desktop (non-TV)
…sition horizontal scrolling and responsive poster scaling

- Added Group By options (None, Decade, Genre, Parental Rating, Studio) to Movies and TV Show libraries.
- Removed outdated Rating option from Sort & Filter menu.
- Sorted Parental Ratings by content severity (all ages upward) and Decades/Genres alphabetically.
- Implemented stateful horizontal row controllers so navigating D-pad Left/Right pins the focused poster in 1st position (matching Home Screen).
- Fixed focus traversal, title visibility, focus ring clipping, and 1-row vertical stretching.
- Restored responsive multi-row poster scaling across Small, Medium, Large, and Extra Large poster sizes.
@RadicalMuffinMan
RadicalMuffinMan merged commit 89ce10e into Moonfin-Client:main Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Row-Based Genre Browsing

2 participants