Conversation
Implement advanced AI playlist creation and enhance UI/UX across library and search screens
- **AI Playlist Lab**:
- Introduces `CreateAiPlaylistDialog`, a comprehensive tool for generating playlists via Gemini API with controls for mood, activity, era, energy, and discovery levels.
- Implements `PlaylistCreationTypeDialog` to allow users to choose between manual and AI-driven creation flows.
- Adds intelligent AI playlist naming logic in `AiStateHolder` that derives titles from user prompts while avoiding common stop words and ensuring name uniqueness.
- Integrates safety checks to verify Gemini API key availability before enabling AI features.
- **Library & Playlists**:
- Overhauls `LibraryActionRow` to streamline the interface, replacing the separate AI button with a unified "Create" action in the Playlists tab.
- Refactors playlist cover color resolution to use a new `resolvePlaylistCoverContentColor` utility, ensuring optimal contrast against Material 3 color tokens.
- Updates `PlaylistBottomSheet` to support the new dual-creation flow.
- **Search & Navigation**:
- Enhances `SearchScreen` by automatically requesting keyboard focus when the search bar becomes active.
- Refines `PlayerInternalNavigationBar` tap logic to handle double-taps on the Search icon more reliably, even when navigating from other tabs.
- **Artist Metadata**:
- Enhances `ArtistImageRepository` to automatically upgrade Deezer artist image URLs to high-resolution ($1000 \times 1000$) versions.
- Configures `ArtistDetailScreen` to request original image sizes for better visual quality in header sections.
- **Performance & Polish**:
- Optimizes component transitions using `MutableTransitionState` and `AnimatedVisibility` for a more fluid dialog experience.
- Centralizes color contrast logic in `PlaylistCoverColors.kt` for better maintainability across different UI components.
- **Library & Playlists**:
- Adds horizontal padding to the `LibraryActionRow` in `LibraryScreen` for better alignment.
- Updates the "Create playlist" dialog header and description to use the primary color scheme with adjusted opacity for improved visual hierarchy.
- Applies the `UnstableApi` annotation to `PlaylistBottomSheet` to handle Media3 compatibility.
- **UI & Layout**:
- Adjusts vertical spacing between sorting options in `LibrarySortBottomSheet` from `3.dp` to `4.dp`.
- Refines text colors in playlist creation dialogs to ensure consistency with the application's primary theme.
- **Playback & Queue Management**:
- Introduces `reorderQueueInPlace` to efficiently synchronize the `Player` timeline with a desired song order using `moveMediaItem` instead of rebuilding the entire queue.
- Updates `toggleShuffle` logic to prioritize in-place reordering for both enabling and disabling shuffle, ensuring a more seamless transition and maintaining playback state.
- Implements a fallback mechanism to `setMediaItems` if the local queue snapshot becomes desynchronized from the player timeline.
- **UI Refinements**:
- Adjusts the bottom content padding of the `DailyMixScreen` list from `8.dp` to `16.dp` to improve spacing relative to the navigation bar and mini-player.
- **Code Quality**:
- Removes an unused `toImmutableList` import in `PlaybackStateHolder`.
- Adds logging in `PlaybackStateHolder` to track queue size or media ID mismatches during reordering.
…ches
- **Database**:
- Adds `getArtistImageUrlByNormalizedName` and `getArtistIdByNormalizedName` to `MusicDao` to allow looking up artist data using case-insensitive, trimmed name matching.
- **Artist Image Repository**:
- Updates `getArtistImage` to resolve a canonical artist ID by name before checking the database cache, mitigating potential mismatches between MediaStore IDs and local database IDs.
- Improves cache lookup by checking both the resolved ID and the normalized name.
- **Music Repository**:
- Refactors `getArtists` to map artists using normalized names rather than strict IDs when retrieving image URLs from the database.
- Optimizes image prefetching by filtering for missing images based on normalized artist names and using distinct entries to avoid redundant API calls.
- Ensures the prefetch logic uses the resolved database ID for more reliable caching.
…position
- **List Rendering**:
- Removes explicit `key` parameters from `items` and `itemsIndexed` calls across `LibraryScreen` and `LibrarySongsTab` for folders, songs, albums, and artists.
- Simplifies Paging library integration by removing `itemKey` usage in paginated song lists.
- **Scroll Behavior**:
- Removes `LaunchedEffect` logic that automatically scrolled to the top of the list when changing sort options or when the favorite songs list updated.
- **Code Cleanup**:
- Removes unused `itemKey` import from `androidx.paging.compose`.
…rSheet`
- **Queue Interaction & Gestures**:
- Improves fling logic by introducing `queueMinFlingTravelPx` to prevent accidental expansions from small upward flicks.
- Synchronizes `queueSheetOffset` with the hidden state via a `LaunchedEffect` to ensure consistent positioning when the queue is dismissed.
- Refines sheet drag logic to prevent redundant state transitions when dragging upward while already in an expanded state.
- **UI & Visuals**:
- Replaces `AnimatedVisibility` for the queue scrim with a manual `graphicsLayer` alpha implementation for more granular control based on scroll fraction.
- Refactors queue open fraction calculations into `queueVisualOpenFraction`, using screen height and current offset for smoother visual transitions.
- Ensures the queue scrim is only active and visible when the `queueScrimAlpha` is greater than zero.
- **Haptic Feedback Infrastructure**:
- Introduces `AppHapticsConfig` and `LocalAppHapticsConfig` to provide a unified way to manage haptic states via `CompositionLocal`.
- Implements `performAppHapticFeedback` and `performAppCompatHapticFeedback` utility functions that respect the global haptics enabled/disabled setting.
- Updates `MainActivity` to provide a `NoOpHapticFeedback` implementation when haptics are disabled, ensuring consistent behavior across the app.
- Refactors `QueueBottomSheet`, `PlaylistDetailScreen`, and `BrickBreakerOverlay` to use the new centralized haptic utilities for gestures, reordering, and game interactions.
- **Settings UI Reorganization**:
- Moves the "Haptic feedback" setting from the "Player" section to a new "Haptics" subsection within the **Behavior** category.
- Updates the **Behavior** category subtitle to explicitly mention "haptics".
- Refines the layout of the "Folders" subsection in `SettingsCategoryScreen` for better visual consistency.
- **Main Activity & Navigation**:
- Wraps the main `Scaffold` and `AppNavigation` in a `CompositionLocalProvider` to inject haptic configurations.
- Improves the logic for calculating player content corner radii and navigation bar visibility transitions.
Implement core haptic feedback utilities and configuration
- **Haptic Feedback**:
- Introduces `AppHapticsConfig` to manage global haptic settings, including an enablement toggle and reserved intensity scaling.
- Provides `LocalAppHapticsConfig` via `staticCompositionLocalOf` for easy access to haptic settings within the Compose hierarchy.
- Implements `NoOpHapticFeedback` as a fallback mechanism to disable haptics when needed.
- Adds extension and helper functions (`performAppHapticFeedback`, `performAppCompatHapticFeedback`) to execute haptic feedback on Android Views while respecting the global configuration.
…rmat
- **Backup & Restore System**:
- Introduces a new `.pxpl` binary backup format using GZIP compression for more efficient data portability.
- Expands backup coverage to include `Engagement Stats` (play counts) and `Playback History` (listening timeline).
- Refines backup granularity by splitting general preferences into `Global Settings` and `Playlists`.
- Updates `AppDataBackupManager` with a robust progress reporting system and support for legacy JSON backup migration.
- **UI & User Experience**:
- Adds a dedicated "Backup & Restore" category to the Settings screen with a refined visual identity.
- Implements a comprehensive `BackupSectionSelectionDialog` featuring detailed section descriptions, "Select All" actions, and Material 3 expressive components.
- Introduces a `BackupTransferProgressDialog` with animated wavy progress indicators and step-by-step status updates.
- Adds an informational `BackupInfoNoticeCard` to explain the backup process, which can be permanently dismissed by the user.
- **Data & Performance**:
- Optimizes `SettingsViewModel` by consolidating preference collectors and integrating data transfer state management.
- Updates `PlaybackStatsRepository` with specialized methods for exporting and merging sanitized playback events during import/export.
- Adds utility methods to `UserPreferencesRepository` for targeted clearing of preference keys (e.g., clearing settings while preserving playlists).
- **Resources**:
- Adds new vector assets for selection management (`round_select_all_24`, `baseline_deselect_24`).
- **Library Screen**:
- Introduces `CompactLibraryPagerIndicator`, a custom animated dot-style indicator for the library tabs.
- Replaces static spacing with the new pager indicator when the search bar is not active.
- **Playback Tracking & History**:
- Implements `loadPlaybackHistory` in `PlaybackStatsRepository` to retrieve recent events with configurable limits.
- Adds `playbackHistory` state to `ListeningStatsTracker` and `PlayerViewModel`, enabling real-time updates of recently played tracks.
- Updates history tracking logic to prepend new entries and enforce a 500-item internal cache limit.
- **Stats Screen**:
- Refines the layout of the summary cards (Time and Plays) by using `IntrinsicSize.Min` and `fillMaxHeight` to ensure consistent height across the row regardless of content.
- **UI Refinements**:
- Adds an explicit `surface` background color to the scrollable content area in `AlbumDetailScreen` for improved visual layering during nested scrolls.
- **Data Models**:
- Defines `PlaybackHistoryEntry` to standardize the representation of song IDs and timestamps across the stats and tracking layers.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cae8f03e17
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| fun initialize(coroutineScope: CoroutineScope) { | ||
| scope = coroutineScope | ||
| scope?.launch(Dispatchers.IO) { | ||
| _playbackHistory.value = playbackStatsRepository.loadPlaybackHistory( | ||
| limit = MAX_INTERNAL_PLAYBACK_HISTORY_ITEMS | ||
| ) | ||
| } |
There was a problem hiding this comment.
Prevent init load from clobbering new history entries
The async load in initialize() assigns _playbackHistory.value after the IO read completes, which can overwrite entries added by finalizeCurrentSession() if a session ends before the load finishes (e.g., app launch → user plays a track quickly). Because the load runs without checking whether the in-memory list already has newer items, the freshly recorded entry can disappear from the UI until the next session or restart. Consider merging with the current list or only setting when still empty.
Useful? React with 👍 / 👎.
No description provided.