Add release date display to AlbumCard overlay

- Add releaseDate prop to AlbumCard component
- Display release date below genre in overlay (format: "Jan 25, 2026")
- Update all AlbumCard usages across views to pass releaseDate:
  - ArtistDetailView (all album sections)
  - HomeView (all featured album sections)
  - SearchView (search results)
  - FavoritesView (favorite albums)
  - LabelView (label albums)
  - AlbumDetailView ("By the same artist" section)
- Add releaseDate to types and adapters
- Skip local library view (VirtualizedAlbumList)
This commit is contained in:
vicrodh committed 2026-01-25 23:47:33 -06:00
1 parent e9e319aa46
commit e9c7e4672c
10 files changed
+73 -6

No files matched your search

+1
View File
@@ -260,6 +260,7 @@ function toArtistAlbumSummary(album: QobuzAlbum): ArtistAlbumSummary {
title: album.title,
artwork,
year: album.release_date_original?.split('-')[0],
releaseDate: album.release_date_original,
quality,
genre: album.genre?.name || "Unknown genre"
};
+37 -2
View File
@@ -15,6 +15,7 @@
title: string;
artist: string;
genre: string;
releaseDate?: string;
quality?: string;
size?: 'standard' | 'large';
searchId?: string;
@@ -40,6 +41,7 @@
title,
artist,
genre,
releaseDate,
quality,
size = 'standard',
searchId,
@@ -90,6 +92,19 @@
imageError = true;
}
function formatReleaseDate(dateStr: string | undefined): string {
if (!dateStr) return '';
const date = new Date(dateStr);
if (isNaN(date.getTime())) return '';
return date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
});
}
const formattedDate = $derived(formatReleaseDate(releaseDate));
async function handleToggleFavorite(event: MouseEvent) {
event.stopPropagation();
if (!albumId || !favoriteAvailable) return;
@@ -184,7 +199,12 @@
<!-- Action Overlay -->
{#if hasOverlay}
<div class="action-overlay" class:menu-open={menuOpen}>
<div class="overlay-genre">{genre}</div>
<div class="overlay-info">
<span class="overlay-genre">{genre}</span>
{#if formattedDate}
<span class="overlay-date">{formattedDate}</span>
{/if}
</div>
<div class="action-buttons">
{#if showFavoriteButton}
<button
@@ -393,15 +413,30 @@
height: 30px;
}
.overlay-genre {
.overlay-info {
align-self: flex-start;
width: 100%;
text-align: left;
padding: 14px 14px;
display: flex;
flex-direction: column;
gap: 4px;
}
.overlay-genre {
font-size: 14px;
font-weight: 600;
color: white;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
word-wrap: break-word;
overflow-wrap: break-word;
}
.overlay-date {
font-size: 12px;
font-weight: 400;
color: rgba(255, 255, 255, 0.85);
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}
:global(.album-card .album-menu) {
@@ -33,6 +33,7 @@
artwork: string;
quality: string;
genre: string;
releaseDate?: string;
}
interface Props {
@@ -485,6 +486,7 @@
title={relatedAlbum.title}
artist={album.artist}
genre={relatedAlbum.genre}
releaseDate={relatedAlbum.releaseDate}
size="large"
quality={relatedAlbum.quality}
onclick={() => onRelatedAlbumClick?.(relatedAlbum.id)}
@@ -1519,6 +1519,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1581,6 +1582,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1642,6 +1644,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1703,6 +1706,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1764,6 +1768,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1888,6 +1893,7 @@
title={album.title}
artist={album.year || ''}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
searchId={`album-${album.id}`}
@@ -1301,6 +1301,7 @@
title={album.title}
artist={album.artist.name}
genre={getGenreLabel(album)}
releaseDate={album.release_date_original}
size="large"
quality={getQualityLabel(album)}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -1374,6 +1375,7 @@
title={album.title}
artist={album.artist.name}
genre={getGenreLabel(album)}
releaseDate={album.release_date_original}
size="large"
quality={getQualityLabel(album)}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
+10 -1
View File
@@ -38,6 +38,7 @@
artist: string;
genre: string;
quality?: string;
releaseDate?: string;
}
interface ArtistCardData {
@@ -334,7 +335,8 @@
title: album.title,
artist: album.artist?.name || 'Unknown Artist',
genre: album.genre?.name || 'Unknown genre',
quality: formatQuality(album.hires_streamable, album.maximum_bit_depth, album.maximum_sampling_rate)
quality: formatQuality(album.hires_streamable, album.maximum_bit_depth, album.maximum_sampling_rate),
releaseDate: album.release_date_original
};
}
@@ -647,6 +649,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -678,6 +681,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -709,6 +713,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -740,6 +745,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -771,6 +777,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -802,6 +809,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -904,6 +912,7 @@
title={album.title}
artist={album.artist}
genre={album.genre}
releaseDate={album.releaseDate}
size="large"
quality={album.quality}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -278,6 +278,7 @@
title={album.title}
artist={album.artist?.name || 'Unknown Artist'}
genre={getGenreLabel(album)}
releaseDate={album.release_date_original}
quality={getQualityLabel(album)}
size="large"
onclick={() => onAlbumClick?.(album.id)}
@@ -726,6 +726,7 @@
title={allResults.albums.items[0].title}
artist={allResults.albums.items[0].artist?.name || 'Unknown Artist'}
genre={getGenreLabel(allResults.albums.items[0])}
releaseDate={allResults.albums.items[0].release_date_original}
size="large"
quality={getQualityLabel(allResults.albums.items[0])}
onPlay={onAlbumPlay ? () => onAlbumPlay(allResults.albums.items[0].id) : undefined}
@@ -863,6 +864,7 @@
title={album.title}
artist={album.artist?.name || 'Unknown Artist'}
genre={getGenreLabel(album)}
releaseDate={album.release_date_original}
size="large"
quality={getQualityLabel(album)}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
@@ -1003,6 +1005,7 @@
title={album.title}
artist={album.artist?.name || 'Unknown Artist'}
genre={getGenreLabel(album)}
releaseDate={album.release_date_original}
size="large"
quality={getQualityLabel(album)}
onPlay={onAlbumPlay ? () => onAlbumPlay(album.id) : undefined}
+6
View File
@@ -188,6 +188,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
@@ -196,6 +197,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
@@ -204,6 +206,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
@@ -212,6 +215,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
@@ -220,6 +224,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
@@ -228,6 +233,7 @@ export interface ArtistDetail {
title: string;
artwork: string;
year?: string;
releaseDate?: string;
quality: string;
genre: string;
}[];
+5 -3
View File
@@ -335,7 +335,7 @@
let isArtistAlbumsLoading = $state(false);
// Artist albums for "By the same artist" section in album view
let albumArtistAlbums = $state<{ id: string; title: string; artwork: string; quality: string; genre: string }[]>([]);
let albumArtistAlbums = $state<{ id: string; title: string; artwork: string; quality: string; genre: string; releaseDate?: string }[]>([]);
// Overlay States (from uiStore subscription)
let isQueueOpen = $state(false);
@@ -456,14 +456,16 @@
title: a.title,
artwork: a.artwork,
quality: a.quality,
genre: a.genre
genre: a.genre,
releaseDate: a.releaseDate
})),
...artistDetail.liveAlbums.map(a => ({
id: a.id,
title: a.title,
artwork: a.artwork,
quality: a.quality,
genre: a.genre
genre: a.genre,
releaseDate: a.releaseDate
}))
].slice(0, 16);