`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.
46 lines
1.9 KiB
TypeScript
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';
|
|
}
|