`;
}
/**
* Subscribes to an artist: their new releases go on the requests
* list as they come out.
*
* The default is new releases only. Following an artist should not
* silently queue forty albums — someone who wants the back
* catalogue can widen it from the requests list, and will not be
* surprised by having done so.
*/
private renderFollowAction() {
if (!this.artistMBID) return nothing;
const request = downloadStore.requestFor(this.artistMBID);
return html`
void this.toggleFollow(request?.id)}
>
${request ? 'Following' : 'Follow for new releases'}
`;
}
private async toggleFollow(requestId: number | undefined): Promise {
if (!this.artistMBID) return;
try {
if (requestId) {
await downloadStore.removeRequest(requestId);
} else {
const libraryId = await libraryStore.getDefaultLibraryId();
if (!libraryId) {
console.error('Could not update the requests list: no library available');
return;
}
await downloadStore.addRequest({
mbid: this.artistMBID,
entity: 'artist',
libraryId,
artist: this.displayName,
title: this.displayName,
scope: 'future',
secondary: false,
} as never);
}
} catch (err) {
console.error('Could not update the requests list:', err);
}
this.requestUpdate();
}
private renderArtistMeta() {
if (this.loadingArtist) {
return html`Loading\u2026`;
}
if (this.errorArtist) {
return html`${this.errorArtist}`;
}
if (!this.artist) return nothing;
const parts: string[] = [];
if (this.artist.type) parts.push(this.artist.type);
if (this.artist.country) parts.push(this.artist.country);
if (this.artist.disambiguation) parts.push(this.artist.disambiguation);
if (parts.length === 0) return nothing;
return html`
${parts.map(
(p, i) =>
html`${i > 0
? html`\u00B7`
: nothing}${p}`,
)}
`;
}
/* ── Top Section (tracks + releases side-by-side) ── */
/** Shared toggle (wide mode) — expands both at once. */
private toggleTopSection() {
const next = !(this.topTracksExpanded && this.topReleasesExpanded);
this.topTracksExpanded = next;
this.topReleasesExpanded = next;
}
/** Per-column toggle (narrow/stacked mode). */
private toggleTopTracks() {
this.topTracksExpanded = !this.topTracksExpanded;
}
private toggleTopReleases() {
this.topReleasesExpanded = !this.topReleasesExpanded;
}
private toggleDiscoGroup(type: string) {
const next = new Set(this.expandedDiscoGroups);
if (next.has(type)) {
next.delete(type);
} else {
next.add(type);
}
this.expandedDiscoGroups = next;
}
private renderTopSection() {
const hasTracks = !this.loadingTracks && this.topTracks.length > 0;
const hasReleases = !this.loadingTopReleases && this.topReleaseGroups.length > 0;
const tracksLoading = this.loadingTracks;
const releasesLoading = this.loadingTopReleases;
// Both still loading — show single loading state.
if (tracksLoading && releasesLoading) {
return html`