Webtoon Reader Fixes (#2662)

This commit is contained in:
Joe Milazzo 2024-01-28 15:04:59 -06:00 committed by GitHub
parent bfc4f17e05
commit 9ebc63db56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 11 deletions

View File

@ -13,7 +13,7 @@
<strong>Scroll Top:</strong> {{getScrollTop()}} <strong>Scroll Top:</strong> {{getScrollTop()}}
</div> </div>
<div *ngIf="atTop" class="spacer top" role="alert" (click)="loadPrevChapter.emit()"> <div *ngIf="atTop" #topSpacer class="spacer top" role="alert" (click)="loadPrevChapter.emit()">
<div style="height: 200px"></div> <div style="height: 200px"></div>
<div> <div>
<button class="btn btn-icon mx-auto"> <button class="btn btn-icon mx-auto">
@ -27,14 +27,15 @@
</div> </div>
</div> </div>
<ng-container *ngFor="let item of webtoonImages | async; let index = index;"> <div infinite-scroll [infiniteScrollDistance]="1" [infiniteScrollThrottle]="50">
<img src="{{item.src}}" style="display: block" <ng-container *ngFor="let item of webtoonImages | async; let index = index;">
class="mx-auto {{pageNum === item.page && showDebugOutline() ? 'active': ''}} {{areImagesWiderThanWindow ? 'full-width' : ''}} {{initFinished ? '' : 'full-opacity'}}" <img src="{{item.src}}" style="display: block"
*ngIf="item.page >= pageNum - bufferPages && item.page <= pageNum + bufferPages" rel="nofollow" alt="image" class="mx-auto {{pageNum === item.page && showDebugOutline() ? 'active': ''}} {{areImagesWiderThanWindow ? 'full-width' : ''}} {{initFinished ? '' : 'full-opacity'}}"
(load)="onImageLoad($event)" id="page-{{item.page}}" [attr.page]="item.page" ondragstart="return false;" onselectstart="return false;"> rel="nofollow" alt="image" (load)="onImageLoad($event)" id="page-{{item.page}}" [attr.page]="item.page" ondragstart="return false;" onselectstart="return false;">
</ng-container> </ng-container>
</div>
<div *ngIf="atBottom" class="spacer bottom" role="alert" (click)="loadNextChapter.emit()"> <div #bottomSpacer class="spacer bottom" role="alert" (click)="loadNextChapter.emit()">
<div> <div>
<button class="btn btn-icon mx-auto"> <button class="btn btn-icon mx-auto">
<i class="fa fa-angle-double-down animate" aria-hidden="true"></i> <i class="fa fa-angle-double-down animate" aria-hidden="true"></i>

View File

@ -1,5 +1,6 @@
import { DOCUMENT, NgIf, NgFor, AsyncPipe } from '@angular/common'; import { DOCUMENT, NgIf, NgFor, AsyncPipe } from '@angular/common';
import { import {
AfterViewInit,
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, DestroyRef, Component, DestroyRef,
@ -13,7 +14,7 @@ import {
OnInit, OnInit,
Output, Output,
Renderer2, Renderer2,
SimpleChanges SimpleChanges, ViewChild
} 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';
@ -25,6 +26,7 @@ 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 {MangaReaderComponent} from "../manga-reader/manga-reader.component";
import {InfiniteScrollModule} from "ngx-infinite-scroll";
/** /**
* 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
@ -59,9 +61,9 @@ const enum DEBUG_MODES {
styleUrls: ['./infinite-scroller.component.scss'], styleUrls: ['./infinite-scroller.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true, standalone: true,
imports: [NgIf, NgFor, AsyncPipe, TranslocoDirective] imports: [NgIf, NgFor, AsyncPipe, TranslocoDirective, InfiniteScrollModule]
}) })
export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy { export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
private readonly mangaReaderService = inject(ManagaReaderService); private readonly mangaReaderService = inject(ManagaReaderService);
private readonly readerService = inject(ReaderService); private readonly readerService = inject(ReaderService);
@ -92,6 +94,11 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
@Input() goToPage: BehaviorSubject<number> | undefined; @Input() goToPage: BehaviorSubject<number> | undefined;
@Input() bookmarkPage: ReplaySubject<number> = new ReplaySubject<number>(); @Input() bookmarkPage: ReplaySubject<number> = new ReplaySubject<number>();
@Input() fullscreenToggled: ReplaySubject<boolean> = new ReplaySubject<boolean>(); @Input() fullscreenToggled: ReplaySubject<boolean> = new ReplaySubject<boolean>();
@ViewChild('bottomSpacer', {static: false}) bottomSpacer!: ElementRef;
bottomSpacerIntersectionObserver: IntersectionObserver = new IntersectionObserver((entries) => this.handleBottomIntersection(entries),
{ threshold: 1.0 });
private readonly destroyRef = inject(DestroyRef); private readonly destroyRef = inject(DestroyRef);
readerElemRef!: ElementRef<HTMLDivElement>; readerElemRef!: ElementRef<HTMLDivElement>;
@ -258,6 +265,10 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
} }
} }
ngAfterViewInit() {
this.bottomSpacerIntersectionObserver.observe(this.bottomSpacer.nativeElement);
}
recalculateImageWidth() { recalculateImageWidth() {
const [_, innerWidth] = this.getInnerDimensions(); const [_, innerWidth] = this.getInnerDimensions();
this.webtoonImageWidth = innerWidth || document.body.clientWidth || document.documentElement.clientWidth; this.webtoonImageWidth = innerWidth || document.body.clientWidth || document.documentElement.clientWidth;
@ -542,6 +553,13 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
} }
} }
handleBottomIntersection(entries: IntersectionObserverEntry[]) {
if (entries.length > 0 && this.pageNum > this.totalPages - 5 && this.initFinished) {
this.debugLog('[Intersection] The whole bottom spacer is visible', entries[0].isIntersecting);
this.loadNextChapter.emit();
}
}
handleIntersection(entries: IntersectionObserverEntry[]) { handleIntersection(entries: IntersectionObserverEntry[]) {
if (!this.allImagesLoaded || this.isScrolling) { if (!this.allImagesLoaded || this.isScrolling) {
this.debugLog('[Intersection] Images are not loaded (or performing scrolling action), skipping any scroll calculations'); this.debugLog('[Intersection] Images are not loaded (or performing scrolling action), skipping any scroll calculations');