mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 10:14:13 -04:00
Adding a metadata editor for shows
This commit is contained in:
parent
e0c9b1f4d8
commit
6801bb620c
@ -35,6 +35,9 @@ 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";
|
||||
import { MetadataEditComponent } from './metadata-edit/metadata-edit.component';
|
||||
import {MatChipsModule} from "@angular/material/chips";
|
||||
import {MatAutocompleteModule} from "@angular/material/autocomplete";
|
||||
|
||||
|
||||
@NgModule({
|
||||
@ -52,7 +55,8 @@ import {CollectionsListComponent} from "./collection-list/collections-list.compo
|
||||
PasswordValidator,
|
||||
FallbackDirective,
|
||||
TrailerDialogComponent,
|
||||
CollectionsListComponent
|
||||
CollectionsListComponent,
|
||||
MetadataEditComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
@ -77,7 +81,9 @@ import {CollectionsListComponent} from "./collection-list/collections-list.compo
|
||||
FormsModule,
|
||||
MatTabsModule,
|
||||
MatCheckboxModule,
|
||||
AuthModule
|
||||
AuthModule,
|
||||
MatChipsModule,
|
||||
MatAutocompleteModule
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
68
src/app/metadata-edit/metadata-edit.component.html
Normal file
68
src/app/metadata-edit/metadata-edit.component.html
Normal file
@ -0,0 +1,68 @@
|
||||
<h2 mat-dialog-title>Editing metadata of {{this.show.title}}</h2>
|
||||
<div matDialogContent>
|
||||
<form #showForm="ngForm">
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Title</mat-label>
|
||||
<input matInput [(ngModel)]="this.show.title" name="title">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Overview</mat-label>
|
||||
<textarea matInput [(ngModel)]="this.show.overview" name="overview"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="w-25 pr-3">
|
||||
<mat-label>Start Year</mat-label>
|
||||
<input matInput [(ngModel)]="this.show.startYear" name="startYear" type="number" [max]="this.show.endYear"/>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-25 pr-3">
|
||||
<mat-label>End Year</mat-label>
|
||||
<input matInput [(ngModel)]="this.show.endYear" name="endYear" type="number" [min]="this.show.startYear"/>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="w-50">
|
||||
<mat-label>Status</mat-label>
|
||||
<mat-select>
|
||||
<mat-option value="Finished">Finished</mat-option>
|
||||
<mat-option value="Airing">Airing</mat-option>
|
||||
<mat-option value="Planned">Planned</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Genres</mat-label>
|
||||
<mat-chip-list #genreList>
|
||||
<mat-chip *ngFor="let genre of this.show.genres" (removed)="removeGenre(genre)" removable="true">
|
||||
{{genre.name}}
|
||||
<mat-icon matChipRemove>cancel</mat-icon>
|
||||
</mat-chip>
|
||||
<input #genreInput placeholder="New genre..." [matChipInputFor]="genreList" (matChipInputTokenEnd)="addGenre($event)"
|
||||
[matAutocomplete]="genreAuto" />
|
||||
<mat-autocomplete #genreAuto="matAutocomplete" (optionSelected)="autocompleteGenre($event)">
|
||||
<mat-option *ngFor="let genre of this.allGenres" [value]="genre">
|
||||
{{genre.name}}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-chip-list>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Trailer</mat-label>
|
||||
<input matInput [(ngModel)]="this.show.trailerUrl" name="trailer">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="w-100">
|
||||
<mat-label>Studio</mat-label>
|
||||
<input matInput [value]="this.show.studio?.name" (input)="this.show.studio = {slug: null, name: $event.target.value}"
|
||||
[matAutocomplete]="studioAuto" name="studio">
|
||||
<mat-autocomplete #studioAuto="matAutocomplete">
|
||||
<mat-option *ngFor="let studio of this.allStudios" [value]="studio.name">
|
||||
{{studio.name}}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</div>
|
||||
<div mat-dialog-actions align="end">
|
||||
<button mat-button mat-dialog-close>Cancel</button>
|
||||
<button mat-button (click)="apply()">Apply</button>
|
||||
</div>
|
0
src/app/metadata-edit/metadata-edit.component.scss
Normal file
0
src/app/metadata-edit/metadata-edit.component.scss
Normal file
71
src/app/metadata-edit/metadata-edit.component.ts
Normal file
71
src/app/metadata-edit/metadata-edit.component.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import {Component, ElementRef, Inject, OnInit, ViewChild} from '@angular/core';
|
||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {Show} from "../../models/show";
|
||||
import {Genre} from "../../models/genre";
|
||||
import {MatChipInputEvent} from "@angular/material/chips";
|
||||
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
|
||||
import {FormControl} from "@angular/forms";
|
||||
import {Studio} from "../../models/studio";
|
||||
|
||||
@Component({
|
||||
selector: 'app-metadata-edit',
|
||||
templateUrl: './metadata-edit.component.html',
|
||||
styleUrls: ['./metadata-edit.component.scss']
|
||||
})
|
||||
export class MetadataEditComponent implements OnInit
|
||||
{
|
||||
@ViewChild("genreInput") genreInput: ElementRef<HTMLInputElement>;
|
||||
|
||||
private allGenres: Genre[];
|
||||
private allStudios: Studio[];
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<MetadataEditComponent>, @Inject(MAT_DIALOG_DATA) public show: Show, private http: HttpClient)
|
||||
{
|
||||
this.http.get<Genre[]>("/api/genres").subscribe(result =>
|
||||
{
|
||||
this.allGenres = result;
|
||||
});
|
||||
this.http.get<Studio[]>("/api/studios").subscribe(result =>
|
||||
{
|
||||
this.allStudios = result;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
}
|
||||
|
||||
apply(): void
|
||||
{
|
||||
this.http.post("/api/show/edit/" + this.show.slug, this.show).subscribe(() =>
|
||||
{
|
||||
this.dialogRef.close(this.show);
|
||||
});
|
||||
}
|
||||
|
||||
addGenre(event: MatChipInputEvent)
|
||||
{
|
||||
const input = event.input;
|
||||
const value = event.value;
|
||||
let genre: Genre = {slug: null, name: value};
|
||||
|
||||
this.show.genres.push(genre);
|
||||
if (input)
|
||||
input.value = "";
|
||||
}
|
||||
|
||||
removeGenre(genre: Genre): void
|
||||
{
|
||||
console.log("Removing a genre");
|
||||
console.log(genre);
|
||||
const i = this.show.genres.indexOf(genre);
|
||||
this.show.genres.splice(i, 1);
|
||||
}
|
||||
|
||||
autocompleteGenre(event: MatAutocompleteSelectedEvent): void
|
||||
{
|
||||
this.show.genres.push(event.option.value);
|
||||
this.genreInput.nativeElement.value = '';
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@
|
||||
<button mat-icon-button matTooltipPosition="above" matTooltip="Watched">
|
||||
<mat-icon>done</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button matTooltipPosition="above" matTooltip="More">
|
||||
<button mat-icon-button matTooltipPosition="above" matTooltip="More" [matMenuTriggerFor]="showMenu">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
@ -39,12 +39,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-menu #showMenu="matMenu">
|
||||
<button mat-menu-item (click)="editMetadata()">Edit metadata</button>
|
||||
</mat-menu>
|
||||
|
||||
<div class="row pt-3 d-md-none">
|
||||
<div class="col">
|
||||
<p class="mr-1 d-inline-block">Studio: <b><a routerLink="/studio/{{this.show.studio?.slug}}">{{this.show.studio?.name}}</a></b></p>
|
||||
<div class="d-sm-none">
|
||||
<p>Genres: <span *ngFor="let genre of this.show.genres; let isLast = last"><b><a routerLink="/genre/{{genre.slug}}">{{genre.name}}</a></b>{{isLast ? "" : ", "}}</span></p>
|
||||
<p>Genres: <span *ngFor="let genre of this.show.genres; let isLast = last"><b><a routerLink="/genre/{{genre.slug}}">{{genre.name}}</a></b>{{isLast ? "" : ", "}}</span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,6 +7,8 @@ import { Episode } from "../../models/episode";
|
||||
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";
|
||||
|
||||
@Component({
|
||||
selector: 'app-show-details',
|
||||
@ -92,6 +94,15 @@ export class ShowDetailsComponent implements OnInit
|
||||
|
||||
openTrailer()
|
||||
{
|
||||
this.dialog.open(TrailerDialogComponent, {width: "80%", height: "45vw", data: this.show.trailerUrl});
|
||||
this.dialog.open(TrailerDialogComponent, {width: "80%", height: "45vw", data: this.show.trailerUrl, panelClass: "panel"});
|
||||
}
|
||||
|
||||
editMetadata()
|
||||
{
|
||||
this.dialog.open(MetadataEditComponent, {width: "80%", data: this.show}).afterClosed().subscribe((result: Show) =>
|
||||
{
|
||||
if (result)
|
||||
this.show = result;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
.panel .mat-dialog-container
|
||||
{
|
||||
overflow-y: hidden;
|
||||
}
|
@ -7,7 +7,7 @@ export interface Show
|
||||
{
|
||||
slug: string;
|
||||
title: string;
|
||||
Aliases: string[];
|
||||
aliases: string[];
|
||||
overview: string;
|
||||
genres: Genre[];
|
||||
status: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user