Skip to content

Optim/player view model migration phase 7#887

Merged
theovilardo merged 7 commits intomasterfrom
optim/player-view-model-migration-phase-7
Jan 22, 2026
Merged

Optim/player view model migration phase 7#887
theovilardo merged 7 commits intomasterfrom
optim/player-view-model-migration-phase-7

Conversation

@theovilardo
Copy link
Copy Markdown
Owner

PlayerViewModel refactored and optimized using StateHolders

…tateHolders

Phase 1:

Extends the modularization of `PlayerViewModel` by extracting connectivity tracking and sleep timer management into standalone components. This reduces the boilerplate and responsibility surface of the main ViewModel.

- **ConnectivityStateHolder**:
    - Centralizes WiFi and Bluetooth state tracking (enabled status, network/device names, connected audio devices).
    - Manages system callbacks for `ConnectivityManager`, `WifiManager`, and `BluetoothManager`.
    - Handles permission checks for Bluetooth and Location required for connectivity info.
- **SleepTimerStateHolder**:
    - Manages duration-based sleep timers using `AlarmManager` for system-level reliability.
    - Implements End-of-Track (EOT) monitoring to pause playback when a specific song finishes.
    - Handles "Counted Play" logic to stop playback after a defined number of tracks.
    - Maintains UI state for timer displays and countdowns.
- **PlayerViewModel**:
    - Delegated all connectivity and sleep timer StateFlows and methods to the new holders.
    - Reduced constructor complexity by replacing direct system service dependencies with the new StateHolders.
    - Cleaned up manual `BroadcastReceiver` and callback registrations.
- **Documentation**: Added `PLAYER_VIEW_MODEL_ANALYSIS.md` providing a comprehensive architectural audit and migration plan for further decomposition.
- Decouples `PlayerViewModel` by delegating core responsibilities to specialized state holders: `LibraryStateHolder` for music data management, `MetadataEditStateHolder` for file modifications, and `ExternalMediaStateHolder` for URI-based playback.
- Replaces paginated library song loading with a full-list approach in `LibrarySongsTab` and `LibraryScreen` to improve sorting consistency and UI responsiveness.
- Implements `LibraryStateHolder` to centralize loading, sorting, and state management for songs, albums, artists, and folders.
- Extends `UserPreferencesRepository` and `DailyMixStateHolder` to support persisting and loading "Your Mix" song IDs.
- Enhances `AudioMetadataReader` to extract additional technical metadata including `albumArtist`, `bitrate`, and `sampleRate` using TagLib.
- Adds `getAllSongsOnce()` to `MusicRepository` and `MusicDao` for efficient one-shot retrieval of the entire music library.
- Optimizes `SortOption` by utilizing lazy initialization for static option lists.
- Fixes a potential metadata loss issue in `MetadataEditStateHolder` by explicitly preserving existing embedded artwork during text-only edits.
… item building into specialized components.

- Introduces `PlaybackStateHolder` to centralize playback controls (play/pause, seek, skip), shuffle/repeat logic, and progress tracking.
- Implements `MediaItemBuilder` to unify the creation of `MediaItem` and `MediaMetadata` with consistent extra bundle keys for song metadata.
- Migrates shuffle and queue manipulation logic to `QueueUtils`.
- Refactors `PlayerViewModel` to delegate playback state and control responsibilities to `PlaybackStateHolder`.
- Improves state synchronization between local playback and Cast sessions within the new state holder.
- Cleans up `PlayerViewModel` by removing redundant constants and helper methods now managed by utility classes.
…e media server foreground management.

- **Refactor Cast Logic**:
    - Extracts Cast session management and playback transfer logic from `PlayerViewModel` into a new `CastTransferStateHolder`.
    - Centralizes remote status updates, queue synchronization, and the "transfer back" logic to local playback.
    - Simplifies `PlayerViewModel` by delegating remote playback commands and state observation to the new holder.

- **Enhance Media Server**:
    - Updates `MediaFileHttpServerService` to automatically start as a foreground service with a persistent notification.
    - Adds `foregroundServiceType="mediaPlayback"` to the manifest for the HTTP server to comply with Android's foreground service requirements.

- **Player Engine Robustness**:
    - Introduces an `initialize()` method in `DualPlayerEngine` to safely handle player recreation if the service is restarted.
    - Ensures `MusicService` calls `engine.initialize()` during `onCreate` to guarantee the underlying `ExoPlayer` instances are ready.
    - Adds safety checks in `DualPlayerEngine.release()` to prevent null pointer exceptions on uninitialized players.
…izing logic into dedicated state holders and externalizing data models.

- **Modularize ViewModels**:
    - Moves `PlayerUiState`, `StablePlayerState`, `PlayerSheetState`, `ColorSchemePair`, and `LyricsSearchUiState` into separate files for better maintainability and code organization.
    - Introduces `ThemeStateHolder` to manage album art color extraction, dynamic palette generation, and the "lava lamp" background colors.
    - Relocates genre generation logic and state into `LibraryStateHolder`.
    - Moves repeat mode management and shuffle preparation logic into `PlaybackStateHolder` and `QueueStateHolder` respectively.

- **Enhance Theme Processing**:
    - Implements an asynchronous color scheme extraction flow in `ThemeStateHolder` using a centralized `ColorSchemeProcessor`.
    - Adds `getAlbumColorSchemeFlow()` with LRU caching to efficiently handle per-album color palettes in list views (e.g., `LibraryScreen`).

- **Improve Playback Logic**:
    - Refactors `playSongsShuffled` to use `QueueStateHolder` for Atomic queue preparation, preventing race conditions during shuffle transitions.
    - Centralizes repeat mode updates (Off/One) into `PlaybackStateHolder.setRepeatMode()`, ensuring consistency across local and Cast playback.
    - Automates lyrics sync offset updates in `LyricsStateHolder` by observing song changes within its initialization.

- **UI Refinement**:
    - Updates `LibraryScreen` to utilize the new `ThemeStateHolder` for fetching album-specific color schemes.
    - Cleans up `PlayerViewModel` by removing redundant state variables and delegating implementation details to injected helper classes.
…e holders and helper classes

- Introduces `ImageCacheManager` to centralize Coil image cache invalidation for cover art.
- Introduces `MediaMapper` to handle the conversion of `MediaItem` objects to `Song` models.
- Refactors `PlayerViewModel` by delegating Google Cast discovery and management logic to `CastStateHolder`.
- Enhances `LyricsStateHolder` to manage remote lyrics fetching, manual searching, and file importing, reducing the ViewModel's responsibility.
- Replaces inline MediaRouter callback logic in `PlayerViewModel` with a more robust implementation within `CastStateHolder`.
- Updates `PlayerViewModel` to observe song and message events from `LyricsStateHolder` for UI synchronization.
- Simplifies `resolveSongFromMediaItem` and `invalidateCoverArtCaches` by utilizing the new helper classes.
- Updates `MainActivity` to use real library data instead of dummy data when benchmarking.
- Significantly reduces `PlayerViewModel` complexity by removing unused imports, constants, and private helper functions.
- Streamlines `PlayerViewModel` initialization and data loading by delegating more responsibilities to specialized state holders (e.g., `LibraryStateHolder`, `ThemeStateHolder`).
- Removes redundant or unused state flows like `paginatedSongs`, `isSheetVisible`, and `playerThemePreference`.
- Cleans up playback logic, removing unused methods for repeat modes and redundant queue matching helpers.
- Simplifies theme preloading and library data fetching, utilizing parallel execution via delegated holders.
- Removes manual artwork loading logic in favor of existing infrastructure.
- Deletes dead code related to folder filtering and old benchmark data generation.
@theovilardo theovilardo merged commit 3d85ecc into master Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant