mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Cleaning up the dynamic routing between /api/items & /api/shows for the browse component
This commit is contained in:
parent
3ec72bbead
commit
3328568bd2
@ -27,30 +27,34 @@ const routes: Routes = [
|
|||||||
{path: "browse", component: ItemsGridComponent, pathMatch: "full",
|
{path: "browse", component: ItemsGridComponent, pathMatch: "full",
|
||||||
resolve: {items: PageResolver.forResource<LibraryItem>("items", ItemsGridComponent.routeMapper)},
|
resolve: {items: PageResolver.forResource<LibraryItem>("items", ItemsGridComponent.routeMapper)},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
canActivate: [AuthGuard.forPermissions("read")],
|
||||||
|
runGuardsAndResolvers: "always"
|
||||||
},
|
},
|
||||||
{path: "browse/:slug", component: ItemsGridComponent,
|
{path: "browse/:slug", component: ItemsGridComponent,
|
||||||
resolve: {items: PageResolver.forResource<LibraryItem>("library/:slug/items", ItemsGridComponent.routeMapper)},
|
resolve: {items: PageResolver.forResource<LibraryItem>("library/:slug/items", ItemsGridComponent.routeMapper)},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
canActivate: [AuthGuard.forPermissions("read")],
|
||||||
|
runGuardsAndResolvers: "always"
|
||||||
},
|
},
|
||||||
|
|
||||||
{path: "genre/:slug", component: ItemsGridComponent, pathMatch: "full",
|
{path: "genre/:slug", component: ItemsGridComponent, pathMatch: "full",
|
||||||
resolve: {items: PageResolver.forResource<LibraryItem>("shows", ["genres", "studio"], "genres=ctn::slug")},
|
resolve: {items: PageResolver.forResource<Show>("shows", ItemsGridComponent.routeMapper, "genres=ctn::slug")},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
canActivate: [AuthGuard.forPermissions("read")],
|
||||||
|
runGuardsAndResolvers: "always"
|
||||||
|
},
|
||||||
|
{path: "studio/:slug", component: ItemsGridComponent, pathMatch: "full",
|
||||||
|
resolve: {items: PageResolver.forResource<Show>("shows", ItemsGridComponent.routeMapper, "studio=:slug")},
|
||||||
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
|
canActivate: [AuthGuard.forPermissions("read")],
|
||||||
|
runGuardsAndResolvers: "always"
|
||||||
},
|
},
|
||||||
|
|
||||||
{path: "show/:slug", component: ShowDetailsComponent,
|
|
||||||
resolve: {show: ItemResolver.forResource<Show>("shows/:slug")},
|
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
|
||||||
},
|
|
||||||
{path: "collection/:slug", component: CollectionComponent,
|
{path: "collection/:slug", component: CollectionComponent,
|
||||||
resolve:
|
resolve:
|
||||||
{
|
{
|
||||||
collection: ItemResolver.forResource<Collection>("collections/:slug"),
|
collection: ItemResolver.forResource<Collection>("collections/:slug"),
|
||||||
shows: PageResolver.forResource<Show>("collections/:slug/shows")
|
shows: PageResolver.forResource<Show>("collections/:slug/shows", ItemsGridComponent.routeMapper)
|
||||||
},
|
},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
canActivate: [AuthGuard.forPermissions("read")]
|
||||||
@ -59,12 +63,18 @@ const routes: Routes = [
|
|||||||
resolve:
|
resolve:
|
||||||
{
|
{
|
||||||
collection: ItemResolver.forResource<Collection>("people/:slug"),
|
collection: ItemResolver.forResource<Collection>("people/:slug"),
|
||||||
shows: PageResolver.forResource<Show>("people/:slug/roles")
|
shows: PageResolver.forResource<Show>("people/:slug/roles", ItemsGridComponent.routeMapper)
|
||||||
},
|
},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
canActivate: [AuthGuard.forPermissions("read")]
|
canActivate: [AuthGuard.forPermissions("read")]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{path: "show/:slug", component: ShowDetailsComponent,
|
||||||
|
resolve: {show: ItemResolver.forResource<Show>("shows/:slug")},
|
||||||
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
|
canActivate: [AuthGuard.forPermissions("read")]
|
||||||
|
},
|
||||||
|
|
||||||
{path: "search/:query", component: SearchComponent,
|
{path: "search/:query", component: SearchComponent,
|
||||||
resolve: {items: ItemResolver.forResource<SearchResult>("search/:query")},
|
resolve: {items: ItemResolver.forResource<SearchResult>("search/:query")},
|
||||||
canLoad: [AuthGuard.forPermissions("read")],
|
canLoad: [AuthGuard.forPermissions("read")],
|
||||||
@ -77,7 +87,7 @@ const routes: Routes = [
|
|||||||
canActivate: [AuthGuard.forPermissions("play")]
|
canActivate: [AuthGuard.forPermissions("play")]
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO implement missing pages: /genre, /studio & an home page.
|
// TODO implement an home page.
|
||||||
|
|
||||||
{path: "", pathMatch: 'full', redirectTo: "/browse"},
|
{path: "", pathMatch: 'full', redirectTo: "/browse"},
|
||||||
{path: "**", component: NotFoundComponent}
|
{path: "**", component: NotFoundComponent}
|
||||||
|
@ -29,6 +29,8 @@ export class ItemsGridComponent implements OnInit
|
|||||||
sortKeys: string[] = ["title", "start year", "end year"]
|
sortKeys: string[] = ["title", "start year", "end year"]
|
||||||
sortUp: boolean = true;
|
sortUp: boolean = true;
|
||||||
|
|
||||||
|
public static readonly showOnlyFilters: string[] = ["genres", "studio"]
|
||||||
|
public static readonly filters: string[] = [].concat(...ItemsGridComponent.showOnlyFilters)
|
||||||
filters: {genres: Genre[], studio: Studio} = {genres: [], studio: null};
|
filters: {genres: Genre[], studio: Studio} = {genres: [], studio: null};
|
||||||
genres: Genre[] = [];
|
genres: Genre[] = [];
|
||||||
studios: Studio[] = [];
|
studios: Studio[] = [];
|
||||||
@ -58,20 +60,31 @@ export class ItemsGridComponent implements OnInit
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO need to put every filter available in one place (it is everywhere for now)
|
|
||||||
// TODO clean route change
|
|
||||||
// TODO support dynamic switching between /genre & /browse & /whatever.
|
// TODO support dynamic switching between /genre & /browse & /whatever.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* /browse -> /api/items | /api/shows
|
||||||
|
* /browse/:library -> /api/library/:slug/items | /api/library/:slug/shows
|
||||||
|
* /genre/:slug -> /api/shows
|
||||||
|
* /studio/:slug -> /api/shows
|
||||||
|
*
|
||||||
|
* /collection/:slug -> /api/collection/:slug/shows |> AS @Input
|
||||||
|
* /people/:slug -> /api/people/:slug/roles |> AS @Input
|
||||||
|
*/
|
||||||
|
|
||||||
static routeMapper(route: ActivatedRouteSnapshot, endpoint: string, query: [string, string][]): string
|
static routeMapper(route: ActivatedRouteSnapshot, endpoint: string, query: [string, string][]): string
|
||||||
{
|
{
|
||||||
const filter: string[] = ["genres", "studio"];
|
let queryParams: [string, string][] = Object.entries(route.queryParams)
|
||||||
let queryParams: [string, string][] = Object.entries(route.queryParams).filter(x => filter.includes(x[0]));
|
.filter(x => ItemsGridComponent.filters.includes(x[0]) || x[0] == "sortBy");
|
||||||
if (query)
|
if (query)
|
||||||
queryParams.push(...query)
|
queryParams.push(...query)
|
||||||
if (queryParams.length > 0)
|
|
||||||
endpoint = "shows";
|
|
||||||
|
|
||||||
let params: string = '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&');
|
if (queryParams.some(x => ItemsGridComponent.showOnlyFilters.includes(x[0])))
|
||||||
|
endpoint = endpoint.replace(/items?$/, "show");
|
||||||
|
|
||||||
|
let params: string = queryParams.length > 0
|
||||||
|
? '?' + queryParams.map(x => `${x[0]}=${x[1]}`).join('&')
|
||||||
|
: "";
|
||||||
return `api/${endpoint}${params}`
|
return `api/${endpoint}${params}`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,63 +104,36 @@ export class ItemsGridComponent implements OnInit
|
|||||||
|
|
||||||
addFilter(category: string, filter: IResource, isArray: boolean = true, isShowOnly: boolean = true)
|
addFilter(category: string, filter: IResource, isArray: boolean = true, isShowOnly: boolean = true)
|
||||||
{
|
{
|
||||||
if (!this.complexFiltersEnabled)
|
if (!this.complexFiltersEnabled && isShowOnly)
|
||||||
return;
|
return;
|
||||||
let useShow: boolean;
|
|
||||||
|
|
||||||
if (isArray)
|
if (isArray)
|
||||||
{
|
{
|
||||||
if (this.filters[category].includes(filter))
|
if (this.filters[category].includes(filter))
|
||||||
{
|
|
||||||
this.filters[category].splice(this.filters[category].indexOf(filter), 1);
|
this.filters[category].splice(this.filters[category].indexOf(filter), 1);
|
||||||
useShow = this.getFilterCount() != 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
this.filters[category].push(filter);
|
this.filters[category].push(filter);
|
||||||
useShow = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this.filters[category] == filter)
|
if (this.filters[category] == filter)
|
||||||
{
|
|
||||||
this.filters[category] = null;
|
this.filters[category] = null;
|
||||||
useShow = false;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
this.filters[category] = filter;
|
this.filters[category] = filter;
|
||||||
useShow = filter != null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let url: URL = new URL(this.page.first);
|
let param: string = null;
|
||||||
if (isShowOnly)
|
|
||||||
{
|
|
||||||
url = useShow
|
|
||||||
? new URL(this.page.changeType("shows"))
|
|
||||||
: new URL(this.page.changeType(this.defaultType));
|
|
||||||
}
|
|
||||||
|
|
||||||
let param: string;
|
|
||||||
if (isArray && this.filters[category].length > 0)
|
if (isArray && this.filters[category].length > 0)
|
||||||
param = `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)
|
else if (!isArray && this.filters[category] != null)
|
||||||
param = filter.slug;
|
param = filter.slug;
|
||||||
|
|
||||||
if (param != null)
|
|
||||||
url.searchParams.set(category, param);
|
|
||||||
else
|
|
||||||
url.searchParams.delete(category)
|
|
||||||
this.router.navigate([], {
|
this.router.navigate([], {
|
||||||
relativeTo: this.route,
|
relativeTo: this.route,
|
||||||
queryParams: { [category]: param },
|
queryParams: { [category]: param },
|
||||||
replaceUrl: true,
|
replaceUrl: true,
|
||||||
queryParamsHandling: "merge"
|
queryParamsHandling: "merge"
|
||||||
});
|
});
|
||||||
this.client.get<Page<Show>>(url.toString())
|
|
||||||
.subscribe(x => this.page = Object.assign(new Page<Show>(), x));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumb(slug: string)
|
getThumb(slug: string)
|
||||||
@ -170,9 +156,12 @@ export class ItemsGridComponent implements OnInit
|
|||||||
this.sortType = type;
|
this.sortType = type;
|
||||||
this.sortUp = order;
|
this.sortUp = order;
|
||||||
|
|
||||||
let url: URL = new URL(this.page.first);
|
let param: string = `${this.sortType.replace(/\s/g, "")}:${this.sortUp ? "asc" : "desc"}`;
|
||||||
url.searchParams.set("sortBy", `${this.sortType.replace(/\s/g, "")}:${this.sortUp ? "asc" : "desc"}`);
|
this.router.navigate([], {
|
||||||
this.client.get<Page<LibraryItem | Show>>(url.toString())
|
relativeTo: this.route,
|
||||||
.subscribe(x => this.page = Object.assign(new Page<LibraryItem | Show>(), x));
|
queryParams: { sortBy: param },
|
||||||
|
replaceUrl: true,
|
||||||
|
queryParamsHandling: "merge"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user