From a8ecc6f6709bdb54c47c7dd7cd18ef371254c3af Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 17 Sep 2018 17:36:46 +0200 Subject: Try to improve infinite pagination --- .../src/app/shared/video/abstract-video-list.html | 2 +- client/src/app/shared/video/abstract-video-list.ts | 29 +++++++++++++++++++--- .../shared/video/infinite-scroller.directive.ts | 13 +++++++--- 3 files changed, 37 insertions(+), 7 deletions(-) (limited to 'client') diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html index 0f48b9a64..4ad4e3568 100644 --- a/client/src/app/shared/video/abstract-video-list.html +++ b/client/src/app/shared/video/abstract-video-list.html @@ -7,7 +7,7 @@
No results.
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index b8fd7f8eb..9df4cfc22 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts @@ -38,7 +38,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { ownerDisplayType: OwnerDisplayType = 'account' protected baseVideoWidth = 215 - protected baseVideoHeight = 230 + protected baseVideoHeight = 205 protected abstract notificationsService: NotificationsService protected abstract authService: AuthService @@ -55,6 +55,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { protected otherRouteParams = {} private resizeSubscription: Subscription + private firstLoadedPage: number abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number}> abstract generateSyndicationList () @@ -100,7 +101,11 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { this.loadMoreVideos(this.pagination.currentPage) } - loadMoreVideos (page: number) { + loadMoreVideos (page: number, loadOnTop = false) { + this.adjustVideoPageHeight() + + const currentY = window.scrollY + if (this.loadedPages[page] !== undefined) return if (this.loadingPage[page] === true) return @@ -111,6 +116,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { ({ videos, totalVideos }) => { this.loadingPage[page] = false + if (this.firstLoadedPage === undefined || this.firstLoadedPage > page) this.firstLoadedPage = page + // Paging is too high, return to the first one if (this.pagination.currentPage > 1 && totalVideos <= ((this.pagination.currentPage - 1) * this.pagination.itemsPerPage)) { this.pagination.currentPage = 1 @@ -125,8 +132,17 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { // Initialize infinite scroller now we loaded the first page if (Object.keys(this.loadedPages).length === 1) { // Wait elements creation - setTimeout(() => this.infiniteScroller.initialize(), 500) + setTimeout(() => { + this.infiniteScroller.initialize() + + // At our first load, we did not load the first page + // Load the previous page so the user can move on the top (and browser previous pages) + if (this.pagination.currentPage > 1) this.loadMoreVideos(this.pagination.currentPage - 1, true) + }, 500) } + + // Insert elements on the top but keep the scroll in the previous position + if (loadOnTop) setTimeout(() => { window.scrollTo(0, currentY + this.pageHeight) }, 0) }, error => { this.loadingPage[page] = false @@ -189,6 +205,13 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy { this.videoPages = Object.values(this.loadedPages) } + protected adjustVideoPageHeight () { + const numberOfPagesLoaded = Object.keys(this.loadedPages).length + if (!numberOfPagesLoaded) return + + this.pageHeight = this.videosElement.nativeElement.offsetHeight / numberOfPagesLoaded + } + protected buildVideoHeight () { // Same ratios than base width/height return this.videosElement.nativeElement.offsetWidth * (this.baseVideoHeight / this.baseVideoWidth) diff --git a/client/src/app/shared/video/infinite-scroller.directive.ts b/client/src/app/shared/video/infinite-scroller.directive.ts index 4dc1f86e7..a02e9444a 100644 --- a/client/src/app/shared/video/infinite-scroller.directive.ts +++ b/client/src/app/shared/video/infinite-scroller.directive.ts @@ -6,10 +6,9 @@ import { fromEvent, Subscription } from 'rxjs' selector: '[myInfiniteScroller]' }) export class InfiniteScrollerDirective implements OnInit, OnDestroy { - private static PAGE_VIEW_TOP_MARGIN = 500 - @Input() containerHeight: number @Input() pageHeight: number + @Input() firstLoadedPage = 1 @Input() percentLimit = 70 @Input() autoInit = false @@ -23,6 +22,7 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy { private scrollDownSub: Subscription private scrollUpSub: Subscription private pageChangeSub: Subscription + private middleScreen: number constructor () { this.decimalLimit = this.percentLimit / 100 @@ -39,6 +39,8 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy { } initialize () { + this.middleScreen = window.innerHeight / 2 + // Emit the last value const throttleOptions = { leading: true, trailing: true } @@ -92,6 +94,11 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy { } private calculateCurrentPage (current: number) { - return Math.max(1, Math.round((current + InfiniteScrollerDirective.PAGE_VIEW_TOP_MARGIN) / this.pageHeight)) + const scrollY = current + this.middleScreen + + const page = Math.max(1, Math.ceil(scrollY / this.pageHeight)) + + // Offset page + return page + (this.firstLoadedPage - 1) } } -- cgit v1.2.3