Only attach scroll end handler on desktop, which is where it's most needed as users scroll without stopping.

Added both touch and click events so when a page is touched, it will set the current page.
This commit is contained in:
Joseph Milazzo 2023-12-09 17:10:34 -06:00
parent ad7d7f82e6
commit 851acb74e0
2 changed files with 24 additions and 21 deletions

View file

@ -31,7 +31,7 @@
<img src="{{item.src}}" style="display: block" <img src="{{item.src}}" style="display: block"
class="mx-auto {{pageNum === item.page && showDebugOutline() ? 'active': ''}} {{areImagesWiderThanWindow ? 'full-width' : ''}} {{initFinished ? '' : 'full-opacity'}}" class="mx-auto {{pageNum === item.page && showDebugOutline() ? 'active': ''}} {{areImagesWiderThanWindow ? 'full-width' : ''}} {{initFinished ? '' : 'full-opacity'}}"
*ngIf="item.page >= pageNum - bufferPages && item.page <= pageNum + bufferPages" rel="nofollow" alt="image" *ngIf="item.page >= pageNum - bufferPages && item.page <= pageNum + bufferPages" rel="nofollow" alt="image"
(load)="onImageLoad($event)" (touchstart)="onTouchStart($event)" id="page-{{item.page}}" [attr.page]="item.page" ondragstart="return false;" onselectstart="return false;"> (load)="onImageLoad($event)" (touchstart)="onTouchStart(item.page)" (click)="onTouchStart(item.page)" id="page-{{item.page}}" [attr.page]="item.page" ondragstart="return false;" onselectstart="return false;">
</ng-container> </ng-container>
<div *ngIf="atBottom" class="spacer bottom" role="alert" (click)="loadNextChapter.emit()"> <div *ngIf="atBottom" class="spacer bottom" role="alert" (click)="loadNextChapter.emit()">

View file

@ -1,8 +1,9 @@
import { DOCUMENT, NgIf, NgFor, AsyncPipe } from '@angular/common'; import {AsyncPipe, DOCUMENT, NgFor, NgIf} from '@angular/common';
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, DestroyRef, Component,
DestroyRef,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
inject, inject,
@ -15,16 +16,16 @@ import {
Renderer2, Renderer2,
SimpleChanges SimpleChanges
} from '@angular/core'; } from '@angular/core';
import { BehaviorSubject, fromEvent, ReplaySubject } from 'rxjs'; import {BehaviorSubject, fromEvent, ReplaySubject} from 'rxjs';
import { debounceTime } from 'rxjs/operators'; import {debounceTime} from 'rxjs/operators';
import { ScrollService } from 'src/app/_services/scroll.service'; import {ScrollService} from 'src/app/_services/scroll.service';
import { ReaderService } from '../../../_services/reader.service'; import {ReaderService} from '../../../_services/reader.service';
import { PAGING_DIRECTION } from '../../_models/reader-enums'; import {PAGING_DIRECTION} from '../../_models/reader-enums';
import { WebtoonImage } from '../../_models/webtoon-image'; import {WebtoonImage} from '../../_models/webtoon-image';
import { ManagaReaderService } from '../../_service/managa-reader.service'; import {ManagaReaderService} from '../../_service/managa-reader.service';
import {takeUntilDestroyed} from "@angular/core/rxjs-interop"; import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {TranslocoDirective} from "@ngneat/transloco"; import {TranslocoDirective} from "@ngneat/transloco";
import {MangaReaderComponent} from "../manga-reader/manga-reader.component"; import {Breakpoint, UtilityService} from "../../../shared/_services/utility.service";
/** /**
* How much additional space should pass, past the original bottom of the document height before we trigger the next chapter load * How much additional space should pass, past the original bottom of the document height before we trigger the next chapter load
@ -64,6 +65,7 @@ const enum DEBUG_MODES {
export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy { export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
private readonly mangaReaderService = inject(ManagaReaderService); private readonly mangaReaderService = inject(ManagaReaderService);
private readonly utilityService = inject(UtilityService);
private readonly readerService = inject(ReaderService); private readonly readerService = inject(ReaderService);
private readonly renderer = inject(Renderer2); private readonly renderer = inject(Renderer2);
private readonly scrollService = inject(ScrollService); private readonly scrollService = inject(ScrollService);
@ -210,9 +212,12 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
.pipe(debounceTime(20), takeUntilDestroyed(this.destroyRef)) .pipe(debounceTime(20), takeUntilDestroyed(this.destroyRef))
.subscribe((event) => this.handleScrollEvent(event)); .subscribe((event) => this.handleScrollEvent(event));
fromEvent(this.isFullscreenMode ? this.readerElemRef.nativeElement : this.document.body, 'scrollend') // Only attach this on non-mobile
.pipe(debounceTime(20), takeUntilDestroyed(this.destroyRef)) if (this.utilityService.getActiveBreakpoint() > Breakpoint.Tablet) {
.subscribe((event) => this.handleScrollEndEvent(event)); fromEvent(this.isFullscreenMode ? this.readerElemRef.nativeElement : this.document.body, 'scrollend')
.pipe(debounceTime(20), takeUntilDestroyed(this.destroyRef))
.subscribe((event) => this.handleScrollEndEvent(event));
}
} }
ngOnInit(): void { ngOnInit(): void {
@ -327,7 +332,6 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
handleScrollEndEvent(event?: any) { handleScrollEndEvent(event?: any) {
if (this.isScrolling) { return; } if (this.isScrolling) { return; }
return;
const closestImages = Array.from(document.querySelectorAll('img[id^="page-"]')) as HTMLImageElement[]; const closestImages = Array.from(document.querySelectorAll('img[id^="page-"]')) as HTMLImageElement[];
const img = this.findClosestVisibleImage(closestImages); const img = this.findClosestVisibleImage(closestImages);
@ -533,13 +537,12 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
} }
/** /**
* When the user touches an image, let's set it as the active page. This ensures their touch always sets the active page * When the user touches/clicks an image, let's set it as the active page. This ensures their touch always sets the active page
* @param event * @param pageNum - Page of the image
*/ */
onTouchStart(event: TouchEvent) { onTouchStart(pageNum: number) {
const newPage = parseInt((event.target as HTMLImageElement).getAttribute('page') || this.pageNum + '', 10); this.debugLog('touch start: ', pageNum);
this.debugLog('touch start: ', newPage); this.setPageNum(pageNum);
this.setPageNum(newPage);
} }
/** /**