Skip to content

Show new overview sections on the Home screen#203

Merged
phanan merged 4 commits into
masterfrom
feat/home-overview-blocks
Jul 12, 2026
Merged

Show new overview sections on the Home screen#203
phanan merged 4 commits into
masterfrom
feat/home-overview-blocks

Conversation

@phanan

@phanan phanan commented Jul 12, 2026

Copy link
Copy Markdown
Member

koel's overview API (FetchOverviewController) now returns more than most-played/top-albums/top-artists. This surfaces the rest on the Home screen.

New sections rendered

Latest Albums, You Might Also Like (similar songs), New Songs, New Artists, Hidden Gems (least played), Random Songs, Random Albums, Random Artists — alongside the existing Recently Played, Most Played, Top Albums, Top Artists.

Block order

Defaults to koel web's default home layout. If the user has reordered their blocks on the web, that preference (home_blocks_order, returned via GET me) is honoured: saved blocks come first in the saved order, the rest keep the default order. The mobile app keeps the Recently Played section pinned at the top (it's a distinct list, not a card scroller), so its position in the saved order is ignored.

Backward compatibility

Older API versions return neither the new overview keys nor the preference. OverviewProvider parses each section with a null-safe fallback (json ?? const []), the Home screen only renders a block when its list is non-empty, and an empty/absent home_blocks_order falls back to the default order. So on an older server nothing new appears and ordering is unchanged.

Notes

  • Extracted _songBlock/_albumBlock/_artistBlock helpers to avoid duplicating card-scroller boilerplate across 11 blocks.
  • Block reordering UI (a web feature) is out of scope — we only honour a preference already saved on the web.

Tests

  • overview_provider_test.dart — every section populates from a full response; omitted keys (older API) stay empty; isEmpty is true for {}.
  • home_block_order_test.dart — default order with no preference; saved blocks move to front; unknown saved ids ignored; unsaved blocks keep default order.
  • user_test.darthome_blocks_order parsed from preferences; defaults to empty when absent; non-string entries dropped.

Summary by CodeRabbit

  • New Features
    • Expanded the home screen with additional discovery sections (recently added, similar, hidden gems/least played, and random) across songs, albums, and artists.
    • Added user-configurable Home block ordering using saved preferences.
    • Added an asHero option to album/artist cards to control Hero animation behavior.
  • Bug Fixes
    • Improved logout behavior to fully clear all overview data before refreshing the UI.
  • Tests
    • Added coverage for overview refresh/empty states, preference parsing, block ordering, and Hero rendering rules.

koel's overview API now also returns latest/random/recently-added
albums and artists, plus new/least-played/random/similar songs.
Parse every section (missing keys stay empty so older servers degrade
gracefully) and render each non-empty block as a card scroller, ordered
to match koel web's default home layout.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e753eac-b9ae-47c1-a39f-68afae0c2780

📥 Commits

Reviewing files that changed from the base of the PR and between c538359 and 6a43867.

📒 Files selected for processing (2)
  • lib/providers/overview_provider.dart
  • lib/ui/screens/home.dart
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/ui/screens/home.dart
  • lib/providers/overview_provider.dart

📝 Walkthrough

Walkthrough

OverviewProvider now tracks additional media sections. User preferences store Home block ordering, while HomeScreen renders expanded sections in the saved order with configurable Hero behavior for repeated cards.

Changes

Overview sections and Home block preferences

Layer / File(s) Summary
Expand and refresh overview sections
lib/providers/overview_provider.dart
Adds categorized song, album, and artist lists with centralized parsing, clearing, emptiness checks, and refresh population.
Validate expanded provider behavior
test/providers/overview_provider_test.dart
Tests complete, partial, and empty overview payloads.
Parse and expose Home block preferences
lib/models/user.dart, lib/providers/auth_provider.dart, test/models/user_test.dart
Parses filtered Home block ordering preferences and exposes nullable authenticated-user state.
Render, order, and animate Home blocks
lib/ui/screens/home.dart, lib/ui/widgets/album_card.dart, lib/ui/widgets/artist_card.dart, test/ui/screens/home_block_order_test.dart, test/ui/widgets/card_hero_test.dart
Builds reusable media scrollers, applies saved ordering, and controls Hero rendering for repeated cards.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant OverviewProvider
  participant OverviewAPI
  participant RecentlyPlayedProvider
  participant AuthProvider
  participant HomeScreen
  participant CardWidgets
  OverviewProvider->>OverviewAPI: request categorized media lists
  OverviewAPI-->>OverviewProvider: return overview payload
  OverviewProvider->>RecentlyPlayedProvider: seed recently played songs
  OverviewProvider-->>HomeScreen: notify refreshed sections
  AuthProvider-->>HomeScreen: provide saved block order
  HomeScreen->>HomeScreen: build and reorder media blocks
  HomeScreen->>CardWidgets: render cards with Hero settings
Loading

Possibly related PRs

  • koel/player#126: Overlaps with the overview refresh flow that seeds recently played state.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding new overview sections to the Home screen.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/home-overview-blocks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
lib/providers/overview_provider.dart (1)

82-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename lambda parameter j to a descriptive name.

Per the coding guidelines, j is only permitted for loop counters; lambda args and callback params should use descriptive names. In .map<Album>((j) => Album.fromJson(j)) and .map<Artist>((j) => Artist.fromJson(j)), j is a lambda parameter representing a JSON entry, not a loop counter.

♻️ Proposed rename
   List<Album> _parseAlbums(dynamic json) => _albumProvider.syncWithVault(
         ((json ?? const []) as List)
-            .map<Album>((j) => Album.fromJson(j))
+            .map<Album>((entry) => Album.fromJson(entry))
             .toList(),
       );

   List<Artist> _parseArtists(dynamic json) => _artistProvider.syncWithVault(
         ((json ?? const []) as List)
-            .map<Artist>((j) => Artist.fromJson(j))
+            .map<Artist>((entry) => Artist.fromJson(entry))
             .toList(),
       );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/providers/overview_provider.dart` around lines 82 - 100, Rename the
lambda parameter j to a descriptive JSON-entry name in both _parseAlbums and
_parseArtists, updating the corresponding Album.fromJson and Artist.fromJson
arguments while preserving behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/providers/overview_provider.dart`:
- Around line 82-100: Rename the lambda parameter j to a descriptive JSON-entry
name in both _parseAlbums and _parseArtists, updating the corresponding
Album.fromJson and Artist.fromJson arguments while preserving behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: df04f6f8-273b-4694-a51f-a4f430c07c11

📥 Commits

Reviewing files that changed from the base of the PR and between 4883cc4 and 2f9ba0b.

📒 Files selected for processing (3)
  • lib/providers/overview_provider.dart
  • lib/ui/screens/home.dart
  • test/providers/overview_provider_test.dart

koel web lets users reorder their home blocks and persists it as the
home_blocks_order preference (returned via GET me). Parse it into the
User model and order the Home screen blocks accordingly, falling back to
koel web's default order when no preference is saved or the server (older
API) doesn't expose one.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
lib/ui/screens/home.dart (1)

42-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Sort comparator parameters should use descriptive names.

Per the project's coding guidelines, single-letter variable names are only allowed for i, j (loop counters) and h (test harness). The sort lambda's a and b should be renamed to descriptive names.

As per coding guidelines: **/*.{dart,ts,tsx,js,jsx,kt,swift}: Don't use single-letter variable names except for: i and j for loop counters, and h for the test harness. For all other cases (callback params, destructured fields, lambda args, etc.), pick a descriptive name that says what it is.

♻️ Optional rename for sort comparator parameters
-    indexed.sort((a, b) => sortKey(a).compareTo(sortKey(b)));
+    indexed.sort((left, right) => sortKey(left).compareTo(sortKey(right)));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/ui/screens/home.dart` around lines 42 - 47, Rename the sort comparator
parameters in the indexed.sort callback to descriptive names representing the
compared entries, and update their references in sortKey calls; leave the
sorting behavior unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/ui/screens/home.dart`:
- Around line 42-47: Rename the sort comparator parameters in the indexed.sort
callback to descriptive names representing the compared entries, and update
their references in sortKey calls; leave the sorting behavior unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b929ddb0-67fb-4861-9bd0-a4eb1b204844

📥 Commits

Reviewing files that changed from the base of the PR and between 2f9ba0b and b5ec94e.

📒 Files selected for processing (5)
  • lib/models/user.dart
  • lib/providers/auth_provider.dart
  • lib/ui/screens/home.dart
  • test/models/user_test.dart
  • test/ui/screens/home_block_order_test.dart

phanan added 2 commits July 12, 2026 19:24
The same album or artist can now appear in several Home blocks, which
produced multiple heroes sharing one tag and crashed the details
transition. Give AlbumCard/ArtistCard an asHero flag and let the Home
screen grant the hero to only the first card per entity id; later
duplicates render without a hero but still navigate.
Address review: use descriptive names for the JSON-entry map lambdas and
the sort comparator params, per the project's no-single-letter-vars rule.
@phanan phanan merged commit 3ed9b5c into master Jul 12, 2026
2 checks passed
@phanan phanan deleted the feat/home-overview-blocks branch July 12, 2026 17:32
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.

1 participant