feat : New dynamic Colors Widget #655
Conversation
…ance - Add `MusicWidget` UI with playback controls, track info, and progress tracking - Update `MusicService` to synchronize playback state and handle widget actions - Implement album art caching and dominant color extraction for widget styling - Add `MusicWidgetReceiver` and necessary XML configurations for app widget support - Integrate `androidx.glance` dependencies and manifest declarations
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 60202a2a38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| private fun onMediaItemTransitionInternal() { | ||
| if (player.playbackState == Player.STATE_IDLE || player.playbackState == Player.STATE_ENDED) { |
There was a problem hiding this comment.
Invoke playback-end transition handlers
The new onMediaItemTransitionInternal() method is never called, so the logic inside it (including scrobbleManager?.onSongStop(), onInfiniteQueueEnabled() when playback ends, and immediate presence updates) no longer runs from the normal playback-state path. In this commit, onPlaybackStateChanged() now returns after queue persistence, so when playback reaches STATE_ENDED/STATE_IDLE these side effects can be skipped entirely until some unrelated event occurs.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
┌────────────────────────┐
│ ◀ ▶ │ ← Floating prev/next
│ │
│ [Album Artwork] │
│ 180×180dp │
│ │
│ ⏯ │ ← Large play/pause
└────────────────────────┘
| if (artFile != null) this[moe.koiverse.archivetune.widget.MusicWidgetKeys.ART_PATH] = artFile.absolutePath | ||
| if (dominantColor != null) this[moe.koiverse.archivetune.widget.MusicWidgetKeys.DOMINANT_COLOR] = dominantColor |
There was a problem hiding this comment.
Clear stale widget artwork state when art is unavailable
Widget state only writes ART_PATH and DOMINANT_COLOR when extraction succeeds, but never removes prior values when a track has no artwork or playback is cleared. That leaves old artwork/colors in DataStore, so widgets can display the previous song’s visuals while title/availability reflect the new empty or artless state.
Useful? React with 👍 / 👎.
Pull Request: Add Home Screen Widgets with Custom Button Shapes
📋 Summary
This PR introduces two new Glance-based home screen widgets for ArchiveTune, providing users with quick access to playback controls directly from their home screen. Both widgets feature custom button shapes, glassmorphism design, and real-time state synchronization.

🎯 Motivation
Users requested the ability to control playback without opening the app. Home screen widgets provide immediate access to currently playing track information and playback controls, enhancing the overall user experience and reducing friction in music control workflows.
✨ Features Added
1. Horizontal Music Widget (4×1 cells)
2. Album Art Widget (2×2 cells)
🏗️ Technical Implementation
Architecture
Key Components
State Management
DataStore Preferences(survives app closure)MusicServicepushes updates viaupdateAppWidgetState()on:onMediaItemTransition)onIsPlayingChanged)Performance Optimizations
updatePeriodMillis="0") instead of pollingMediaControllerreleased immediately after each command📦 Files Changed
New Files
app/src/main/kotlin/moe/koiverse/archivetune/widget/MusicWidget.ktapp/src/main/kotlin/moe/koiverse/archivetune/widget/MusicWidgetReceiver.ktapp/src/main/kotlin/moe/koiverse/archivetune/widget/AlbumArtWidget.ktapp/src/main/kotlin/moe/koiverse/archivetune/widget/AlbumArtWidgetReceiver.ktapp/src/main/kotlin/moe/koiverse/archivetune/widget/MusicWidgetKeys.ktapp/src/main/kotlin/moe/koiverse/archivetune/widget/MusicWidgetActions.ktapp/src/main/res/xml/widget_music_info.xmlapp/src/main/res/xml/widget_album_art_info.xmlapp/src/main/res/drawable/widget_triangle_prev.xmlapp/src/main/res/drawable/widget_triangle_next.xmlModified Files
app/build.gradle.kts- Added Glance dependenciesapp/src/main/AndroidManifest.xml- Registered widget receiversapp/src/main/res/values/app_name.xml- Added widget descriptionsapp/src/main/kotlin/moe/koiverse/archivetune/playback/MusicService.kt- Added widget state push logic🧪 Testing Checklist
TransactionTooLargeExceptionin logcat📸 Screenshots
Horizontal Music Widget
Album Art Widget
🔧 Dependencies Added
📝 Breaking Changes
None. This is a purely additive feature.
🎓 Documentation
Widget implementation follows the official Glance best practices documented in
AGENT.md. Key architectural decisions:🔍 Code Quality
All code follows ArchiveTune's architectural manifesto:
🚀 Performance Impact
🙏 Acknowledgments
Implementation based on:
Type: Feature
Priority: Medium