From 44753c4634c78b3f56033af5e445d0cbfd927d58 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sat, 4 Apr 2020 15:30:26 +0200 Subject: [PATCH] Adding collections to the search page --- src/app/app.module.ts | 4 +- .../collections-list.component.html | 10 ++ .../collections-list.component.scss | 142 ++++++++++++++++++ .../collections-list.component.ts | 50 ++++++ src/app/search/search.component.html | 4 + src/app/search/search.component.ts | 4 +- src/app/services/search-resolver.service.ts | 8 +- src/models/search-result.ts | 4 +- 8 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 src/app/collection-list/collections-list.component.html create mode 100644 src/app/collection-list/collections-list.component.scss create mode 100644 src/app/collection-list/collections-list.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 10b3b828..13b9a07b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -34,6 +34,7 @@ import {FallbackDirective} from "./misc/fallback.directive"; import {AuthModule} from "./auth/auth.module"; import {AuthRoutingModule} from "./auth/auth-routing.module"; import { TrailerDialogComponent } from './trailer-dialog/trailer-dialog.component'; +import {CollectionsListComponent} from "./collection-list/collections-list.component"; @NgModule({ @@ -50,7 +51,8 @@ import { TrailerDialogComponent } from './trailer-dialog/trailer-dialog.componen ShowsListComponent, PasswordValidator, FallbackDirective, - TrailerDialogComponent + TrailerDialogComponent, + CollectionsListComponent ], imports: [ BrowserModule, diff --git a/src/app/collection-list/collections-list.component.html b/src/app/collection-list/collections-list.component.html new file mode 100644 index 00000000..682e4daf --- /dev/null +++ b/src/app/collection-list/collections-list.component.html @@ -0,0 +1,10 @@ +
+ + + +
diff --git a/src/app/collection-list/collections-list.component.scss b/src/app/collection-list/collections-list.component.scss new file mode 100644 index 00000000..9aecbf4a --- /dev/null +++ b/src/app/collection-list/collections-list.component.scss @@ -0,0 +1,142 @@ +@import "~bootstrap/scss/functions"; +@import "~bootstrap/scss/variables"; +@import "~bootstrap/scss/mixins/breakpoints"; + +.collections-container +{ + display: flex; + padding-left: 15px; + padding-right: 15px; + overflow-x: auto; + min-width: 100%; + flex-shrink: 0; + flex-direction: row; + + &::-webkit-scrollbar + { + height: 4px; + background: transparent; + } + + &::-webkit-scrollbar-thumb + { + background-color: #999; + border-radius: 90px; + + &:host-context(.hoverEnabled) &:hover + { + background-color: rgb(134, 127, 127); + } + } +} + +.collection +{ + width: 33%; + min-width: 120px; + max-width: 200px; + list-style: none; + padding: .5em; + text-decoration: none; + color: inherit; + outline: none; + flex-shrink: 0; + flex-grow: 0; + + @include media-breakpoint-up(sm) + { + width: 25%; + } + + @include media-breakpoint-up(md) + { + width: 20%; + padding: 1em; + } + + @include media-breakpoint-up(lg) + { + width: 18%; + } + + @include media-breakpoint-up(xl) + { + width: 15%; + } + + + &:focus, &:hover + { + > div + { + outline: solid var(--accentColor); + } + + > .title + { + text-decoration: underline; + } + } + + > div + { + width: 100%; + height: 0; + padding-top: 147.0588%; + background-size: cover; + background-color: #333333; + } + + > p + { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-align: center; + margin-bottom: 0px; + opacity: 1; + } + + &:host-context(.hoverEnabled) &:hover + { + cursor: pointer; + } +} + +.scroll-row +{ + position: relative; + + &:host-context(.hoverEnabled) &:hover + { + .scrollBtn + { + display: block; + } + } +} + +.scrollBtn +{ + padding: 0; + outline: none; + min-width: 0; + position: absolute; + top: 30%; + bottom: 40%; + display: none; + + &.leftBtn + { + left: 0; + padding-left: 10px; + padding-right: 2px; + } + + &.rightBtn + { + right: 0; + padding-right: 10px; + padding-left: 2px; + } +} diff --git a/src/app/collection-list/collections-list.component.ts b/src/app/collection-list/collections-list.component.ts new file mode 100644 index 00000000..1851e0db --- /dev/null +++ b/src/app/collection-list/collections-list.component.ts @@ -0,0 +1,50 @@ +import {Component, ElementRef, Input, ViewChild} from "@angular/core"; +import {Collection} from "../../models/collection"; +import {MatButton} from "@angular/material/button"; +import {DomSanitizer} from "@angular/platform-browser"; + +@Component({ + selector: 'app-collections-list', + templateUrl: './collections-list.component.html', + styleUrls: ['./collections-list.component.scss'] +}) +export class CollectionsListComponent +{ + @Input() collections: Collection[]; + @ViewChild("scrollView", {static: true}) private scrollView: ElementRef; + @ViewChild("leftBtn", {static: false}) private leftBtn: MatButton; + @ViewChild("rightBtn", {static: false}) private rightBtn: MatButton; + + constructor(private sanitizer: DomSanitizer) + { + } + + scrollLeft() + { + let scroll: number = this.scrollView.nativeElement.offsetWidth * 0.80; + this.scrollView.nativeElement.scrollBy({top: 0, left: -scroll, behavior: "smooth"}); + } + + scrollRight() + { + let scroll: number = this.scrollView.nativeElement.offsetWidth * 0.80; + this.scrollView.nativeElement.scrollBy({top: 0, left: scroll, behavior: "smooth"}); + } + + 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"); + } + + getThumb(slug: string) + { + return this.sanitizer.bypassSecurityTrustStyle("url(/poster/" + slug + ")"); + } +} \ No newline at end of file diff --git a/src/app/search/search.component.html b/src/app/search/search.component.html index cf75bcff..fd55ce73 100644 --- a/src/app/search/search.component.html +++ b/src/app/search/search.component.html @@ -1,3 +1,7 @@ +
+

Collections

+
+

Shows

diff --git a/src/app/search/search.component.ts b/src/app/search/search.component.ts index a92a7c56..d79f6657 100644 --- a/src/app/search/search.component.ts +++ b/src/app/search/search.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from "@angular/router"; -import { SearchResut } from "../../models/search-result"; +import { SearchResult } from "../../models/search-result"; import { Title } from "@angular/platform-browser"; @Component({ @@ -10,7 +10,7 @@ import { Title } from "@angular/platform-browser"; }) export class SearchComponent implements OnInit, OnDestroy { - items: SearchResut; + items: SearchResult; constructor(private route: ActivatedRoute, private title: Title) { } diff --git a/src/app/services/search-resolver.service.ts b/src/app/services/search-resolver.service.ts index ca579a0a..c6fd3984 100644 --- a/src/app/services/search-resolver.service.ts +++ b/src/app/services/search-resolver.service.ts @@ -4,19 +4,19 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; import { EMPTY, Observable } from 'rxjs'; import { catchError } from 'rxjs/operators'; -import { SearchResut } from "../../models/search-result"; +import { SearchResult } from "../../models/search-result"; @Injectable({ providedIn: 'root' }) -export class SearchResolverService implements Resolve +export class SearchResolverService implements Resolve { constructor(private http: HttpClient, private snackBar: MatSnackBar) { } - resolve(route: ActivatedRouteSnapshot): SearchResut | Observable | Promise + resolve(route: ActivatedRouteSnapshot): SearchResult | Observable | Promise { let query: string = route.paramMap.get("query"); - return this.http.get("api/search/" + query).pipe(catchError((error: HttpErrorResponse) => + return this.http.get("api/search/" + query).pipe(catchError((error: HttpErrorResponse) => { console.log(error.status + " - " + error.message); this.snackBar.open("An unknow error occured.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 }); diff --git a/src/models/search-result.ts b/src/models/search-result.ts index 671dd086..6416fea5 100644 --- a/src/models/search-result.ts +++ b/src/models/search-result.ts @@ -3,10 +3,12 @@ import { Episode } from "./episode"; import { People } from "./people"; import { Studio } from "./studio"; import { Genre } from "./genre"; +import {Collection} from "./collection"; -export interface SearchResut +export interface SearchResult { query: string; + collections: Collection[]; shows: Show[]; episodes: Episode[]; people: People[];