mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
the /browse endpoint now allow filters to be added from the queryParams
This commit is contained in:
parent
c83d80ab51
commit
52797d869c
@ -1,11 +1,11 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {ItemsGridComponent} from './components/items-grid/items-grid.component';
|
||||
import {NotFoundComponent} from './pages/not-found/not-found.component';
|
||||
import {PageResolver} from './services/page-resolver.service';
|
||||
import {ShowDetailsComponent} from './pages/show-details/show-details.component';
|
||||
import {AuthGuard} from "./auth/misc/authenticated-guard.service";
|
||||
import {LibraryItem} from "../models/resources/library-item";
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { ItemsGridComponent } from './components/items-grid/items-grid.component';
|
||||
import { NotFoundComponent } from './pages/not-found/not-found.component';
|
||||
import { PageResolver } from './services/page-resolver.service';
|
||||
import { ShowDetailsComponent } from './pages/show-details/show-details.component';
|
||||
import { AuthGuard } from "./auth/misc/authenticated-guard.service";
|
||||
import { LibraryItem } from "../models/resources/library-item";
|
||||
import {
|
||||
EpisodeService,
|
||||
LibraryItemService,
|
||||
@ -14,29 +14,29 @@ import {
|
||||
SeasonService,
|
||||
ShowService
|
||||
} from "./services/api.service";
|
||||
import {Show} from "../models/resources/show";
|
||||
import {ItemResolver} from "./services/item-resolver.service";
|
||||
import {CollectionComponent} from "./pages/collection/collection.component";
|
||||
import {Collection} from "../models/resources/collection";
|
||||
import {SearchComponent} from "./pages/search/search.component";
|
||||
import {SearchResult} from "../models/search-result";
|
||||
import {PlayerComponent} from "./pages/player/player.component";
|
||||
import {WatchItem} from "../models/watch-item";
|
||||
import { Show } from "../models/resources/show";
|
||||
import { ItemResolver } from "./services/item-resolver.service";
|
||||
import { CollectionComponent } from "./pages/collection/collection.component";
|
||||
import { Collection } from "../models/resources/collection";
|
||||
import { SearchComponent } from "./pages/search/search.component";
|
||||
import { SearchResult } from "../models/search-result";
|
||||
import { PlayerComponent } from "./pages/player/player.component";
|
||||
import { WatchItem } from "../models/watch-item";
|
||||
|
||||
const routes: Routes = [
|
||||
{path: "browse", component: ItemsGridComponent, pathMatch: "full",
|
||||
resolve: { items: PageResolver.forResource<LibraryItem>("items") },
|
||||
resolve: {items: PageResolver.forResource<LibraryItem>("items", ItemsGridComponent.routeMapper)},
|
||||
canLoad: [AuthGuard.forPermissions("read")],
|
||||
canActivate: [AuthGuard.forPermissions("read")]
|
||||
},
|
||||
{path: "browse/:slug", component: ItemsGridComponent,
|
||||
resolve: { items: PageResolver.forResource<LibraryItem>("library/:slug/items") },
|
||||
resolve: {items: PageResolver.forResource<LibraryItem>("library/:slug/items", ItemsGridComponent.routeMapper)},
|
||||
canLoad: [AuthGuard.forPermissions("read")],
|
||||
canActivate: [AuthGuard.forPermissions("read")]
|
||||
},
|
||||
|
||||
{path: "show/:slug", component: ShowDetailsComponent,
|
||||
resolve: { show: ItemResolver.forResource<Show>("shows/:slug") },
|
||||
resolve: {show: ItemResolver.forResource<Show>("shows/:slug")},
|
||||
canLoad: [AuthGuard.forPermissions("read")],
|
||||
canActivate: [AuthGuard.forPermissions("read")]
|
||||
},
|
||||
@ -60,13 +60,13 @@ const routes: Routes = [
|
||||
},
|
||||
|
||||
{path: "search/:query", component: SearchComponent,
|
||||
resolve: { items: ItemResolver.forResource<SearchResult>("search/:query") },
|
||||
resolve: {items: ItemResolver.forResource<SearchResult>("search/:query")},
|
||||
canLoad: [AuthGuard.forPermissions("read")],
|
||||
canActivate: [AuthGuard.forPermissions("read")]
|
||||
},
|
||||
|
||||
{path: "watch/:item", component: PlayerComponent,
|
||||
resolve: { item: ItemResolver.forResource<WatchItem>("watch/:item") },
|
||||
resolve: {item: ItemResolver.forResource<WatchItem>("watch/:item")},
|
||||
canLoad: [AuthGuard.forPermissions("play")],
|
||||
canActivate: [AuthGuard.forPermissions("play")]
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Component, Input, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { ActivatedRoute, ActivatedRouteSnapshot, Router } from "@angular/router";
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { Genre } from "../../../models/resources/genre";
|
||||
import { LibraryItem } from "../../../models/resources/library-item";
|
||||
@ -36,7 +36,8 @@ export class ItemsGridComponent implements OnInit
|
||||
constructor(private route: ActivatedRoute,
|
||||
private sanitizer: DomSanitizer,
|
||||
private loader: PreLoaderService,
|
||||
public client: HttpClient)
|
||||
public client: HttpClient,
|
||||
private router: Router)
|
||||
{
|
||||
this.route.data.subscribe((data) =>
|
||||
{
|
||||
@ -45,13 +46,29 @@ export class ItemsGridComponent implements OnInit
|
||||
this.loader.load<Genre>("/api/genres?limit=0").subscribe(data =>
|
||||
{
|
||||
this.genres = data;
|
||||
let selectedGenres: string[] = [];
|
||||
if (this.route.snapshot.queryParams.genres?.startsWith("ctn:"))
|
||||
selectedGenres = this.route.snapshot.queryParams.genres.substr(4).split(',');
|
||||
this.filters.genres = this.genres.filter(x => selectedGenres.includes(x.slug));
|
||||
});
|
||||
this.loader.load<Studio>("/api/studios?limit=0").subscribe(data =>
|
||||
{
|
||||
this.studios = data;
|
||||
this.filters.studio = this.studios.find(x => x.slug == this.route.params["studio"]);
|
||||
});
|
||||
}
|
||||
|
||||
static routeMapper(route: ActivatedRouteSnapshot, endpoint: string): string
|
||||
{
|
||||
const filter: string[] = ["genres", "studio"];
|
||||
let queryParams: [string, string][] = Object.entries(route.queryParams).filter(x => filter.includes(x[0]));
|
||||
if (queryParams.length > 0)
|
||||
endpoint = "shows";
|
||||
|
||||
let params: string = '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&');
|
||||
return `api/${endpoint}${params}`
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.defaultType = this.page.this.match(/\/(\w*)($|\?)/)[1];
|
||||
@ -107,12 +124,22 @@ export class ItemsGridComponent implements OnInit
|
||||
: new URL(this.page.changeType(this.defaultType));
|
||||
}
|
||||
|
||||
let param: string;
|
||||
if (isArray && this.filters[category].length > 0)
|
||||
url.searchParams.set(category, `ctn:${this.filters[category].map(x => x.slug).join(',')}`);
|
||||
param = `ctn:${this.filters[category].map(x => x.slug).join(',')}`;
|
||||
else if (!isArray && this.filters[category] != null)
|
||||
url.searchParams.set(category, filter.slug)
|
||||
param = filter.slug;
|
||||
|
||||
if (param != null)
|
||||
url.searchParams.set(category, param);
|
||||
else
|
||||
url.searchParams.delete(category)
|
||||
this.router.navigate([], {
|
||||
relativeTo: this.route,
|
||||
queryParams: { [category]: param },
|
||||
replaceUrl: true,
|
||||
queryParamsHandling: "merge"
|
||||
});
|
||||
this.client.get<Page<Show>>(url.toString())
|
||||
.subscribe(x => this.page = Object.assign(new Page<Show>(), x));
|
||||
}
|
||||
|
@ -7,12 +7,14 @@ import {catchError, map} from 'rxjs/operators';
|
||||
import {Page} from "../../models/page";
|
||||
import {IResource} from "../../models/resources/resource";
|
||||
|
||||
type RouteMapper = (route: ActivatedRouteSnapshot, endpoint: string) => string;
|
||||
|
||||
@Injectable()
|
||||
export class PageResolver
|
||||
{
|
||||
public static resolvers: any[] = [];
|
||||
|
||||
static forResource<T extends IResource>(resource: string)
|
||||
static forResource<T extends IResource>(resource: string, copyParams: boolean | string[] | RouteMapper = false)
|
||||
{
|
||||
@Injectable()
|
||||
class Resolver implements Resolve<Page<T>>
|
||||
@ -24,8 +26,21 @@ export class PageResolver
|
||||
resolve(route: ActivatedRouteSnapshot): Page<T> | Observable<Page<T>> | Promise<Page<T>>
|
||||
{
|
||||
let res: string = resource.replace(/:(.*?)(\/|$)/, (x, y) => `${route.paramMap.get(y)}/`);
|
||||
let uri: string;
|
||||
if (typeof copyParams == "function")
|
||||
uri = copyParams(route, res);
|
||||
else
|
||||
{
|
||||
let queryParams: [string, string][] = copyParams == true
|
||||
? Object.entries(route.queryParams)
|
||||
: Object.entries(route.queryParams).filter(x => copyParams && copyParams.includes(x[0]));
|
||||
let params: string = queryParams.length > 0
|
||||
? '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&')
|
||||
: "";
|
||||
uri = `api/${res}${params}`;
|
||||
}
|
||||
|
||||
return this.http.get<Page<T>>(`api/${res}`)
|
||||
return this.http.get<Page<T>>(uri)
|
||||
.pipe(
|
||||
map(x => Object.assign(new Page<T>(), x)),
|
||||
catchError((error: HttpErrorResponse) =>
|
||||
|
Loading…
x
Reference in New Issue
Block a user