* Adding multiple cases for comic naming conventions
* Changing "Chapter" to "Issue" for comic libraries
* Fixed an issue where the Parse method was using filename with extension to run regex matching, while it should be running on name without extension.
* Refactored to use Getter
* Cleaned up file to use conditional labelling rather than conditional html fragments
* Refactored code to properly check against library type for a given readinglist item
* Cleaned up series detail
* Conditionally remove special tags during parse
* Setup ParseInfoTests for ComicParserTests and also added unit tests from other comic issues created.
* Added more regex cases for naming patterns reported to be common with comics. Some cases added without regex.
* Pushing up changes
Fixed issue with cleanTitleTest.
Tried some patterns for "Cyberpunk 2077" but reverted
* Updated some cases and some spacing on Parser. Cyberpunk 2077 is not implemented as long as there is a # before issue number.
* Fixed the case for Special parsing on TPB. Fixed a piece of code that got deleted that prevented specials from rendering on volumes tab.
* Potential fix for parsing Cyberpunk 2077
- Added a ComicsSeriesSpecialCasesRegex and passed any filename that contains "Cyberpunk 2077" over to it so we can parse it separately. This could be used for any other potential problem series.
* Revert "Potential fix for parsing Cyberpunk 2077"
This reverts commit a14417e640.
* Added more tests
* Refactored all places in Kavita to use Book, Issue, or Chapter depending on the Library type. Updated Volumes/Chapters to remove Volumes to make it cleaner.
* Removed some leftover test code
Co-authored-by: Joseph Milazzo <joseph.v.milazzo@gmail.com>
140 lines
No EOL
8.8 KiB
HTML
140 lines
No EOL
8.8 KiB
HTML
<div class="container-fluid" *ngIf="series !== undefined" style="padding-top: 10px">
|
|
<div class="row mb-3">
|
|
<div class="col-md-2 col-xs-4 col-sm-6">
|
|
<img class="poster lazyload" [src]="imageSerivce.placeholderImage" [attr.data-src]="seriesImage"
|
|
(error)="imageSerivce.updateErroredImage($event)" aria-hidden="true">
|
|
</div>
|
|
<div class="col-md-10 col-xs-8 col-sm-6">
|
|
<div class="row no-gutters">
|
|
|
|
<h2>
|
|
{{series?.name}}
|
|
</h2>
|
|
</div>
|
|
<div class="row no-gutters">
|
|
<div>
|
|
<button class="btn btn-primary" (click)="read()" [disabled]="isLoading">
|
|
<span>
|
|
<i class="fa {{showBook ? 'fa-book-open' : 'fa-book'}}"></i>
|
|
</span>
|
|
<span class="read-btn--text"> {{(hasReadingProgress) ? 'Continue' : 'Read'}}</span>
|
|
</button>
|
|
</div>
|
|
<div class="ml-2" *ngIf="isAdmin">
|
|
<button class="btn btn-secondary" (click)="openEditSeriesModal()" title="Edit Series information">
|
|
<span>
|
|
<i class="fa fa-pen" aria-hidden="true"></i>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
<div class="ml-2" *ngIf="isAdmin || hasDownloadingRole">
|
|
<button class="btn btn-secondary" (click)="downloadSeries()" title="Download Series" [disabled]="downloadInProgress">
|
|
<ng-container *ngIf="downloadInProgress; else notDownloading">
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="sr-only">Downloading...</span>
|
|
</ng-container>
|
|
<ng-template #notDownloading>
|
|
<i class="fa fa-arrow-alt-circle-down" aria-hidden="true"></i>
|
|
</ng-template>
|
|
</button>
|
|
</div>
|
|
<div class="ml-2">
|
|
<div class="card-actions">
|
|
<app-card-actionables [disabled]="actionInProgress" (actionHandler)="performAction($event)" [actions]="seriesActions" [labelBy]="series.name" iconClass="fa-ellipsis-h" btnClass="btn-secondary"></app-card-actionables>
|
|
</div>
|
|
</div>
|
|
<div class="ml-2">
|
|
<ngb-rating class="rating-star" [(rate)]="series!.userRating" (rateChange)="updateRating($event)" (click)="promptToReview()"></ngb-rating>
|
|
<button *ngIf="series?.userRating || series.userRating" class="btn btn-sm btn-icon" (click)="openReviewModal(true)" placement="top" ngbTooltip="Edit Review" attr.aria-label="Edit Review"><i class="fa fa-pen" aria-hidden="true"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="row no-gutters">
|
|
<app-read-more class="user-review {{userReview ? 'mt-1' : ''}}" [text]="series?.userReview || ''" [maxLength]="250"></app-read-more>
|
|
</div>
|
|
<div class="row no-gutters {{series?.userReview ? '' : 'mt-2'}}">
|
|
<app-read-more [text]="seriesSummary" [maxLength]="250"></app-read-more>
|
|
</div>
|
|
<div *ngIf="seriesMetadata" class="mt-2">
|
|
<div class="row no-gutters" *ngIf="seriesMetadata.genres && seriesMetadata.genres.length > 0">
|
|
<div class="col-md-4">
|
|
<h5>Genres</h5>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<app-tag-badge *ngFor="let genre of seriesMetadata.genres" [selectionMode]="TagBadgeCursor.Clickable">{{genre}}</app-tag-badge>
|
|
</div>
|
|
</div>
|
|
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.tags && seriesMetadata.tags.length > 0">
|
|
<div class="col-md-4">
|
|
<h5>Collections</h5>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<app-tag-badge *ngFor="let tag of seriesMetadata.tags" a11y-click="13,32" class="clickable" routerLink="/collections/{{tag.id}}" [selectionMode]="TagBadgeCursor.Clickable">
|
|
{{tag.title}}
|
|
</app-tag-badge>
|
|
</div>
|
|
</div>
|
|
<div class="row no-gutters mt-1" *ngIf="seriesMetadata.persons && seriesMetadata.persons.length > 0">
|
|
<div class="col-md-4">
|
|
<h5>People</h5>
|
|
</div>
|
|
<div class="col-md-8">
|
|
<app-person-badge *ngFor="let person of seriesMetadata.persons">
|
|
<div name>{{person.name}}</div>
|
|
<div role>{{person.role}}</div>
|
|
</app-person-badge>
|
|
</div>
|
|
</div>
|
|
<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>
|
|
</div>
|
|
|
|
<div>
|
|
<app-bulk-operations [actionCallback]="bulkActionCallback"></app-bulk-operations>
|
|
<ul ngbNav #nav="ngbNav" [(activeId)]="activeTabId" class="nav-tabs nav-pills" [destroyOnHide]="false">
|
|
<li [ngbNavItem]="1" *ngIf="hasSpecials">
|
|
<a ngbNavLink>Specials</a>
|
|
<ng-template ngbNavContent>
|
|
<div class="row no-gutters">
|
|
<div *ngFor="let chapter of specials; let idx = index; trackBy: trackByChapterIdentity">
|
|
<app-card-item class="col-auto" *ngIf="chapter.isSpecial" [entity]="chapter" [title]="chapter.title || chapter.range" (click)="openChapter(chapter)"
|
|
[imageUrl]="imageService.getChapterCoverImage(chapter.id)"
|
|
[read]="chapter.pagesRead" [total]="chapter.pages" [actions]="chapterActions" (selection)="bulkSelectionService.handleCardSelection('special', idx, chapters.length, $event)" [selected]="bulkSelectionService.isCardSelected('special', idx)" [allowSelection]="true"></app-card-item>
|
|
</div>
|
|
</div>
|
|
</ng-template>
|
|
</li>
|
|
<li [ngbNavItem]="2" *ngIf="hasNonSpecialVolumeChapters">
|
|
<a ngbNavLink>{{utilityService.formatChapterName(libraryType) + 's'}}</a>
|
|
<ng-template ngbNavContent>
|
|
<div class="row no-gutters">
|
|
<div *ngFor="let volume of volumes; let idx = index; trackBy: trackByVolumeIdentity">
|
|
<app-card-item class="col-auto" *ngIf="volume.number != 0" [entity]="volume" [title]="'Volume ' + volume.name" (click)="openVolume(volume)"
|
|
[imageUrl]="imageService.getVolumeCoverImage(volume.id) + '&offset=' + coverImageOffset"
|
|
[read]="volume.pagesRead" [total]="volume.pages" [actions]="volumeActions" (selection)="bulkSelectionService.handleCardSelection('volume', idx, volumes.length, $event)" [selected]="bulkSelectionService.isCardSelected('volume', idx)" [allowSelection]="true"></app-card-item>
|
|
</div>
|
|
<div *ngFor="let chapter of chapters; let idx = index; trackBy: trackByChapterIdentity">
|
|
<app-card-item class="col-auto" *ngIf="!chapter.isSpecial" [entity]="chapter" [title]="utilityService.formatChapterName(libraryType, true, true) + chapter.range" (click)="openChapter(chapter)"
|
|
[imageUrl]="imageService.getChapterCoverImage(chapter.id) + '&offset=' + coverImageOffset"
|
|
[read]="chapter.pagesRead" [total]="chapter.pages" [actions]="chapterActions" (selection)="bulkSelectionService.handleCardSelection('chapter', idx, chapters.length, $event)" [selected]="bulkSelectionService.isCardSelected('chapter', idx)" [allowSelection]="true"></app-card-item>
|
|
</div>
|
|
</div>
|
|
</ng-template>
|
|
</li>
|
|
</ul>
|
|
<div [ngbNavOutlet]="nav"></div>
|
|
</div>
|
|
|
|
<div class="mx-auto" *ngIf="isLoading" style="width: 200px;">
|
|
<div class="spinner-border text-secondary loading" role="status">
|
|
<span class="invisible">Loading...</span>
|
|
</div>
|
|
</div>
|
|
</div> |