Finishing the progress bar, theming the material app and creating resolvers.

This commit is contained in:
Zoe Roux 2019-08-22 21:51:08 +02:00
parent edc5def19a
commit 82d61506a2
11 changed files with 199 additions and 84 deletions

View File

@ -133,6 +133,23 @@
"tslib": "^1.9.0"
}
},
"@angular/cdk": {
"version": "8.1.3",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-8.1.3.tgz",
"integrity": "sha512-+DOS6x05/nNdnoRmEi3bgQxKym34PeCRGD6dimdw0l7ZgM57qhlaBWo0dXB7QSyR9E44uVT91e4h8ye+/ne1DQ==",
"requires": {
"parse5": "^5.0.0",
"tslib": "^1.7.1"
},
"dependencies": {
"parse5": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
"integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
"optional": true
}
}
},
"@angular/cli": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-8.2.1.tgz",
@ -976,6 +993,14 @@
"integrity": "sha512-BTCYLiSz1TUKAyIGnYI3X5zhf4R5wGQZjYIaUnl8iWLIGG6zAmz++9mgDRlnP12u/6KEotJYzqllH72blxWGHw==",
"dev": true
},
"@angular/material": {
"version": "8.1.3",
"resolved": "https://registry.npmjs.org/@angular/material/-/material-8.1.3.tgz",
"integrity": "sha512-qZVWrJ/EO1y0lJCy7pe536RlYiih3p3fQzj7tgus7JdOpspyF+zBLzn8gNrdAFACXpVWwq2kLorieoR3BB47ZQ==",
"requires": {
"tslib": "^1.7.1"
}
},
"@angular/platform-browser": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.2.1.tgz",
@ -5931,7 +5956,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}

View File

@ -12,10 +12,12 @@
"private": true,
"dependencies": {
"@angular/animations": "~8.2.0",
"@angular/cdk": "^8.1.3",
"@angular/common": "~8.2.0",
"@angular/compiler": "~8.2.0",
"@angular/core": "~8.2.0",
"@angular/forms": "~8.2.0",
"@angular/material": "^8.1.3",
"@angular/platform-browser": "~8.2.0",
"@angular/platform-browser-dynamic": "~8.2.0",
"@angular/router": "~8.2.0",

View File

@ -4,17 +4,20 @@ import { Routes, RouterModule } from '@angular/router';
import { BrowseComponent } from './browse/browse.component';
import { ShowDetailsComponent } from './show-details/show-details.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { ShowResolverService } from './services/show-resolver.service';
import { LibraryResolverService } from './services/library-resolver.service';
const routes: Routes = [
{ path: "browse", component: BrowseComponent, pathMatch: "full" },
{ path: "browse/:library-slug", component: BrowseComponent },
{ path: "shows/:show-slug", component: ShowDetailsComponent },
{ path: "browse", component: BrowseComponent, pathMatch: "full", resolve: { shows: LibraryResolverService } },
{ path: "browse/:library-slug", component: BrowseComponent, resolve: { shows: LibraryResolverService } },
{ path: "shows/:show-slug", component: ShowDetailsComponent, resolve: { show: ShowResolverService } },
{ path: "**", component: NotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
exports: [RouterModule],
providers: [LibraryResolverService, ShowResolverService]
})
export class AppRoutingModule { }

View File

@ -1,35 +1,38 @@
<header style="height: 64px;">
<nav class="navbar fixed-top navbar-dark bg-secondary">
<a class="navbar-brand nav-item ml-3" routerLink="/">
Kyoo
</a>
<header style="height: 68px;">
<div class="fixed-top">
<nav class="navbar navbar-dark bg-secondary">
<a class="navbar-brand nav-item ml-3" routerLink="/">
Kyoo
</a>
<ul class="navbar-nav flex-row">
<li class="nav-item">
<a class="nav-link" routerLink="/browse" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">All</a>
</li>
<li class="nav-item" *ngFor="let library of this.libraries">
<a class="nav-link" routerLink="/browse/{{library.slug}}" routerLinkActive="active">{{library.name}}</a>
</li>
</ul>
<ul class="navbar-nav flex-row">
<li class="nav-item">
<a class="nav-link" routerLink="/browse" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">All</a>
</li>
<li class="nav-item" *ngFor="let library of this.libraries">
<a class="nav-link" routerLink="/browse/{{library.slug}}" routerLinkActive="active">{{library.name}}</a>
</li>
</ul>
<ul class="navbar-nav flex-row ml-auto">
<li class="nav-item icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>Search</title>
<path fill="#ffffff" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
</li>
<li class="nav-item">
<a class="icon" routerLink="/login" routerLinkActive="active">
<ul class="navbar-nav flex-row ml-auto">
<li class="nav-item icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>Account</title>
<path fill="#ffffff" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z" />
<title>Search</title>
<path fill="#ffffff" d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
</svg>
</a>
</li>
</ul>
</nav>
</li>
<li class="nav-item">
<a class="icon" routerLink="/login" routerLinkActive="active">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>Account</title>
<path fill="#ffffff" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z" />
</svg>
</a>
</li>
</ul>
</nav>
<mat-progress-bar *ngIf="this.isLoading" color="accent" mode="indeterminate"> </mat-progress-bar>
</div>
</header>
<main >

View File

@ -1,5 +1,6 @@
import { Component, Inject } from '@angular/core';
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Event, Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
@Component({
selector: 'app-root',
@ -9,13 +10,38 @@ import { HttpClient } from '@angular/common/http';
export class AppComponent
{
libraries: Library[];
isLoading: boolean = false;
constructor(http: HttpClient)
constructor(http: HttpClient, private router: Router)
{
http.get<Library[]>("api/libraries").subscribe(result =>
{
this.libraries = result;
}, error => console.error(error));
this.router.events.subscribe((event: Event) =>
{
switch (true)
{
case event instanceof NavigationStart:
{
this.isLoading = true;
break;
}
case event instanceof NavigationEnd:
case event instanceof NavigationCancel:
case event instanceof NavigationError:
{
this.isLoading = false;
break;
}
default:
{
break;
}
}
});
}
}

View File

@ -7,6 +7,9 @@ import { AppComponent } from './app.component';
import { NotFoundComponent } from './not-found/not-found.component';
import { BrowseComponent } from './browse/browse.component';
import { ShowDetailsComponent } from './show-details/show-details.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatProgressBarModule } from '@angular/material/progress-bar';
@NgModule({
declarations: [
@ -18,7 +21,10 @@ import { ShowDetailsComponent } from './show-details/show-details.component';
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule
AppRoutingModule,
BrowserAnimationsModule,
MatSnackBarModule,
MatProgressBarModule
],
providers: [],
bootstrap: [AppComponent]

View File

@ -1,7 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer, SafeStyle } from '@angular/platform-browser';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-browse',
@ -12,36 +11,11 @@ export class BrowseComponent implements OnInit
{
shows: Show[];
private watch: any;
constructor(private http: HttpClient, private route: ActivatedRoute, private sanitizer: DomSanitizer) {}
constructor(private route: ActivatedRoute, private sanitizer: DomSanitizer) { }
ngOnInit()
{
this.watch = this.route.params.subscribe(params =>
{
var slug: string = params["library-slug"];
if (slug == null)
{
this.http.get<Show[]>("api/shows").subscribe(result =>
{
this.shows = result;
}, error => console.log(error));
}
else
{
this.http.get<Show[]>("api/library/" + slug).subscribe(result =>
{
this.shows = result;
}, error => console.log(error));
}
});
}
ngOnDestroy()
{
this.watch.unsubscribe();
this.shows = this.route.snapshot.data.shows;
}
getThumb(slug: string)

View File

@ -0,0 +1,44 @@
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, EMPTY } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material/snack-bar';
@Injectable()
export class LibraryResolverService implements Resolve<Show[]>
{
constructor(private http: HttpClient, private snackBar: MatSnackBar) { console.log("Library Resolver Created"); }
resolve(route: ActivatedRouteSnapshot): Show[] | Observable<Show[]> | Promise<Show[]>
{
let slug: string = route.paramMap.get("library-slug");
if (slug == null)
{
return this.http.get<Show[]>("api/shows").pipe(catchError((error: HttpErrorResponse) =>
{
console.log(error.status + " - " + error.message);
this.snackBar.open("An unknow error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
return EMPTY;
}));
}
else
{
return this.http.get<Show[]>("api/library/" + slug).pipe(catchError((error: HttpErrorResponse) =>
{
console.log(error.status + " - " + error.message);
if (error.status == 404)
{
this.snackBar.open("Library \"" + slug + "\" not found.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
}
else
{
this.snackBar.open("An unknow error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
}
return EMPTY;
}));
}
}
}

View File

@ -0,0 +1,31 @@
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable, EMPTY } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { MatSnackBar } from '@angular/material/snack-bar';
@Injectable()
export class ShowResolverService implements Resolve<Show>
{
constructor(private http: HttpClient, private snackBar: MatSnackBar) { }
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 unknow error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
}
return EMPTY;
}));
}
}

View File

@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-show-details',
@ -11,26 +10,10 @@ export class ShowDetailsComponent implements OnInit
{
show: Show;
private watch: any;
constructor(private http: HttpClient, private route: ActivatedRoute) { }
constructor(private route: ActivatedRoute) { }
ngOnInit()
{
this.watch = this.route.params.subscribe(params =>
{
var slug: string = params["show-slug"];
this.http.get<Show>("api/shows/" + slug).subscribe(result =>
{
this.show = result;
}, error => console.log(error));
});
this.show = this.route.snapshot.data.show;
}
ngOnDestroy()
{
this.watch.unsubscribe();
}
}

View File

@ -1,3 +1,4 @@
//Bootstrap configuration
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@ -12,3 +13,21 @@ $body-bg: theme-color("primary");
$body-color: theme-color("textPrimary");
@import "~bootstrap/scss/bootstrap";
//Material Angular Configuration
@import '~@angular/material/theming';
@include mat-core();
// Define the default theme (same as the example above).
$primary: (default: #0a1128);
$accent: (default: #e23c00, lighter: #ff9149);
$theme: mat-light-theme($primary, $accent);
// Include the default theme styles.
@include angular-material-theme($theme);
.snackError {
background-color: theme-color("accentColor");
color: theme-color("textPrimary");
}