diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3642142..be12dce 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -59,6 +59,7 @@ import { ComicsListComponent } from './comics-list/comics-list.component'; import { ComicComponent } from './comic/comic.component'; import { ImageListLoaderComponent } from './image-list-loader/image-list-loader.component'; import { ToolbarActionsComponent } from './toolbar-actions/toolbar-actions.component'; +import { JoinPipe } from './utils/join.pipe'; const MAT_MODULES = [ @@ -102,7 +103,8 @@ const MAT_MODULES = [ ComicsListComponent, ComicComponent, ImageListLoaderComponent, - ToolbarActionsComponent + ToolbarActionsComponent, + JoinPipe ], imports: [ BrowserModule, diff --git a/src/app/browse/browse.component.ts b/src/app/browse/browse.component.ts index fb7e5dc..5a58383 100644 --- a/src/app/browse/browse.component.ts +++ b/src/app/browse/browse.component.ts @@ -7,6 +7,7 @@ import { HydrusFilesService } from '../hydrus-files.service'; import { Subscription } from 'rxjs'; import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { SettingsService } from '../settings.service'; +import { HydrusSearchTags } from '../hydrus-tags'; enum FilterOption { archive, @@ -39,7 +40,7 @@ export class BrowseComponent implements OnInit, AfterViewInit { } currentSearchIDs: number[] = []; - searchTags: string[] = []; + searchTags: HydrusSearchTags = []; searchSub: Subscription; @@ -65,7 +66,7 @@ export class BrowseComponent implements OnInit, AfterViewInit { } } - tagsChanged(tags: string[]) { + tagsChanged(tags: HydrusSearchTags) { this.searchTags = tags; this.search(); } diff --git a/src/app/comic/comic.component.ts b/src/app/comic/comic.component.ts index 07b8475..5be7de1 100644 --- a/src/app/comic/comic.component.ts +++ b/src/app/comic/comic.component.ts @@ -5,7 +5,7 @@ import { SearchService } from '../search.service'; import { ActivatedRoute } from '@angular/router'; import { switchMap, map } from 'rxjs/operators'; import { HydrusFilesService } from '../hydrus-files.service'; -import { TagUtils } from '../tag-utils'; +import { TagUtils } from '../utils/tag-utils'; @Component({ selector: 'app-comic', diff --git a/src/app/comics.service.ts b/src/app/comics.service.ts index 2a179b1..4cffb5a 100644 --- a/src/app/comics.service.ts +++ b/src/app/comics.service.ts @@ -3,7 +3,7 @@ import { HydrusFilesService } from './hydrus-files.service'; import { SearchService } from './search.service'; import { forkJoin, from } from 'rxjs'; import { map, switchMap, filter, mergeMap, toArray, delay, concatMap, tap, reduce, distinct, retry } from 'rxjs/operators'; -import { TagUtils } from './tag-utils'; +import { TagUtils } from './utils/tag-utils'; import { HydrusFile } from './hydrus-file'; import { ProgressBarMode } from '@angular/material/progress-bar'; diff --git a/src/app/file-info-sheet/file-info-sheet.component.ts b/src/app/file-info-sheet/file-info-sheet.component.ts index 878529f..66accef 100644 --- a/src/app/file-info-sheet/file-info-sheet.component.ts +++ b/src/app/file-info-sheet/file-info-sheet.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, Inject } from '@angular/core'; import { HydrusFile, HydrusFileType, ServiceNamesToStatusesToTags } from '../hydrus-file'; import {MAT_BOTTOM_SHEET_DATA} from '@angular/material/bottom-sheet'; -import { TagUtils } from '../tag-utils'; +import { TagUtils } from '../utils/tag-utils'; import { HydrusFilesService } from '../hydrus-files.service'; import { saveAs } from 'file-saver'; import { MatSnackBar } from '@angular/material/snack-bar'; diff --git a/src/app/hydrus-files.service.ts b/src/app/hydrus-files.service.ts index 4129a62..359bc32 100644 --- a/src/app/hydrus-files.service.ts +++ b/src/app/hydrus-files.service.ts @@ -3,7 +3,7 @@ import { HydrusFile, HydrusFileFromAPI, HydrusFileType } from './hydrus-file'; import { Observable, of, forkJoin } from 'rxjs'; import { HydrusApiService } from './hydrus-api.service'; import { map, tap } from 'rxjs/operators'; -import { TagUtils } from './tag-utils'; +import { TagUtils } from './utils/tag-utils'; function chunk(array: T[], size: number): T[][] { const chunked = []; diff --git a/src/app/hydrus-tags.ts b/src/app/hydrus-tags.ts index 287e6a2..b1756f6 100644 --- a/src/app/hydrus-tags.ts +++ b/src/app/hydrus-tags.ts @@ -1,4 +1,7 @@ + export interface HydrusTagSearchTag { value: string, count: number } + +export type HydrusSearchTags = (string | HydrusSearchTags)[]; diff --git a/src/app/search.service.ts b/src/app/search.service.ts index 228532b..60730b2 100644 --- a/src/app/search.service.ts +++ b/src/app/search.service.ts @@ -2,6 +2,7 @@ import { HydrusApiService } from './hydrus-api.service'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; +import { HydrusSearchTags } from './hydrus-tags'; @Injectable({ providedIn: 'root' @@ -11,7 +12,7 @@ export class SearchService { constructor(private api: HydrusApiService) { } - public searchFiles(tags: string[], options?: {system_inbox?: boolean, system_archive?: boolean}): Observable { + public searchFiles(tags: HydrusSearchTags, options?: {system_inbox?: boolean, system_archive?: boolean}): Observable { return this.api.searchFiles( encodeURIComponent(JSON.stringify(tags)), { diff --git a/src/app/settings.ts b/src/app/settings.ts index a1d4813..7825ad7 100644 --- a/src/app/settings.ts +++ b/src/app/settings.ts @@ -1,8 +1,10 @@ +import { HydrusSearchTags } from "./hydrus-tags"; + export interface AppSettingsV1 { version: 1; browseSearchOnLoad: boolean; - browseDefaultSearchTags: string[]; + browseDefaultSearchTags: HydrusSearchTags; } export type AppSettings = AppSettingsV1; diff --git a/src/app/tag-input/tag-input.component.html b/src/app/tag-input/tag-input.component.html index a3bca2e..866e778 100644 --- a/src/app/tag-input/tag-input.component.html +++ b/src/app/tag-input/tag-input.component.html @@ -1,12 +1,22 @@ - - {{tag}} - cancel - + + + {{tag}} + cancel + + + + {{$any(tag) | flatten | join:' OR '}} + cancel + + + (); + tags = new EventEmitter(); @ViewChild('tagInput') tagInput: ElementRef; @ViewChild('auto') matAutocomplete: MatAutocomplete; @@ -114,12 +114,12 @@ export class TagInputComponent implements OnInit, ControlValueAccessor { - removeSearchTag(tag: string): void { - const index = this.searchTags.indexOf(tag); + removeSearchTag(index: number): void { + //const index = this.searchTags.indexOf(tag); - if (index >= 0) { - this.searchTags.splice(index, 1); - } + //if (index >= 0) { + this.searchTags.splice(index, 1); + //} this.tags.emit(this.searchTags); } diff --git a/src/app/utils/array-utils.ts b/src/app/utils/array-utils.ts new file mode 100644 index 0000000..f8efbe1 --- /dev/null +++ b/src/app/utils/array-utils.ts @@ -0,0 +1,26 @@ +function *range(a: number, b: number) { + for (let i = a; i <= b; ++i) { yield i; } +} + +export function rangeArray(a: number, b: number): number[] { + return Array.from(range(a, b)); +} + +export function chunk(array: T[], size: number): T[][] { + const chunked = []; + for (let i = 0; i < array.length; i = i + size) { + chunked.push(array.slice(i, i + size)); + } + return chunked; +} + +/** + * In an ngFor directive, don't destroy and re-create the HTML elements every + * time the list changes. + * + * (Abstractly, this function says that an HTML element's "identity" is + * determined by its position in the list, not by its value.) + */ +export function trackByIndex(index: number, item: any) { + return index; +} diff --git a/src/app/utils/join.pipe.ts b/src/app/utils/join.pipe.ts new file mode 100644 index 0000000..a8151c1 --- /dev/null +++ b/src/app/utils/join.pipe.ts @@ -0,0 +1,10 @@ +import { Pipe, PipeTransform } from "@angular/core"; + +@Pipe({ + name: 'join' +}) +export class JoinPipe implements PipeTransform { + transform(input:Array, sep = ','): string { + return input.join(sep); + } +} diff --git a/src/app/tag-utils.ts b/src/app/utils/tag-utils.ts similarity index 95% rename from src/app/tag-utils.ts rename to src/app/utils/tag-utils.ts index fd4732f..318c72d 100644 --- a/src/app/tag-utils.ts +++ b/src/app/utils/tag-utils.ts @@ -1,4 +1,4 @@ -import { HydrusFile, ServiceNamesToStatusesToTags } from './hydrus-file'; +import { HydrusFile, ServiceNamesToStatusesToTags } from '../hydrus-file'; export class TagUtils { public static getNamespace(tag: string): string {