Skip to content

Add home-screen quick actions#205

Merged
phanan merged 5 commits into
masterfrom
feat/home-screen-quick-actions
Jul 12, 2026
Merged

Add home-screen quick actions#205
phanan merged 5 commits into
masterfrom
feat/home-screen-quick-actions

Conversation

@phanan

@phanan phanan commented Jul 12, 2026

Copy link
Copy Markdown
Member

Long-pressing the app icon now offers quick actions, mirroring Apple Music, via the quick_actions plugin.

Actions

  • Search — opens the app on the Search tab and focuses the search field.
  • Play Favorite Songs — shuffle-plays the user's favourites.
  • Play Downloaded — shuffle-plays downloaded songs (works offline).
  • Play Most Recent — resumes the persisted queue where it left off; subtitled with the last track (e.g. Skid Row - 18 and Life). Only shown when there's a recent track.

How it works

  • KoelQuickActions (lib/utils/quick_actions.dart) wraps the plugin: registers the shortcut items, formats the "Most Recent" subtitle, and exposes an action stream plus a search-focus signal.
  • Initialized in main() so a cold launch via a shortcut is captured; the action is buffered and consumed once MainScreen is ready.
  • MainScreen sets the shortcuts, refreshes the "Most Recent" subtitle whenever the current track changes, and dispatches actions. Cold-start "resume" waits for the persisted queue to finish restoring before playing.
  • SearchScreen focuses its field on the search action, whether it was already alive or is built as a result of the action.

Dynamic shortcuts need no native config (no Info.plist / manifest changes).

Tests

quick_actions_test.dart (against a fake QuickActionsPlatform): the shortcut item set with/without a recent track; the "Artist - Title" subtitle formatting; setShortcuts forwarding to the platform; action buffering + streaming; and the search-focus signal.

Summary by CodeRabbit

  • New Features
    • Added home-screen quick actions for Search, play favorites, play downloaded tracks, and resume the recent queue (including “Play Most Recent” when available).
    • Quick actions work during cold launches by buffering the triggered action until startup finishes.
    • Search quick actions open Search and automatically focus the search field.
    • Added iOS icons for the new quick actions.
  • Bug Fixes
    • Improved quick-action playback and navigation by restoring the needed queue/state before handling actions.
  • Tests
    • Added unit tests for shortcut configuration, pending-action buffering, recent-label formatting, and search-focus requests.

Icons

Each action has a monochrome glyph shipped as a native resource (the plugin's icon is a platform resource name, not a Flutter asset):

  • iOS — an asset catalog imageset per icon, template-rendered so it picks up the system tint.
  • Android — a drawable per icon in Koel's accent pink (stays visible on light and dark shortcut sheets).

Glyphs: magnifying glass, star, download arrow, clock.

Long-pressing the app icon now offers four shortcuts, mirroring Apple
Music:
- Search: opens the Search tab and focuses the field
- Play Favorite Songs: shuffle-plays favourites
- Play Downloaded: shuffle-plays downloaded songs
- Play Most Recent: resumes the persisted queue, subtitled with the last
  track ("Artist - Title")

A KoelQuickActions service registers the shortcuts (refreshing the
recent subtitle as the current track changes) and buffers an action from
a cold launch until the main screen can act on it.
@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: d5808287-50f2-4095-a584-0459780a9c37

📥 Commits

Reviewing files that changed from the base of the PR and between 839e075 and 47b3fd9.

⛔ Files ignored due to path filters (16)
  • android/app/src/main/res/drawable-xxxhdpi/quick_action_download.png is excluded by !**/*.png
  • android/app/src/main/res/drawable-xxxhdpi/quick_action_favorites.png is excluded by !**/*.png
  • android/app/src/main/res/drawable-xxxhdpi/quick_action_recent.png is excluded by !**/*.png
  • android/app/src/main/res/drawable-xxxhdpi/quick_action_search.png is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_download.imageset/icon.png is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_download.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_download.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_favorites.imageset/icon.png is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_favorites.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_favorites.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_recent.imageset/icon.png is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_recent.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_recent.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_search.imageset/icon.png is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_search.imageset/[email protected] is excluded by !**/*.png
  • ios/Runner/Assets.xcassets/quick_action_search.imageset/[email protected] is excluded by !**/*.png
📒 Files selected for processing (2)
  • lib/ui/screens/main.dart
  • lib/ui/screens/search.dart
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/ui/screens/main.dart
  • lib/ui/screens/search.dart

📝 Walkthrough

Walkthrough

The app adds home-screen quick actions for search and playback. Actions initialize before runApp, buffer cold-launch triggers, route through MainScreen, and connect to search focus and audio queue playback.

Changes

Quick Actions

Layer / File(s) Summary
Quick-action service and validation
pubspec.yaml, lib/utils/quick_actions.dart, test/utils/quick_actions_test.dart, ios/Runner/Assets.xcassets/quick_action_*/Contents.json
Adds the platform dependency, shortcut construction and buffering, search-focus requests, lifecycle cleanup, iOS shortcut assets, and unit coverage.
Startup and playback dispatch
lib/main.dart, lib/ui/screens/main.dart
Initializes quick actions during startup and routes pending or emitted actions to search, favorites playback, downloaded playback, or queue resumption.
Search focus lifecycle
lib/ui/screens/search.dart
Subscribes to search-focus requests, consumes cold-launch focus state, schedules field focus, and cleans up subscriptions.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant QuickActionsPlatform
  participant KoelQuickActions
  participant MainScreen
  participant SearchScreen
  participant AudioHandler

  QuickActionsPlatform->>KoelQuickActions: deliver shortcut action
  KoelQuickActions->>MainScreen: emit or provide pending action
  MainScreen->>SearchScreen: switch tab and request focus
  MainScreen->>AudioHandler: replace queue and start playback
Loading
🚥 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 summarizes the main change: adding home-screen quick actions.
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-screen-quick-actions

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.

Actionable comments posted: 1

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

58-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Dispose _focusNode and _controller in dispose().

Both FocusNode (line 33) and TextEditingController (line 32) hold native resources and should be disposed. Since dispose() was modified in this PR, this is a natural opportunity to add the missing calls.

♻️ Proposed fix
   `@override`
   void dispose() {
     unsubscribeAll();
+    _focusNode.dispose();
+    _controller.dispose();
     super.dispose();
   }
🤖 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/search.dart` around lines 58 - 62, Update the Search screen’s
dispose() method to call dispose() on both _focusNode and _controller before
super.dispose(), while preserving the existing unsubscribeAll() cleanup.
🤖 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.

Inline comments:
In `@lib/ui/screens/main.dart`:
- Around line 145-155: Wrap the entire asynchronous body of _resumeQueue in a
catch-all that ignores errors, matching the existing behavior of _shufflePlay.
Ensure failures from waiting on audioHandler.queue or calling
audioHandler.play() are swallowed so _handleQuickAction does not emit unhandled
async errors.

---

Nitpick comments:
In `@lib/ui/screens/search.dart`:
- Around line 58-62: Update the Search screen’s dispose() method to call
dispose() on both _focusNode and _controller before super.dispose(), while
preserving the existing unsubscribeAll() cleanup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe868c58-40e9-4519-b168-4a2ee8c4924b

📥 Commits

Reviewing files that changed from the base of the PR and between a21e84f and 7d01e88.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • lib/main.dart
  • lib/ui/screens/main.dart
  • lib/ui/screens/search.dart
  • lib/utils/quick_actions.dart
  • pubspec.yaml
  • test/utils/quick_actions_test.dart

Comment thread lib/ui/screens/main.dart
phanan added 4 commits July 12, 2026 20:13
Ship monochrome glyphs (search, star, download, clock) as native
resources — an iOS asset catalog (template-rendered) and an Android
drawable — and reference them from each ShortcutItem.
Replace the hand-drawn icons with the Lucide search, star, arrow-down-to-line
and clock-9 outlines, rendered from SVG for a cleaner, consistent look.
Pad the icons within their canvas (~60% glyph) so they don't render
edge-to-edge and oversized next to system shortcuts.
Address review: dispose the Search screen's focus node and controller,
and swallow errors in _resumeQueue like the other quick-action handlers.
@phanan phanan merged commit 834d0b9 into master Jul 12, 2026
2 checks passed
@phanan phanan deleted the feat/home-screen-quick-actions branch July 12, 2026 18:55
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