refactor(artwork): route song own-art through primaryImageTag; align chunk size

Cleanups surfaced by /simplify: the song mapper's own-art branch reimplemented
primaryImageTag's tag+blurhash-map construction (and its one-entry invariant) — route
it through the helper so that invariant lives in one place. Tie artworkChunkSize to a
whole multiple of artworkBatchSize so a cursor page re-chunks into even hydration
batches. Hoist a duplicated imageLoading && blurHash boolean in the album grid.
This commit is contained in:
Deluan 2026-07-24 10:46:59 -04:00
parent f74bf6484e
commit a1eb5e8343
3 changed files with 10 additions and 13 deletions

View File

@ -11,9 +11,9 @@ import (
"github.com/pocketbase/dbx"
)
// artworkChunkSize bounds the id IN-list of each chunk fetch, keeping it under SQLite's bound
// parameter limit.
const artworkChunkSize = 500
// artworkChunkSize bounds each chunk fetch's id IN-list (under SQLite's bound-parameter limit); a
// whole multiple of artworkBatchSize so a page re-chunks into even hydration batches.
const artworkChunkSize = artworkBatchSize * 3
// streamByIDs yields the rows of ids in chunks, fetching each chunk through the caller's hydrating
// fetch. Resolving ids first keeps OFFSET out of the joined query (spec §6).

View File

@ -192,13 +192,11 @@ func SongToBaseItem(mf model.MediaFile, fields Fields) BaseItemDto {
} else if mf.Genre != "" {
item.Genres = []string{mf.Genre}
}
// A track's own cover wins in Finamp's precedence (ImageTags.Primary before AlbumId); emit only
// the matching blurhash, since Go sorts map keys and a second entry could pair the wrong one.
// A track's own cover wins in Finamp's precedence (ImageTags.Primary before AlbumId).
if mf.ImageHash != "" && mf.ImageHash != mf.AlbumImage.ImageHash {
item.ImageTags = map[string]string{"Primary": mf.ImageHash}
if mf.BlurHash != "" {
item.ImageBlurHashes = map[string]map[string]string{"Primary": {mf.ImageHash: mf.BlurHash}}
}
tag, blurs := primaryImageTag(mf.ItemImage, mf.ID)
item.ImageTags = map[string]string{"Primary": tag}
item.ImageBlurHashes = blurs
} else if mf.AlbumID != "" {
if tag, blurs := primaryImageTag(mf.AlbumImage, mf.AlbumID); tag != "" {
item.AlbumPrimaryImageTag = tag

View File

@ -141,11 +141,12 @@ const Cover = withContentRect('bounds')(({
const url = subsonic.getCoverArtUrl(record, config.uiCoverArtSize, true)
const { imgUrl, loading: imageLoading } = useImageUrl(url)
const showBlurHash = imageLoading && record.blurHash
return (
<div ref={measureRef} className={classes.coverContainer}>
<div ref={dragAlbumRef} style={{ position: 'relative' }}>
{imageLoading && record.blurHash && (
{showBlurHash && (
<BlurHashCanvas hash={record.blurHash} className={classes.cover} />
)}
<img
@ -153,9 +154,7 @@ const Cover = withContentRect('bounds')(({
alt={record.name}
className={`${classes.cover} ${imageLoading ? classes.coverLoading : ''}`}
style={
imageLoading && record.blurHash
? { position: 'absolute', left: 0, top: 0 }
: undefined
showBlurHash ? { position: 'absolute', left: 0, top: 0 } : undefined
}
/>
</div>