mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 18:24:14 -04:00
Adding a chip per genre (only loading genres once)
This commit is contained in:
parent
8d5ee797ec
commit
e4621bbdea
@ -40,6 +40,7 @@ import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
|||||||
import {MatExpansionModule} from "@angular/material/expansion";
|
import {MatExpansionModule} from "@angular/material/expansion";
|
||||||
import {InfiniteScrollModule} from "ngx-infinite-scroll";
|
import {InfiniteScrollModule} from "ngx-infinite-scroll";
|
||||||
import {ShowGridComponent} from "./components/show-grid/show-grid.component";
|
import {ShowGridComponent} from "./components/show-grid/show-grid.component";
|
||||||
|
import {MatBadgeModule} from "@angular/material/badge";
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -87,7 +88,8 @@ import {ShowGridComponent} from "./components/show-grid/show-grid.component";
|
|||||||
MatChipsModule,
|
MatChipsModule,
|
||||||
MatAutocompleteModule,
|
MatAutocompleteModule,
|
||||||
MatExpansionModule,
|
MatExpansionModule,
|
||||||
InfiniteScrollModule
|
InfiniteScrollModule,
|
||||||
|
MatBadgeModule
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<div class="container-fluid justify-content-center" *ngIf="this.sortEnabled">
|
<div class="container-fluid justify-content-center" *ngIf="this.sortEnabled">
|
||||||
<button mat-icon-button matTooltipPosition="below" matTooltip="Filter">
|
<button mat-icon-button matTooltipPosition="below" matTooltip="Filter" [matMenuTriggerFor]="filterMenu">
|
||||||
<mat-icon>filter_list</mat-icon>
|
<mat-icon [matBadge]="this.filters.length.toString()" [matBadgeHidden]="this.filters.length == 0"
|
||||||
|
matBadgeColor="warn" matBadgeSize="small">
|
||||||
|
filter_list
|
||||||
|
</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-button matTooltipPosition="below" matTooltip="Sort" [matMenuTriggerFor]="sortMenu">
|
<button mat-button matTooltipPosition="below" matTooltip="Sort" [matMenuTriggerFor]="sortMenu">
|
||||||
<mat-icon>sort</mat-icon> Sort by {{this.sortType}}
|
<mat-icon>sort</mat-icon> Sort by {{this.sortType}}
|
||||||
@ -9,6 +12,12 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<mat-menu #filterMenu="matMenu">
|
||||||
|
<mat-chip-list>
|
||||||
|
<mat-chip *ngFor="let genre of this.genres">{{genre.name}}</mat-chip>
|
||||||
|
</mat-chip-list>
|
||||||
|
</mat-menu>
|
||||||
|
|
||||||
<mat-menu #sortMenu="matMenu">
|
<mat-menu #sortMenu="matMenu">
|
||||||
<div *ngFor="let type of this.sortKeys">
|
<div *ngFor="let type of this.sortKeys">
|
||||||
<button *ngIf="type != this.sortType; else elseBlock;" mat-menu-item (click)="sort(type, true)">
|
<button *ngIf="type != this.sortType; else elseBlock;" mat-menu-item (click)="sort(type, true)">
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
import {DomSanitizer} from '@angular/platform-browser';
|
import {DomSanitizer} from '@angular/platform-browser';
|
||||||
|
import { Genre } from "../../../models/resources/genre";
|
||||||
import {LibraryItem} from "../../../models/resources/library-item";
|
import {LibraryItem} from "../../../models/resources/library-item";
|
||||||
import {Page} from "../../../models/page";
|
import {Page} from "../../../models/page";
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {Show, ShowRole} from "../../../models/resources/show";
|
import {Show, ShowRole} from "../../../models/resources/show";
|
||||||
import {Collection} from "../../../models/resources/collection";
|
import {Collection} from "../../../models/resources/collection";
|
||||||
import {ItemsUtils} from "../../misc/items-utils";
|
import {ItemsUtils} from "../../misc/items-utils";
|
||||||
|
import { PreLoaderService } from "../../services/pre-loader.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-items-grid',
|
selector: 'app-items-grid',
|
||||||
@ -20,15 +22,22 @@ export class ItemsGridComponent
|
|||||||
sortType: string = "title";
|
sortType: string = "title";
|
||||||
sortKeys: string[] = ["title", "start year", "end year"]
|
sortKeys: string[] = ["title", "start year", "end year"]
|
||||||
sortUp: boolean = true;
|
sortUp: boolean = true;
|
||||||
|
filters: string[] = [];
|
||||||
|
genres: Genre[];
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private sanitizer: DomSanitizer,
|
private sanitizer: DomSanitizer,
|
||||||
|
private loader: PreLoaderService,
|
||||||
public client: HttpClient)
|
public client: HttpClient)
|
||||||
{
|
{
|
||||||
this.route.data.subscribe((data) =>
|
this.route.data.subscribe((data) =>
|
||||||
{
|
{
|
||||||
this.page = data.items;
|
this.page = data.items;
|
||||||
});
|
});
|
||||||
|
this.loader.load<Genre>("/api/genres?limit=0").subscribe(data =>
|
||||||
|
{
|
||||||
|
this.genres = data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumb(slug: string)
|
getThumb(slug: string)
|
||||||
|
27
src/app/services/pre-loader.service.ts
Normal file
27
src/app/services/pre-loader.service.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { HttpClient } from "@angular/common/http";
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Page } from "../../models/page";
|
||||||
|
import { Observable, of } from "rxjs"
|
||||||
|
import { map } from "rxjs/operators"
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class PreLoaderService
|
||||||
|
{
|
||||||
|
private cache: [string, any[]][] = [];
|
||||||
|
|
||||||
|
constructor(private http: HttpClient) { }
|
||||||
|
|
||||||
|
load<T>(route: string): Observable<T[]>
|
||||||
|
{
|
||||||
|
let loaded = this.cache.find(x => x[0] == route);
|
||||||
|
if (loaded != null)
|
||||||
|
return of(loaded[1]);
|
||||||
|
return this.http.get<Page<T>>(route).pipe(map(newData =>
|
||||||
|
{
|
||||||
|
this.cache.push([route, newData.items]);
|
||||||
|
return newData.items;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
241
tslint.json
241
tslint.json
@ -1,92 +1,153 @@
|
|||||||
{
|
{
|
||||||
"extends": "tslint:recommended",
|
"extends": "tslint:recommended",
|
||||||
"rules": {
|
"rulesDirectory": [
|
||||||
"array-type": false,
|
"codelyzer"
|
||||||
"arrow-parens": false,
|
],
|
||||||
"deprecation": {
|
"rules": {
|
||||||
"severity": "warning"
|
"align": {
|
||||||
},
|
"options": [
|
||||||
"component-class-suffix": true,
|
"parameters",
|
||||||
"contextual-lifecycle": true,
|
"statements"
|
||||||
"directive-class-suffix": true,
|
]
|
||||||
"directive-selector": [
|
},
|
||||||
true,
|
"array-type": false,
|
||||||
"attribute",
|
"arrow-return-shorthand": true,
|
||||||
"app",
|
"curly": true,
|
||||||
"camelCase"
|
"deprecation": {
|
||||||
],
|
"severity": "warning"
|
||||||
"component-selector": [
|
},
|
||||||
true,
|
"eofline": true,
|
||||||
"element",
|
"import-blacklist": [
|
||||||
"app",
|
true,
|
||||||
"kebab-case"
|
"rxjs/Rx"
|
||||||
],
|
],
|
||||||
"import-blacklist": [
|
"import-spacing": true,
|
||||||
true,
|
"indent": {
|
||||||
"rxjs/Rx"
|
"options": [
|
||||||
],
|
"tabs"
|
||||||
"interface-name": false,
|
]
|
||||||
"max-classes-per-file": false,
|
},
|
||||||
"max-line-length": [
|
"max-classes-per-file": false,
|
||||||
true,
|
"max-line-length": [
|
||||||
140
|
true,
|
||||||
],
|
120
|
||||||
"member-access": false,
|
],
|
||||||
"member-ordering": [
|
"member-ordering": [
|
||||||
true,
|
true,
|
||||||
{
|
{
|
||||||
"order": [
|
"order": [
|
||||||
"static-field",
|
"static-field",
|
||||||
"instance-field",
|
"instance-field",
|
||||||
"static-method",
|
"static-method",
|
||||||
"instance-method"
|
"instance-method"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"no-consecutive-blank-lines": false,
|
"no-console": [
|
||||||
"no-console": [
|
true,
|
||||||
true,
|
"debug",
|
||||||
"debug",
|
"info",
|
||||||
"info",
|
"time",
|
||||||
"time",
|
"timeEnd",
|
||||||
"timeEnd",
|
"trace"
|
||||||
"trace"
|
],
|
||||||
],
|
"no-empty": false,
|
||||||
"no-empty": false,
|
"no-inferrable-types": [
|
||||||
"no-inferrable-types": [
|
true,
|
||||||
true,
|
"ignore-params"
|
||||||
"ignore-params"
|
],
|
||||||
],
|
"no-non-null-assertion": true,
|
||||||
"no-non-null-assertion": true,
|
"no-redundant-jsdoc": true,
|
||||||
"no-redundant-jsdoc": true,
|
"no-switch-case-fall-through": true,
|
||||||
"no-switch-case-fall-through": true,
|
"no-var-requires": false,
|
||||||
"no-use-before-declare": true,
|
"object-literal-key-quotes": [
|
||||||
"no-var-requires": false,
|
true,
|
||||||
"object-literal-key-quotes": [
|
"as-needed"
|
||||||
true,
|
],
|
||||||
"as-needed"
|
"quotemark": [
|
||||||
],
|
true,
|
||||||
"object-literal-sort-keys": false,
|
"double"
|
||||||
"ordered-imports": false,
|
],
|
||||||
"quotemark": [
|
"semicolon": {
|
||||||
true,
|
"options": [
|
||||||
"single"
|
"always"
|
||||||
],
|
]
|
||||||
"trailing-comma": false,
|
},
|
||||||
"no-conflicting-lifecycle": true,
|
"space-before-function-paren": {
|
||||||
"no-host-metadata-property": true,
|
"options": {
|
||||||
"no-input-rename": true,
|
"anonymous": "never",
|
||||||
"no-inputs-metadata-property": true,
|
"asyncArrow": "always",
|
||||||
"no-output-native": true,
|
"constructor": "never",
|
||||||
"no-output-on-prefix": true,
|
"method": "never",
|
||||||
"no-output-rename": true,
|
"named": "never"
|
||||||
"no-outputs-metadata-property": true,
|
}
|
||||||
"template-banana-in-box": true,
|
},
|
||||||
"template-no-negated-async": true,
|
"typedef": [
|
||||||
"use-lifecycle-interface": true,
|
true,
|
||||||
"use-pipe-transform-interface": true
|
"call-signature"
|
||||||
},
|
],
|
||||||
"rulesDirectory": [
|
"typedef-whitespace": {
|
||||||
"codelyzer"
|
"options": [
|
||||||
]
|
{
|
||||||
|
"call-signature": "nospace",
|
||||||
|
"index-signature": "nospace",
|
||||||
|
"parameter": "nospace",
|
||||||
|
"property-declaration": "nospace",
|
||||||
|
"variable-declaration": "nospace"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"call-signature": "onespace",
|
||||||
|
"index-signature": "onespace",
|
||||||
|
"parameter": "onespace",
|
||||||
|
"property-declaration": "onespace",
|
||||||
|
"variable-declaration": "onespace"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"variable-name": {
|
||||||
|
"options": [
|
||||||
|
"ban-keywords",
|
||||||
|
"check-format",
|
||||||
|
"allow-pascal-case"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"whitespace": {
|
||||||
|
"options": [
|
||||||
|
"check-branch",
|
||||||
|
"check-decl",
|
||||||
|
"check-operator",
|
||||||
|
"check-separator",
|
||||||
|
"check-type",
|
||||||
|
"check-typecast",
|
||||||
|
"check-module"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"component-class-suffix": true,
|
||||||
|
"contextual-lifecycle": true,
|
||||||
|
"directive-class-suffix": true,
|
||||||
|
"no-conflicting-lifecycle": true,
|
||||||
|
"no-host-metadata-property": true,
|
||||||
|
"no-input-rename": true,
|
||||||
|
"no-inputs-metadata-property": true,
|
||||||
|
"no-output-native": true,
|
||||||
|
"no-output-on-prefix": true,
|
||||||
|
"no-output-rename": true,
|
||||||
|
"no-outputs-metadata-property": true,
|
||||||
|
"template-banana-in-box": true,
|
||||||
|
"template-no-negated-async": true,
|
||||||
|
"use-lifecycle-interface": true,
|
||||||
|
"use-pipe-transform-interface": true,
|
||||||
|
"directive-selector": [
|
||||||
|
true,
|
||||||
|
"attribute",
|
||||||
|
"app",
|
||||||
|
"camelCase"
|
||||||
|
],
|
||||||
|
"component-selector": [
|
||||||
|
true,
|
||||||
|
"element",
|
||||||
|
"app",
|
||||||
|
"kebab-case"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user