Shakeout testing Fixes (#952)
* Cleaned up some old code in download bookmark that could create pointless temp folders. * Fixed a bad http call on reading list remove read and cleaned up the messaging * Undid an optimization in finding cover image due to it perfoming depth first rather than breadth. * Updated CleanComicInfo to have Translators and CoverArtists, which were previously missing. * Renamed Refresh Metadata to Refresh Covers on the UI, given Metadata refresh is done in Scan. * Library detail will now retain the search query in the UI. Reduced the amount of api calls to the backend on load. * Reverted allowing the filter to reside in the UI (even though it does work). * Updated the Age Rating to match the v2.1 spec. * Fixed a bug where progress wasn't being saved * Fixed line height not having any effect due to not applying to children elements in the reader * Fixed some wording for Refresh Covers confirmation * Delete Series will now send an event to the UI informing that series was deleted. * Change Progress widget to show Refreshing Covers for * When we exit early due to potential missing folders/drives in a scan, tell the UI that scan is 100% done. * Fixed manage library not supressing scan loader when a complete came in * Fixed a spelling difference for Publication Status between filter and series detail * Fixed a bug where collection detail page would flash on first load due to duplicate load events * Added bookmarks to backups * Fixed issues where fullscreen mode would break infinite scroller contiunous reader
This commit is contained in:
parent
b4229f5442
commit
680240af8d
23 changed files with 251 additions and 89 deletions
|
@ -1,6 +1,6 @@
|
|||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { BehaviorSubject, fromEvent, ReplaySubject, Subject } from 'rxjs';
|
||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
import { Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { BehaviorSubject, fromEvent, merge, ReplaySubject, Subject } from 'rxjs';
|
||||
import { debounceTime, take, takeUntil } from 'rxjs/operators';
|
||||
import { ReaderService } from '../../_services/reader.service';
|
||||
import { PAGING_DIRECTION } from '../_models/reader-enums';
|
||||
import { WebtoonImage } from '../_models/webtoon-image';
|
||||
|
@ -64,7 +64,9 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
@Input() goToPage: ReplaySubject<number> = new ReplaySubject<number>();
|
||||
@Input() bookmarkPage: ReplaySubject<number> = new ReplaySubject<number>();
|
||||
@Input() fullscreenToggled: ReplaySubject<boolean> = new ReplaySubject<boolean>();
|
||||
|
||||
|
||||
readerElemRef!: ElementRef<HTMLDivElement>;
|
||||
|
||||
/**
|
||||
* Stores and emits all the src urls
|
||||
*/
|
||||
|
@ -111,6 +113,10 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
* If the user has scrolled all the way to the top. This is used solely for continuous reading
|
||||
*/
|
||||
atTop: boolean = false;
|
||||
/**
|
||||
* If the manga reader is in fullscreen. Some math changes based on this value.
|
||||
*/
|
||||
isFullscreenMode: boolean = false;
|
||||
/**
|
||||
* Keeps track of the previous scrolling height for restoring scroll position after we inject spacer block
|
||||
*/
|
||||
|
@ -129,7 +135,8 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
}
|
||||
|
||||
get areImagesWiderThanWindow() {
|
||||
return this.webtoonImageWidth > (window.innerWidth || document.documentElement.clientWidth);
|
||||
let [innerWidth, _] = this.getInnerDimensions();
|
||||
return this.webtoonImageWidth > (innerWidth || document.documentElement.clientWidth);
|
||||
}
|
||||
|
||||
|
||||
|
@ -137,7 +144,13 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
private readonly onDestroy = new Subject<void>();
|
||||
|
||||
constructor(private readerService: ReaderService, private renderer: Renderer2) {}
|
||||
constructor(private readerService: ReaderService, private renderer: Renderer2) {
|
||||
// This will always exist at this point in time since this is used within manga reader
|
||||
const reader = document.querySelector('.reader');
|
||||
if (reader !== null) {
|
||||
this.readerElemRef = new ElementRef(reader as HTMLDivElement);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.hasOwnProperty('totalPages') && changes['totalPages'].previousValue != changes['totalPages'].currentValue) {
|
||||
|
@ -152,12 +165,21 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.onDestroy.complete();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
const reader = document.querySelector('.reader') || window;
|
||||
fromEvent(reader, 'scroll')
|
||||
.pipe(debounceTime(20), takeUntil(this.onDestroy))
|
||||
/**
|
||||
* Responsible for binding the scroll handler to the correct event. On non-fullscreen, window is correct. However, on fullscreen, we must use the reader as that is what
|
||||
* gets promoted to fullscreen.
|
||||
*/
|
||||
initScrollHandler() {
|
||||
fromEvent(this.isFullscreenMode ? this.readerElemRef.nativeElement : window, 'scroll')
|
||||
.pipe(debounceTime(20), takeUntil(this.onDestroy))
|
||||
.subscribe((event) => this.handleScrollEvent(event));
|
||||
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.initScrollHandler();
|
||||
|
||||
if (this.goToPage) {
|
||||
this.goToPage.pipe(takeUntil(this.onDestroy)).subscribe(page => {
|
||||
this.debugLog('[GoToPage] jump has occured from ' + this.pageNum + ' to ' + page);
|
||||
|
@ -189,20 +211,39 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
if (this.fullscreenToggled) {
|
||||
this.fullscreenToggled.pipe(takeUntil(this.onDestroy)).subscribe(isFullscreen => {
|
||||
this.debugLog('[FullScreen] Fullscreen mode: ', isFullscreen);
|
||||
this.isFullscreenMode = isFullscreen;
|
||||
const [innerWidth, _] = this.getInnerDimensions();
|
||||
this.webtoonImageWidth = innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
this.initScrollHandler();
|
||||
this.setPageNum(this.pageNum, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getVerticalOffset() {
|
||||
const reader = this.isFullscreenMode ? this.readerElemRef.nativeElement : window;
|
||||
|
||||
let offset = 0;
|
||||
if (reader instanceof Window) {
|
||||
offset = reader.scrollY;
|
||||
} else {
|
||||
offset = reader.scrollTop;
|
||||
}
|
||||
|
||||
return (offset
|
||||
|| document.documentElement.scrollTop
|
||||
|| document.body.scrollTop || 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* On scroll in document, calculate if the user/javascript has scrolled to the current image element (and it's visible), update that scrolling has ended completely,
|
||||
* and calculate the direction the scrolling is occuring. This is not used for prefetching.
|
||||
* @param event Scroll Event
|
||||
*/
|
||||
handleScrollEvent(event?: any) {
|
||||
const verticalOffset = (window.pageYOffset
|
||||
|| document.documentElement.scrollTop
|
||||
|| document.body.scrollTop || 0);
|
||||
// Need a fullscreen handler here too
|
||||
let verticalOffset = this.getVerticalOffset();
|
||||
|
||||
|
||||
if (verticalOffset > this.prevScrollPosition) {
|
||||
this.scrollingDirection = PAGING_DIRECTION.FORWARD;
|
||||
|
@ -211,6 +252,10 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
}
|
||||
this.prevScrollPosition = verticalOffset;
|
||||
|
||||
console.log('CurrentPageElem: ', this.currentPageElem);
|
||||
if (this.currentPageElem != null) {
|
||||
console.log('Element Visible: ', this.isElementVisible(this.currentPageElem));
|
||||
}
|
||||
if (this.isScrolling && this.currentPageElem != null && this.isElementVisible(this.currentPageElem)) {
|
||||
this.debugLog('[Scroll] Image is visible from scroll, isScrolling is now false');
|
||||
this.isScrolling = false;
|
||||
|
@ -239,9 +284,15 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
return totalHeight;
|
||||
}
|
||||
getTotalScroll() {
|
||||
if (this.isFullscreenMode) {
|
||||
return this.readerElemRef.nativeElement.offsetHeight + this.readerElemRef.nativeElement.scrollTop;
|
||||
}
|
||||
return document.documentElement.offsetHeight + document.documentElement.scrollTop;
|
||||
}
|
||||
getScrollTop() {
|
||||
if (this.isFullscreenMode) {
|
||||
return this.readerElemRef.nativeElement.scrollTop;
|
||||
}
|
||||
return document.documentElement.scrollTop;
|
||||
}
|
||||
|
||||
|
@ -276,7 +327,7 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.atTop = true;
|
||||
// Scroll user back to original location
|
||||
this.previousScrollHeightMinusTop = document.documentElement.scrollHeight - document.documentElement.scrollTop;
|
||||
requestAnimationFrame(() => window.scrollTo(0, SPACER_SCROLL_INTO_PX));
|
||||
requestAnimationFrame(() => window.scrollTo(0, SPACER_SCROLL_INTO_PX)); // TODO: does this need to be fullscreen protected?
|
||||
} else if (this.getScrollTop() < 5 && this.pageNum === 0 && this.atTop) {
|
||||
// If already at top, then we moving on
|
||||
this.loadPrevChapter.emit();
|
||||
|
@ -285,6 +336,17 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
}
|
||||
|
||||
getInnerDimensions() {
|
||||
let innerHeight = window.innerHeight;
|
||||
let innerWidth = window.innerWidth;
|
||||
|
||||
if (this.isFullscreenMode) {
|
||||
innerHeight = this.readerElemRef.nativeElement.clientHeight;
|
||||
innerWidth = this.readerElemRef.nativeElement.clientWidth;
|
||||
}
|
||||
return [innerHeight, innerWidth];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is any part of the element visible in the scrollport. Does not take into account
|
||||
* style properites, just scroll port visibility.
|
||||
|
@ -297,10 +359,16 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
// NOTE: This will say an element is visible if it is 1 px offscreen on top
|
||||
var rect = elem.getBoundingClientRect();
|
||||
|
||||
let [innerHeight, innerWidth] = this.getInnerDimensions();
|
||||
|
||||
|
||||
console.log('innerHeight: ', innerHeight);
|
||||
console.log('innerWidth: ', innerWidth);
|
||||
|
||||
return (rect.bottom >= 0 &&
|
||||
rect.right >= 0 &&
|
||||
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
|
||||
rect.top <= (innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.left <= (innerWidth || document.documentElement.clientWidth)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -315,12 +383,15 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
var rect = elem.getBoundingClientRect();
|
||||
|
||||
let [innerHeight, innerWidth] = this.getInnerDimensions();
|
||||
|
||||
|
||||
if (rect.bottom >= 0 &&
|
||||
rect.right >= 0 &&
|
||||
rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
|
||||
rect.top <= (innerHeight || document.documentElement.clientHeight) &&
|
||||
rect.left <= (innerWidth || document.documentElement.clientWidth)
|
||||
) {
|
||||
const topX = (window.innerHeight || document.documentElement.clientHeight);
|
||||
const topX = (innerHeight || document.documentElement.clientHeight);
|
||||
return Math.abs(rect.top / topX) <= 0.25;
|
||||
}
|
||||
return false;
|
||||
|
@ -328,6 +399,8 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
|
||||
initWebtoonReader() {
|
||||
const [innerWidth, _] = this.getInnerDimensions();
|
||||
this.webtoonImageWidth = innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||
this.imagesLoaded = {};
|
||||
this.webtoonImages.next([]);
|
||||
this.atBottom = false;
|
||||
|
@ -424,7 +497,6 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||
* Performs the scroll for the current page element. Updates any state variables needed.
|
||||
*/
|
||||
scrollToCurrentPage() {
|
||||
this.debugLog('Scrolling to ', this.pageNum);
|
||||
this.currentPageElem = document.querySelector('img#page-' + this.pageNum);
|
||||
if (!this.currentPageElem) { return; }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue