Files
yellowjacket/frontend/src/utils/library-status.ts
T
logan 451b46e63c fix(explore): show a requested album as queued, not absent
`library-status-indicator` has had three states since it was written
and produced two: all eight call sites were a two-way ternary between
`in-library` and `not-in-library`, so the `queued` state it styles and
labels was unreachable.

The result was the app contradicting itself on one page. An album added
to the request list showed a plus and announced "is not in your
library", forty pixels from a filled button reading "Wanted".

The rule was written at eight places, which is why none of them had all
of it, so it is `utils/library-status.ts` now: owning outranks wanting,
a satisfied request is not queued, and a request is by MBID — a track
inside a requested album is not itself requested and still says so.

`explore-view` gains the `downloadStore` subscription both detail views
already had, registered `whileActive` because it is a cached view that
never unmounts. `top-results-row` needs its own: its host re-rendering
sets the same `results` array back, so Lit stops at the property and
the row never hears about a change.
2026-08-13 14:13:30 -04:00

46 lines
1.9 KiB
TypeScript

import { downloadStore } from '@store/download-store';
import type { LibraryStatus } from '../components/library-status-indicator/library-status-indicator';
/**
* What the tick/hourglass/plus badge should say about one entity.
*
* This exists because the rule was written at all eight call sites and
* so none of them had the whole of it: every one was a two-way ternary
* between `in-library` and `not-in-library`, and the badge's third
* state — `queued`, styled and labelled since it was written — was
* produced by nothing. An album the user had already asked for through
* the "Want this" button showed a plus and said it was not in their
* library, on the same page, forty pixels from a filled button reading
* "Wanted".
*
* Two rules decide the answer, and both are about honesty rather than
* precedence for its own sake:
*
* - **Owning outranks wanting.** A request that has been satisfied by
* any route — downloaded here, ripped, bought elsewhere — is not
* news; what the user has is.
* - **A request is by MBID, and the badge answers about the entity it
* is on.** A track inside a requested album is not itself requested,
* so it stays a plus. Saying otherwise would promise that clicking
* it later would find *that* recording.
*
* A `satisfied` request is deliberately not `queued`: nothing is coming.
* A `paused` one is, because the user did ask for it and it is still on
* the list — "queued" is a slight overstatement of a paused request and
* a much smaller one than "not in your library".
*/
export function libraryStatusFor(
owned: boolean,
mbid?: string | null,
): LibraryStatus {
if (owned) return 'in-library';
if (!mbid) return 'not-in-library';
const request = downloadStore.requestFor(mbid);
if (request && request.state !== 'satisfied') return 'queued';
return 'not-in-library';
}