summaryrefslogtreecommitdiff
path: root/player-android/lib/providers/api_client_provider.dart
AgeCommit message (Collapse)Author
2026-05-22Pass session cookie to ExoPlayer/just_audio for authenticated streamingPaul Buetow
The audio/video players spawn a localhost proxy (just_audio) or call ExoPlayer directly (video_player) using their own HTTP stack, which does not share Dio's cookie jar. Without the session cookie those requests hit the stream endpoint anonymously and fail with 401. Expose the Dio CookieJar via a Riverpod provider (cookieJarProvider) and attach a Cookie header (alongside the existing Authorization: Bearer) to both AudioSource.uri and VideoPlayerController.networkUrl. Also enable android:usesCleartextTraffic="true" on the Application — just_audio's headers-injection proxy listens on 127.0.0.1 and Android 28+ blocks cleartext to it without the explicit opt-in. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22Implement public ShareViewerScreen with Android deep-link intent-filter (9b)Paul Buetow
- New ShareViewerScreen (/share/:token): unauthenticated share-viewer that fetches share metadata via publicApiClientProvider, renders filename, type, duration, thumbnail, and a Play button routing to the video/audio player. - New publicApiClientProvider: bare Dio client (no auth interceptors) for the public share endpoint; shares kPlayerBaseUrl with the authenticated client. - AndroidManifest: http + https deep-link intent-filters for /share/.* so Android routes share URLs directly into the app (App Links / autoVerify). - router.dart: /share/:token bypasses the authentication redirect; guard uses AppRoutes.shareViewerPrefix constant instead of a raw '/share/' string (DIP). - app_routes.dart: shareViewer route constant, shareViewerPrefix, shareViewerPath helper. - error_mappers.dart: shareViewerErrorMessage — 404 invalid/revoked, 410 expired. - player_api_client.dart: baseUrl getter encapsulates rawDio.options.baseUrl so screens never access transport internals directly (ISP, DIP). - Review fixes: OCP icon map in _FallbackThumbnail, LSP explicit baseUrl overrides in test fakes, DIP shareViewerPrefix constant. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20Implement DioPlayerApiClient with real HTTP bodies for core API methods (oa)Paul Buetow
Replace UnimplementedError stubs with concrete Dio calls for bootstrap, login, logout, listSets, browseSet, listMedia, getMedia, streamMedia, downloadMedia, getThumbnail, healthz, and readyz. Wire DioPlayerApiClient into the Riverpod provider. Add http_mock_adapter dev dependency and 25 unit tests covering success + error paths for all implemented methods. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20Add go_router + Riverpod wiring and extract SOLID-clean screen/nav layers (na)Paul Buetow
Introduces flutter_riverpod and go_router dependencies. Wires up the app with a Riverpod-managed GoRouter, auth-guarded redirect logic, and a shared navigator key used by DioClient for 401 → /login redirects. SOLID fixes applied: - navigatorKey extracted to navigation_key.dart (DIP: breaks cross-layer import from router.dart into api_client_provider.dart) - AppRoutes extracted to app_routes.dart (SRP + avoids circular import when screen files reference route constants) - LoginScreen, HomeScreen, MediaDetailScreen, ShareScreen each moved to their own file under lib/screens/ (SRP: router.dart is routing-only) - router.dart re-exports AppRoutes for backward-compatible callers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>