diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-21 23:22:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-21 23:22:57 +0300 |
| commit | d40a585b5848cc5bfe788c372a2bd1c028b9308d (patch) | |
| tree | 46a7cbd0669b1e5e512922a4843dc74abaf93975 /player-android/lib/utils/duration_formatter.dart | |
| parent | b33983f51c96db1d1b9e4e18d1478a3a993beb03 (diff) | |
Implement FolderBrowserScreen with browseSet endpoint and breadcrumb navigation (va)
Adds a FolderBrowserScreen that calls browseSet on init and pull-to-refresh,
renders subfolders first (with cover via setFolderCoverUrl) then media items,
and provides a scrollable breadcrumb bar for navigating the folder hierarchy.
Key changes:
- player-android/lib/screens/folder_browser_screen.dart: new screen with
loading/empty/error/refresh states, generation-counter cancellation, and
no Dio import in the screen layer (DIP).
- player-android/lib/api/player_api_client.dart: add setFolderCoverUrl() so
screens never access rawDio directly for URL construction (DIP).
- player-android/lib/utils/duration_formatter.dart: extract shared
formatDuration() from MediaGridScreen to eliminate the DRY violation.
- player-android/lib/screens/media_grid_screen.dart: delegate to
formatDuration() from the shared utility.
- player-android/lib/utils/error_mappers.dart: add folderErrorMessage().
- player-android/lib/app_routes.dart: add folderBrowser and folderBrowserPath().
- player-android/lib/router.dart: wire /browse/:setId GoRoute.
- player-android/test/screens/folder_browser_screen_test.dart: 16 widget tests
covering renders, breadcrumbs, folder/media tap navigation, empty, error,
retry, and pull-to-refresh.
All 298 tests pass; flutter analyze reports no issues.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'player-android/lib/utils/duration_formatter.dart')
| -rw-r--r-- | player-android/lib/utils/duration_formatter.dart | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/player-android/lib/utils/duration_formatter.dart b/player-android/lib/utils/duration_formatter.dart new file mode 100644 index 0000000..72e810b --- /dev/null +++ b/player-android/lib/utils/duration_formatter.dart @@ -0,0 +1,29 @@ +// Duration formatting utilities shared across screen widgets. +// +// Centralises the conversion of fractional seconds to a human-readable string +// so that [MediaGridScreen] and [FolderBrowserScreen] do not each carry their +// own copy of the same logic (DRY / Single Responsibility). +// +// All functions are pure data-transformations: no widget state, no Riverpod +// reads, no BuildContext — making them easy to unit-test in isolation. + +/// Formats [seconds] as `h:mm:ss` or `m:ss`, omitting leading zeros in the +/// hours and minutes positions. +/// +/// Examples: +/// - 7320.0 → "2:02:00" +/// - 210.5 → "3:30" +/// - 30.0 → "0:30" +/// +/// Uses integer arithmetic only — no [Duration] dependency — so the helper +/// is lightweight and independently testable. +String formatDuration(double seconds) { + final total = seconds.truncate(); + final h = total ~/ 3600; + final m = (total % 3600) ~/ 60; + final s = total % 60; + if (h > 0) { + return '$h:${m.toString().padLeft(2, '0')}:${s.toString().padLeft(2, '0')}'; + } + return '$m:${s.toString().padLeft(2, '0')}'; +} |
