PDF Reader Settings, New Reading Modes, and lots of fixes (#2828)

Co-authored-by: Elry <144011449+ElryWeeb@users.noreply.github.com>
Co-authored-by: AlienHack <the4got10@windowslive.com>
Co-authored-by: William Brockhus <pickeringw@gmail.com>
Co-authored-by: Shivam Amin <xShivam.Amin@gmail.com>
This commit is contained in:
Joe Milazzo 2024-03-30 15:07:03 -05:00 committed by GitHub
parent f22f30b5a9
commit 2bde0ac82a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 4410 additions and 439 deletions

View file

@ -33,25 +33,54 @@
[backgroundColor]="backgroundColor"
[customToolbar]="multiToolbar"
[language]="user.preferences.locale"
[(scrollMode)]="scrollMode"
[pageViewMode]="pageLayoutMode"
[spread]="spreadMode"
(pageChange)="saveProgress()"
(pdfLoadingStarts)="updateLoading(true)"
(pdfLoaded)="updateLoading(false)"
(progress)="updateLoadProgress($event)"
(zoomChange)="calcScrollbarNeeded()"
>
</ngx-extended-pdf-viewer>
@if (scrollMode === ScrollModeType.page) {
<div class="left" (click)="prevPage()"></div>
<div class="{{scrollbarNeeded ? 'right-with-scrollbar' : 'right'}}" (click)="nextPage()"></div>
}
<ng-template #multiToolbar>
<div style="min-height: 36px" id="toolbarViewer" [ngStyle]="{'background-color': backgroundColor, 'color': fontColor}">
<div id="toolbarViewerLeft">
<pdf-toggle-sidebar></pdf-toggle-sidebar>
<pdf-find-button></pdf-find-button>
<pdf-paging-area></pdf-paging-area>
@if (utilityService.getActiveBreakpoint() > Breakpoint.Mobile) {
<button class="btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton" [ngbTooltip]="bookTitle">
<i class="toolbar-icon fa-solid fa-info" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{bookTitle}}</span>
</button>
}
<button *ngIf="incognitoMode" [ngbTooltip]="t('toggle-incognito')" (click)="turnOffIncognito()" class="btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton">
<i class="toolbar-icon fa fa-glasses" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{t('incognito-mode')}}</span>
</button>
<button class="btn-icon col-2 col-xs-1 mt-0 mb-0 pt-1 pb-0 toolbarButton" (click)="closeReader()" [ngbTooltip]="t('close-reader-alt')">
<i class="toolbar-icon fa fa-times-circle" aria-hidden="true" [ngStyle]="{color: fontColor}"></i>
<span class="visually-hidden">{{t('close-reader-alt')}}</span>
</button>
</div>
<pdf-zoom-toolbar ></pdf-zoom-toolbar>
@if (utilityService.getActiveBreakpoint() > Breakpoint.Tablet) {
<pdf-zoom-toolbar ></pdf-zoom-toolbar>
}
<div id="toolbarViewerRight">
<pdf-hand-tool></pdf-hand-tool>
@ -59,42 +88,66 @@
<pdf-presentation-mode></pdf-presentation-mode>
<!-- This is not yet supported by the underlying library
<button (click)="toggleBookPageMode()" class="btn btn-icon toolbarButton">
<i class="toolbar-icon fa-solid {{this.bookMode !== 'book' ? 'fa-book' : 'fa-book-open'}}" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{this.bookMode !== 'book' ? 'Book Mode' : 'Normal Mode'}}</span>
</button> -->
@if (utilityService.getActiveBreakpoint() > Breakpoint.Mobile) {
<button (click)="toggleBookPageMode()" class="btn-icon toolbarButton" [ngbTooltip]="pageLayoutMode | pdfLayoutMode" [disabled]="scrollMode === ScrollModeType.page">
<i class="toolbar-icon fa-solid {{this.pageLayoutMode !== 'book' ? 'fa-book' : 'fa-book-open'}}" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{this.pageLayoutMode | pdfLayoutMode}}</span>
</button>
}
<button class="btn btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton" [ngbTooltip]="bookTitle">
<i class="toolbar-icon fa-solid fa-info" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{bookTitle}}</span>
<!-- scroll mode should be disabled when book mode is used -->
<button (click)="toggleScrollMode()" class="btn-icon toolbarButton" [ngbTooltip]="scrollMode | pdfScrollMode" [disabled]="this.pageLayoutMode === 'book'">
@switch (scrollMode) {
@case (ScrollModeType.vertical) {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px" viewBox="0 0 24 24"><path fill="currentColor" d="M9.5 4c1 0 1.5.5 1.5 1.5v5c0 1-.5 1.5-1.5 1.5h-3c-1 0-1.5-.5-1.5-1.5v-5C5 4.5 5.5 4 6.5 4zM11 0v.5c0 1-.5 1.5-1.5 1.5h-3C5.5 2 5 1.5 5 .5V0h6zM11 16v-.5c0-1-.5-1.5-1.5-1.5h-3c-1 0-1.5.5-1.5 1.5v.5h6z"></path></svg>
}
@case (ScrollModeType.page) {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px" viewBox="0 0 24 24"><path fill="currentColor" d="M10,7V9H12V17H14V7H10Z"></path></svg>
}
@case (ScrollModeType.horizontal) {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px"> <path fill="currentColor" d="M0 4h1.5c1 0 1.5.5 1.5 1.5v5c0 1-.5 1.5-1.5 1.5H0zM9.5 4c1 0 1.5.5 1.5 1.5v5c0 1-.5 1.5-1.5 1.5h-3c-1 0-1.5-.5-1.5-1.5v-5C5 4.5 5.5 4 6.5 4zM16 4h-1.5c-1 0-1.5.5-1.5 1.5v5c0 1 .5 1.5 1.5 1.5H16z"></path> </svg>
}
@case (ScrollModeType.wrapped) {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px" viewBox="0 0 24 24"><path fill="currentColor" d="M5.5 4c1 0 1.5.5 1.5 1.5v5c0 1-.5 1.5-1.5 1.5h-3c-1 0-1.5-.5-1.5-1.5v-5C1 4.5 1.5 4 2.5 4zM7 0v.5C7 1.5 6.5 2 5.5 2h-3C1.5 2 1 1.5 1 .5V0h6zM7 16v-.5c0-1-.5-1.5-1.5-1.5h-3c-1 0-1.5.5-1.5 1.5v.5h6zM13.5 4c1 0 1.5.5 1.5 1.5v5c0 1-.5 1.5-1.5 1.5h-3c-1 0-1.5-.5-1.5-1.5v-5c0-1 .5-1.5 1.5-1.5zM15 0v.5c0 1-.5 1.5-1.5 1.5h-3C9.5 2 9 1.5 9 .5V0h6zM15 16v-.507c0-1-.5-1.5-1.5-1.5h-3C9.5 14 9 14.5 9 15.5v.5h6z"></path></svg>
}
}
<span class="visually-hidden">{{scrollMode | pdfScrollMode}}</span>
</button>
<button *ngIf="incognitoMode" (click)="turnOffIncognito()" class="btn btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton">
<i class="toolbar-icon fa fa-glasses" [ngStyle]="{color: fontColor}" aria-hidden="true"></i><span class="visually-hidden">{{t('incognito-mode')}}</span>
<button (click)="toggleSpreadMode()" class="btn-icon toolbarButton" [ngbTooltip]="spreadMode | pdfSpreadMode" [disabled]="this.pageLayoutMode === 'book'">
@switch (spreadMode) {
@case ('off') {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px" viewBox="0 0 24 24"><path fill="currentColor" d="M6 3c-1 0-1.5.5-1.5 1.5v7c0 1 .5 1.5 1.5 1.5h4c1 0 1.5-.5 1.5-1.5v-7c0-1-.5-1.5-1.5-1.5z"></path></svg>
}
@case ('odd') {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px" viewBox="0 0 24 24"><path fill="currentColor" d="M10.56 3.5C9.56 3.5 9 4 9 5v6.5c0 1 .5 1.5 1.5 1.5h4c1 0 1.5-.5 1.5-1.5V5c0-1-.5-1.5-1.5-1.5zm1.93 1.2c.8 0 1.4.2 1.8.64.5.4.7 1 .7 1.7 0 .5-.2 1-.5 1.44-.2.3-.6.6-1 .93l-.6.4c-.4.3-.6.4-.7.55-.1.1-.2.2-.3.4h3.2v1.27h-5c0-.5.1-1 .3-1.43.2-.49.7-1 1.5-1.54.7-.5 1.1-.8 1.3-1.02.3-.3.4-.7.4-1.05 0-.3-.1-.6-.3-.77-.2-.2-.4-.3-.7-.3-.4 0-.7.2-.9.5-.1.2-.1.5-.2.9h-1.4c0-.6.2-1.1.3-1.5.4-.7 1.1-1.1 2-1.1zM1.54 3.5C.54 3.5 0 4 0 5v6.5c0 1 .5 1.5 1.54 1.5h4c1 0 1.5-.5 1.5-1.5V5c0-1-.5-1.5-1.5-1.5zm1.8 1.125H4.5V12H3V6.9H1.3v-1c.5 0 .8 0 .97-.03.33-.07.53-.17.73-.37.1-.2.2-.3.25-.5.05-.2.05-.3.05-.3z"></path></svg>
}
@case ('even') {
<svg aria-hidden="true" [ngStyle]="{color: fontColor}" style="width: 24px; height: 24px; margin-top: 3px"><path fill="currentColor" d="M1.5 3.5C.5 3.5 0 4 0 5v6.5c0 1 .5 1.5 1.5 1.5h4c1 0 1.5-.5 1.5-1.5V5c0-1-.5-1.5-1.5-1.5zm2 1.2c.8 0 1.4.2 1.8.6.5.4.7 1 .7 1.7 0 .5-.2 1-.5 1.4-.2.3-.5.7-1 1l-.6.4c-.4.3-.6.4-.75.56-.15.14-.25.24-.35.44H6v1.3H1c0-.6.1-1.1.3-1.5.3-.6.7-1 1.5-1.6.7-.4 1.1-.8 1.28-1 .32-.3.42-.6.42-1 0-.3-.1-.6-.23-.8-.17-.2-.37-.3-.77-.3s-.7.1-.9.5c-.04.2-.1.5-.1.9H1.1c0-.6.1-1.1.3-1.5.4-.7 1.1-1.1 2.1-1.1zM10.54 3.54C9.5 3.54 9 4 9 5v6.5c0 1 .5 1.5 1.54 1.5h4c.96 0 1.46-.5 1.46-1.5V5c0-1-.5-1.46-1.5-1.46zm1.9.95c.7 0 1.3.2 1.7.5.4.4.6.8.6 1.4 0 .4-.1.8-.4 1.1-.2.2-.3.3-.5.4.1 0 .3.1.6.3.4.3.5.8.5 1.4 0 .6-.2 1.2-.6 1.6-.4.5-1.1.7-1.9.7-1 0-1.8-.3-2.2-1-.14-.29-.24-.69-.24-1.29h1.4c0 .3 0 .5.1.7.2.4.5.5 1 .5.3 0 .5-.1.7-.3.2-.2.3-.5.3-.8 0-.5-.2-.8-.6-.95-.2-.05-.5-.15-1-.15v-1c.5 0 .8-.1 1-.14.3-.1.5-.4.5-.9 0-.3-.1-.5-.2-.7-.2-.2-.4-.3-.7-.3-.3 0-.6.1-.75.3-.2.2-.2.5-.2.86h-1.34c0-.4.1-.7.19-1.1 0-.12.2-.32.4-.62.2-.2.4-.3.7-.4.3-.1.6-.1 1-.1z"></path></svg>
}
}
<span class="visually-hidden">{{spreadMode | pdfSpreadMode}}</span>
</button>
<!-- This is pretty experimental, so it might not work perfectly -->
<button (click)="toggleTheme()" class="btn btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton">
<button (click)="toggleTheme()" class="btn-icon mt-0 mb-0 pt-1 pb-0 toolbarButton toolbar-btn-fix">
<i class="toolbar-icon fa-solid {{this.theme === 'light' ? 'fa-sun' : 'fa-moon'}}" [ngStyle]="{color: fontColor}" aria-hidden="true"></i>
<span class="visually-hidden">{{this.theme === 'light' ? t('light-theme-alt') : t('dark-theme-alt')}}</span>
</button>
<button class="btn btn-icon col-2 col-xs-1 mt-0 mb-0 pt-1 pb-0 toolbarButton" (click)="closeReader()">
<i class="toolbar-icon fa fa-times-circle" aria-hidden="true" [ngStyle]="{color: fontColor}"></i>
<span class="visually-hidden">{{t('close-reader-alt')}}</span>
</button>
<div class="verticalToolbarSeparator hiddenSmallView"></div>
<pdf-toggle-secondary-toolbar></pdf-toggle-secondary-toolbar>
<pdf-single-page-mode [show]="true" [scrollMode]="scrollMode"></pdf-single-page-mode>
<pdf-vertical-scroll-mode [show]="true" [scrollMode]="scrollMode"></pdf-vertical-scroll-mode>
<pdf-horizontal-scroll [show]="true" [scrollMode]="scrollMode"></pdf-horizontal-scroll>
<pdf-wrapped-scroll-mode [show]="true" [scrollMode]="scrollMode"></pdf-wrapped-scroll-mode>
<pdf-no-spread [show]=true [scrollMode]="scrollMode"></pdf-no-spread>
<pdf-odd-spread [show]=true [scrollMode]="scrollMode"></pdf-odd-spread>
<pdf-even-spread [show]="true" [scrollMode]="scrollMode"></pdf-even-spread>
</div>
</div>

View file

@ -2,6 +2,9 @@
font-size: 19px;
}
.btn-icon {
border: none;
}
.book-title {
margin: 8px 0 4px !important;
@ -24,3 +27,76 @@
// NOTE: We have to override due to theme variables not being available
background-color: #3B9E76;
}
$pagination-color: transparent;
$pagination-opacity: 0;
//$pagination-color: red;
//$pagination-opacity: 0.7;
$action-bar-height: 36px;
// Tap to Paginate
.right {
position: absolute;
right: 0px;
top: $action-bar-height;
width: 20vw;
z-index: 3;
background: $pagination-color;
border-color: transparent;
border: none !important;
opacity: $pagination-opacity;
outline: none;
height: 100%;
&.immersive {
top: 0px;
}
&.no-pointer-events {
pointer-events: none;
}
}
// This class pushes the click area to the left a bit to let users click the scrollbar
.right-with-scrollbar {
position: absolute;
right: 17px;
top: $action-bar-height;
width: 18vw;
z-index: 3;
background: $pagination-color;
opacity: $pagination-opacity;
border-color: transparent;
border: none !important;
outline: none;
height: 100%;
cursor: pointer;
&.immersive {
top: 0px;
}
}
.left {
position: absolute;
left: 0px;
top: $action-bar-height;
width: 20vw;
background: $pagination-color;
opacity: $pagination-opacity;
border-color: transparent;
border: none !important;
z-index: 3;
outline: none;
height: 100%;
cursor: pointer;
&.immersive {
top: 0px;
}
}

View file

@ -1,27 +1,43 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component, ElementRef,
HostListener,
inject, OnDestroy,
OnInit, ViewChild
Component,
ElementRef,
HostListener, inject, Inject,
OnDestroy,
OnInit,
ViewChild
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { NgxExtendedPdfViewerService, PageViewModeType, ScrollModeType, ProgressBarEvent, NgxExtendedPdfViewerModule } from 'ngx-extended-pdf-viewer';
import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs';
import { BookService } from 'src/app/book-reader/_services/book.service';
import { KEY_CODES } from 'src/app/shared/_services/utility.service';
import { Chapter } from 'src/app/_models/chapter';
import { User } from 'src/app/_models/user';
import { AccountService } from 'src/app/_services/account.service';
import { NavService } from 'src/app/_services/nav.service';
import { CHAPTER_ID_DOESNT_EXIST, ReaderService } from 'src/app/_services/reader.service';
import { SeriesService } from 'src/app/_services/series.service';
import { ThemeService } from 'src/app/_services/theme.service';
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
import { NgIf, NgStyle, AsyncPipe } from '@angular/common';
import {ActivatedRoute, Router} from '@angular/router';
import {
NgxExtendedPdfViewerModule,
NgxExtendedPdfViewerService,
PageViewModeType,
ProgressBarEvent,
ScrollModeType
} from 'ngx-extended-pdf-viewer';
import {ToastrService} from 'ngx-toastr';
import {take} from 'rxjs';
import {BookService} from 'src/app/book-reader/_services/book.service';
import {Breakpoint, KEY_CODES, UtilityService} from 'src/app/shared/_services/utility.service';
import {Chapter} from 'src/app/_models/chapter';
import {User} from 'src/app/_models/user';
import {AccountService} from 'src/app/_services/account.service';
import {NavService} from 'src/app/_services/nav.service';
import {CHAPTER_ID_DOESNT_EXIST, ReaderService} from 'src/app/_services/reader.service';
import {SeriesService} from 'src/app/_services/series.service';
import {ThemeService} from 'src/app/_services/theme.service';
import {NgbTooltip} from '@ng-bootstrap/ng-bootstrap';
import {AsyncPipe, DOCUMENT, NgIf, NgStyle} from '@angular/common';
import {translate, TranslocoDirective} from "@ngneat/transloco";
import {PdfLayoutMode} from "../../../_models/preferences/pdf-layout-mode";
import {PdfScrollMode} from "../../../_models/preferences/pdf-scroll-mode";
import {PdfTheme} from "../../../_models/preferences/pdf-theme";
import {PdfSpreadMode} from "../../../_models/preferences/pdf-spread-mode";
import {SpreadType} from "ngx-extended-pdf-viewer/lib/options/spread-type";
import {PdfLayoutModePipe} from "../../_pipe/pdf-layout-mode.pipe";
import {PdfScrollModePipe} from "../../_pipe/pdf-scroll-mode.pipe";
import {PdfSpreadModePipe} from "../../_pipe/pdf-spread-mode.pipe";
@Component({
selector: 'app-pdf-reader',
@ -29,10 +45,26 @@ import {translate, TranslocoDirective} from "@ngneat/transloco";
styleUrls: ['./pdf-reader.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [NgIf, NgStyle, NgxExtendedPdfViewerModule, NgbTooltip, AsyncPipe, TranslocoDirective]
imports: [NgIf, NgStyle, NgxExtendedPdfViewerModule, NgbTooltip, AsyncPipe, TranslocoDirective,
PdfLayoutModePipe, PdfScrollModePipe, PdfSpreadModePipe]
})
export class PdfReaderComponent implements OnInit, OnDestroy {
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);
private readonly seriesService = inject(SeriesService);
private readonly navService = inject(NavService);
private readonly toastr = inject(ToastrService);
private readonly bookService = inject(BookService);
private readonly themeService = inject(ThemeService);
private readonly cdRef = inject(ChangeDetectorRef);
public readonly accountService = inject(AccountService);
public readonly readerService = inject(ReaderService);
public readonly utilityService = inject(UtilityService);
protected readonly ScrollModeType = ScrollModeType;
protected readonly Breakpoint = Breakpoint;
@ViewChild('container') container!: ElementRef;
libraryId!: number;
@ -82,20 +114,13 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
* How much of the current document is loaded
*/
loadPercent: number = 0;
scrollbarNeeded = false;
/**
* This can't be updated dynamically:
* https://github.com/stephanrauh/ngx-extended-pdf-viewer/issues/1415
*/
bookMode: PageViewModeType = 'multiple';
pageLayoutMode: PageViewModeType = 'multiple';
scrollMode: ScrollModeType = ScrollModeType.vertical;
spreadMode: SpreadType = 'off';
constructor(private route: ActivatedRoute, private router: Router, public accountService: AccountService,
private seriesService: SeriesService, public readerService: ReaderService,
private navService: NavService, private toastr: ToastrService,
private bookService: BookService, private themeService: ThemeService,
private readonly cdRef: ChangeDetectorRef, private pdfViewerService: NgxExtendedPdfViewerService) {
constructor(@Inject(DOCUMENT) private document: Document) {
this.navService.hideNavBar();
this.themeService.clearThemes();
this.navService.hideSideNav();
@ -108,6 +133,13 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
}
}
@HostListener('window:resize', ['$event'])
@HostListener('window:orientationchange', ['$event'])
onResize(){
// Update the window Height
this.calcScrollbarNeeded();
}
ngOnDestroy(): void {
this.themeService.currentTheme$.pipe(take(1)).subscribe(theme => {
this.themeService.setTheme(theme.name);
@ -150,7 +182,71 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
});
}
calcScrollbarNeeded() {
const viewContainer = this.document.querySelector('#viewerContainer');
if (viewContainer == null) return;
this.scrollbarNeeded = viewContainer.scrollHeight > this.container?.nativeElement?.clientHeight;
this.cdRef.markForCheck();
}
convertPdfLayoutMode(mode: PdfLayoutMode) {
switch (mode) {
case PdfLayoutMode.Multiple:
return 'multiple';
case PdfLayoutMode.Single:
return 'single';
case PdfLayoutMode.Book:
return 'book';
case PdfLayoutMode.InfiniteScroll:
return 'infinite-scroll';
}
}
convertPdfScrollMode(mode: PdfScrollMode) {
switch (mode) {
case PdfScrollMode.Vertical:
return ScrollModeType.vertical;
case PdfScrollMode.Horizontal:
return ScrollModeType.horizontal;
case PdfScrollMode.Wrapped:
return ScrollModeType.wrapped;
case PdfScrollMode.Page:
return ScrollModeType.page;
}
}
convertPdfSpreadMode(mode: PdfSpreadMode): SpreadType {
switch (mode) {
case PdfSpreadMode.None:
return 'off' as SpreadType;
case PdfSpreadMode.Odd:
return 'odd' as SpreadType;
case PdfSpreadMode.Even:
return 'even' as SpreadType;
}
}
convertPdfTheme(theme: PdfTheme) {
switch (theme) {
case PdfTheme.Dark:
return 'dark';
case PdfTheme.Light:
return 'light';
}
}
init() {
this.pageLayoutMode = this.convertPdfLayoutMode(this.user.preferences.pdfLayoutMode || PdfLayoutMode.Multiple);
this.scrollMode = this.convertPdfScrollMode(this.user.preferences.pdfScrollMode || PdfScrollMode.Vertical);
this.spreadMode = this.convertPdfSpreadMode(this.user.preferences.pdfSpreadMode || PdfSpreadMode.None);
this.theme = this.convertPdfTheme(this.user.preferences.pdfTheme || PdfTheme.Dark);
this.backgroundColor = this.themeMap[this.theme].background;
this.fontColor = this.themeMap[this.theme].font; // TODO: Move this to an observable or something
this.calcScrollbarNeeded();
this.bookService.getBookInfo(this.chapterId).subscribe(info => {
this.volumeId = info.volumeId;
this.bookTitle = info.bookTitle;
@ -171,7 +267,7 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
}
this.cdRef.markForCheck();
});
this.readerService.enableWakeLock(this.container.nativeElement);
setTimeout(() => this.readerService.enableWakeLock(this.container.nativeElement), 1000); // TODO: This needs to be in afterviewinit i think
}
/**
@ -197,11 +293,33 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
this.cdRef.markForCheck();
}
toggleScrollMode() {
const options: Array<ScrollModeType> = [ScrollModeType.vertical, ScrollModeType.horizontal, ScrollModeType.page];
let index = options.indexOf(this.scrollMode) + 1;
if (index >= options.length) index = 0;
this.scrollMode = options[index];
this.calcScrollbarNeeded();
this.cdRef.markForCheck();
}
toggleSpreadMode() {
const options: Array<SpreadType> = ['off', 'odd', 'even'];
let index = options.indexOf(this.spreadMode) + 1;
if (index >= options.length) index = 0;
this.spreadMode = options[index];
this.cdRef.markForCheck();
}
toggleBookPageMode() {
if (this.bookMode === 'book') {
this.bookMode = 'multiple';
if (this.pageLayoutMode === 'book') {
this.pageLayoutMode = 'multiple';
} else {
this.bookMode = 'book';
this.pageLayoutMode = 'book';
// If the fit is automatic, let's adjust to 100% to ensure it renders correctly (can't do this, but it doesn't always happen)
}
this.cdRef.markForCheck();
}
@ -225,4 +343,16 @@ export class PdfReaderComponent implements OnInit, OnDestroy {
this.cdRef.markForCheck();
}
prevPage() {
this.currentPage--;
if (this.currentPage < 0) this.currentPage = 0;
this.cdRef.markForCheck();
}
nextPage() {
this.currentPage++;
if (this.currentPage > this.maxPages) this.currentPage = this.maxPages;
this.cdRef.markForCheck();
}
}

View file

@ -0,0 +1,26 @@
import {inject, Pipe, PipeTransform} from '@angular/core';
import {PageViewModeType} from "ngx-extended-pdf-viewer";
import {TranslocoService} from "@ngneat/transloco";
@Pipe({
name: 'pdfLayoutMode',
standalone: true
})
export class PdfLayoutModePipe implements PipeTransform {
translocoService = inject(TranslocoService);
transform(value: PageViewModeType): string {
switch (value) {
case "single":
return this.translocoService.translate('pdf-layout-mode-pipe.single');
case "book":
return this.translocoService.translate('pdf-layout-mode-pipe.book');
case "multiple":
return this.translocoService.translate('pdf-layout-mode-pipe.multiple');
case "infinite-scroll":
return this.translocoService.translate('pdf-layout-mode-pipe.infinite-scroll');
}
}
}

View file

@ -0,0 +1,24 @@
import {inject, Pipe, PipeTransform} from '@angular/core';
import {TranslocoService} from "@ngneat/transloco";
import {ScrollModeType} from "ngx-extended-pdf-viewer";
@Pipe({
name: 'pdfScrollMode',
standalone: true
})
export class PdfScrollModePipe implements PipeTransform {
translocoService = inject(TranslocoService);
transform(value: ScrollModeType): string {
switch (value) {
case ScrollModeType.vertical:
return this.translocoService.translate('pdf-scroll-mode-pipe.vertical');
case ScrollModeType.horizontal:
return this.translocoService.translate('pdf-scroll-mode-pipe.horizontal');
case ScrollModeType.wrapped:
return this.translocoService.translate('pdf-scroll-mode-pipe.wrapped');
case ScrollModeType.page:
return this.translocoService.translate('pdf-scroll-mode-pipe.page');
}
}
}

View file

@ -0,0 +1,24 @@
import {inject, Pipe, PipeTransform} from '@angular/core';
import {TranslocoService} from "@ngneat/transloco";
import {SpreadType} from "ngx-extended-pdf-viewer/lib/options/spread-type";
@Pipe({
name: 'pdfSpreadMode',
standalone: true
})
export class PdfSpreadModePipe implements PipeTransform {
translocoService = inject(TranslocoService);
transform(value: SpreadType): string {
switch (value) {
case 'off' as SpreadType:
return this.translocoService.translate('pdf-spread-mode-pipe.off');
case "even":
return this.translocoService.translate('pdf-spread-mode-pipe.even');
case "odd":
return this.translocoService.translate('pdf-spread-mode-pipe.odd');
}
return this.translocoService.translate('pdf-spread-mode-pipe.off');
}
}