Kavita+ Enhancements (#2616)

This commit is contained in:
Joe Milazzo 2024-01-17 17:45:39 -06:00 committed by GitHub
parent 625c56b265
commit dd44f55747
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 1056 additions and 468 deletions

View file

@ -108,45 +108,52 @@
<li [ngbNavItem]="tabs[TabID.Files]" [disabled]="(isAdmin$ | async) === false">
<a ngbNavLink>{{t(tabs[TabID.Files].title)}}</a>
<ng-template ngbNavContent>
<h4 *ngIf="!utilityService.isChapter(data)">{{utilityService.formatChapterName(libraryType) + 's'}}</h4>
@if (!utilityService.isChapter(data)) {
<h4>{{utilityService.formatChapterName(libraryType) + 's'}}</h4>
}
<ul class="list-unstyled">
<li class="d-flex my-4" *ngFor="let chapter of chapters">
<!-- TODO: Localize title -->
<a (click)="readChapter(chapter)" href="javascript:void(0);" title="Read {{utilityService.formatChapterName(libraryType, true, false)}} {{formatChapterNumber(chapter)}}">
<app-image class="me-2" width="74px" [imageUrl]="imageService.getChapterCoverImage(chapter.id)"></app-image>
</a>
<div class="flex-grow-1">
<h5 class="mt-0 mb-1">
<span>
<span>
<app-card-actionables (actionHandler)="performAction($event, chapter)" [actions]="chapterActions"
[labelBy]="utilityService.formatChapterName(libraryType, true, true) + formatChapterNumber(chapter)"></app-card-actionables>
<ng-container *ngIf="chapter.number !== '0'; else specialHeader">
{{utilityService.formatChapterName(libraryType, true, false) }} {{formatChapterNumber(chapter)}}
</ng-container>
</span>
<span class="badge bg-primary rounded-pill ms-1">
<span *ngIf="chapter.pagesRead > 0 && chapter.pagesRead < chapter.pages">{{chapter.pagesRead}} / {{chapter.pages}}</span>
<span *ngIf="chapter.pagesRead === 0">{{t('unread') | uppercase}}</span>
<span *ngIf="chapter.pagesRead === chapter.pages">{{t('read') | uppercase}}</span>
</span>
</span>
<span>
<span>
<app-card-actionables (actionHandler)="performAction($event, chapter)" [actions]="chapterActions"
[labelBy]="utilityService.formatChapterName(libraryType, true, true) + formatChapterNumber(chapter)"></app-card-actionables>
<ng-container *ngIf="chapter.number !== '0'; else specialHeader">
{{utilityService.formatChapterName(libraryType, true, false) }} {{formatChapterNumber(chapter)}}
</ng-container>
</span>
<span class="badge bg-primary rounded-pill ms-1">
<span *ngIf="chapter.pagesRead > 0 && chapter.pagesRead < chapter.pages">{{chapter.pagesRead}} / {{chapter.pages}}</span>
<span *ngIf="chapter.pagesRead === 0">{{t('unread') | uppercase}}</span>
<span *ngIf="chapter.pagesRead === chapter.pages">{{t('read') | uppercase}}</span>
</span>
</span>
<ng-template #specialHeader>{{t('files')}}</ng-template>
</h5>
<ul class="list-group">
<li *ngFor="let file of chapter.files" class="list-group-item no-hover">
<span>{{file.filePath}}</span>
<div class="row g-0">
<div class="col">
{{t('pages')}} {{file.pages | number:''}}
@for (file of chapter.files; track file.id) {
<li class="list-group-item no-hover">
<span>{{file.filePath}}</span>
<div class="row g-0">
<div class="col">
{{t('pages')}} {{file.pages | number:''}}
</div>
@if (data.hasOwnProperty('created')) {
<div class="col">
{{t('added')}} {{file.created | date: 'short' | defaultDate}}
</div>
}
<div class="col">
{{t('size')}} {{file.bytes | bytes}}
</div>
</div>
<div class="col" *ngIf="data.hasOwnProperty('created')">
{{t('added')}} {{file.created | date: 'short' | defaultDate}}
</div>
<div class="col">
{{t('size')}} {{file.bytes | bytes}}
</div>
</div>
</li>
</li>
}
</ul>
</div>
</li>

View file

@ -68,12 +68,17 @@ enum TabID {
})
export class CardDetailDrawerComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
protected readonly MangaFormat = MangaFormat;
protected readonly Breakpoint = Breakpoint;
protected readonly LibraryType = LibraryType;
protected readonly TabID = TabID;
@Input() parentName = '';
@Input() seriesId: number = 0;
@Input() libraryId: number = 0;
@Input({required: true}) data!: Volume | Chapter;
private readonly destroyRef = inject(DestroyRef);
/**
* If this is a volume, this will be first chapter for said volume.
@ -104,26 +109,13 @@ export class CardDetailDrawerComponent implements OnInit {
];
active = this.tabs[0];
chapterMetadata!: ChapterMetadata;
chapterMetadata: ChapterMetadata | undefined;
summary: string = '';
downloadInProgress: boolean = false;
get MangaFormat() {
return MangaFormat;
}
get Breakpoint() {
return Breakpoint;
}
get LibraryType() {
return LibraryType;
}
get TabID() {
return TabID;
}
constructor(public utilityService: UtilityService,
public imageService: ImageService, private uploadService: UploadService, private toastr: ToastrService,
@ -160,7 +152,7 @@ export class CardDetailDrawerComponent implements OnInit {
this.chapterActions = this.actionFactoryService.getChapterActions(this.handleChapterActionCallback.bind(this))
.filter(item => item.action !== Action.Edit);
this.chapterActions.push({title: 'Read', action: Action.Read, callback: this.handleChapterActionCallback.bind(this), requiresAdmin: false, children: []});
this.chapterActions.push({title: 'read', action: Action.Read, callback: this.handleChapterActionCallback.bind(this), requiresAdmin: false, children: []});
if (this.isChapter) {
const chapter = this.utilityService.asChapter(this.data);
this.chapterActions = this.actionFactoryService.filterSendToAction(this.chapterActions, chapter);

View file

@ -277,26 +277,9 @@ export class CardItemComponent implements OnInit {
});
this.download$ = this.downloadService.activeDownloads$.pipe(takeUntilDestroyed(this.destroyRef), map((events) => {
if(this.utilityService.isSeries(this.entity)) {
return events.find(e => e.entityType === 'series' && e.id == this.entity.id
&& e.subTitle === this.downloadService.downloadSubtitle('series', (this.entity as Series))) || null;
}
if(this.utilityService.isVolume(this.entity)) {
return events.find(e => e.entityType === 'volume' && e.id == this.entity.id
&& e.subTitle === this.downloadService.downloadSubtitle('volume', (this.entity as Volume))) || null;
}
if(this.utilityService.isChapter(this.entity)) {
return events.find(e => e.entityType === 'chapter' && e.id == this.entity.id
&& e.subTitle === this.downloadService.downloadSubtitle('chapter', (this.entity as Chapter))) || null;
}
// Is PageBookmark[]
if(this.entity.hasOwnProperty('length')) {
return events.find(e => e.entityType === 'bookmark'
&& e.subTitle === this.downloadService.downloadSubtitle('bookmark', [(this.entity as PageBookmark)])) || null;
}
return null;
console.log('Card Item download obv called for entity: ', this.entity);
return this.downloadService.mapToEntityType(events, this.entity);
}));
}