42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import { skipToken } from '@reduxjs/toolkit/query';
|
|
import { useGetTrackQuery } from '../api/endpoints/library';
|
|
import type { QueueEntry } from '../store/slices/queue';
|
|
|
|
export interface ResolvedQueueEntry {
|
|
trackId: string;
|
|
title: string;
|
|
artistName: string;
|
|
albumTitle: string;
|
|
durationMs: number;
|
|
hasCover: boolean;
|
|
albumArtUrl?: string;
|
|
format?: string;
|
|
}
|
|
|
|
/**
|
|
* Merge a queue entry's play-time snapshot with the live `Track` cache.
|
|
*
|
|
* The queue slice stores denormalized display fields (title/artist/…) captured
|
|
* when a track was queued, so they go stale after metadata enrichment updates
|
|
* the track. This reads through to the RTKQ `Track` cache — invalidated by the
|
|
* same tags that refresh the library — and prefers its fresh values, falling
|
|
* back to the snapshot for instant render and offline. Returns undefined when
|
|
* there is no current entry.
|
|
*/
|
|
export function useResolvedQueueEntry(
|
|
entry: QueueEntry | undefined,
|
|
): ResolvedQueueEntry | undefined {
|
|
const { data } = useGetTrackQuery(entry?.trackId ?? skipToken);
|
|
if (!entry) return undefined;
|
|
return {
|
|
trackId: entry.trackId,
|
|
title: data?.title ?? entry.title,
|
|
artistName: data?.artistName ?? entry.artistName,
|
|
albumTitle: data?.albumTitle ?? entry.albumTitle,
|
|
durationMs: data?.durationMs ?? entry.durationMs,
|
|
hasCover: data?.hasCover ?? false,
|
|
albumArtUrl: data?.albumArtUrl ?? entry.albumArtUrl,
|
|
format: data?.format,
|
|
};
|
|
}
|