feat: matchedAlbum on item detail, onLoan collection filter
This commit is contained in:
@@ -62,3 +62,37 @@ export function resolveRipStatusBatch(
|
||||
return albumKeys.has(key) ? 'ripped' : 'not_ripped'
|
||||
})
|
||||
}
|
||||
|
||||
export interface MatchedAlbum {
|
||||
id: number
|
||||
subsonicId: string
|
||||
lastPlayedAt: string | null
|
||||
}
|
||||
|
||||
/** Album behind an item's rip match — link wins, else confident fuzzy match. Independent of rip_override. */
|
||||
export function findMatchedAlbum(db: DB, userId: number, itemId: number): MatchedAlbum | null {
|
||||
const item = db
|
||||
.prepare('SELECT id, title, artist FROM collection_items WHERE id = ? AND user_id = ?')
|
||||
.get(itemId, userId) as { id: number; title: string; artist: string } | undefined
|
||||
if (!item) return null
|
||||
|
||||
const link = db
|
||||
.prepare(
|
||||
`SELECT da.id, da.subsonic_id, da.last_played_at FROM match_links ml
|
||||
JOIN digital_albums da ON da.id = ml.album_id WHERE ml.item_id = ?`
|
||||
)
|
||||
.get(itemId) as { id: number; subsonic_id: string; last_played_at: string | null } | undefined
|
||||
if (link) {
|
||||
return { id: link.id, subsonicId: link.subsonic_id, lastPlayedAt: link.last_played_at }
|
||||
}
|
||||
|
||||
const album = db
|
||||
.prepare(
|
||||
`SELECT id, subsonic_id, last_played_at, title, artist FROM digital_albums WHERE user_id = ?`
|
||||
)
|
||||
.all(userId) as { id: number; subsonic_id: string; last_played_at: string | null; title: string; artist: string }[]
|
||||
const match = album.find((a) => isConfidentMatch(item, a))
|
||||
return match
|
||||
? { id: match.id, subsonicId: match.subsonic_id, lastPlayedAt: match.last_played_at }
|
||||
: null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user