New PDF Reader (#1324)
* Refactored all the code that opens the reader to use a unified function. Added new library and setup basic pdf reader route. * Progress saving is implemented. Targeting ES6 now. * Customized the toolbar to remove things we don't want, made the download button download with correct filename. Adjusted zoom setting to work well on first load regardless of device. * Stream the pdf file to the UI rather than handling the download ourselves. * Started implementing a custom toolbar. * Fixed up the jump bar calculations * Fixed filtering being broken * Pushing up for Robbie to cleanup the toolbar layout * Added an additional button. Working on logic while robbie takes styling * Tried to fix the code for robbie * Tweaks for fonts * Added button for book mode, but doesn't seem to work after renderer is built * Removed book mode * Removed the old image caching code for pdfs as it's not needed with new reader * Removed the interfaces to extract images from pdf. * Fixed original pagination area not scaling correctly * Integrated series remove events to library detail * Cleaned up the getter naming convention * Cleaned up some of the manga reader code to reduce cluter and improve re-use * Implemented Japanese parser support for volume and chapters. * Fixed a bug where resetting scroll in manga reader wasn't working * Fixed a bug where word count grew on each scan. * Removed unused variable * Ensure we calculate word count on files with their own cache timestamp * Adjusted size of reel headers * Put some code in for moving on original image with keyboard, but it's not in use. * Cleaned up the css for the pdf reader * Cleaned up the code * Tweaked the list item so we show scrollbar now when fully read
This commit is contained in:
parent
384fac68c4
commit
3ab3a10ae7
45 changed files with 2309 additions and 208 deletions
15
UI/Web/src/app/manga-reader/fullscreen-icon.pipe.ts
Normal file
15
UI/Web/src/app/manga-reader/fullscreen-icon.pipe.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Returns the icon for the given state of fullscreen mode
|
||||
*/
|
||||
@Pipe({
|
||||
name: 'fullscreenIcon'
|
||||
})
|
||||
export class FullscreenIconPipe implements PipeTransform {
|
||||
|
||||
transform(isFullscreen: boolean): string {
|
||||
return isFullscreen ? 'fa-compress-alt' : 'fa-expand-alt';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,7 +21,11 @@
|
|||
<!-- {{this.pageNum}} -->
|
||||
<!-- {{readerService.imageUrlToPageNum(canvasImage.src)}}<ng-container *ngIf="ShouldRenderDoublePage && (this.pageNum + 1 <= maxPages - 1 && this.pageNum > 0)"> - {{PageNumber + 1}}</ng-container> -->
|
||||
|
||||
<button *ngIf="!bookmarkMode" class="btn btn-icon btn-small" role="checkbox" [attr.aria-checked]="isCurrentPageBookmarked" title="{{isCurrentPageBookmarked ? 'Unbookmark Page' : 'Bookmark Page'}}" (click)="bookmarkPage()"><i class="{{isCurrentPageBookmarked ? 'fa' : 'far'}} fa-bookmark" aria-hidden="true"></i><span class="visually-hidden">{{isCurrentPageBookmarked ? 'Unbookmark Page' : 'Bookmark Page'}}</span></button>
|
||||
<button *ngIf="!bookmarkMode" class="btn btn-icon btn-small" role="checkbox" [attr.aria-checked]="CurrentPageBookmarked"
|
||||
title="{{CurrentPageBookmarked ? 'Unbookmark Page' : 'Bookmark Page'}}" (click)="bookmarkPage()">
|
||||
<i class="{{CurrentPageBookmarked ? 'fa' : 'far'}} fa-bookmark" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">{{CurrentPageBookmarked ? 'Unbookmark Page' : 'Bookmark Page'}}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -47,7 +51,10 @@
|
|||
title="Previous Page" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="{{readerMode === ReaderMode.LeftRight ? 'right' : 'bottom'}} {{clickOverlayClass('right')}}" (click)="handlePageChange($event, 'right')" [ngStyle]="{'height': (readerMode === ReaderMode.LeftRight ? ImageHeight: '25%'), 'left': (readerMode === ReaderMode.LeftRight && (this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.ORIGINAL) ? ImageWidth: 'inherit'), 'right': rightPaginationOffset + 'px'}">
|
||||
<div class="{{readerMode === ReaderMode.LeftRight ? 'right' : 'bottom'}} {{clickOverlayClass('right')}}" (click)="handlePageChange($event, 'right')"
|
||||
[ngStyle]="{'height': (readerMode === ReaderMode.LeftRight ? ImageHeight: '25%'),
|
||||
'left': 'inherit',
|
||||
'right': rightPaginationOffset + 'px'}">
|
||||
<div *ngIf="showClickOverlay">
|
||||
<i class="fa fa-angle-{{readingDirection === ReadingDirection.LeftToRight ? 'double-' : ''}}{{readerMode === ReaderMode.LeftRight ? 'right' : 'down'}}"
|
||||
title="Next Page" aria-hidden="true"></i>
|
||||
|
|
@ -56,12 +63,12 @@
|
|||
</div>
|
||||
|
||||
<div class="image-container {{getFittingOptionClass()}}" [ngClass]="{'d-none': renderWithCanvas, 'center-double': ShouldRenderDoublePage,
|
||||
'fit-to-width-double-offset' : this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.WIDTH && ShouldRenderDoublePage,
|
||||
'fit-to-height-double-offset': this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.HEIGHT && ShouldRenderDoublePage,
|
||||
'original-double-offset' : this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.ORIGINAL && ShouldRenderDoublePage,
|
||||
'fit-to-width-double-offset' : FittingOption === FITTING_OPTION.WIDTH && ShouldRenderDoublePage,
|
||||
'fit-to-height-double-offset': FittingOption === FITTING_OPTION.HEIGHT && ShouldRenderDoublePage,
|
||||
'original-double-offset' : FittingOption === FITTING_OPTION.ORIGINAL && ShouldRenderDoublePage,
|
||||
'reverse': ShouldRenderReverseDouble}">
|
||||
<img #image [src]="canvasImage.src" id="image-1"
|
||||
class="{{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}">
|
||||
class="{{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}">
|
||||
|
||||
<ng-container *ngIf="ShouldRenderDoublePage && (this.pageNum + 1 <= maxPages - 1 && this.pageNum > 0)">
|
||||
<img [src]="getPageUrl(PageNumber + 1)" id="image-2" class="image-2 {{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}} {{ShouldRenderReverseDouble ? 'reverse' : ''}}">
|
||||
|
|
@ -115,13 +122,13 @@
|
|||
</div>
|
||||
<div class="col">
|
||||
<button class="btn btn-icon" title="Reading Mode" (click)="toggleReaderMode();resetMenuCloseTimer();">
|
||||
<i class="fa {{readerModeIcon}}" aria-hidden="true"></i>
|
||||
<i class="fa {{ReaderModeIcon}}" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">Reading Mode</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button class="btn btn-icon" title="{{this.isFullscreen ? 'Collapse' : 'Fullscreen'}}" (click)="toggleFullscreen();resetMenuCloseTimer();">
|
||||
<i class="fa {{this.isFullscreen ? 'fa-compress-alt' : 'fa-expand-alt'}}" aria-hidden="true"></i>
|
||||
<i class="fa {{this.isFullscreen | fullscreenIcon}}" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">{{this.isFullscreen ? 'Collapse' : 'Fullscreen'}}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -138,7 +145,7 @@
|
|||
<div class="col-md-6 col-sm-12">
|
||||
<label for="page-splitting" class="form-label">Image Splitting</label>
|
||||
<div class="split fa fa-image">
|
||||
<div class="{{splitIconClass}}"></div>
|
||||
<div class="{{SplitIconClass}}"></div>
|
||||
</div>
|
||||
<select class="form-control" id="page-splitting" formControlName="pageSplitOption">
|
||||
<option *ngFor="let opt of pageSplitOptions" [value]="opt.value">{{opt.text}}</option>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import { LibraryType } from '../_models/library';
|
|||
import { ShorcutsModalComponent } from '../reader-shared/_modals/shorcuts-modal/shorcuts-modal.component';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { LayoutMode } from './_models/layout-mode';
|
||||
import { SeriesService } from '../_services/series.service';
|
||||
|
||||
const PREFETCH_PAGES = 8;
|
||||
|
||||
|
|
@ -284,7 +283,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
return (this.layoutMode === LayoutMode.DoubleReversed) && !this.isCoverImage();
|
||||
}
|
||||
|
||||
get isCurrentPageBookmarked() {
|
||||
get CurrentPageBookmarked() {
|
||||
return this.bookmarks.hasOwnProperty(this.pageNum);
|
||||
}
|
||||
|
||||
|
|
@ -302,21 +301,20 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
get ImageHeight() {
|
||||
// If we are a cover image and implied fit to screen, then we need to take screen height rather than image height
|
||||
if (this.isCoverImage() || this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.WIDTH) {
|
||||
if (this.isCoverImage() || this.FittingOption === FITTING_OPTION.WIDTH) {
|
||||
return this.WindowHeight;
|
||||
}
|
||||
return this.image?.nativeElement.height + 'px';
|
||||
}
|
||||
|
||||
|
||||
get RightPaginationOffset() {
|
||||
if (this.readerMode === ReaderMode.LeftRight && this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.HEIGHT) {
|
||||
if (this.readerMode === ReaderMode.LeftRight && this.FittingOption === FITTING_OPTION.HEIGHT) {
|
||||
return (this.readingArea?.nativeElement?.scrollLeft || 0) * -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
get splitIconClass() {
|
||||
get SplitIconClass() {
|
||||
if (this.isSplitLeftToRight()) {
|
||||
return 'left-side';
|
||||
} else if (this.isNoSplit()) {
|
||||
|
|
@ -325,7 +323,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
return 'right-side';
|
||||
}
|
||||
|
||||
get readerModeIcon() {
|
||||
get ReaderModeIcon() {
|
||||
switch(this.readerMode) {
|
||||
case ReaderMode.LeftRight:
|
||||
return 'fa-exchange-alt';
|
||||
|
|
@ -361,13 +359,16 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
return FITTING_OPTION;
|
||||
}
|
||||
|
||||
get FittingOption() {
|
||||
return this.generalSettingsForm.get('fittingOption')?.value;
|
||||
}
|
||||
|
||||
constructor(private route: ActivatedRoute, private router: Router, private accountService: AccountService,
|
||||
public readerService: ReaderService, private location: Location,
|
||||
private formBuilder: FormBuilder, private navService: NavService,
|
||||
private toastr: ToastrService, private memberService: MemberService,
|
||||
public utilityService: UtilityService, private renderer: Renderer2,
|
||||
@Inject(DOCUMENT) private document: Document, private modalService: NgbModal,
|
||||
private seriesService: SeriesService) {
|
||||
@Inject(DOCUMENT) private document: Document, private modalService: NgbModal) {
|
||||
this.navService.hideNavBar();
|
||||
this.navService.hideSideNav();
|
||||
}
|
||||
|
|
@ -376,7 +377,6 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
const libraryId = this.route.snapshot.paramMap.get('libraryId');
|
||||
const seriesId = this.route.snapshot.paramMap.get('seriesId');
|
||||
const chapterId = this.route.snapshot.paramMap.get('chapterId');
|
||||
|
||||
if (libraryId === null || seriesId === null || chapterId === null) {
|
||||
this.router.navigateByUrl('/libraries');
|
||||
return;
|
||||
|
|
@ -394,89 +394,80 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.readingListId = parseInt(readingListId, 10);
|
||||
}
|
||||
|
||||
|
||||
this.continuousChaptersStack.push(this.chapterId);
|
||||
|
||||
this.accountService.currentUser$.pipe(take(1)).subscribe(user => {
|
||||
if (user) {
|
||||
this.user = user;
|
||||
this.readingDirection = this.user.preferences.readingDirection;
|
||||
this.scalingOption = this.user.preferences.scalingOption;
|
||||
this.pageSplitOption = this.user.preferences.pageSplitOption;
|
||||
this.autoCloseMenu = this.user.preferences.autoCloseMenu;
|
||||
this.readerMode = this.user.preferences.readerMode;
|
||||
this.layoutMode = this.user.preferences.layoutMode || LayoutMode.Single;
|
||||
this.backgroundColor = this.user.preferences.backgroundColor || '#000000';
|
||||
this.readerService.setOverrideStyles(this.backgroundColor);
|
||||
|
||||
|
||||
this.generalSettingsForm = this.formBuilder.group({
|
||||
autoCloseMenu: this.autoCloseMenu,
|
||||
pageSplitOption: this.pageSplitOption,
|
||||
fittingOption: this.translateScalingOption(this.scalingOption),
|
||||
layoutMode: this.layoutMode
|
||||
});
|
||||
|
||||
this.updateForm();
|
||||
|
||||
this.generalSettingsForm.get('layoutMode')?.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(val => {
|
||||
this.layoutMode = parseInt(val, 10);
|
||||
|
||||
if (this.layoutMode === LayoutMode.Single) {
|
||||
this.generalSettingsForm.get('pageSplitOption')?.enable();
|
||||
|
||||
} else {
|
||||
this.generalSettingsForm.get('pageSplitOption')?.setValue(PageSplitOption.FitSplit);
|
||||
this.generalSettingsForm.get('pageSplitOption')?.disable();
|
||||
|
||||
this.canvasImage2 = this.cachedImages.peek();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.generalSettingsForm.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe((changes: SimpleChanges) => {
|
||||
this.autoCloseMenu = this.generalSettingsForm.get('autoCloseMenu')?.value;
|
||||
const needsSplitting = this.isCoverImage();
|
||||
// If we need to split on a menu change, then we need to re-render.
|
||||
if (needsSplitting) {
|
||||
this.loadPage();
|
||||
}
|
||||
});
|
||||
|
||||
this.memberService.hasReadingProgress(this.libraryId).pipe(take(1)).subscribe(progress => {
|
||||
if (!progress) {
|
||||
this.toggleMenu();
|
||||
this.toastr.info('Tap the image at any time to open the menu. You can configure different settings or go to page by clicking progress bar. Tap sides of image move to next/prev page.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// If no user, we can't render
|
||||
if (!user) {
|
||||
this.router.navigateByUrl('/login');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.user = user;
|
||||
this.readingDirection = this.user.preferences.readingDirection;
|
||||
this.scalingOption = this.user.preferences.scalingOption;
|
||||
this.pageSplitOption = this.user.preferences.pageSplitOption;
|
||||
this.autoCloseMenu = this.user.preferences.autoCloseMenu;
|
||||
this.readerMode = this.user.preferences.readerMode;
|
||||
this.layoutMode = this.user.preferences.layoutMode || LayoutMode.Single;
|
||||
this.backgroundColor = this.user.preferences.backgroundColor || '#000000';
|
||||
this.readerService.setOverrideStyles(this.backgroundColor);
|
||||
|
||||
this.generalSettingsForm = this.formBuilder.group({
|
||||
autoCloseMenu: this.autoCloseMenu,
|
||||
pageSplitOption: this.pageSplitOption,
|
||||
fittingOption: this.translateScalingOption(this.scalingOption),
|
||||
layoutMode: this.layoutMode
|
||||
});
|
||||
|
||||
this.updateForm();
|
||||
|
||||
this.generalSettingsForm.get('layoutMode')?.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe(val => {
|
||||
this.layoutMode = parseInt(val, 10);
|
||||
|
||||
if (this.layoutMode === LayoutMode.Single) {
|
||||
this.generalSettingsForm.get('pageSplitOption')?.enable();
|
||||
} else {
|
||||
this.generalSettingsForm.get('pageSplitOption')?.setValue(PageSplitOption.FitSplit);
|
||||
this.generalSettingsForm.get('pageSplitOption')?.disable();
|
||||
this.canvasImage2 = this.cachedImages.peek();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.generalSettingsForm.valueChanges.pipe(takeUntil(this.onDestroy)).subscribe((changes: SimpleChanges) => {
|
||||
this.autoCloseMenu = this.generalSettingsForm.get('autoCloseMenu')?.value;
|
||||
const needsSplitting = this.isCoverImage();
|
||||
// If we need to split on a menu change, then we need to re-render.
|
||||
if (needsSplitting) {
|
||||
this.loadPage();
|
||||
}
|
||||
});
|
||||
|
||||
this.memberService.hasReadingProgress(this.libraryId).pipe(take(1)).subscribe(progress => {
|
||||
if (!progress) {
|
||||
this.toggleMenu();
|
||||
this.toastr.info('Tap the image at any time to open the menu. You can configure different settings or go to page by clicking progress bar. Tap sides of image move to next/prev page.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
||||
fromEvent(this.readingArea.nativeElement, 'scroll').pipe(debounceTime(20), takeUntil(this.onDestroy)).subscribe(evt => {
|
||||
if (this.readerMode === ReaderMode.Webtoon) return;
|
||||
if (this.readerMode === ReaderMode.LeftRight && this.generalSettingsForm.get('fittingOption')?.value === FITTING_OPTION.HEIGHT) {
|
||||
if (this.readerMode === ReaderMode.LeftRight && this.FittingOption === FITTING_OPTION.HEIGHT) {
|
||||
this.rightPaginationOffset = (this.readingArea.nativeElement.scrollLeft) * -1;
|
||||
return;
|
||||
}
|
||||
this.rightPaginationOffset = 0;
|
||||
});
|
||||
this.getWindowDimensions();
|
||||
|
||||
if (this.canvas) {
|
||||
this.ctx = this.canvas.nativeElement.getContext('2d', { alpha: false });
|
||||
this.canvasImage.onload = () => this.renderPage();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
|
@ -495,8 +486,10 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
switch (this.readerMode) {
|
||||
case ReaderMode.LeftRight:
|
||||
if (event.key === KEY_CODES.RIGHT_ARROW) {
|
||||
//if (!this.checkIfPaginationAllowed()) return;
|
||||
this.readingDirection === ReadingDirection.LeftToRight ? this.nextPage() : this.prevPage();
|
||||
} else if (event.key === KEY_CODES.LEFT_ARROW) {
|
||||
//if (!this.checkIfPaginationAllowed()) return;
|
||||
this.readingDirection === ReadingDirection.LeftToRight ? this.prevPage() : this.nextPage();
|
||||
}
|
||||
break;
|
||||
|
|
@ -531,6 +524,21 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
// if there is scroll room and on original, then don't paginate
|
||||
checkIfPaginationAllowed() {
|
||||
// This is not used atm due to the complexity it adds with keyboard.
|
||||
if (this.readingArea === undefined || this.readingArea.nativeElement === undefined) return true;
|
||||
|
||||
const scrollLeft = this.readingArea?.nativeElement?.scrollLeft || 0;
|
||||
const totalScrollWidth = this.readingArea?.nativeElement?.scrollWidth;
|
||||
// need to also check if there is scrolll needed
|
||||
|
||||
if (this.FittingOption === FITTING_OPTION.ORIGINAL && scrollLeft < totalScrollWidth) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
clickOverlayClass(side: 'right' | 'left') {
|
||||
if (!this.showClickOverlay) {
|
||||
return '';
|
||||
|
|
@ -593,10 +601,10 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}).pipe(take(1)).subscribe(results => {
|
||||
|
||||
|
||||
if (this.readingListMode && results.chapterInfo.seriesFormat === MangaFormat.EPUB) {
|
||||
if (this.readingListMode && (results.chapterInfo.seriesFormat === MangaFormat.EPUB || results.chapterInfo.seriesFormat === MangaFormat.PDF)) {
|
||||
// Redirect to the book reader.
|
||||
const params = this.readerService.getQueryParamsObject(this.incognitoMode, this.readingListMode, this.readingListId);
|
||||
this.router.navigate(['library', results.chapterInfo.libraryId, 'series', results.chapterInfo.seriesId, 'book', this.chapterId], {queryParams: params});
|
||||
this.router.navigate(this.readerService.getNavigationArray(results.chapterInfo.libraryId, results.chapterInfo.seriesId, this.chapterId, results.chapterInfo.seriesFormat), {queryParams: params});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -831,7 +839,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
*/
|
||||
isNoSplit() {
|
||||
const splitValue = parseInt(this.generalSettingsForm?.get('pageSplitOption')?.value, 10);
|
||||
return splitValue === PageSplitOption.NoSplit || splitValue === PageSplitOption.FitSplit;
|
||||
return splitValue === PageSplitOption.NoSplit || splitValue === PageSplitOption.FitSplit;
|
||||
}
|
||||
|
||||
updateSplitPage() {
|
||||
|
|
@ -1072,7 +1080,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
// Reset scroll on non HEIGHT Fits
|
||||
if (this.getFit() !== FITTING_OPTION.HEIGHT) {
|
||||
this.document.body.scroll(0, 0)
|
||||
this.readingArea.nativeElement.scroll(0,0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1088,7 +1096,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|| document.body.clientHeight;
|
||||
|
||||
const needsSplitting = this.isCoverImage();
|
||||
let newScale = this.generalSettingsForm.get('fittingOption')?.value;
|
||||
let newScale = this.FittingOption;
|
||||
const widthRatio = windowWidth / (this.canvasImage.width / (needsSplitting ? 2 : 1));
|
||||
const heightRatio = windowHeight / (this.canvasImage.height);
|
||||
|
||||
|
|
@ -1340,7 +1348,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
bookmarkPage() {
|
||||
const pageNum = this.pageNum;
|
||||
|
||||
if (this.isCurrentPageBookmarked) {
|
||||
if (this.CurrentPageBookmarked) {
|
||||
let apis = [this.readerService.unbookmark(this.seriesId, this.volumeId, this.chapterId, pageNum)];
|
||||
if (this.layoutMode === LayoutMode.Double) apis.push(this.readerService.unbookmark(this.seriesId, this.volumeId, this.chapterId, pageNum + 1));
|
||||
forkJoin(apis).pipe(take(1)).subscribe(() => {
|
||||
|
|
@ -1394,16 +1402,6 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
getWindowDimensions() {
|
||||
const windowWidth = window.innerWidth
|
||||
|| document.documentElement.clientWidth
|
||||
|| document.body.clientWidth;
|
||||
const windowHeight = window.innerHeight
|
||||
|| document.documentElement.clientHeight
|
||||
|| document.body.clientHeight;
|
||||
return [windowWidth, windowHeight];
|
||||
}
|
||||
|
||||
openShortcutModal() {
|
||||
let ref = this.modalService.open(ShorcutsModalComponent, { scrollable: true, size: 'md' });
|
||||
ref.componentInstance.shortcuts = [
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ import { SharedModule } from '../shared/shared.module';
|
|||
import { NgxSliderModule } from '@angular-slider/ngx-slider';
|
||||
import { InfiniteScrollerComponent } from './infinite-scroller/infinite-scroller.component';
|
||||
import { ReaderSharedModule } from '../reader-shared/reader-shared.module';
|
||||
import { FullscreenIconPipe } from './fullscreen-icon.pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
MangaReaderComponent,
|
||||
InfiniteScrollerComponent
|
||||
InfiniteScrollerComponent,
|
||||
FullscreenIconPipe
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue