{
const version = ++this.searchVersion;
this.searching = true;
this.errorMessage = '';
this.candidates = [];
this.autoPicked = false;
try {
const result = await downloadStore.start({
libraryId: this.libraryId,
releaseMbid: this.releaseMbid,
releaseGroupMbid: this.releaseGroupMbid,
artist: this.artist,
album: this.album,
query: '',
expected: this.expected ?? [],
} as download.SearchRequest);
if (version !== this.searchVersion) return;
this.downloadId = result.downloadId;
this.candidates = result.candidates ?? [];
this.autoPicked = result.autoPicked;
} catch (err) {
if (version !== this.searchVersion) return;
console.error('download search failed', err);
this.errorMessage = explainError(
err,
'The search did not finish.',
);
} finally {
if (version === this.searchVersion) {
this.searching = false;
}
}
}
private async onPick(event: CustomEvent<{ candidateId: string }>) {
if (this.picking) return;
this.picking = true;
this.errorMessage = '';
try {
await downloadStore.pick(this.downloadId, event.detail.candidateId);
this.close();
} catch (err) {
console.error('download pick failed', err);
this.errorMessage = explainError(
err,
'That download could not be started.',
);
} finally {
this.picking = false;
}
}
private close() {
this.open = false;
this.dispatchEvent(
new CustomEvent('picker-close', { bubbles: true, composed: true }),
);
}
override render() {
return html`
this.close()}
>
${this.album || 'Unknown album'}
${this.artist}
${this.renderBody()}
this.close()}>
Close
`;
}
private renderBody() {
if (this.errorMessage) {
return html`
${this.errorMessage}
`;
}
if (this.searching) {
return html`
Searching your download clients…
`;
}
if (this.autoPicked) {
return html`
Found a clear match and started downloading it. Progress is
on the Downloads page.
`;
}
if (this.candidates.length === 0) {
return html`
Nothing found. Try a different spelling, or connect more
download clients in Settings.
`;
}
return html`
${this.candidates.map(
(candidate, index) => html`
`,
)}
${this.renderFootnote()}
`;
}
private renderFootnote() {
const best = this.candidates[0];
if (!best?.match) return nothing;
// Say plainly why nothing was auto-picked, so the dialog does
// not look like it is asking a question it could have answered.
if (!best.match.anchored) {
return html`
`;
}
return html`
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'download-picker': DownloadPicker;
}
}