Feature/local metadata more tags (#832)

* Stashing code

* removed some debug code on series detail page. Now detail is collapsed by default.

* Added AgeRating

* Fixed a crash when NetVips tries to write a cover file and cover directory is not existing.

* When a card is selected for bulk actions, show an outline in addition to select box

* Added AgeRating into the metadata parsing. Added a hack where ComicInfo uses Number in ComicInfo rather than Volume. This is to test out the effects on users libraries.

* Added AgeRating and ReleaseDate to the metadata implelentation.
This commit is contained in:
Joseph Milazzo 2021-12-06 13:59:47 -06:00 committed by GitHub
parent 46f37069db
commit af24c928d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 2825 additions and 101 deletions

View file

@ -19,7 +19,10 @@ export interface Chapter {
created: string;
titleName: string;
year: string;
/**
* This is only Year and Month, Day is not supported from underlying sources
*/
releaseDate: string;
writers: Array<Person>;
penciller: Array<Person>;
inker: Array<Person>;

View file

@ -0,0 +1,15 @@
export enum AgeRating {
Unknown = 0,
AdultsOnly = 1,
EarlyChildhood = 2,
Everyone = 3,
Everyone10Plus = 4,
G = 5,
KidsToAdults = 6,
Mature = 7,
Mature15Plus = 8,
Mature17Plus = 9,
RatingPending = 10,
Teen = 11,
X18Plus = 12
}

View file

@ -1,5 +1,6 @@
import { CollectionTag } from "./collection-tag";
import { Genre } from "./genre";
import { AgeRating } from "./metadata/age-rating";
import { Person } from "./person";
export interface SeriesMetadata {
@ -16,6 +17,7 @@ export interface SeriesMetadata {
colorists: Array<Person>;
letterers: Array<Person>;
editors: Array<Person>;
ageRating: AgeRating;
releaseYear: number;
seriesId: number;
}

View file

@ -1,7 +1,10 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { ChapterMetadata } from '../_models/chapter-metadata';
import { AgeRating } from '../_models/metadata/age-rating';
@Injectable({
providedIn: 'root'
@ -10,9 +13,25 @@ export class MetadataService {
baseUrl = environment.apiUrl;
private ageRatingTypes: {[key: number]: string} | undefined = undefined;
constructor(private httpClient: HttpClient) { }
getChapterMetadata(chapterId: number) {
return this.httpClient.get<ChapterMetadata>(this.baseUrl + 'series/chapter-metadata?chapterId=' + chapterId);
// getChapterMetadata(chapterId: number) {
// return this.httpClient.get<ChapterMetadata>(this.baseUrl + 'series/chapter-metadata?chapterId=' + chapterId);
// }
getAgeRating(ageRating: AgeRating) {
if (this.ageRatingTypes != undefined && this.ageRatingTypes.hasOwnProperty(ageRating)) {
return of(this.ageRatingTypes[ageRating]);
}
return this.httpClient.get<string>(this.baseUrl + 'series/age-rating?ageRating=' + ageRating, {responseType: 'text' as 'json'}).pipe(map(l => {
if (this.ageRatingTypes === undefined) {
this.ageRatingTypes = {};
}
this.ageRatingTypes[ageRating] = l;
return this.ageRatingTypes[ageRating];
}));
}
}

View file

@ -1,4 +1,4 @@
<div class="card">
<div class="card {{selected ? 'selected-highlight' : ''}}">
<div class="overlay" (click)="handleClick($event)">
<img *ngIf="total > 0 || supressArchiveWarning" class="img-top lazyload" [src]="imageService.placeholderImage" [attr.data-src]="imageUrl"
(error)="imageService.updateErroredImage($event)" aria-hidden="true" height="230px" width="158px">

View file

@ -38,6 +38,9 @@ $image-width: 160px;
margin-bottom: 0px;
}
.selected-highlight {
outline: 2px solid colors.$primary-color;
}
.img-top {

View file

@ -1,14 +1,14 @@
<ng-container *ngIf="chapter !== undefined">
<div class="container-fluid">
<h4>{{chapter.range}}</h4>
Title: {{chapter.titleName || '-'}}
<!-- Year: {{metadata.year || '-'}} -->
Arc Information
<!-- <h4>{{libraryType !== LibraryType.Comic ? 'Chapter ' : 'Issue #'}} {{chapter.number}} <span title="Id">({{chapter.id}})</span></h4> -->
<!-- Arc Information -->
<div class="row no-gutters">
<div class="col">
Id: {{chapter.id}}
Title: {{chapter.titleName || '-'}}
</div>
<div class="col">
Pages: {{chapter.pages}}
@ -20,7 +20,7 @@
Added: {{(chapter.created | date: 'short') || '-'}}
</div>
<div class="col">
Pages: {{chapter.pages}}
Release Date: {{(chapter.releaseDate | date: 'shortDate') || '-'}}
</div>
</div>
</div>
@ -33,7 +33,8 @@
<div class="media-body">
<h5 class="mt-0 mb-1">
<span *ngIf="chapter.number !== '0'; else specialHeader">
<!-- <span>
<!-- TODO: Add back in
<span>
<app-card-actionables (actionHandler)="performAction($event, chapter)" [actions]="chapterActions" [labelBy]="utilityService.formatChapterName(libraryType, true, true) + formatChapterNumber(chapter)"></app-card-actionables>&nbsp;
{{utilityService.formatChapterName(libraryType, true, false) }} {{formatChapterNumber(chapter)}}
</span> -->

View file

@ -55,16 +55,16 @@
<app-read-more [text]="seriesSummary" [maxLength]="250"></app-read-more>
</div>
<div *ngIf="seriesMetadata" class="mt-2">
<app-series-metadata-detail [seriesMetadata]="seriesMetadata"></app-series-metadata-detail>
<app-series-metadata-detail [seriesMetadata]="seriesMetadata" [series]="series"></app-series-metadata-detail>
<div class="row no-gutters mt-1" *ngIf="series.format != MangaFormat.UNKNOWN">
<!-- <div class="row no-gutters mt-1" *ngIf="series.format != MangaFormat.UNKNOWN">
<div class="col-md-4">
<h5>Type</h5>
</div>
<div class="col-md-8">
<app-tag-badge [selectionMode]="TagBadgeCursor.NotAllowed"><app-series-format [format]="series.format">{{utilityService.mangaFormat(series.format)}}</app-series-format></app-tag-badge>
</div>
</div>
</div> -->
</div>

View file

@ -1,3 +1,16 @@
<!-- This first row will have random information about the series-->
<div class="row no-gutters" *ngIf="seriesMetadata.ageRating">
<app-tag-badge title="Age Rating">{{ageRatingName}}</app-tag-badge>
<ng-container *ngIf="series">
<!-- Maybe we can put the library this resides in to make it easier to get back -->
<!-- tooltip here explaining how this is year of first issue -->
<app-tag-badge *ngIf="seriesMetadata.releaseYear > 0" title="Release date">{{seriesMetadata.releaseYear}}</app-tag-badge>
<app-tag-badge [selectionMode]="TagBadgeCursor.NotAllowed">
<app-series-format [format]="series.format">{{utilityService.mangaFormat(series.format)}}</app-series-format>
</app-tag-badge>
</ng-container>
</div>
<div class="row no-gutters" *ngIf="seriesMetadata.genres && seriesMetadata.genres.length > 0">
<div class="col-md-4">
<h5>Genres</h5>
@ -31,7 +44,6 @@
</div>
<div #collapse="ngbCollapse" [(ngbCollapse)]="isCollapsed" id="extended-series-metadata">
Stuff
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.artists && seriesMetadata.artists.length > 0">
<div class="col-md-4">
<h5>Artists</h5>
@ -41,15 +53,6 @@
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.publishers && seriesMetadata.publishers.length > 0">
<div class="col-md-4">
<h5>Publishers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.publishers" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.characters && seriesMetadata.characters.length > 0">
<div class="col-md-4">
<h5>Characters</h5>
@ -58,25 +61,7 @@
<app-person-badge *ngFor="let person of seriesMetadata.characters" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.pencillers && seriesMetadata.pencillers.length > 0">
<div class="col-md-4">
<h5>Pencillers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.pencillers" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.inkers && seriesMetadata.inkers.length > 0">
<div class="col-md-4">
<h5>Inkers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.inkers" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.colorists && seriesMetadata.colorists.length > 0">
<div class="col-md-4">
<h5>Colorists</h5>
@ -85,7 +70,25 @@
<app-person-badge *ngFor="let person of seriesMetadata.colorists" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.editors && seriesMetadata.editors.length > 0">
<div class="col-md-4">
<h5>Editors</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.editors" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.inkers && seriesMetadata.inkers.length > 0">
<div class="col-md-4">
<h5>Inkers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.inkers" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.letterers && seriesMetadata.letterers.length > 0">
<div class="col-md-4">
<h5>Letterers</h5>
@ -95,12 +98,21 @@
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.editors && seriesMetadata.editors.length > 0">
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.pencillers && seriesMetadata.pencillers.length > 0">
<div class="col-md-4">
<h5>Editors</h5>
<h5>Pencillers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.editors" [person]="person"></app-person-badge>
<app-person-badge *ngFor="let person of seriesMetadata.pencillers" [person]="person"></app-person-badge>
</div>
</div>
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.publishers && seriesMetadata.publishers.length > 0">
<div class="col-md-4">
<h5>Publishers</h5>
</div>
<div class="col-md-8">
<app-person-badge *ngFor="let person of seriesMetadata.publishers" [person]="person"></app-person-badge>
</div>
</div>
</div>

View file

@ -2,7 +2,9 @@ import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/cor
import { TagBadgeCursor } from '../shared/tag-badge/tag-badge.component';
import { UtilityService } from '../shared/_services/utility.service';
import { MangaFormat } from '../_models/manga-format';
import { Series } from '../_models/series';
import { SeriesMetadata } from '../_models/series-metadata';
import { MetadataService } from '../_services/metadata.service';
@Component({
selector: 'app-series-metadata-detail',
@ -12,10 +14,16 @@ import { SeriesMetadata } from '../_models/series-metadata';
export class SeriesMetadataDetailComponent implements OnInit, OnChanges {
@Input() seriesMetadata!: SeriesMetadata;
@Input() series!: Series;
isCollapsed: boolean = false;
isCollapsed: boolean = true;
hasExtendedProperites: boolean = false;
/**
* String representation of AgeRating enum
*/
ageRatingName: string = '';
get MangaFormat(): typeof MangaFormat {
return MangaFormat;
}
@ -24,7 +32,7 @@ export class SeriesMetadataDetailComponent implements OnInit, OnChanges {
return TagBadgeCursor;
}
constructor(public utilityService: UtilityService) { }
constructor(public utilityService: UtilityService, private metadataService: MetadataService) { }
ngOnChanges(changes: SimpleChanges): void {
this.hasExtendedProperites = this.seriesMetadata.colorists.length > 0 ||
@ -34,6 +42,10 @@ export class SeriesMetadataDetailComponent implements OnInit, OnChanges {
this.seriesMetadata.letterers.length > 0 ||
this.seriesMetadata.pencillers.length > 0 ||
this.seriesMetadata.publishers.length > 0;
this.metadataService.getAgeRating(this.seriesMetadata.ageRating).subscribe(rating => {
this.ageRatingName = rating;
});
}
ngOnInit(): void {
@ -43,4 +55,5 @@ export class SeriesMetadataDetailComponent implements OnInit, OnChanges {
this.isCollapsed = !this.isCollapsed;
}
}

View file

@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
import { Chapter } from 'src/app/_models/chapter';
import { LibraryType } from 'src/app/_models/library';
import { MangaFormat } from 'src/app/_models/manga-format';
import { AgeRating } from 'src/app/_models/metadata/age-rating';
import { Series } from 'src/app/_models/series';
import { Volume } from 'src/app/_models/volume';