Separated track selection UI from player controls overlay to prevent
the gesture layer from dismissing the track selection panel when
selecting options. Created PersistentOverlayContainer that manages
its own visibility state independent of player controls.
Wrap all JellyfinApiClient suspend functions with withContext(Dispatchers.IO)
so callers (ViewModels on Main dispatcher) no longer block the UI thread.
Replace runBlocking in JellyfinAuthInterceptor with a reactive cached token
to avoid blocking OkHttp threads. Add IO dispatching to player MediaRepository
for DataStore reads.
- Inject UserSessionRepository into MediaRepository to access server URL
- Build artwork URLs using JellyfinImageHelper for both initial and next-up episodes
- Add artworkUrl parameter to MediaItem metadata via setArtworkUri()
- Fix PlayerQueuePanel thumbnail display with proper 4:3 aspect ratio
- Increase next-up queue count from 2 to 5 episodes
- Implement `loadLatestLibraryContent` in `InMemoryMediaRepository` to fetch and categorize latest media from Jellyfin libraries.
- Update `HomePageViewModel` to use `mapLatest` and `stateIn` for asynchronous, thread-safe loading of "Continue Watching" and "Latest" content.
- Refactor `HomePage` and its UI components (`HomeContent`, `HomeDrawer`, `HomeSections`) to pass data and callbacks as parameters instead of using `hiltViewModel()` internally.
- Enhance `PosterCard` and `ContinueWatchingCard` with explicit click listeners and image request optimization using `Coil`.
- Add `SeasonMedia` type to the `Media` sealed class to support more granular library item tracking.
- Standardize `UUID` usage for media selection callbacks across `LibraryViewModel` and common UI components.
- Improve UI styling by replacing shadows with subtle borders and consistent corner radii on media cards.
- Rename `getNextUpEpisode` to `getNextUpEpisodes` and update it to return a list of episodes with expanded request fields.
- Rename `getMediaPlaybackInfo` to `getMediaPlaybackUrl` and update its usages in `MediaRepository`.
- Simplify logging format by removing curly brace placeholders across multiple API call methods.
- Reorder `getContinueWatching` and `getLibraryContent` for better class organization.
- Remove unused `episode` import in `MediaRepository`.
- Integrate Room database with entities for `Movie`, `Series`, `Season`, `Episode`, and `CastMember`.
- Implement `RoomMediaLocalDataSource` to handle persistent storage and retrieval of media data.
- Refactor `InMemoryMediaRepository` to use the local data source and synchronize with the Jellyfin API.
- Update `HomePageViewModel`, `SeriesViewModel`, and `EpisodeScreenViewModel` to leverage the new repository logic.
- Replace generic `ItemDto` with specific `MovieDto`, `SeriesDto`, and `EpisodeDto` for type-safe navigation.
- Refactor UI models and components in `SeriesScreen`, `EpisodeScreen`, and `HomeSections` to use domain models directly.
- Enhance `JellyfinApiClient` requests to include necessary fields like `CHILD_COUNT` and `PARENT_ID`.
- Update Gradle dependencies to include Room and KSP.
- Introduce `PlayerManager` to encapsulate `Media3` player interactions, state management, and UI updates.
- Manages playback state (playing, buffering, ended, error), progress, metadata, track selection, and the media queue.
- Exposes state via `StateFlow` for reactive UI updates.
- Handles player lifecycle and event listeners.
- Create `MediaRepository` to fetch media items and upcoming episodes from the Jellyfin API.
- Abstracts away the logic for retrieving media sources, playback URLs, and constructing `MediaItem` objects.
- Includes a method to get the next episodes for auto-play, avoiding duplicates already in the queue.
- Implement `TrackMapper` to convert Media3 `Tracks` into a `TrackSelectionState` model for the UI.
- Refactor `PlayerViewModel` to delegate all player and data-fetching logic to `PlayerManager` and `MediaRepository`.
- The ViewModel now observes state flows from the manager and orchestrates UI actions (e.g., auto-hiding controls).
- Simplifies the ViewModel by removing direct player listener implementation, progress loops, and track parsing.
- Improves error handling for invalid media IDs and data loading issues.
- Implement `getNextEpisodes` in `JellyfinApiClient` to fetch a list of upcoming episodes for a given series.
- In `PlayerViewModel`, automatically load the next few episodes into the media queue when a new item starts playing.
- Attach `MediaMetadata` (e.g., title) to `MediaItem` objects to ensure the correct title is displayed for queued items.
- Trigger loading of the next episodes in the `onMediaItemTransition` player callback.
- Refactor video playback and queueing methods (`playVideo`, `addVideoUri`) to accept and utilize `MediaMetadata`.
- Replace the horizontal `PlayerSideSliders` with a new vertical `PlayerAdjustmentIndicator` for brightness and volume, displaying it in the center of the screen.
- Create `PlayerAdjustmentIndicator.kt`, a new composable that shows an icon, a vertical progress bar, and a percentage value within a semi-transparent black background.
- Update `PlayerScreen` to use the new centered indicator instead of the old side-aligned sliders when brightness or volume is adjusted via gestures.
- Pass a `modifier` to `ValueChangeTimedVisibility` to correctly position the new indicators.
- Change the background color of the "Seek to" toast message from a theme surface color to semi-transparent black for better consistency.
- Replace `LaunchedEffect` and manual state handling for showing/hiding player overlays (brightness, volume, seek feedback) with new reusable timed visibility composables.
- Introduce `ValueChangeTimedVisibility` to automatically show brightness and volume sliders for a short duration when their values change.
- Implement `EmptyValueTimedVisibility` to display the horizontal seek amount indicator and hide it after a delay.
- Remove redundant state variables (`brightnessOverlayVisible`, `volumeOverlayVisible`, `showFeedbackPreview`) and related logic from `PlayerScreen`.
- Clean up `PlayerGesturesLayer` by removing the `setFeedBackPreview` callback, simplifying its responsibility.
- Remove the auto-hide `LaunchedEffect` from `PlayerSideSliders` as this is now handled externally.
- Rename `PlayerGesturesLayer` parameters to be more descriptive of the gesture type (e.g., `onDoubleTapLeft`, `onDoubleTapCenter`, `onDoubleTapRight`).
- Update the `PlayerScreen` to use the new, more specific gesture handler names.
- Rename `PlayerGesturesLayer` parameters to be more descriptive of the gesture type (e.g., `onDoubleTapLeft`, `onDoubleTapCenter`, `onDoubleTapRight`).
- Update the `PlayerScreen` to use the new, more specific gesture handler names.
- Replace basic `AndroidView` player with a comprehensive `PlayerScreen` including custom controls, gestures, and state management.
- Implement `PlayerViewModel` logic for playback state, track selection (audio, subtitles, quality), progress updates, and auto-hiding controls.
- Add `PlayerUiState` and related models to track buffering, playback speed, tracks, and media queue.
- Create several reusable player components:
- `PlayerControlsOverlay`: Top/center/bottom bars for navigation, playback actions, and time info.
- `PlayerGesturesLayer`: Support for double-tap to seek and vertical drags for brightness/volume.
- `PlayerSeekBar`: Custom seek bar with buffer visualization and chapter/ad markers.
- `PlayerSettingsSheet`: Bottom sheet for adjusting playback speed and selecting media tracks.
- `PlayerQueuePanel`: Slide-out panel to view and navigate the current playlist.
- `PlayerSideSliders`: Visual overlays for brightness and volume adjustments.
- Update `PlayerActivity` to support immersive mode and use a dark theme for playback.
- Enable `trackSelector` in `VideoPlayerModule` to facilitate manual track switching.
- Replace `Button` with `IconButton` for the media play action in `HomeSections.kt`.
- Style the play button with a circular background, custom sizing, and theme-specific colors.
- Adjust layout positioning and padding for the play icon within the item card.
- Rename `MediaGhostIconButton` to `GhostIconButton` and move it to the common components package.
- Implement `PurefinIconButton` as a new reusable UI component.
- Refactor `PosterItem` to include `imageUrl`, shifting image URL generation to the ViewModel.
- Update `HomePageViewModel` and `LibraryViewModel` to use `stateIn` for the server URL and handle image URL generation.
- Decouple `PosterCard` from `HomePageViewModel` by passing click lambdas as parameters.
- Add `LibraryTopBar` and navigation support (back button, item selection) to the `LibraryScreen`.
- Enhance `PurefinAsyncImage` to handle empty string models by treating them as null to trigger placeholders.
- Update `HomeTopBar` styling and replace the custom refresh button with `PurefinIconButton`.
- Update `SeasonTabs` to handle selection state and provide an `onSelect` callback.
- Implement `selectedSeason` state in `SeriesScreen` using `remember` and `mutableStateOf`.
- Refactor `SeriesScreen` to display episodes based on the currently selected season.
- Adjust spacing and remove redundant styling from `EpisodeCarousel` items.
- Clean up unused imports and commented-out code in `SeriesComponents.kt`.