mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Bugfixes (#1004)
* Refactored the code for choosing the tab to select when updates occur or first load. Specials will no longer be auto-selected if present. We will always try to select Storyline. * Fixed a bug where marking a chapter as unread was actually making it read * When loading a book, put a spinner in the action bar * Fixed an issue with last page not getting marked as read with epubs due to a bugfix from last release * Removed some debug code
This commit is contained in:
parent
6fadbb5231
commit
868eb70506
@ -214,7 +214,7 @@ export class ActionService implements OnDestroy {
|
||||
* @param callback Optional callback to perform actions after API completes
|
||||
*/
|
||||
markChapterAsUnread(seriesId: number, chapter: Chapter, callback?: ChapterActionCallback) {
|
||||
this.readerService.saveProgress(seriesId, chapter.volumeId, chapter.id, chapter.pages).pipe(take(1)).subscribe(results => {
|
||||
this.readerService.saveProgress(seriesId, chapter.volumeId, chapter.id, 0).pipe(take(1)).subscribe(results => {
|
||||
chapter.pagesRead = 0;
|
||||
this.toastr.success('Marked as unread');
|
||||
if (callback) {
|
||||
|
@ -129,18 +129,28 @@
|
||||
<button class="btn btn-outline-secondary btn-icon col-2 col-xs-1" (click)="prevPage()"
|
||||
[disabled]="IsPrevDisabled"
|
||||
title="{{readingDirection === ReadingDirection.LeftToRight ? 'Previous' : 'Next'}} Page">
|
||||
<i class="fa {{(readingDirection === ReadingDirection.LeftToRight ? pageNum === 0 : pageNum + 1 >= maxPages - 1) ? 'fa-angle-double-left' : 'fa-angle-left'}}" aria-hidden="true"></i>
|
||||
<i class="fa {{(readingDirection === ReadingDirection.LeftToRight ? IsPrevChapter : IsNextChapter) ? 'fa-angle-double-left' : 'fa-angle-left'}}" aria-hidden="true"></i>
|
||||
<span class="phone-hidden"> {{readingDirection === ReadingDirection.LeftToRight ? 'Previous' : 'Next'}}</span>
|
||||
</button>
|
||||
<button *ngIf="!this.adhocPageHistory.isEmpty()" class="btn btn-outline-secondary btn-icon col-2 col-xs-1" (click)="goBack()" title="Go Back"><i class="fa fa-reply" aria-hidden="true"></i><span class="phone-hidden"> Go Back</span></button>
|
||||
<button class="btn btn-secondary col-2 col-xs-1" (click)="toggleDrawer()"><i class="fa fa-bars" aria-hidden="true"></i><span class="phone-hidden"> Settings</span></button>
|
||||
<div class="book-title col-2 phone-hidden">{{bookTitle}} <span *ngIf="incognitoMode" (click)="turnOffIncognito()" role="button" aria-label="Incognito mode is on. Toggle to turn off.">(<i class="fa fa-glasses" aria-hidden="true"></i><span class="sr-only">Incognito Mode</span>)</span></div>
|
||||
<div class="book-title col-2 phone-hidden">
|
||||
<ng-container *ngIf="isLoading; else showTitle">
|
||||
<div class="spinner-border spinner-border-sm text-primary" style="border-radius: 50%;" role="status">
|
||||
<span class="sr-only">Loading book...</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-template #showTitle>
|
||||
{{bookTitle}}
|
||||
<span *ngIf="incognitoMode" (click)="turnOffIncognito()" role="button" aria-label="Incognito mode is on. Toggle to turn off.">(<i class="fa fa-glasses" aria-hidden="true"></i><span class="sr-only">Incognito Mode</span>)</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
<button class="btn btn-secondary col-2 col-xs-1" (click)="closeReader()"><i class="fa fa-times-circle" aria-hidden="true"></i><span class="phone-hidden"> Close</span></button>
|
||||
<button class="btn btn-outline-secondary btn-icon col-2 col-xs-1"
|
||||
[disabled]="IsNextDisabled"
|
||||
(click)="nextPage()" title="{{readingDirection === ReadingDirection.LeftToRight ? 'Next' : 'Previous'}} Page">
|
||||
<span class="phone-hidden">{{readingDirection === ReadingDirection.LeftToRight ? 'Next' : 'Previous'}} </span>
|
||||
<i class="fa {{(readingDirection === ReadingDirection.LeftToRight ? pageNum + 1 > maxPages - 1 : pageNum === 0) ? 'fa-angle-double-right' : 'fa-angle-right'}}" aria-hidden="true"></i>
|
||||
<i class="fa {{(readingDirection === ReadingDirection.LeftToRight ? IsNextChapter : IsPrevChapter) ? 'fa-angle-double-right' : 'fa-angle-right'}}" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -235,6 +235,13 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
get IsNextChapter(): boolean {
|
||||
return this.pageNum + 1 >= this.maxPages;
|
||||
}
|
||||
get IsPrevChapter(): boolean {
|
||||
return this.pageNum === 0;
|
||||
}
|
||||
|
||||
get drawerBackgroundColor() {
|
||||
return this.darkMode ? '#010409': '#fff';
|
||||
}
|
||||
@ -344,12 +351,24 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.lastSeenScrollPartPath = path;
|
||||
}
|
||||
|
||||
if (this.lastSeenScrollPartPath !== '' && !this.incognitoMode) {
|
||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, this.pageNum, this.lastSeenScrollPartPath).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||
if (this.lastSeenScrollPartPath !== '') {
|
||||
this.saveProgress();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
saveProgress() {
|
||||
let tempPageNum = this.pageNum;
|
||||
if (this.pageNum == this.maxPages - 1) {
|
||||
tempPageNum = this.pageNum + 1;
|
||||
}
|
||||
|
||||
if (!this.incognitoMode) {
|
||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, tempPageNum, this.lastSeenScrollPartPath).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
const bodyNode = this.document.querySelector('body');
|
||||
if (bodyNode !== undefined && bodyNode !== null && this.originalBodyColor !== undefined) {
|
||||
@ -450,9 +469,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
if (this.pageNum >= this.maxPages) {
|
||||
this.pageNum = this.maxPages - 1;
|
||||
if (!this.incognitoMode) {
|
||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, this.pageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||
}
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
this.readerService.getNextChapter(this.seriesId, this.volumeId, this.chapterId, this.readingListId).pipe(take(1)).subscribe(chapterId => {
|
||||
@ -711,9 +728,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
loadPage(part?: string | undefined, scrollTop?: number | undefined) {
|
||||
this.isLoading = true;
|
||||
|
||||
if (!this.incognitoMode) {
|
||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, this.pageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||
}
|
||||
this.saveProgress();
|
||||
|
||||
this.bookService.getBookPage(this.chapterId, this.pageNum).pipe(take(1)).subscribe(content => {
|
||||
this.page = this.domSanitizer.bypassSecurityTrustHtml(content);
|
||||
@ -764,8 +779,8 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
setPageNum(pageNum: number) {
|
||||
if (pageNum < 0) {
|
||||
this.pageNum = 0;
|
||||
} else if (pageNum >= this.maxPages) {
|
||||
this.pageNum = this.maxPages - 1;
|
||||
} else if (pageNum >= this.maxPages - 1) { // This case handles when we are using the pager to move to the next volume/chapter, the pageNum will get incremented past maxPages // NOTE: I made a change where I removed - 1 in comparison, it's breaking page progress
|
||||
this.pageNum = this.maxPages; //
|
||||
} else {
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
@ -794,6 +809,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
prevPage() {
|
||||
const oldPageNum = this.pageNum;
|
||||
|
||||
if (this.readingDirection === ReadingDirection.LeftToRight) {
|
||||
this.setPageNum(this.pageNum - 1);
|
||||
} else {
|
||||
@ -816,18 +832,21 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
const oldPageNum = this.pageNum;
|
||||
if (oldPageNum + 1 === this.maxPages) {
|
||||
// Move to next volume/chapter automatically
|
||||
this.loadNextChapter();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (this.readingDirection === ReadingDirection.LeftToRight) {
|
||||
this.setPageNum(this.pageNum + 1);
|
||||
} else {
|
||||
this.setPageNum(this.pageNum - 1);
|
||||
}
|
||||
|
||||
if (oldPageNum + 1 === this.maxPages) {
|
||||
// Move to next volume/chapter automatically
|
||||
this.loadNextChapter();
|
||||
}
|
||||
|
||||
|
||||
if (oldPageNum === this.pageNum) { return; }
|
||||
|
||||
@ -1051,7 +1070,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
const newRoute = this.readerService.getNextChapterUrl(this.router.url, this.chapterId, this.incognitoMode, this.readingListMode, this.readingListId);
|
||||
window.history.replaceState({}, '', newRoute);
|
||||
this.toastr.info('Incognito mode is off. Progress will now start being tracked.');
|
||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, this.pageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||
this.saveProgress();
|
||||
}
|
||||
|
||||
toggleFullscreen() {
|
||||
|
@ -63,7 +63,7 @@
|
||||
<div>
|
||||
<app-bulk-operations [actionCallback]="bulkActionCallback"></app-bulk-operations>
|
||||
<ul ngbNav #nav="ngbNav" [(activeId)]="activeTabId" class="nav-tabs nav-pills" [destroyOnHide]="false" (navChange)="onNavChange($event)">
|
||||
<li [ngbNavItem]="1" *ngIf="hasSpecials">
|
||||
<li [ngbNavItem]="TabID.Specials" *ngIf="hasSpecials">
|
||||
<a ngbNavLink>Specials</a>
|
||||
<ng-template ngbNavContent>
|
||||
<div class="row no-gutters">
|
||||
@ -75,7 +75,7 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
</li>
|
||||
<li [ngbNavItem]="2" *ngIf="libraryType !== LibraryType.Book && (hasNonSpecialVolumeChapters || hasNonSpecialNonVolumeChapters)">
|
||||
<li [ngbNavItem]="TabID.Storyline" *ngIf="libraryType !== LibraryType.Book && (hasNonSpecialVolumeChapters || hasNonSpecialNonVolumeChapters)">
|
||||
<a ngbNavLink>Storyline</a>
|
||||
<ng-template ngbNavContent>
|
||||
<div class="row no-gutters">
|
||||
@ -92,7 +92,7 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
</li>
|
||||
<li [ngbNavItem]="3" *ngIf="hasNonSpecialVolumeChapters">
|
||||
<li [ngbNavItem]="TabID.Volumes" *ngIf="hasNonSpecialVolumeChapters">
|
||||
<a ngbNavLink>Volumes</a>
|
||||
<ng-template ngbNavContent>
|
||||
<div class="row no-gutters">
|
||||
@ -104,7 +104,7 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
</li>
|
||||
<li [ngbNavItem]="4" *ngIf="hasNonSpecialNonVolumeChapters">
|
||||
<li [ngbNavItem]="TabID.Chapters" *ngIf="hasNonSpecialNonVolumeChapters">
|
||||
<a ngbNavLink>{{utilityService.formatChapterName(libraryType) + 's'}}</a>
|
||||
<ng-template ngbNavContent>
|
||||
<div class="row no-gutters">
|
||||
|
@ -33,6 +33,13 @@ import { ReaderService } from '../_services/reader.service';
|
||||
import { SeriesService } from '../_services/series.service';
|
||||
|
||||
|
||||
enum TabID {
|
||||
Specials = 1,
|
||||
Storyline = 2,
|
||||
Volumes = 3,
|
||||
Chapters = 4
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-series-detail',
|
||||
templateUrl: './series-detail.component.html',
|
||||
@ -61,7 +68,7 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
|
||||
|
||||
hasSpecials = false;
|
||||
specials: Array<Chapter> = [];
|
||||
activeTabId = 2;
|
||||
activeTabId = TabID.Storyline;
|
||||
hasNonSpecialVolumeChapters = false;
|
||||
hasNonSpecialNonVolumeChapters = false;
|
||||
|
||||
@ -148,6 +155,10 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
|
||||
return TagBadgeCursor;
|
||||
}
|
||||
|
||||
get TabID(): typeof TabID {
|
||||
return TabID;
|
||||
}
|
||||
|
||||
constructor(private route: ActivatedRoute, private seriesService: SeriesService,
|
||||
private router: Router, public bulkSelectionService: BulkSelectionService,
|
||||
private modalService: NgbModal, public readerService: ReaderService,
|
||||
@ -383,31 +394,7 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
// This shows Chapters/Issues tab
|
||||
// If this has chapters that are not specials
|
||||
if (this.chapters.filter(c => !c.isSpecial).length > 0) {
|
||||
if (this.utilityService.formatChapterName(this.libraryType) == 'Book') {
|
||||
this.activeTabId = 4;
|
||||
}
|
||||
this.hasNonSpecialNonVolumeChapters = true;
|
||||
}
|
||||
|
||||
// This shows Volumes tab
|
||||
if (this.volumes.filter(v => v.number !== 0).length !== 0) {
|
||||
if (this.utilityService.formatChapterName(this.libraryType) == 'Book') {
|
||||
this.activeTabId = 3;
|
||||
}
|
||||
this.hasNonSpecialVolumeChapters = true;
|
||||
}
|
||||
|
||||
// If an update occured and we were on specials, re-activate Volumes/Chapters
|
||||
if (!this.hasSpecials && !this.hasNonSpecialVolumeChapters && this.activeTabId != 2) {
|
||||
this.activeTabId = 3;
|
||||
}
|
||||
|
||||
if (this.hasSpecials) {
|
||||
this.activeTabId = 1;
|
||||
}
|
||||
this.updateSelectedTab();
|
||||
|
||||
this.isLoading = false;
|
||||
});
|
||||
@ -416,6 +403,36 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This will update the selected tab
|
||||
*
|
||||
* This assumes loadPage() has already primed all the calculations and state variables. Do not call directly.
|
||||
*/
|
||||
updateSelectedTab() {
|
||||
// This shows Chapters/Issues tab
|
||||
|
||||
// If this has chapters that are not specials
|
||||
if (this.chapters.filter(c => !c.isSpecial).length > 0) {
|
||||
this.hasNonSpecialNonVolumeChapters = true;
|
||||
}
|
||||
|
||||
// This shows Volumes tab
|
||||
if (this.volumes.filter(v => v.number !== 0).length !== 0) {
|
||||
this.hasNonSpecialVolumeChapters = true;
|
||||
}
|
||||
|
||||
// If an update occured and we were on specials, re-activate Volumes/Chapters
|
||||
if (!this.hasSpecials && !this.hasNonSpecialVolumeChapters && this.activeTabId != TabID.Storyline) {
|
||||
this.activeTabId = TabID.Storyline;
|
||||
}
|
||||
|
||||
if (this.hasNonSpecialVolumeChapters || this.hasNonSpecialNonVolumeChapters) {
|
||||
this.activeTabId = TabID.Storyline;
|
||||
} else {
|
||||
this.activeTabId = TabID.Specials;
|
||||
}
|
||||
}
|
||||
|
||||
createHTML() {
|
||||
this.userReview = (this.series.userReview === null ? '' : this.series.userReview).replace(/\n/g, '<br>');
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user