More Reader Bugfixes (#1255)

* Added css to center images

* Better scaling css

* Removing vertical height css for actionbar calc

* Fixed a bug where book settings couldn't be saved due to typo in model

* fixing height across layouts

* Fixed an issue where column mode would reset to user preference default between continuous reader loads

* Fixing some more logic

* Reading direction arrow keys now flip

* Small code cleanup on Robbie's code

Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joseph Milazzo 2022-05-14 17:02:58 -05:00 committed by GitHub
parent be5b997259
commit d458a823ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 71 deletions

View File

@ -1,4 +1,4 @@
<div class="container-flex {{darkMode ? 'dark-mode' : ''}} reader-container" tabindex="0" #reader>
<div class="container-flex {{darkMode ? 'dark-mode' : ''}} reader-container {{ColumnLayout}}" tabindex="0" #reader>
<div class="fixed-top" #stickyTop>
<a class="visually-hidden-focusable focus-visible" href="javascript:void(0);" (click)="moveFocus()">Skip to main content</a>
<ng-container [ngTemplateOutlet]="actionBar"></ng-container>
@ -53,7 +53,7 @@
(clickToPaginateChanged)="showPaginationOverlay($event)"
(fullscreen)="toggleFullscreen()"
(layoutModeUpdate)="updateLayoutMode($event)"
(readingDirection)="readingDirection = $event"
(readingDirection)="updateReadingDirection($event)"
(immersiveMode)="immersiveMode = $event"
></app-reader-settings>
</ng-template>
@ -73,17 +73,19 @@
</div>
<div #readingSection class="reading-section {{ColumnLayout}}" [@isLoading]="isLoading ? true : false">
<div #readingCont class="book-container {{ColumnLayout}}">
<div #readingHtml class="book-content" [ngStyle]="{'max-height': ColumnHeight, 'column-width': ColumnWidth}"
[innerHtml]="page" *ngIf="page !== undefined" (click)="toggleMenu($event)" (mousedown)="mouseDown($event)"></div>
<div #readingHtml class="book-content {{ColumnLayout}}" [ngStyle]="{'max-height': ColumnHeight, 'column-width': ColumnWidth}"
[innerHtml]="page" *ngIf="page !== undefined" (click)="toggleMenu($event)" (mousedown)="mouseDown($event)"></div>
<ng-container *ngIf="clickToPaginate">
<div class="left {{clickOverlayClass('left')}} no-observe" (click)="movePage(readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.BACKWARDS : PAGING_DIRECTION.FORWARD)" tabindex="-1"></div>
<div class="{{scrollbarNeeded ? 'right-with-scrollbar' : 'right'}} {{clickOverlayClass('right')}} no-observe" (click)="movePage(readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.FORWARD : PAGING_DIRECTION.BACKWARDS)" tabindex="-1"></div>
</ng-container>
<ng-container *ngIf="clickToPaginate">
<div class="left {{clickOverlayClass('left')}} no-observe" (click)="movePage(readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.BACKWARDS : PAGING_DIRECTION.FORWARD)" tabindex="-1"></div>
<div class="{{scrollbarNeeded ? 'right-with-scrollbar' : 'right'}} {{clickOverlayClass('right')}} no-observe" (click)="movePage(readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.FORWARD : PAGING_DIRECTION.BACKWARDS)" tabindex="-1"></div>
</ng-container>
<div *ngIf="page !== undefined && (scrollbarNeeded || layoutMode !== BookPageLayoutMode.Default)" (click)="$event.stopPropagation();">
<ng-container [ngTemplateOutlet]="actionBar"></ng-container>
<div *ngIf="page !== undefined && (scrollbarNeeded || layoutMode !== BookPageLayoutMode.Default)" (click)="$event.stopPropagation();">
<ng-container [ngTemplateOutlet]="actionBar"></ng-container>
</div>
</div>
</div>

View File

@ -44,6 +44,7 @@
$dark-form-background-no-opacity: rgb(1, 4, 9);
$primary-color: #0062cc;
$action-bar-height: 38px;
// Drawer
@ -92,8 +93,8 @@ $primary-color: #0062cc;
background-color: var(--br-actionbar-bg-color);
overflow: hidden;
box-shadow: 0 0 6px 0 rgb(0 0 0 / 70%);
max-height: 38px;
height: 38px;
max-height: $action-bar-height;
height: $action-bar-height;
.book-title-text {
text-align: center;
@ -122,26 +123,62 @@ $primary-color: #0062cc;
}
}
.reading-section {
max-height: 100vh;
width: 100%;
//overflow: auto; // This will break progress reporting
height: calc(var(--vh, 1vh) * 100);
padding-top: 38px;
}
.reader-container {
outline: none; // Only the reading section itself shouldn't receive any outline. We use it to shift focus in fullscreen mode
overflow: auto;
height: calc(var(--vh, 1vh) * 100);
position: relative;
&.column-layout-1 {
height: calc(var(--vh) * 100);
}
&.column-layout-2 {
height: calc(var(--vh) * 100);
}
}
.reading-section {
width: 100%;
//overflow: auto; // This will break progress reporting
height: 100vh;
padding-top: $action-bar-height;
position: relative;
&.column-layout-1 {
height: calc((var(--vh, 1vh) * 100) - $action-bar-height);
}
&.column-layout-2 {
height: calc((var(--vh, 1vh) * 100) - $action-bar-height);
}
}
.book-container {
position: relative;
height: 100%;
&.column-layout-1 {
height: calc((var(--vh, 1vh) * 100) - $action-bar-height);
}
&.column-layout-2 {
height: calc((var(--vh, 1vh) * 100) - $action-bar-height);
}
}
.book-content {
position: relative;
padding: 20px 0;
margin: 0px 0px;
height: calc(var(--vh, 1vh) * 100); // This will ensure bottom bar extends to the bottom of the screen
&.column-layout-1 {
height: calc((var(--vh) * 100) - calc($action-bar-height * 2));
}
&.column-layout-2 {
height: calc((var(--vh) * 100) - calc($action-bar-height * 2));
}
a, :link {
color: var(--brtheme-link-text-color);
@ -238,7 +275,7 @@ $primary-color: #0062cc;
cursor: pointer;
opacity: 0;
background: transparent;
padding-top: 38px;
padding-top: $action-bar-height;
}
// This class pushes the click area to the left a bit to let users click the scrollbar
@ -252,7 +289,7 @@ $primary-color: #0062cc;
cursor: pointer;
opacity: 0;
background: transparent;
padding-top: 38px;
padding-top: $action-bar-height;
}
.left {
@ -265,7 +302,7 @@ $primary-color: #0062cc;
cursor: pointer;
opacity: 0;
background: transparent;
padding-top: 38px;
padding-top: $action-bar-height;
}
.highlight {

View File

@ -524,8 +524,9 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
this.libraryType = type;
});
this.updateLayoutMode(this.user.preferences.bookReaderLayoutMode || BookPageLayoutMode.Default);
// We need to think about if the user modified this and this function call is a continuous reader one
//this.updateLayoutMode(this.user.preferences.bookReaderLayoutMode || BookPageLayoutMode.Default);
this.updateImagesWithHeight();
if (this.pageNum >= this.maxPages) {
@ -586,9 +587,9 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
@HostListener('window:keydown', ['$event'])
handleKeyPress(event: KeyboardEvent) {
if (event.key === KEY_CODES.RIGHT_ARROW) {
this.nextPage();
this.movePage(this.readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.FORWARD : PAGING_DIRECTION.BACKWARDS);
} else if (event.key === KEY_CODES.LEFT_ARROW) {
this.prevPage();
this.movePage(this.readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.BACKWARDS : PAGING_DIRECTION.FORWARD);
} else if (event.key === KEY_CODES.ESC_KEY) {
this.closeReader();
} else if (event.key === KEY_CODES.SPACE) {
@ -791,7 +792,8 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
* Applies a max-height inline css property on each image in the page if the layout mode is column-based, else it removes the property
*/
updateImagesWithHeight() {
const images = this.readingSectionElemRef.nativeElement.querySelectorAll('img') || [];
const images = this.readingSectionElemRef?.nativeElement.querySelectorAll('img') || [];
if (this.layoutMode !== BookPageLayoutMode.Default) {
const height = this.ColumnHeight;
@ -807,7 +809,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
setupPage(part?: string | undefined, scrollTop?: number | undefined) {
this.isLoading = false;
this.scrollbarNeeded = this.readingHtml.nativeElement.clientHeight > this.readingSectionElemRef.nativeElement.clientHeight;
this.scrollbarNeeded = this.readingHtml.nativeElement.clientHeight > this.reader.nativeElement.clientHeight;
// Virtual Paging stuff
this.updateWidthAndHeightCalcs();
@ -877,6 +879,10 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
/**
* Given a direction, calls the next or prev page method
* @param direction Direction to move
*/
movePage(direction: PAGING_DIRECTION) {
if (direction === PAGING_DIRECTION.BACKWARDS) {
this.prevPage();
@ -896,7 +902,6 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
const [currentVirtualPage, _, pageWidth] = this.getVirtualPage();
if (currentVirtualPage > 1) {
// -2 apparently goes back 1 virtual page...
this.scrollService.scrollToX((currentVirtualPage - 2) * pageWidth, this.readingHtml.nativeElement);
this.handleScrollEvent();
@ -904,11 +909,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
if (this.readingDirection === ReadingDirection.LeftToRight) {
this.setPageNum(this.pageNum - 1);
} else {
this.setPageNum(this.pageNum + 1);
}
this.setPageNum(this.pageNum - 1);
if (oldPageNum === 0) {
// Move to next volume/chapter automatically
@ -933,7 +934,6 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
const [currentVirtualPage, totalVirtualPages, pageWidth] = this.getVirtualPage();
if (currentVirtualPage < totalVirtualPages) {
//this.scrollService.scrollToX(scrollOffset + pageWidth, this.readingHtml.nativeElement);
// +0 apparently goes forward 1 virtual page...
this.scrollService.scrollToX((currentVirtualPage) * pageWidth, this.readingHtml.nativeElement);
this.handleScrollEvent();
@ -949,11 +949,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
}
if (this.readingDirection === ReadingDirection.LeftToRight) {
this.setPageNum(this.pageNum + 1);
} else {
this.setPageNum(this.pageNum - 1);
}
this.setPageNum(this.pageNum + 1);
if (oldPageNum === this.pageNum) { return; }
@ -982,23 +978,8 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
const scrollOffset = this.readingHtml.nativeElement.scrollLeft;
const totalScroll = this.readingHtml.nativeElement.scrollWidth;
const pageWidth = this.getPageWidth();
// console.log('scrollOffset: ', scrollOffset);
// console.log('totalScroll: ', totalScroll);
// console.log('page width: ', pageWidth);
// console.log('delta: ', totalScroll - scrollOffset)
// // If everything fits on a single page
// if (totalScroll - pageWidth === 0) {
// return [1, 1, pageWidth];
// }
// // totalVirtualPages needs to be -1 because we can't scroll to totalOffset only on page 2
// const currentVirtualPage = Math.max(1, (scrollOffset === 0) ? 1 : Math.round(scrollOffset / pageWidth));
const delta = totalScroll - scrollOffset;
//let totalVirtualPages = Math.max(1, Math.round((totalScroll - pageWidth) / pageWidth));
const totalVirtualPages = Math.max(1, Math.round((totalScroll) / pageWidth));
let currentVirtualPage = 1;
@ -1014,8 +995,6 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
currentVirtualPage = Math.min(Math.max(1, Math.round((scrollOffset + pageWidth) / pageWidth)), totalVirtualPages);
}
console.log('currentPage: ', currentVirtualPage , ' totalPage: ', totalVirtualPages);
return [currentVirtualPage, totalVirtualPages, pageWidth];
}
@ -1205,6 +1184,10 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
this.updateImagesWithHeight();
}
updateReadingDirection(readingDirection: ReadingDirection) {
this.readingDirection = readingDirection;
}
// Table of Contents
cleanIdSelector(id: string) {
const tokens = id.split('/');

View File

@ -38,7 +38,7 @@
ondragstart="return false;" onselectstart="return false;">
</canvas>
</div>
<div class="image-container" [ngClass]="{'d-none': renderWithCanvas, 'center-double': ShouldRenderDoublePage,
<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,

View File

@ -18,15 +18,13 @@ img {
}
.reading-area {
display: flex;
justify-content: center;
position: relative;
overflow: auto;
height: calc(var(--vh)*100);
}
.image-container {
text-align: center;
height: 100vh;
// Original
//display: block;
@ -35,6 +33,22 @@ img {
//display: flex; // Leave this off as it can cutoff the image
align-items: center;
&.full-width {
width: 100vw;
height: calc(var(--vh)*100);
display: grid;
}
&.full-height {
height: 100vh;
display: grid;
}
&.original {
height: 100vh;
display: grid;
}
#image-1 {
&.double {
margin: 0 0 0 auto;
@ -95,17 +109,22 @@ img {
.full-height {
width: auto;
margin: 0 auto;
max-height: 100%;
max-height: calc(var(--vh)*100);
vertical-align: top;
}
.original {
align-self: center;
align-self: center;
width: auto;
margin: 0 auto;
vertical-align: top;
}
.full-width {
max-width: 100%;
align-self: center;
width: 100%;
margin: 0 auto;
vertical-align: top;
max-width: fit-content;
&.double {
width: 50%;

View File

@ -134,7 +134,7 @@
<label id="immersivemode-label" class="form-label"></label>
<div class="mb-3">
<div class="form-check form-switch">
<input type="checkbox" role="switch" id="immersivemode" formControlName="bookReaderImmersivemode" class="form-check-input" [value]="true" aria-labelledby="immersivemode-label">
<input type="checkbox" role="switch" id="immersivemode" formControlName="bookReaderImmersiveMode" class="form-check-input" [value]="true" aria-labelledby="immersivemode-label">
<label id="immersivemode" class="form-check-label">Immersive Mode</label>&nbsp;<i class="fa fa-info-circle" aria-hidden="true" placement="right" [ngbTooltip]="immersivemodeOptionTooltip" role="button" tabindex="0"></i>
<ng-template #immersivemodeOptionTooltip>This will hide the menu behind a click on the reader document and turn tap to paginate on</ng-template>
<span class="visually-hidden" id="settings-immersivemode-option-help">This will hide the menu behind a click on the reader document and turn tap to paginate on</span>