feat: min 2-char query gate, result caps at 10 per section
Don't fire search for single-character queries — show 'Keep typing…' instead. Cap rendered results at 10 per section (artists, albums, tracks) to reduce noise. Top results already capped at 3.
This commit is contained in:
@@ -12,6 +12,8 @@ import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
|||||||
|
|
||||||
/* ── Constants ── */
|
/* ── Constants ── */
|
||||||
const DEBOUNCE_MS = 300;
|
const DEBOUNCE_MS = 300;
|
||||||
|
const MIN_QUERY_LENGTH = 2;
|
||||||
|
const MAX_SECTION_RESULTS = 10;
|
||||||
const CAA_GROUP_BASE = 'https://coverartarchive.org/release-group';
|
const CAA_GROUP_BASE = 'https://coverartarchive.org/release-group';
|
||||||
const TOP_RESULTS_COUNT = 3;
|
const TOP_RESULTS_COUNT = 3;
|
||||||
|
|
||||||
@@ -67,6 +69,7 @@ export class ExploreView extends LitElement {
|
|||||||
@state() private results: MBSearchResult | null = null;
|
@state() private results: MBSearchResult | null = null;
|
||||||
@state() private loading = false;
|
@state() private loading = false;
|
||||||
@state() private error = '';
|
@state() private error = '';
|
||||||
|
@state() private queryTooShort = false;
|
||||||
|
|
||||||
/** Monotonic counter to discard stale responses. */
|
/** Monotonic counter to discard stale responses. */
|
||||||
private searchVersion = 0;
|
private searchVersion = 0;
|
||||||
@@ -481,13 +484,26 @@ export class ExploreView extends LitElement {
|
|||||||
this.debounceTimer = null;
|
this.debounceTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.searchQuery.trim()) {
|
const trimmed = this.searchQuery.trim();
|
||||||
|
|
||||||
|
if (!trimmed) {
|
||||||
this.results = null;
|
this.results = null;
|
||||||
this.error = '';
|
this.error = '';
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.queryTooShort = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (trimmed.length < MIN_QUERY_LENGTH) {
|
||||||
|
this.results = null;
|
||||||
|
this.error = '';
|
||||||
|
this.loading = false;
|
||||||
|
this.queryTooShort = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.queryTooShort = false;
|
||||||
|
|
||||||
this.debounceTimer = setTimeout(() => {
|
this.debounceTimer = setTimeout(() => {
|
||||||
this.debounceTimer = null;
|
this.debounceTimer = null;
|
||||||
void this.executeSearch();
|
void this.executeSearch();
|
||||||
@@ -499,6 +515,7 @@ export class ExploreView extends LitElement {
|
|||||||
this.results = null;
|
this.results = null;
|
||||||
this.error = '';
|
this.error = '';
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.queryTooShort = false;
|
||||||
if (this.debounceTimer !== null) {
|
if (this.debounceTimer !== null) {
|
||||||
clearTimeout(this.debounceTimer);
|
clearTimeout(this.debounceTimer);
|
||||||
this.debounceTimer = null;
|
this.debounceTimer = null;
|
||||||
@@ -666,6 +683,13 @@ export class ExploreView extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderBody() {
|
private renderBody() {
|
||||||
|
// Query too short
|
||||||
|
if (this.queryTooShort) {
|
||||||
|
return html`<div class="status-message">
|
||||||
|
Keep typing\u2026
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
// No query entered yet
|
// No query entered yet
|
||||||
if (!this.searchQuery.trim() && !this.results) {
|
if (!this.searchQuery.trim() && !this.results) {
|
||||||
return html`<div class="status-message">
|
return html`<div class="status-message">
|
||||||
@@ -696,13 +720,13 @@ export class ExploreView extends LitElement {
|
|||||||
? this.renderTopResults(topResults)
|
? this.renderTopResults(topResults)
|
||||||
: nothing}
|
: nothing}
|
||||||
${hasArtists
|
${hasArtists
|
||||||
? this.renderArtistsSection(this.results.artists!)
|
? this.renderArtistsSection(this.results.artists!.slice(0, MAX_SECTION_RESULTS))
|
||||||
: nothing}
|
: nothing}
|
||||||
${hasAlbums
|
${hasAlbums
|
||||||
? this.renderAlbumsSection(this.results.releaseGroups!)
|
? this.renderAlbumsSection(this.results.releaseGroups!.slice(0, MAX_SECTION_RESULTS))
|
||||||
: nothing}
|
: nothing}
|
||||||
${hasTracks
|
${hasTracks
|
||||||
? this.renderTracksSection(this.results.recordings!)
|
? this.renderTracksSection(this.results.recordings!.slice(0, MAX_SECTION_RESULTS))
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user