mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Adding collections to the search page
This commit is contained in:
parent
038e071450
commit
44753c4634
@ -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,
|
||||
|
10
src/app/collection-list/collections-list.component.html
Normal file
10
src/app/collection-list/collections-list.component.html
Normal file
@ -0,0 +1,10 @@
|
||||
<div class="scroll-row mb-5">
|
||||
<div class="collections-container" #scrollView (scroll)="onScroll()">
|
||||
<a class="collection" *ngFor="let collection of this.collections" routerLink="/collection/{{collection.slug}}" href="/collection/{{collection.slug}}">
|
||||
<div matRipple [style.background-image]="getThumb(collection.slug)"> </div>
|
||||
<p class="title">{{collection.name}}</p>
|
||||
</a>
|
||||
</div>
|
||||
<button mat-raised-button color="accent" class="scrollBtn leftBtn d-none" #leftBtn (click)="scrollLeft()"><mat-icon>arrow_left</mat-icon></button>
|
||||
<button mat-raised-button color="accent" class="scrollBtn rightBtn" #rightBtn (click)="scrollRight()"><mat-icon>arrow_right</mat-icon></button>
|
||||
</div>
|
142
src/app/collection-list/collections-list.component.scss
Normal file
142
src/app/collection-list/collections-list.component.scss
Normal file
@ -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;
|
||||
}
|
||||
}
|
50
src/app/collection-list/collections-list.component.ts
Normal file
50
src/app/collection-list/collections-list.component.ts
Normal file
@ -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 + ")");
|
||||
}
|
||||
}
|
@ -1,3 +1,7 @@
|
||||
<div *ngIf="items.collections.length > 0" class="container-fluid mt-3">
|
||||
<h3>Collections</h3>
|
||||
</div>
|
||||
<app-collections-list [collections]="items.collections"></app-collections-list>
|
||||
<div *ngIf="items.shows.length > 0" class="container-fluid mt-3">
|
||||
<h3>Shows</h3>
|
||||
</div>
|
||||
|
@ -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) { }
|
||||
|
||||
|
@ -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<SearchResut>
|
||||
export class SearchResolverService implements Resolve<SearchResult>
|
||||
{
|
||||
constructor(private http: HttpClient, private snackBar: MatSnackBar) { }
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot): SearchResut | Observable<SearchResut> | Promise<SearchResut>
|
||||
resolve(route: ActivatedRouteSnapshot): SearchResult | Observable<SearchResult> | Promise<SearchResult>
|
||||
{
|
||||
let query: string = route.paramMap.get("query");
|
||||
return this.http.get<SearchResut>("api/search/" + query).pipe(catchError((error: HttpErrorResponse) =>
|
||||
return this.http.get<SearchResult>("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 });
|
||||
|
@ -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[];
|
||||
|
Loading…
x
Reference in New Issue
Block a user