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:
parent
f22f30b5a9
commit
2bde0ac82a
55 changed files with 4410 additions and 439 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
26
UI/Web/src/app/pdf-reader/_pipe/pdf-layout-mode.pipe.ts
Normal file
26
UI/Web/src/app/pdf-reader/_pipe/pdf-layout-mode.pipe.ts
Normal 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');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
24
UI/Web/src/app/pdf-reader/_pipe/pdf-scroll-mode.pipe.ts
Normal file
24
UI/Web/src/app/pdf-reader/_pipe/pdf-scroll-mode.pipe.ts
Normal 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');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
24
UI/Web/src/app/pdf-reader/_pipe/pdf-spread-mode.pipe.ts
Normal file
24
UI/Web/src/app/pdf-reader/_pipe/pdf-spread-mode.pipe.ts
Normal 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');
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue