diff --git a/UI/Web/src/app/_services/search.service.ts b/UI/Web/src/app/_services/search.service.ts index e995063ea..e166b1d43 100644 --- a/UI/Web/src/app/_services/search.service.ts +++ b/UI/Web/src/app/_services/search.service.ts @@ -1,6 +1,5 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Subject } from '@microsoft/signalr'; import { distinctUntilChanged, filter, map, Observable, of, ReplaySubject, startWith, switchMap } from 'rxjs'; import { environment } from 'src/environments/environment'; import { SearchResultGroup } from '../_models/search/search-result-group'; @@ -13,27 +12,23 @@ export class SearchService { baseUrl = environment.apiUrl; - private searchSubject: ReplaySubject = new ReplaySubject(); + private searchSubject: ReplaySubject = new ReplaySubject(1); searchResults$: Observable; constructor(private httpClient: HttpClient) { this.searchResults$ = this.searchSubject.pipe( startWith(''), map(val => val.trim()), - filter(term => term !== '' && term !== null && term !== undefined), distinctUntilChanged(), switchMap(term => { - return this.httpClient.get(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term)); + if (term === '' || term === null || term === undefined) return of(new SearchResultGroup()); + return this.httpClient.get(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term)) }) ); } search(term: string) { this.searchSubject.next(term); - if (term === '') { - return of(new SearchResultGroup()); - } - return this.httpClient.get(this.baseUrl + 'search/search?queryString=' + encodeURIComponent(term)); } getSeriesForMangaFile(mangaFileId: number) { diff --git a/UI/Web/src/app/cards/edit-series-relation/edit-series-relation.component.ts b/UI/Web/src/app/cards/edit-series-relation/edit-series-relation.component.ts index d44f5535a..d30d38ee4 100644 --- a/UI/Web/src/app/cards/edit-series-relation/edit-series-relation.component.ts +++ b/UI/Web/src/app/cards/edit-series-relation/edit-series-relation.component.ts @@ -129,11 +129,14 @@ export class EditSeriesRelationComponent implements OnInit, OnDestroy { seriesSettings.id = 'relation--' + index; seriesSettings.unique = true; seriesSettings.addIfNonExisting = false; - seriesSettings.fetchFn = (searchFilter: string) => this.searchService.search(searchFilter).pipe( - map(group => group.series), - map(items => seriesSettings.compareFn(items, searchFilter)), - map(series => series.filter(s => s.seriesId !== this.series.id)), - ); + seriesSettings.fetchFn = (searchFilter: string) => { + this.searchService.search(searchFilter); + return this.searchService.searchResults$.pipe( + map(group => group.series), + map(items => seriesSettings.compareFn(items, searchFilter)), + map(series => series.filter(s => s.seriesId !== this.series.id)), + ); + } seriesSettings.compareFn = (options: SearchResult[], filter: string) => { return options.filter(m => this.utilityService.filter(m.name, filter)); @@ -144,7 +147,8 @@ export class EditSeriesRelationComponent implements OnInit, OnDestroy { } if (series !== undefined) { - return this.searchService.search(series.name).pipe( + this.searchService.search(series.name) + return this.searchService.searchResults$.pipe( map(group => group.series), map(results => { seriesSettings.savedData = results.filter(s => s.seriesId === series.id); return seriesSettings; diff --git a/UI/Web/src/app/nav/nav-header/nav-header.component.html b/UI/Web/src/app/nav/nav-header/nav-header.component.html index 671283630..1bc715340 100644 --- a/UI/Web/src/app/nav/nav-header/nav-header.component.html +++ b/UI/Web/src/app/nav/nav-header/nav-header.component.html @@ -192,7 +192,7 @@ NZ0ZV4zm4/L1dfnYNCrjTFq9G03rmj5D+Y4i0OHuL3GFPJytaM54AAAAAElFTkSuQmCC [minQueryLength]="2" initialValue="" placeholder="Search…" - [grouppedData]="(searchService.searchResults$ | async) || searchResults" + [grouppedData]="(search$ | async) || emptyResult" (inputChanged)="onChangeSearch($event)" (clearField)="clearSearch()" (focusChanged)="focusUpdate($event)" diff --git a/UI/Web/src/app/nav/nav-header/nav-header.component.ts b/UI/Web/src/app/nav/nav-header/nav-header.component.ts index 8a8967fab..9bcfcbde0 100644 --- a/UI/Web/src/app/nav/nav-header/nav-header.component.ts +++ b/UI/Web/src/app/nav/nav-header/nav-header.component.ts @@ -1,8 +1,8 @@ import { DOCUMENT } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { NavigationEnd, Router } from '@angular/router'; -import { fromEvent, Subject } from 'rxjs'; -import { debounceTime, distinctUntilChanged, filter, takeUntil, tap } from 'rxjs/operators'; +import { fromEvent, Observable, of, Subject } from 'rxjs'; +import { catchError, debounceTime, distinctUntilChanged, filter, startWith, takeUntil, tap } from 'rxjs/operators'; import { Chapter } from 'src/app/_models/chapter'; import { MangaFile } from 'src/app/_models/manga-file'; import { ScrollService } from 'src/app/_services/scroll.service'; @@ -31,7 +31,8 @@ export class NavHeaderComponent implements OnInit, OnDestroy { isLoading = false; debounceTime = 300; imageStyles = {width: '24px', 'margin-top': '5px'}; - searchResults: SearchResultGroup = new SearchResultGroup(); + emptyResult: SearchResultGroup = new SearchResultGroup(); + search$!: Observable; searchTerm = ''; customFilter: (items: SearchResult[], query: string) => SearchResult[] = (items: SearchResult[], query: string) => { const normalizedQuery = query.trim().toLowerCase(); @@ -54,6 +55,21 @@ export class NavHeaderComponent implements OnInit, OnDestroy { public imageService: ImageService, @Inject(DOCUMENT) private document: Document, private scrollService: ScrollService, public searchService: SearchService, private readonly cdRef: ChangeDetectorRef) { this.scrollElem = this.document.body; + + this.search$ = this.searchService.searchResults$.pipe( + startWith(new SearchResultGroup()), + takeUntil(this.onDestroy), + tap((_) => { + this.isLoading = false; + this.cdRef.markForCheck(); + }), + catchError(() => { + this.isLoading = false; + this.searchTerm = ''; + this.cdRef.markForCheck(); + return of(); + }) + ); } ngOnInit(): void { @@ -107,20 +123,8 @@ export class NavHeaderComponent implements OnInit, OnDestroy { onChangeSearch(val: string) { this.isLoading = true; this.searchTerm = val.trim(); - this.cdRef.markForCheck(); - - this.searchService.search(val.trim()); - - this.searchService.search(val.trim()).pipe(takeUntil(this.onDestroy)).subscribe((results: SearchResultGroup) => { - //this.searchResults = results; - this.isLoading = false; - this.cdRef.markForCheck(); - }, err => { - this.searchResults.reset(); - this.isLoading = false; - this.searchTerm = ''; - this.cdRef.markForCheck(); - }); + this.searchService.search(val); + this.cdRef.markForCheck(); } goTo(queryParamName: string, filter: any) { @@ -173,7 +177,7 @@ export class NavHeaderComponent implements OnInit, OnDestroy { clearSearch() { this.searchViewRef.clear(); this.searchTerm = ''; - this.searchResults = new SearchResultGroup(); + this.searchService.search(''); this.cdRef.markForCheck(); }