mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 10:14:13 -04:00
Making the show details page use the new api for shows, seasons & episodes
This commit is contained in:
parent
b8d5265316
commit
09f8328900
@ -1,20 +1,14 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {LibraryItemGridComponent} from './components/library-item-grid/library-item-grid.component';
|
||||
import {CollectionComponent} from "./collection/collection.component";
|
||||
import {NotFoundComponent} from './not-found/not-found.component';
|
||||
import {PlayerComponent} from "./pages/player/player.component";
|
||||
import {SearchComponent} from "./pages/search/search.component";
|
||||
import {CollectionResolverService} from "./services/resolvers/collection-resolver.service";
|
||||
import {PageResolver} from './services/resolvers/page-resolver.service';
|
||||
import {PeopleResolverService} from "./services/resolvers/people-resolver.service";
|
||||
import {SearchResolverService} from "./services/resolvers/search-resolver.service";
|
||||
import {ShowResolverService} from './services/resolvers/show-resolver.service';
|
||||
import {StreamResolverService} from "./services/resolvers/stream-resolver.service";
|
||||
import {ShowDetailsComponent} from './pages/show-details/show-details.component';
|
||||
import {AuthGuard} from "./auth/misc/authenticated-guard.service";
|
||||
import {LibraryItem} from "../models/library-item";
|
||||
import {LibraryItemService, LibraryService} from "./services/api.service";
|
||||
import {Show} from "../models/show";
|
||||
import {ItemResolver} from "./services/resolvers/item-resolver.service";
|
||||
|
||||
const routes: Routes = [
|
||||
{path: "browse", component: LibraryItemGridComponent, pathMatch: "full",
|
||||
@ -28,11 +22,16 @@ const routes: Routes = [
|
||||
canActivate: [AuthGuard.forPermissions("read")]
|
||||
},
|
||||
|
||||
{path: "show/:show-slug", component: ShowDetailsComponent, resolve: { show: ShowResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
{path: "collection/:collection-slug", component: CollectionComponent, resolve: { collection: CollectionResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
{path: "people/:people-slug", component: CollectionComponent, resolve: { collection: PeopleResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
{path: "watch/:item", component: PlayerComponent, resolve: { item: StreamResolverService }, canLoad: [AuthGuard.forPermissions("play")], canActivate: [AuthGuard.forPermissions("play")]},
|
||||
{path: "search/:query", component: SearchComponent, resolve: { items: SearchResolverService }, canLoad: [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: "collection/:collection-slug", component: CollectionComponent, resolve: { collection: CollectionResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
//
|
||||
// {path: "people/:people-slug", component: CollectionComponent, resolve: { collection: PeopleResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
// {path: "watch/:item", component: PlayerComponent, resolve: { item: StreamResolverService }, canLoad: [AuthGuard.forPermissions("play")], canActivate: [AuthGuard.forPermissions("play")]},
|
||||
// {path: "search/:query", component: SearchComponent, resolve: { items: SearchResolverService }, canLoad: [AuthGuard.forPermissions("read")], canActivate: [AuthGuard.forPermissions("read")]},
|
||||
{path: "**", component: NotFoundComponent}
|
||||
];
|
||||
|
||||
@ -46,11 +45,7 @@ const routes: Routes = [
|
||||
LibraryService,
|
||||
LibraryItemService,
|
||||
PageResolver.resolvers,
|
||||
ShowResolverService,
|
||||
CollectionResolverService,
|
||||
PeopleResolverService,
|
||||
StreamResolverService,
|
||||
SearchResolverService
|
||||
ItemResolver.resolvers,
|
||||
]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="root">
|
||||
<div class="episodes" #scrollView (scroll)="onScroll()">
|
||||
<div class="episode" *ngFor="let episode of this.episodes" #episodeDom >
|
||||
<div class="episode" *ngFor="let episode of this.episodes?.items" #itemsDom >
|
||||
<button mat-icon-button class="moreBtn" [matMenuTriggerFor]="more" [matMenuTriggerData]="{episode: episode}"><i class="material-icons">more_vert</i></button>
|
||||
<a routerLink="/watch/{{episode.slug}}" href="/watch/{{episode.slug}}">
|
||||
<div matRipple class="img" [style.background-image]="sanitize(episode.thumb)">
|
||||
|
@ -1,56 +1,22 @@
|
||||
import { Component, ElementRef, Input, ViewChild } from '@angular/core';
|
||||
import { MatButton } from "@angular/material/button";
|
||||
import { Component, Input} from '@angular/core';
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { Episode } from "../../../models/episode";
|
||||
import {HorizontalScroller} from "../../misc/horizontal-scroller";
|
||||
import {Page} from "../../../models/page";
|
||||
|
||||
@Component({
|
||||
selector: 'app-episodes-list',
|
||||
templateUrl: './episodes-list.component.html',
|
||||
styleUrls: ['./episodes-list.component.scss']
|
||||
})
|
||||
export class EpisodesListComponent
|
||||
export class EpisodesListComponent extends HorizontalScroller
|
||||
{
|
||||
@Input() displayShowTitle: boolean = false;
|
||||
@Input() episodes: Episode[];
|
||||
@ViewChild("scrollView", { static: true }) private scrollView: ElementRef;
|
||||
@ViewChild("leftBtn", { static: false }) private leftBtn: MatButton;
|
||||
@ViewChild("rightBtn", { static: false }) private rightBtn: MatButton;
|
||||
@ViewChild("episodeDom", { static: false }) private episode: ElementRef;
|
||||
@Input() episodes: Page<Episode>;
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) { }
|
||||
|
||||
scrollLeft()
|
||||
constructor(private sanitizer: DomSanitizer)
|
||||
{
|
||||
let scroll: number = this.roundScroll(this.scrollView.nativeElement.offsetWidth * 0.80);
|
||||
this.scrollView.nativeElement.scrollBy({ top: 0, left: -scroll, behavior: "smooth" });
|
||||
}
|
||||
|
||||
scrollRight()
|
||||
{
|
||||
let scroll: number = this.roundScroll(this.scrollView.nativeElement.offsetWidth * 0.80);
|
||||
this.scrollView.nativeElement.scrollBy({ top: 0, left: scroll, behavior: "smooth" });
|
||||
}
|
||||
|
||||
roundScroll(offset: number): number
|
||||
{
|
||||
let episodeSize: number = this.episode.nativeElement.scrollWidth;
|
||||
|
||||
offset = Math.round(offset / episodeSize) * episodeSize;
|
||||
if (offset == 0)
|
||||
offset = episodeSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
onScroll()
|
||||
{
|
||||
if (this.scrollView.nativeElement.scrollLeft <= 0)
|
||||
this.leftBtn._elementRef.nativeElement.classList.add("d-none");
|
||||
else
|
||||
this.leftBtn._elementRef.nativeElement.classList.remove("d-none");
|
||||
if (this.scrollView.nativeElement.scrollLeft >= this.scrollView.nativeElement.scrollWidth - this.scrollView.nativeElement.clientWidth)
|
||||
this.rightBtn._elementRef.nativeElement.classList.add("d-none");
|
||||
else
|
||||
this.rightBtn._elementRef.nativeElement.classList.remove("d-none");
|
||||
super();
|
||||
}
|
||||
|
||||
sanitize(url: string)
|
||||
|
@ -16,7 +16,7 @@ export class LibraryItemGridComponent
|
||||
@Input() page: Page<LibraryItem>;
|
||||
@Input() sortEnabled: boolean = true;
|
||||
sortType: string = "title";
|
||||
sortKeys: string[] = ["title", "start year", "end year", "status", "type"]
|
||||
sortKeys: string[] = ["title", "start year", "end year"]
|
||||
sortUp: boolean = true;
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
@ -48,7 +48,7 @@ export class LibraryItemGridComponent
|
||||
this.sortType = type;
|
||||
this.sortUp = order;
|
||||
|
||||
this.items.getAll({sort: `${this.sortType.replace(/\s/g, "")}:${this.sortUp ? "asc" : "desc"}`})
|
||||
this.items.getAll({sortBy: `${this.sortType.replace(/\s/g, "")}:${this.sortUp ? "asc" : "desc"}`})
|
||||
.subscribe(x => this.page = x);
|
||||
}
|
||||
}
|
||||
|
44
src/app/misc/horizontal-scroller.ts
Normal file
44
src/app/misc/horizontal-scroller.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import {ElementRef, ViewChild} from "@angular/core";
|
||||
import {MatButton} from "@angular/material/button";
|
||||
|
||||
export class HorizontalScroller
|
||||
{
|
||||
@ViewChild("scrollView", { static: true }) private scrollView: ElementRef;
|
||||
@ViewChild("leftBtn", { static: false }) private leftBtn: MatButton;
|
||||
@ViewChild("rightBtn", { static: false }) private rightBtn: MatButton;
|
||||
@ViewChild("itemsDom", { static: false }) private items: ElementRef;
|
||||
|
||||
scrollLeft()
|
||||
{
|
||||
let scroll: number = this.roundScroll(this.scrollView.nativeElement.offsetWidth * 0.80);
|
||||
this.scrollView.nativeElement.scrollBy({ top: 0, left: -scroll, behavior: "smooth" });
|
||||
}
|
||||
|
||||
scrollRight()
|
||||
{
|
||||
let scroll: number = this.roundScroll(this.scrollView.nativeElement.offsetWidth * 0.80);
|
||||
this.scrollView.nativeElement.scrollBy({ top: 0, left: scroll, behavior: "smooth" });
|
||||
}
|
||||
|
||||
roundScroll(offset: number): number
|
||||
{
|
||||
let itemSize: number = this.items.nativeElement.scrollWidth;
|
||||
|
||||
offset = Math.round(offset / itemSize) * itemSize;
|
||||
if (offset == 0)
|
||||
offset = itemSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
onScroll()
|
||||
{
|
||||
if (this.scrollView.nativeElement.scrollLeft <= 0)
|
||||
this.leftBtn._elementRef.nativeElement.classList.add("d-none");
|
||||
else
|
||||
this.leftBtn._elementRef.nativeElement.classList.remove("d-none");
|
||||
if (this.scrollView.nativeElement.scrollLeft >= this.scrollView.nativeElement.scrollWidth - this.scrollView.nativeElement.clientWidth)
|
||||
this.rightBtn._elementRef.nativeElement.classList.add("d-none");
|
||||
else
|
||||
this.rightBtn._elementRef.nativeElement.classList.remove("d-none");
|
||||
}
|
||||
}
|
@ -78,12 +78,12 @@
|
||||
<div class="container-fluid mt-3">
|
||||
<mat-form-field>
|
||||
<mat-label>Season</mat-label>
|
||||
<mat-select [(value)]="season" (selectionChange)="getEpisodes()">
|
||||
<mat-option *ngFor="let season of this.show.seasons" [value]="season.seasonNumber">{{season.title}}</mat-option>
|
||||
<mat-select [(value)]="season" (selectionChange)="getEpisodes(season.seasonNumber)">
|
||||
<mat-option *ngFor="let season of this.seasons" [value]="season.seasonNumber">{{season.title}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<app-episodes-list [episodes]="episodes"></app-episodes-list>
|
||||
<app-episodes-list [episodes]="episodes[season]"></app-episodes-list>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid mt-5">
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||
import { Title } from '@angular/platform-browser';
|
||||
@ -8,7 +7,9 @@ import { Show } from "../../../models/show";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {TrailerDialogComponent} from "../trailer-dialog/trailer-dialog.component";
|
||||
import {MetadataEditComponent} from "../metadata-edit/metadata-edit.component";
|
||||
import {Account} from "../../../models/account";
|
||||
import {Season} from "../../../models/season";
|
||||
import {EpisodeService, SeasonService} from "../../services/api.service";
|
||||
import {Page} from "../../../models/page";
|
||||
|
||||
@Component({
|
||||
selector: 'app-show-details',
|
||||
@ -18,17 +19,24 @@ import {Account} from "../../../models/account";
|
||||
export class ShowDetailsComponent implements OnInit
|
||||
{
|
||||
show: Show;
|
||||
episodes: Episode[] = null;
|
||||
season: number;
|
||||
seasons: Season[];
|
||||
season: number = 1;
|
||||
episodes: Page<Episode>[] = [];
|
||||
|
||||
private toolbar: HTMLElement;
|
||||
private backdrop: HTMLElement;
|
||||
|
||||
constructor(private route: ActivatedRoute, private http: HttpClient, private snackBar: MatSnackBar, private title: Title, private router: Router, private dialog: MatDialog)
|
||||
constructor(private route: ActivatedRoute,
|
||||
private snackBar: MatSnackBar,
|
||||
private title: Title,
|
||||
private router: Router,
|
||||
private dialog: MatDialog,
|
||||
private seasonService: SeasonService,
|
||||
private episodeService: EpisodeService)
|
||||
{
|
||||
this.route.queryParams.subscribe(params =>
|
||||
{
|
||||
this.season = params["season"];
|
||||
this.season = params["season"] ?? 1;
|
||||
});
|
||||
|
||||
this.route.data.subscribe(data =>
|
||||
@ -36,10 +44,19 @@ export class ShowDetailsComponent implements OnInit
|
||||
this.show = data.show;
|
||||
this.title.setTitle(this.show.title + " - Kyoo");
|
||||
|
||||
if (this.season == undefined || this.show.seasons == undefined || this.show.seasons.find(x => x.seasonNumber == this.season) == null)
|
||||
this.season = 1;
|
||||
if (this.show.isMovie)
|
||||
return;
|
||||
|
||||
this.getEpisodes();
|
||||
this.seasonService.getForShow(this.show.slug, {limit: 0}).subscribe(x =>
|
||||
{
|
||||
this.seasons = x.items;
|
||||
if (x.items.find(x => x.seasonNumber == this.season) == null)
|
||||
{
|
||||
this.season = 1;
|
||||
this.getEpisodes(1);
|
||||
}
|
||||
});
|
||||
this.getEpisodes(this.season);
|
||||
});
|
||||
}
|
||||
|
||||
@ -72,23 +89,17 @@ export class ShowDetailsComponent implements OnInit
|
||||
this.router.navigate(["/watch/" + this.show.slug + "-s1e1"]);
|
||||
}
|
||||
|
||||
getEpisodes()
|
||||
getEpisodes(season: number)
|
||||
{
|
||||
if (this.show == undefined || this.show.seasons == undefined)
|
||||
if (season < 0)
|
||||
return;
|
||||
|
||||
if (this.show.seasons.find(x => x.seasonNumber == this.season).episodes != null)
|
||||
this.episodes = this.show.seasons.find(x => x.seasonNumber == this.season).episodes;
|
||||
if (this.episodes[season] != undefined)
|
||||
return;
|
||||
|
||||
|
||||
this.http.get<Episode[]>("api/episodes/" + this.show.slug + "/season/" + this.season).subscribe((episodes: Episode[]) =>
|
||||
this.episodeService.getFromSeasonNumber(this.show.slug, this.season).subscribe(x =>
|
||||
{
|
||||
this.show.seasons.find(x => x.seasonNumber == this.season).episodes = episodes;
|
||||
this.episodes = episodes;
|
||||
}, error =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open("An unknow error occured while getting episodes.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
this.episodes[season] = x;
|
||||
});
|
||||
}
|
||||
|
||||
@ -108,10 +119,10 @@ export class ShowDetailsComponent implements OnInit
|
||||
|
||||
redownloadImages()
|
||||
{
|
||||
this.http.post("api/show/download-images/" + this.show.slug, undefined).subscribe(() => { }, error =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open("An unknown error occured while re-downloading images.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
});
|
||||
// this.http.post("api/show/download-images/" + this.show.slug, undefined).subscribe(() => { }, error =>
|
||||
// {
|
||||
// console.log(error.status + " - " + error.message);
|
||||
// this.snackBar.open("An unknown error occured while re-downloading images.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
@ -6,24 +6,38 @@ import {IResource} from "../../models/resources/resource";
|
||||
import {Library} from "../../models/library";
|
||||
import {LibraryItem} from "../../models/library-item";
|
||||
import {map} from "rxjs/operators";
|
||||
import {Season} from "../../models/season";
|
||||
import {Episode} from "../../models/episode";
|
||||
|
||||
export interface ApiArgs
|
||||
{
|
||||
sortBy?: string;
|
||||
limit?: number;
|
||||
afterID?: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
class CrudApi<T extends IResource>
|
||||
{
|
||||
constructor(private client: HttpClient, private route: string) {}
|
||||
constructor(protected client: HttpClient, private route: string) {}
|
||||
|
||||
get(id: number | string): Observable<T>
|
||||
{
|
||||
return this.client.get<T>(`/api/${this.route}/${id}`);
|
||||
}
|
||||
|
||||
getAll(args: {sort: string} = null): Observable<Page<T>>
|
||||
protected ArgsAsQuery(args: ApiArgs): string
|
||||
{
|
||||
let params: string = "?";
|
||||
if (args && args.sort)
|
||||
params += "sortBy=" + args.sort;
|
||||
if (params == "?")
|
||||
params = "";
|
||||
return this.client.get<Page<T>>(`/api/${this.route}${params}`)
|
||||
if (args == null)
|
||||
return "";
|
||||
let params: string = Object.keys(args).map(x => `${x}=${args[x]}`).join("&");
|
||||
|
||||
return params ? `?${params}` : "";
|
||||
}
|
||||
|
||||
getAll(args?: ApiArgs): Observable<Page<T>>
|
||||
{
|
||||
return this.client.get<Page<T>>(`/api/${this.route}${this.ArgsAsQuery(args)}`)
|
||||
.pipe(map(x => Object.assign(new Page<T>(), x)));
|
||||
}
|
||||
|
||||
@ -64,3 +78,43 @@ export class LibraryItemService extends CrudApi<LibraryItem>
|
||||
super(client, "items");
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class SeasonService extends CrudApi<Season>
|
||||
{
|
||||
constructor(client: HttpClient)
|
||||
{
|
||||
super(client, "seasons");
|
||||
}
|
||||
|
||||
getForShow(show: string | number, args?: ApiArgs): Observable<Page<Season>>
|
||||
{
|
||||
return this.client.get(`/api/show/${show}/seasons${this.ArgsAsQuery(args)}`)
|
||||
.pipe(map(x => Object.assign(new Page<Season>(), x)));
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class EpisodeService extends CrudApi<Episode>
|
||||
{
|
||||
constructor(client: HttpClient)
|
||||
{
|
||||
super(client, "episodes");
|
||||
}
|
||||
|
||||
getFromSeason(season: string | number, args?: ApiArgs): Observable<Page<Episode>>
|
||||
{
|
||||
return this.client.get(`/api/seasons/${season}/episodes${this.ArgsAsQuery(args)}`)
|
||||
.pipe(map(x => Object.assign(new Page<Episode>(), x)));
|
||||
}
|
||||
|
||||
getFromSeasonNumber(show: string | number, seasonNumber: number, args?: ApiArgs): Observable<Page<Episode>>
|
||||
{
|
||||
return this.client.get(`/api/seasons/${show}-${seasonNumber}/episodes${this.ArgsAsQuery(args)}`)
|
||||
.pipe(map(x => Object.assign(new Page<Episode>(), x)));
|
||||
}
|
||||
}
|
||||
|
44
src/app/services/resolvers/item-resolver.service.ts
Normal file
44
src/app/services/resolvers/item-resolver.service.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||
import {ActivatedRouteSnapshot, Resolve} from '@angular/router';
|
||||
import {Observable, EMPTY} from 'rxjs';
|
||||
import {catchError} from 'rxjs/operators';
|
||||
import {IResource} from "../../../models/resources/resource";
|
||||
|
||||
@Injectable()
|
||||
export class ItemResolver
|
||||
{
|
||||
public static resolvers: any[] = [];
|
||||
|
||||
static forResource<T extends IResource>(resource: string)
|
||||
{
|
||||
@Injectable()
|
||||
class Resolver implements Resolve<T>
|
||||
{
|
||||
constructor(private http: HttpClient,
|
||||
private snackBar: MatSnackBar)
|
||||
{ }
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot): T | Observable<T> | Promise<T>
|
||||
{
|
||||
let res: string = resource.replace(/:(.*?)(\/|$)/, (x, y) => `${route.paramMap.get(y)}/`);
|
||||
|
||||
return this.http.get<T>(`api/${res}`)
|
||||
.pipe(
|
||||
catchError((error: HttpErrorResponse) =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open(`An unknown error occurred: ${error.message}.`, null, {
|
||||
horizontalPosition: "left",
|
||||
panelClass: ['snackError'],
|
||||
duration: 2500
|
||||
});
|
||||
return EMPTY;
|
||||
}));
|
||||
}
|
||||
}
|
||||
ItemResolver.resolvers.push(Resolver);
|
||||
return Resolver;
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ 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 res: string = resource.replace(/:(.*?)(\/|$)/, (x, y) => `${route.paramMap.get(y)}/`);
|
||||
|
||||
return this.http.get<Page<T>>(`api/${res}`)
|
||||
.pipe(
|
||||
|
@ -13,15 +13,15 @@ export class ShowResolverService implements Resolve<Show>
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot): Show | Observable<Show> | Promise<Show>
|
||||
{
|
||||
let slug: string = route.paramMap.get("show-slug");
|
||||
return this.http.get<Show>("api/shows/" + slug).pipe(catchError((error: HttpErrorResponse) =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
if (error.status == 404)
|
||||
this.snackBar.open("Show \"" + slug + "\" not found.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
else
|
||||
this.snackBar.open("An unknown error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
}));
|
||||
let slug: string = route.paramMap.get("show-slug");
|
||||
return this.http.get<Show>("api/shows/" + slug).pipe(catchError((error: HttpErrorResponse) =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
if (error.status == 404)
|
||||
this.snackBar.open("Show \"" + slug + "\" not found.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
else
|
||||
this.snackBar.open("An unknown error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {ExternalID} from "./external-id";
|
||||
import {IResource} from "./resources/resource";
|
||||
|
||||
export interface Episode
|
||||
export interface Episode extends IResource
|
||||
{
|
||||
seasonNumber: number;
|
||||
episodeNumber: number;
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Episode } from "./episode";
|
||||
import {ExternalID} from "./external-id";
|
||||
import {IResource} from "./resources/resource";
|
||||
|
||||
export interface Season
|
||||
export interface Season extends IResource
|
||||
{
|
||||
seasonNumber: number;
|
||||
title: string;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Season } from "./season";
|
||||
import { Genre } from "./genre";
|
||||
import { People } from "./people";
|
||||
import { Studio } from "./studio";
|
||||
import {Season} from "./season";
|
||||
import {Genre} from "./genre";
|
||||
import {People} from "./people";
|
||||
import {Studio} from "./studio";
|
||||
import {ExternalID} from "./external-id";
|
||||
import {IResource} from "./resources/resource";
|
||||
|
||||
export interface Show
|
||||
export interface Show extends IResource
|
||||
{
|
||||
slug: string;
|
||||
title: string;
|
||||
aliases: string[];
|
||||
overview: string;
|
||||
@ -16,7 +16,6 @@ export interface Show
|
||||
people: People[];
|
||||
seasons: Season[];
|
||||
trailerUrl: string;
|
||||
isCollection: boolean;
|
||||
isMovie: boolean;
|
||||
startYear: number;
|
||||
endYear : number;
|
||||
|
Loading…
x
Reference in New Issue
Block a user