diff --git a/frontend/src/components/search-bar/search-bar.ts b/frontend/src/components/search-bar/search-bar.ts index 769491c..f06a5dd 100644 --- a/frontend/src/components/search-bar/search-bar.ts +++ b/frontend/src/components/search-bar/search-bar.ts @@ -10,6 +10,7 @@ import '@awesome.me/webawesome/dist/components/icon/icon.js'; @customElement('search-bar') export class SearchBar extends LitElement { private searchCtrl = new SearchController(this); + private searchDebounceTimer: ReturnType | null = null; @query('input') private inputEl!: HTMLInputElement; @@ -105,7 +106,22 @@ export class SearchBar extends LitElement { private handleInput = (e: Event) => { const input = e.target as HTMLInputElement; - this.searchCtrl.term = input.value; + const value = input.value; + + if (this.searchDebounceTimer !== null) { + clearTimeout(this.searchDebounceTimer); + this.searchDebounceTimer = null; + } + + if (value === '') { + // Instant clear for responsive feedback. + this.searchCtrl.term = ''; + } else { + this.searchDebounceTimer = setTimeout(() => { + this.searchDebounceTimer = null; + this.searchCtrl.term = value; + }, 150); + } }; private handleClear = () => { diff --git a/frontend/src/store/library-store.ts b/frontend/src/store/library-store.ts index 4f7f363..88a8c3e 100644 --- a/frontend/src/store/library-store.ts +++ b/frontend/src/store/library-store.ts @@ -46,6 +46,7 @@ class LibraryStore { }; private subscribers = new Set(); + private notifyScheduled = false; constructor() { EventsOn(Events.LibraryScanComplete, () => { @@ -340,7 +341,12 @@ class LibraryStore { } private notify(): void { - this.subscribers.forEach((callback) => callback()); + if (this.notifyScheduled) return; + this.notifyScheduled = true; + queueMicrotask(() => { + this.notifyScheduled = false; + this.subscribers.forEach((callback) => callback()); + }); } // ===================================================================