Repository navigation
Add the Flick Replay home screen widget and responsive widget layouts - #313
Merged
Merged
Conversation
Extract WidgetViews, WidgetLayoutPolicy, WidgetPlaybackState, and WidgetUpcomingTrack helpers so all widget providers share layout, text, playback, and art logic. Add responsive layouts for compact, flagship, and mini widgets including a square compact fallback and gradient surfaces. Cache rendered bitmaps and parsed cover art.
Replace static oval shapes with ripple drawables for play and transport buttons, add active transport background, and update widget layouts to use outline clipping. Add widget dimension resources for compact sizing. Enable resizing on the flagship widget and support vertical/horizontal resize. Restructure flagship and mini player layouts to use included sub-layouts and a thumbnail-based mini player design. Add accessibility strings for playback state and elapsed/duration labels.
- New ReplayWidgetProvider with four look presets (acid, night, signal, artwork) - Widget settings screen gains a Replay tab that opens today's listening recap - WidgetSyncService watches listening history and refreshes the Replay snapshot on change and at midnight - WidgetIntentHandler adds categorized recap/queue intents and a native launch handshake with generation-based lifecycle guarding - Default replay look is acid; selection persists via app preferences
Introduce a responsive "Flick Replay" widget that shows today's listening snapshot (time, plays, deltas, top covers) styled after the in-app Replay card, with Acid/Signal/Night/Artwork looks. Includes shared layout policy, text/artwork/progress rendering helpers, palette math, and a launch inbox that buffers widget taps until the Dart channel handler is ready.
Introduce widget resources for compact, flagship, and replay variants, including drawables, sizes, styles, and dims. Legacy launchers infer spans from dp, so compact keeps a 156dp minimum on older versions while v31 requesters get the 110dp 2x2 target. Add layout policy, replay state, launch inbox, and resource tests covering geometry, accessibility targets, and palette contrast.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a "Flick Replay" home screen widget that shows today's listening snapshot
and gives the existing widgets a shared responsive-layout and interaction polish
pass.
Flick Replay widget (new)
ReplayWidgetProviderrenders today's listening snapshot — listening time,play count, day-over-day deltas, and today's top album covers — styled after the
in-app Replay card. Four looks: Acid (default), Night, Signal, and Album, which
tints the surface from today's top cover and picks a readable foreground +
secondary/accent palette from measured contrast.
WidgetLayoutPolicy.replay(...): itsizes the headline values, keeps the two metric columns readable, loses rear
sleeves before sacrificing them, drops the comparison caption at short heights,
and exposes a spoken content description (summary, deltas, and the open action).
WidgetReplayArtwork) witha rotation-contained ornament orbit, RTL-aware positioning, and a byte-bounded
LRU cache; the widget is registered in the manifest with a resizable 4×2 provider.
Replay data sync (Dart)
WidgetSyncServicegains a Replay path: it watches listening history (debounced)plus a midnight timer, reads today's and yesterday's
ListeningRecap, andpublishes time/plays, percent deltas, and up to three local album covers to the
shared widget state. Unchanged snapshots are skipped, refreshes are coalesced so
a stale write cannot land, and a not-yet-ready database keeps the retry flag set
instead of publishing misleading zeros.
that races a write cannot mix yesterday's covers with today. A day-key mismatch
makes the native widget render an empty state, so a stale snapshot never looks
current.
WidgetReplaySnapshotcentralizes the local-only cover filter (nativewidgets cannot read remote/SAF URIs), the day key, and the clamped/unknown delta math.
WidgetIntentHandleradds theflickwidget://recap/openintent, ageneration-guarded native launch handshake (channel-ready inbox + detach
acknowledgement) so taps arriving before/after the Dart handler are dispatched
exactly once, and
NavigationHelper.navigateToRecapfor the destination.Widget settings
options. The choice persists through app preferences (
widgetReplayLook,default
acid) and is pushed to the widget immediately.Responsive layouts and interaction polish
ResponsiveWidgetProviderbase renders Android 12+OPTION_APPWIDGET_SIZESvariants (capped at 16) and portrait/landscape sizes for older launchers; the
mini, flagship, compact, and replay providers all share it.
while legacy launchers keep a 156dp minimum, restructures the flagship and mini
layouts into included sub-layouts with a thumbnail-based mini player, and enables
flagship resizing.
adds an active-transport background and outline clipping, and adds accessibility
strings for playback state and elapsed/duration labels.
Related issue
none
Checklist
flutter analyzepassesflutter testpassescargo test --manifest-path rust/Cargo.tomlpassesflutter run --flavor full)CHANGELOG.mdupdated for user-facing changes