Add home-screen quick actions#205
Conversation
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.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (16)
📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe app adds home-screen quick actions for search and playback. Actions initialize before ChangesQuick Actions
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
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
lib/ui/screens/search.dart (1)
58-62: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDispose
_focusNodeand_controllerindispose().Both
FocusNode(line 33) andTextEditingController(line 32) hold native resources and should be disposed. Sincedispose()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
⛔ Files ignored due to path filters (1)
pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
lib/main.dartlib/ui/screens/main.dartlib/ui/screens/search.dartlib/utils/quick_actions.dartpubspec.yamltest/utils/quick_actions_test.dart
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.
Long-pressing the app icon now offers quick actions, mirroring Apple Music, via the
quick_actionsplugin.Actions
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.main()so a cold launch via a shortcut is captured; the action is buffered and consumed onceMainScreenis ready.MainScreensets 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.SearchScreenfocuses 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 fakeQuickActionsPlatform): the shortcut item set with/without a recent track; the "Artist - Title" subtitle formatting;setShortcutsforwarding to the platform; action buffering + streaming; and the search-focus signal.Summary by CodeRabbit
Icons
Each action has a monochrome glyph shipped as a native resource (the plugin's
iconis a platform resource name, not a Flutter asset):Glyphs: magnifying glass, star, download arrow, clock.