Skip to content

feat(android-auto): consolidated browsing with user-selectable mode - #1601

Open
pdebuitlear wants to merge 14 commits into
finamp-app:redesignfrom
pdebuitlear:feature/android-auto-consolidated
Open

feat(android-auto): consolidated browsing with user-selectable mode#1601
pdebuitlear wants to merge 14 commits into
finamp-app:redesignfrom
pdebuitlear:feature/android-auto-consolidated

Conversation

@pdebuitlear

@pdebuitlear pdebuitlear commented Apr 15, 2026

Copy link
Copy Markdown

Summary

Consolidates Android Auto browsing features with a user-configurable option to choose between:

  • Flat list (default) — traditional paginated view with "Browse by Letter" node
  • Letter-first — skip flat list, go straight to A–Z index

Addresses feedback from #1576 and #1579 to keep both approaches available behind a setting.

Features

  • Recently Played Albums — shows up to 20 recently played albums in root menu
  • Artist Albums Browsing — tap an artist to browse their albums
  • Letter-first Navigation — optional A–Z index for Albums & Artists

Settings

New "Android Auto" section in Settings → Android Auto with dropdown to select browsing mode.

Default: Flat list (preserves existing behavior)

Display Rendering

Items in letter-filtered pages render as a plain text list (not grid with icons), addressing the maintainer's feedback about long names being cut off.

@pdebuitlear
pdebuitlear force-pushed the feature/android-auto-consolidated branch 2 times, most recently from 930d938 to aca7f21 Compare April 15, 2026 18:05
recentlyPlayed,
}

@JsonSerializable(converters: [BaseItemIdConverter()])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding includeIfNull: false here with all these usually empty fields.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added includeIfNull: false to the @JsonSerializable annotation on MediaItemId.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this change.

Comment thread lib/models/finamp_models.dart Outdated
static const androidAutoBrowsingMode = AndroidAutoBrowsingMode.flat;
}

@HiveType(typeId: 79)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class should be at the end of the file with a higher typeId than the current highest.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — moved AndroidAutoBrowsingMode to the end of the file. Kept typeId 79 to avoid breaking existing Hive boxes on devices that already have the setting stored.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the ID.

Comment thread lib/screens/android_auto_settings_screen.dart Outdated
Comment thread lib/services/music_player_background_task.dart Outdated
Comment thread lib/services/android_auto_helper.dart Outdated
Comment thread lib/services/android_auto_helper.dart Outdated
Comment thread lib/services/android_auto_helper.dart
limit: onlineModeLimit,
);
return items ?? [];
final List<BaseItemDto> allItems = [];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a reason to paginate these server requests. We're just outputting the whole list, and the main app doesn't currently paginate the item requests this covers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — left the server requests in getBaseItems unpaginated as before. The pagination only applies to the root collection browse pages.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this change.

Comment thread lib/services/android_auto_helper.dart Outdated
Comment thread lib/services/android_auto_helper.dart
padraigbutler and others added 14 commits May 9, 2026 10:28
Fixes finamp-app#1576

Returning entire album/artist collections in a single Android Auto
getChildren response causes a FAILED BINDER TRANSACTION crash due to
the ~1MB Binder IPC buffer limit. This replaces the unbounded fetch
with a 200-item paginated approach and adds a Browse-by-Letter hybrid
for navigating large libraries by initial letter.

Changes:
- Limit root collection responses to 200 items per page; append a
  "More… (N remaining)" browse node when further pages exist
- Add a "Browse by Letter" node at the top of page 1 for Albums and
  Artists, opening an A–Z + # index; each letter page is independently
  paginated with its own "More…" node
- Add nameFilter and pageStartIndex fields to MediaItemId (HiveFields
  4 & 5) to encode browse state inside Android Auto node IDs
- Add NameStartsWith query parameter to getItems, getArtists, and
  getAlbumArtists Jellyfin API calls for server-side letter filtering
- Set CONTENT_STYLE_BROWSABLE_HINT=4 (category grid) on Albums and
  Artists root nodes to hint at non-alphabetical rendering
- Add docs/android_auto_browsing.md with implementation notes and
  Android Auto platform learnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new private method that fetches up to 20 recently played albums
or artists from Jellyfin (sorted by DatePlayed descending, filtered to
IsPlayed), and wires it into getMediaItems() via a recentlyPlayed
parentType dispatch branch. Offline mode returns a non-playable
placeholder item.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Jellyfin's IsPlayed filter requires all tracks to have been played,
which is far too strict for albums/artists. Sort by DatePlayed
descending and filter client-side on userData.lastPlayedDate != null
to match the pattern used elsewhere in the app.
Jellyfin only sets DatePlayed on track items, not on albums or artists.
Query recently played tracks (Filters=IsPlayed works for tracks), deduplicate
by albumId or albumArtist, then fetch the actual album/artist items by ID.
…le mode

Consolidates three Android Auto feature improvements into a single PR with a
user-configurable browsing mode for Albums and Artists:

**New Setting: Albums & Artists Browsing Mode**
- Default: Flat list (paginated) — preserves existing behavior
- Alternative: Letter-first (A-Z) — skips flat list, goes straight to A-Z index

**Features included:**
1. Recently Played Albums/Artists (from integration/android-auto-features)
2. Artist Albums Browsing (from integration/android-auto-features)
3. Letter-first Navigation for Albums/Artists (alternative approach)

**Implementation Details:**
- New enum: AndroidAutoBrowsingMode {flat, letterFirst}
- New settings screen: AndroidAutoSettingsScreen
- Settings persist via Hive
- Display hints (CONTENT_STYLE_BROWSABLE_HINT) adapt based on user choice:
  - Flat mode: Grid layout (traditional)
  - Letter-first mode: List layout (cleaner for letter navigation)
- getMediaItems() routes based on setting
- "Browse by Letter" node only appears in flat mode (now redundant in letter-first)

**Fixes:**
- Letter nodes render with proper display hints for child content
- Items within letter pages render consistently across both modes

**Test Plan:**
- [ ] Settings screen accessible via Settings → Android Auto
- [ ] Default setting is "Flat list (paginated)"
- [ ] Switching to "Letter-first" changes browsing immediately
- [ ] Setting persists across app restarts
- [ ] Tap Albums/Artists in flat mode: see flat list + "Browse by Letter"
- [ ] Tap Albums/Artists in letter-first mode: see A-Z index directly
- [ ] No FAILED BINDER TRANSACTION in logcat
- [ ] Recently Played Albums still appears in root menu

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Letter-filtered items (artists/albums within a letter page) should render
as a text list rather than a grid with icons that cut off names.

Set both CONTENT_STYLE_BROWSABLE_HINT and PLAYABLE_HINT to 1 (list) on
letter nodes to ensure all children render as a list.
- Move AndroidAutoBrowsingMode enum to end of finamp_models.dart (keep typeId 79)
- Add localization strings for all Android Auto UI text
- Use contentViewType setting for browsing hints in _getRootMenu
- Define constants for CONTENT_STYLE hint values
- Remove pointless ternary in _getLetterNodes
- Increase recently played tracks fetch limit to 300
- Enable letter browsing for tracks tab
- Replace empty string sentinel with 'letter_root' for Browse by Letter node
- Fix negative remaining count bug for playlists pagination
- Use pageStart for '#' bucket server request
- Mark artists as non-playable in letter-browse mode so tapping shows albums
@pdebuitlear
pdebuitlear force-pushed the feature/android-auto-consolidated branch from aca7f21 to 74c5e81 Compare May 9, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants