* 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:
Joseph Milazzo 2022-01-28 08:47:16 -08:00 committed by GitHub
parent 6fadbb5231
commit 868eb70506
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 96 additions and 50 deletions

View File

@ -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) {

View File

@ -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">&nbsp;{{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">&nbsp;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">&nbsp;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">&nbsp;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'}}&nbsp;</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>

View File

@ -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() {

View File

@ -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">

View File

@ -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>');
}