Skip to content

feat(ui): add smooth image transitions to album, artist, and playlist covers #4120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2025

Conversation

deluan
Copy link
Member

@deluan deluan commented May 26, 2025

Summary

This PR enhances the user experience by adding smooth loading transitions to cover art images across the application, including albums, artists, and playlists.

Changes Made

Image Transition Effects

  • AlbumGridView: Added smooth opacity transitions (0.3s ease-in-out) for album covers in grid view
  • AlbumDetails: Enhanced album cover display with loading states and error handling
  • ArtistDetails (Desktop & Mobile): Improved artist image display with proper loading transitions
  • PlaylistDetails: Added playlist cover art support with smooth transitions

Technical Improvements

  • Loading States: Images show 50% opacity while loading, then transition to full opacity
  • Error Handling: Proper error handling prevents lightbox opening on failed image loads
  • Cache Management: Force re-rendering when records change using key props
  • Layout Stability: Reserved space for images to prevent layout shifts

API Updates

  • Subsonic Client: Updated getCoverArtUrl to support playlists using sync property
  • Playlist Support: Added proper playlist cover art URL generation with pl- prefix

Testing

  • Comprehensive Tests: Added tests for playlist cover art URL generation
  • Error Scenarios: Tests cover both success and error cases
  • Cache Busting: Tests verify proper timestamp handling for playlists

User Experience

  • Smooth Transitions: All cover art now loads with elegant fade-in effects
  • Visual Feedback: Loading states provide clear visual feedback to users
  • Consistent Behavior: Same transition effects applied across all image displays
  • No Layout Shifts: Images reserve space to prevent content jumping

Technical Details

  • Uses CSS opacity transitions with 0.3s ease-in-out timing
  • Loading state shows opacity: 0.5 for visual feedback
  • Error handling prevents broken image interactions
  • Key props ensure proper re-rendering when switching between records

All tests pass and the implementation maintains backward compatibility while significantly improving the visual polish of the application.

…and transitions

Signed-off-by: Deluan <deluan@navidrome.org>
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @deluan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

Summary of Changes

Hello team, Gemini here with a summary of this pull request. This PR aims to significantly enhance the user experience by implementing smooth loading transitions for cover art images across the application, specifically for albums, artists, and playlists. The changes introduce visual feedback during image loading, prevent layout shifts, and improve error handling for images, ensuring a more polished and consistent look and feel.

Highlights

  • Smooth Image Transitions: Implemented smooth opacity transitions (0.3s ease-in-out) for cover art images in Album Details, Album Grid View, and both Desktop and Mobile Artist Details views.
  • Loading and Error States: Added visual feedback for image loading (50% opacity) and proper error handling to prevent interactions like opening a lightbox on failed image loads. The cursor changes to 'default' on error.
  • Playlist Cover Art Support: Updated the Subsonic client logic to correctly identify playlists using the sync property (instead of songCount) and generate the appropriate cover art URL with the pl- prefix. The timestamp parameter previously added for playlists has been removed.
  • Layout Stability and Cache Management: Ensured reserved space for images in relevant components to prevent layout shifts. Added key props to image elements to force re-rendering and proper state reset when navigating between different records (albums, artists).
  • Test Updates: Updated unit tests for the Subsonic client's getCoverArtUrl function to reflect the changes in playlist identification (sync property) and the removal of the timestamp parameter, while also adding checks for size and square parameters.

Changelog

Click here to see the changelog
  • ui/src/album/AlbumDetails.jsx
    • Added CSS classes coverLoading and styles for smooth opacity transition and loading state (opacity 0.5).
    • Introduced imageLoading and imageError state variables.
    • Added useEffect to reset image state (imageLoading, imageError) when the album record changes.
    • Implemented onLoad and onError handlers for the CardMedia component to update image state.
    • Conditionally applied the coverLoading class based on imageLoading state.
    • Added key={record.id} to CardMedia to force re-render on album change.
    • Modified handleOpenLightbox to only open if !imageError.
    • Updated the Lightbox rendering condition to include !imageError.
    • Added style to change cursor to 'default' on image error.
    • Added flexbox and centering styles to the cover parent container.
  • ui/src/album/AlbumGridView.jsx
    • Added CSS classes coverLoading and styles for smooth opacity transition and loading state (opacity 0.5).
    • Introduced imageLoading and imageError state variables.
    • Added useEffect to reset image state when the record changes.
    • Implemented onLoad and onError handlers for the img element.
    • Conditionally applied the coverLoading class based on imageLoading state.
    • Added key={record.id} to the img element to force re-render on record change.
  • ui/src/artist/DesktopArtistDetails.jsx
    • Added CSS classes coverLoading and styles for smooth opacity transition and loading state (opacity 0.5).
    • Added minWidth, minHeight, width, height and flexbox/centering styles to the artist image container for layout stability.
    • Introduced imageLoading and imageError state variables.
    • Added useEffect to reset image state when the artist record changes.
    • Implemented onLoad and onError handlers for the CardMedia component.
    • Conditionally applied the coverLoading class based on imageLoading state.
    • Added key={record.id} to CardMedia to force re-render on artist change.
    • Modified handleOpenLightbox to only open if !imageError.
    • Updated the Lightbox rendering condition to include !imageError.
    • Added style to change cursor to 'default' on image error.
  • ui/src/artist/MobileArtistDetails.jsx
    • Added CSS classes coverLoading and styles for smooth opacity transition and loading state (opacity 0.5).
    • Added backgroundColor, transition, and objectFit styles to the cover image.
    • Introduced imageLoading and imageError state variables.
    • Added useEffect to reset image state when the artist record changes.
    • Implemented onLoad and onError handlers for the CardMedia component.
    • Conditionally applied the coverLoading class based on imageLoading state.
    • Added key={record.id} to CardMedia to force re-render on artist change.
    • Modified handleOpenLightbox to only open if !imageError.
    • Updated the Lightbox rendering condition to include !imageError.
    • Added style to change cursor to 'default' on image error.
  • ui/src/subsonic/index.js
    • Changed playlist identification logic in getCoverArtUrl from checking songCount to checking the sync property.
    • Removed the logic that added a timestamp (_) query parameter to playlist cover art URLs.
  • ui/src/subsonic/index.test.js
    • Updated tests for getCoverArtUrl to use the sync property for identifying playlists.
    • Removed the expectation for the timestamp (_) query parameter in playlist URL tests.
    • Updated tests for album, song (media file), and artist cover art URLs to include checks for size and square parameters.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.


Images appear,
Softly fading, smooth and clear,
No more sudden pop.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces smooth image loading transitions for album, artist, and playlist covers, significantly enhancing the visual polish and user experience. The implementation of loading states, error handling, and opacity transitions in the UI components is well-executed and consistent.

The API updates to getCoverArtUrl for playlists and the corresponding test changes are noted. Overall, a solid improvement to the UI.

Summary of Findings

  • Potential Cache Stale Issue for Playlist Covers: The removal of the fallback cache-busting mechanism (_ = new Date().getTime()) for playlist cover art URLs when updatedAt is not present might lead to users seeing stale images if a playlist cover changes on the server but its ID and updatedAt field (if missing) remain unchanged. This was observed in ui/src/subsonic/index.js and confirmed by changes in ui/src/subsonic/index.test.js.
  • UI Enhancements: The introduction of smooth transitions, loading states, and error handling for images across various views (album, artist, playlist) is a significant UX improvement and has been implemented consistently.
  • API Client Update: The getCoverArtUrl function was updated to use the sync property for identifying playlists, which aligns better with the data model.

Merge Readiness

The pull request brings valuable UI improvements with smooth image transitions. The implementation of these visual enhancements is well done.

However, there's a concern regarding a change in the cache-busting strategy for playlist cover art when the updatedAt field is not available. This could potentially lead to stale images being displayed. I've raised this as a medium severity issue in the review comments for ui/src/subsonic/index.js and its corresponding test file.

I recommend clarifying the intent behind this change or addressing the potential for stale cached images before merging. As a reviewer, I am not authorized to approve pull requests, but based on this review, I suggest further discussion or changes related to the cache-busting behavior.

@deluan deluan merged commit d26e2e2 into master May 26, 2025
20 checks passed
@deluan deluan deleted the album-artist-image-transitions branch May 26, 2025 12:57
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