diff --git a/src/app/browse/browse.component.html b/src/app/browse/browse.component.html index db3cea1..8ce4eea 100644 --- a/src/app/browse/browse.component.html +++ b/src/app/browse/browse.component.html @@ -29,8 +29,18 @@ + + + + + + + + @for (sortGroupOrType of displaySortGroups; track sortGroupOrType) { diff --git a/src/app/browse/browse.component.ts b/src/app/browse/browse.component.ts index 88c9911..4bbc809 100644 --- a/src/app/browse/browse.component.ts +++ b/src/app/browse/browse.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, AfterViewInit, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; import { SearchService } from '../search.service'; import { HydrusFilesService } from '../hydrus-files.service'; -import { BehaviorSubject, catchError, combineLatest, filter, map, Observable, of, shareReplay, Subject, switchMap, tap } from 'rxjs'; +import { BehaviorSubject, catchError, combineLatest, filter, firstValueFrom, map, Observable, of, shareReplay, Subject, switchMap, tap } from 'rxjs'; import { UntilDestroy } from '@ngneat/until-destroy'; import { SettingsService } from '../settings.service'; import { HydrusSearchTags } from '../hydrus-tags'; @@ -9,6 +9,10 @@ import { defaultSort, displaySortGroups, HydrusSortType, isDisplaySortMetaTypeGr import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { ErrorService } from '../error.service'; +import { ALL_KNOWN_TAGS_SERVICE_KEY, ALL_MY_FILES_SERVICE_KEY, getTagServices, isFileService, isNonDeletedFileService } from '../hydrus-services'; +import { ServiceSelectDialogComponent } from '../service-select-dialog/service-select-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; +import { HydrusServicesService } from '../hydrus-services.service'; @UntilDestroy() @Component({ @@ -26,6 +30,8 @@ export class BrowseComponent implements OnInit, AfterViewInit, OnDestroy { private route: ActivatedRoute, private router: Router, private errorService: ErrorService, + private dialog: MatDialog, + private hydrusServices: HydrusServicesService ) { } @@ -40,7 +46,16 @@ export class BrowseComponent implements OnInit, AfterViewInit, OnDestroy { refresh$ = new Subject(); + tagServiceKey$ = new BehaviorSubject(ALL_KNOWN_TAGS_SERVICE_KEY); + fileServiceKey$ = new BehaviorSubject(ALL_MY_FILES_SERVICE_KEY); + tagService$ = combineLatest([this.tagServiceKey$, this.hydrusServices.hydrusServicesArray$]).pipe( + map(([serviceKey, services]) => services.find(s => s.service_key === serviceKey)) + ) + + fileService$ = combineLatest([this.fileServiceKey$, this.hydrusServices.hydrusServicesArray$]).pipe( + map(([serviceKey, services]) => services.find(s => s.service_key === serviceKey)) + ) displaySortGroups = displaySortGroups; isDisplaySortMetaTypeGroup = isDisplaySortMetaTypeGroup; @@ -48,14 +63,16 @@ export class BrowseComponent implements OnInit, AfterViewInit, OnDestroy { sortToString = sortToString; defaultSort = defaultSort; - currentSearch$: Observable = combineLatest([this.searchTags$, this.sort$, this.refresh$]).pipe( + currentSearch$: Observable = combineLatest([this.searchTags$, this.sort$, this.tagServiceKey$, this.fileServiceKey$, this.refresh$]).pipe( filter(([searchTags]) => this.settingsService.appSettings.browseSearchWhenEmpty || searchTags.length > 0), tap(() => this.searching$.next(true)), - switchMap(([searchTags, sort]) => this.searchService.searchFiles( + switchMap(([searchTags, sort, tagService, fileService]) => this.searchService.searchFiles( searchTags, { file_sort_type: sort.sortType, - file_sort_asc: sort.sortAsc + file_sort_asc: sort.sortAsc, + tag_service_key: tagService, + file_service_key: fileService } ).pipe( catchError(error => { @@ -112,12 +129,28 @@ export class BrowseComponent implements OnInit, AfterViewInit, OnDestroy { setSort(sortType: HydrusSortType, sortAsc: boolean) { this.setSortInfo({sortType, sortAsc}); } - - resetSort() { this.setSortInfo(defaultSort); } + async tagServiceDialog() { + const serviceDialog = ServiceSelectDialogComponent.open(this.dialog, {serviceFilter: (services) => getTagServices(services)}) + const service = await firstValueFrom(serviceDialog.afterClosed()) + if(!service) { + return; + } + this.tagServiceKey$.next(service.service_key); + } + + async fileServiceDialog() { + const serviceDialog = ServiceSelectDialogComponent.open(this.dialog, {serviceFilter: (services) => services.filter(isNonDeletedFileService)}) + const service = await firstValueFrom(serviceDialog.afterClosed()) + if(!service) { + return; + } + this.fileServiceKey$.next(service.service_key); + } + /* search() { if(!this.settingsService.appSettings.browseSearchWhenEmpty && this.searchTags.length === 0) { return; diff --git a/src/app/hydrus-api.service.ts b/src/app/hydrus-api.service.ts index d0c2b0b..190e2cf 100644 --- a/src/app/hydrus-api.service.ts +++ b/src/app/hydrus-api.service.ts @@ -149,15 +149,12 @@ export class HydrusApiService { public searchFiles( tags: HydrusSearchTags, params: { - file_service_name?: string; - file_service_key?: string; - tag_service_name?: string; tag_service_key?: string; file_sort_type?: HydrusSortType; file_sort_asc?: boolean; return_hashes?: Hashes; return_file_ids?: IDs; - } = {}, + } & HydrusRequestFileDomain = {}, ): Observable< (Hashes extends true ? { hashes: string[] } : Record) & (IDs extends true ? { file_ids: number[] } : Record) diff --git a/src/app/hydrus-services.ts b/src/app/hydrus-services.ts index c338b1e..6ae02ac 100644 --- a/src/app/hydrus-services.ts +++ b/src/app/hydrus-services.ts @@ -113,8 +113,13 @@ export function getLocalTagServices(serviceArray: HydrusService[]) { return serviceArray.filter(s => s.type === HydrusServiceType.LOCAL_TAG) } +export const ALL_KNOWN_TAGS_SERVICE_KEY = '616c6c206b6e6f776e2074616773'; + +export const ALL_KNOWN_FILES_SERVICE_KEY = '616c6c206b6e6f776e2066696c6573'; +export const ALL_MY_FILES_SERVICE_KEY = '616c6c206c6f63616c206d65646961'; + export function getAllKnownTagsService(services: HydrusServices) { - return services['616c6c206b6e6f776e2074616773']; + return services[ALL_KNOWN_TAGS_SERVICE_KEY]; } export function isFileService(service: HydrusServiceSimple) { @@ -130,3 +135,16 @@ export function isFileService(service: HydrusServiceSimple) { HydrusServiceType.COMBINED_DELETED_FILE ].includes(service.type); } + +export function isNonDeletedFileService(service: HydrusServiceSimple) { + return [ + HydrusServiceType.FILE_REPOSITORY, + HydrusServiceType.LOCAL_FILE_DOMAIN, + HydrusServiceType.LOCAL_FILE_UPDATE_DOMAIN, + HydrusServiceType.COMBINED_LOCAL_FILE, + HydrusServiceType.COMBINED_LOCAL_MEDIA, + HydrusServiceType.COMBINED_FILE, + HydrusServiceType.IPFS + ].includes(service.type); +} + diff --git a/src/app/search.service.ts b/src/app/search.service.ts index 956d308..2f2087f 100644 --- a/src/app/search.service.ts +++ b/src/app/search.service.ts @@ -4,6 +4,7 @@ import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { HydrusSearchTags } from './hydrus-tags'; import { HydrusSortType } from './hydrus-sort'; +import { HydrusRequestFileDomain } from './hydrus-api'; @Injectable({ providedIn: 'root' @@ -14,13 +15,10 @@ export class SearchService { public searchFiles(tags: HydrusSearchTags, options?: { - file_service_name?: string; - file_service_key?: string; - tag_service_name?: string; tag_service_key?: string; file_sort_type?: HydrusSortType; file_sort_asc?: boolean; - }): Observable { + } & HydrusRequestFileDomain): Observable { return this.api.searchFiles( tags, {