mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-06-23 15:30:34 -04:00
Webtoon Reader Fixes (#2662)
This commit is contained in:
parent
bfc4f17e05
commit
9ebc63db56
@ -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>
|
||||||
|
@ -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');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user