63 Commits
Author SHA1 Message Date
edde746 69fadc220d chore: clean up code comments 2026-08-10 20:28:41 +02:00
edde746 a9f0532f5f fix(ui): keep pushed screens clear of the Android navigation bar
Plezy is edge-to-edge on Android whether it asks to be or not: targetSdk is
36, Android 15 enforces edge-to-edge for apps targeting 35+, and Android 16
disables the windowOptOutEdgeToEdgeEnforcement escape hatch. The only
SystemUiMode.edgeToEdge call in the app fires on video-player exit, so on
API 35+ the window is edge-to-edge from the first frame and
MediaQuery.padding.bottom is a real ~48dp overlap under 3-button navigation.

MainScreen's phone layout hides that. It supplies a bottomNavigationBar and
never sets extendBody, so Flutter's Scaffold strips padding.bottom from the
body MediaQuery and every tab is already safe. Routes pushed on the profile
navigator are full-screen siblings of MainScreen with no bottom bar, so they
receive the untouched inset and nothing consumes it - the last settings card
and the final log lines render under the back, home, and recents buttons.

Three shared hosts own most of those routes, so the inset is consumed there:
FocusedScrollScaffold (25 screens, counting the SettingsPage wrapper) and
FocusableDetailScreenMixin.buildDetailScaffold (4) now append a trailing
SliverSystemBottomInset, and the four screens that build their own Scaffold
around a CustomScrollView append it directly.

The new widget codifies the convention this repository had already written
down but open-coded - insets baked into the scroll content rather than a
SafeArea around the scroll view - so content still paints under the bar while
the scroll extent grows enough to bring the last row above it. It reads
padding from its own context and collapses to zero height wherever the inset
is already zero: desktop, Android TV, tvOS via _AppleTvScale, and inside
MainScreen's tab bodies. No platform branching, and it stacks additively with
the music detail screens' existing mini-player spacers, which is correct
because the mini-player itself floats above the navigation bar on a pushed
route.

Scroll views that are not sliver lists take the inset in their own padding:
the companion remote's ListView, the auth screen's scroll container, and the
two SliverFillRemaining sign-in forms, whose children size themselves from
the extent remaining before them and so cannot be helped by a trailing
sliver. The logs empty state is left alone for the same reason inverted - it
already fills the viewport, and a trailing inset would only add scroll slack.

Verified on a Pixel 7 running Android 16 (API 36) with 3-button navigation:
Settings, Logs, and Video Playback all end clear of the bar.

close #1766
2026-08-03 00:05:21 +02:00
edde746 9429a76acc refactor: share search field, auth dialog, and list-download plumbing
The search screens, the out-of-band auth dialogs, the live TV guide and the
list-download paths each carried their own copy of the same shell. Extracts
SearchInputField and PendingAuthDialog and routes the duplicated download
and guide helpers through one implementation.
2026-07-26 06:09:49 +02:00
edde746 352b88109b refactor: extract shared mixins and helpers, drop dead abstractions
Introduces shared seams for paginated views, D-pad reorder, media control
routing, async singletons and the device method channel, then points the
open-coded copies at them.

Also removes unused models and duplicated provider/server plumbing, folds
the twice-implemented artifact store in the server, and factors the
repeated Flutter toolchain prologue in CI into a composite action.
2026-07-26 06:09:48 +02:00
edde746 4307c49cd2 refactor: remove unreachable code paths and unused members
Drops dead code across services, models, utils and widgets, including the
connection auth service, which had no implementer, and the Live TV DVR
provisioning models, which had no caller.

Tests that only covered deleted behaviour are removed or trimmed. No
behaviour change.
2026-07-26 06:09:47 +02:00
edde746 f8bfecf57d fix(media): serialize browsing and metadata mutations 2026-07-24 03:46:50 +02:00
edde746 70cd7e8c67 fix(music): keep now playing state current
close #1600
2026-07-17 16:30:10 +02:00
edde746 517c3f57ce fix(music): keep collection and playlist artwork square 2026-07-16 12:37:02 +02:00
edde746 d5f3e581df fix: eliminate cross-app consistency drift 2026-07-13 23:13:53 +02:00
edde746 e4db04fa62 fix: align UI focus and sheet behavior 2026-07-13 11:28:32 +02:00
edde746 2101f1d7f0 perf: isolate focus and media rebuilds 2026-07-12 19:00:11 +02:00
edde746 ceae98b75f refactor(paging): share continuation loading 2026-07-12 08:42:25 +02:00
edde746 7d6a747aa7 feat(music): now-playing, mini-player, queue and lyrics UI
Persistent mini-player over the profile navigator (route-aware
suppression, bottom-bar inset), slide-up now-playing screen with
mobile/desktop/TV layouts (blurred-art background, pause shape morphs,
dpad seek chain), queue sheet with reorder/remove/jump, synced lyrics
view, TV rail now-playing item, sleep timer, and audio playlist
playback. Adds download affordances on music surfaces.
2026-07-05 21:50:11 +02:00
edde746 9b48f26463 refactor(watch): shared point-of-use resolution across consumers
Adds context.withFreshWatchState/readFreshWatchState and sweeps the
remaining session-critical readers: context menu actions, folder tree
rows, discover hero, and TV spotlight minutes-left.
2026-06-10 05:38:33 +02:00
edde746 3753967caf fix(watch): resolve watch state per item at cards and playback open
Cards consult the hierarchy-aware store so container marks flip episode
rows instantly and a stale per-episode patch can no longer shadow a newer
show/season mark; playback opens with the session-fresh resume offset.
2026-06-10 05:23:09 +02:00
edde746 516925cf50 refactor(watch): promote overlay to hierarchy-aware WatchStateStore
Resolution now considers parentChain ancestors (newest event wins) and
watched patches set container leaf counts, so container marks reach
descendant cards and vice versa.
2026-06-10 05:18:02 +02:00
edde746 74b8dc4561 refactor: type server identifiers 2026-06-01 11:06:03 +02:00
edde746 e1e9adbb01 fix(ios): handle status bar scroll taps
close #1101
2026-05-22 15:40:03 +02:00
edde746 fc231a9e72 fix(playlists): load paginated items mutably
close #1100
2026-05-22 05:28:03 +02:00
edde746 e98d7febdd chore: upgrade Flutter to 3.44 2026-05-18 22:52:51 +02:00
edde746 5a68711f7b feat(ui): add pointer cursors to clickable controls
close #1068
2026-05-18 15:56:41 +02:00
edde746 c855dba3be fix(media): paginate large server lists 2026-05-17 20:25:39 +02:00
edde746 7a3f63683e fix(ui): refresh stale watch state 2026-05-09 06:00:36 +02:00
edde746 ed4be7b96d refactor: strip obvious comments 2026-05-04 22:40:18 +02:00
edde746 31d2d9dc98 feat: jellyfin 2026-05-01 01:20:36 +02:00
edde746 d0a93d57dd refactor: codebase review cleanup 2026-04-25 03:16:11 +02:00
edde746 2479e1faaa feat: tvos support 2026-04-24 14:11:24 +02:00
edde746 eb49ead83b fix: paginate collection/playlist/person endpoints
close #903
2026-04-21 21:51:20 +02:00
edde746 93d196572f fix: clamp playlist focus index on remove 2026-04-21 12:36:15 +02:00
edde746 a715f4e26b feat: collection/playlist sync rules 2026-04-19 17:45:03 +02:00
edde746 3da51f9d64 chore: pre-commit ci hook, dart format 2026-04-18 12:40:35 +02:00
edde746 d0934295b0 feat: download all playlist items
close #241
2026-04-08 12:37:03 +02:00
edde746 4f736c555b fix: make PlexMetadata type/key/title nullable for folder items
Plex API returns Directory entries without type field, causing
TypeError crash in fromJson. Made fields nullable and migrated
callers to use mediaType enum and displayTitle getter instead
of raw string access.
2026-03-14 05:40:14 +01:00
edde746 82b0de9223 feat: display movie edition titles across all views 2026-03-09 16:16:37 +01:00
edde746 cd2ab9d9cd refactor: deduplicate shared patterns, replace hardcoded colors 2026-03-03 22:43:00 +01:00
edde746 cc30bee83a refactor: extract FocusableActionBar widget for reusable app bar actions
Replace duplicated focusable action button pattern across 8 screens with
a shared FocusableActionBar widget that handles focus nodes, D-pad
navigation, back key, and focus decoration automatically.
2026-02-27 11:55:19 +01:00
edde746 d1d5b808bb fix: reduce widget tree depth 2026-02-24 02:40:04 +01:00
edde746 04438c8e45 refactor: code quality & format 2026-02-15 04:07:09 +01:00
edde746 6e9b78e5b5 fix: missing translations, simplify translations 2026-02-10 21:37:27 +01:00
edde746 44eae4ef84 refactor: extract BaseNotifier and HierarchicalEventMixin 2026-02-06 17:01:56 +01:00
edde746 e4b42cbc1e fix errors & warnings 2026-02-04 12:09:30 +01:00
edde746 a7ac681fdc refactor: extract shared mixins and helpers 2026-02-04 11:11:01 +01:00
edde746 16884a7bca refactor: eliminate duplicate logic across detail screens and helpers 2026-02-04 09:46:45 +01:00
edde746 96c6462d13 fix: use layout constraints for grid column count 2026-02-04 09:06:05 +01:00
edde746 cf3d81ebf5 chore: format 2026-02-04 07:50:38 +01:00
edde746 0a0aa13e66 fix: make playlist drag tap target bigger 2026-02-03 04:37:41 +01:00
edde746 c3e7fae312 fix: platlist drag performance 2026-02-03 04:19:36 +01:00
edde746 a3b5dfecfb refactor: clean up 2026-01-28 05:22:56 +01:00
edde746 0fc2708a51 fix: back improvements 2026-01-24 21:40:02 +01:00
edde746 54e8e0c621 refactor: abstract player & deduplicate 2026-01-24 04:06:58 +01:00