aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/video
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/video')
-rw-r--r--client/src/app/shared/video/abstract-video-list.html2
-rw-r--r--client/src/app/shared/video/abstract-video-list.ts6
-rw-r--r--client/src/app/shared/video/infinite-scroller.directive.ts65
-rw-r--r--client/src/app/shared/video/videos-selection.component.html2
4 files changed, 52 insertions, 23 deletions
diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html
index efd369bca..13aedcc74 100644
--- a/client/src/app/shared/video/abstract-video-list.html
+++ b/client/src/app/shared/video/abstract-video-list.html
@@ -19,7 +19,7 @@
19 19
20 <div class="no-results" i18n *ngIf="pagination.totalItems === 0">No results.</div> 20 <div class="no-results" i18n *ngIf="pagination.totalItems === 0">No results.</div>
21 <div 21 <div
22 myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" 22 myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()"
23 class="videos" 23 class="videos"
24 > 24 >
25 <ng-container *ngFor="let video of videos; trackBy: videoById;"> 25 <ng-container *ngFor="let video of videos; trackBy: videoById;">
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts
index 8a247a9af..2926b179b 100644
--- a/client/src/app/shared/video/abstract-video-list.ts
+++ b/client/src/app/shared/video/abstract-video-list.ts
@@ -1,7 +1,7 @@
1import { debounceTime, first, tap } from 'rxjs/operators' 1import { debounceTime, first, tap } from 'rxjs/operators'
2import { OnDestroy, OnInit } from '@angular/core' 2import { OnDestroy, OnInit } from '@angular/core'
3import { ActivatedRoute, Router } from '@angular/router' 3import { ActivatedRoute, Router } from '@angular/router'
4import { fromEvent, Observable, of, Subscription } from 'rxjs' 4import { fromEvent, Observable, of, Subject, Subscription } from 'rxjs'
5import { AuthService } from '../../core/auth' 5import { AuthService } from '../../core/auth'
6import { ComponentPagination } from '../rest/component-pagination.model' 6import { ComponentPagination } from '../rest/component-pagination.model'
7import { VideoSortField } from './sort-field.type' 7import { VideoSortField } from './sort-field.type'
@@ -59,6 +59,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
59 blacklistInfo: false 59 blacklistInfo: false
60 } 60 }
61 61
62 onDataSubject = new Subject<any[]>()
63
62 protected abstract notifier: Notifier 64 protected abstract notifier: Notifier
63 protected abstract authService: AuthService 65 protected abstract authService: AuthService
64 protected abstract route: ActivatedRoute 66 protected abstract route: ActivatedRoute
@@ -147,6 +149,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableFor
147 if (this.groupByDate) this.buildGroupedDateLabels() 149 if (this.groupByDate) this.buildGroupedDateLabels()
148 150
149 this.onMoreVideos() 151 this.onMoreVideos()
152
153 this.onDataSubject.next(data)
150 }, 154 },
151 155
152 error => this.notifier.error(error.message) 156 error => this.notifier.error(error.message)
diff --git a/client/src/app/shared/video/infinite-scroller.directive.ts b/client/src/app/shared/video/infinite-scroller.directive.ts
index b1e88882c..9f613c5fa 100644
--- a/client/src/app/shared/video/infinite-scroller.directive.ts
+++ b/client/src/app/shared/video/infinite-scroller.directive.ts
@@ -1,14 +1,15 @@
1import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators' 1import { distinctUntilChanged, filter, map, share, startWith, tap, throttleTime } from 'rxjs/operators'
2import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' 2import { AfterContentChecked, Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'
3import { fromEvent, Subscription } from 'rxjs' 3import { fromEvent, Observable, Subscription } from 'rxjs'
4 4
5@Directive({ 5@Directive({
6 selector: '[myInfiniteScroller]' 6 selector: '[myInfiniteScroller]'
7}) 7})
8export class InfiniteScrollerDirective implements OnInit, OnDestroy { 8export class InfiniteScrollerDirective implements OnInit, OnDestroy, AfterContentChecked {
9 @Input() percentLimit = 70 9 @Input() percentLimit = 70
10 @Input() autoInit = false 10 @Input() autoInit = false
11 @Input() onItself = false 11 @Input() onItself = false
12 @Input() dataObservable: Observable<any[]>
12 13
13 @Output() nearOfBottom = new EventEmitter<void>() 14 @Output() nearOfBottom = new EventEmitter<void>()
14 15
@@ -17,10 +18,22 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
17 private scrollDownSub: Subscription 18 private scrollDownSub: Subscription
18 private container: HTMLElement 19 private container: HTMLElement
19 20
21 private checkScroll = false
22
20 constructor (private el: ElementRef) { 23 constructor (private el: ElementRef) {
21 this.decimalLimit = this.percentLimit / 100 24 this.decimalLimit = this.percentLimit / 100
22 } 25 }
23 26
27 ngAfterContentChecked () {
28 if (this.checkScroll) {
29 this.checkScroll = false
30
31 console.log('Checking if the initial state has a scroll.')
32
33 if (this.hasScroll() === false) this.nearOfBottom.emit()
34 }
35 }
36
24 ngOnInit () { 37 ngOnInit () {
25 if (this.autoInit === true) return this.initialize() 38 if (this.autoInit === true) return this.initialize()
26 } 39 }
@@ -30,14 +43,15 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
30 } 43 }
31 44
32 initialize () { 45 initialize () {
33 if (this.onItself) { 46 this.container = this.onItself
34 this.container = this.el.nativeElement 47 ? this.el.nativeElement
35 } 48 : document.documentElement
36 49
37 // Emit the last value 50 // Emit the last value
38 const throttleOptions = { leading: true, trailing: true } 51 const throttleOptions = { leading: true, trailing: true }
39 52
40 const scrollObservable = fromEvent(this.container || window, 'scroll') 53 const scrollableElement = this.onItself ? this.container : window
54 const scrollObservable = fromEvent(scrollableElement, 'scroll')
41 .pipe( 55 .pipe(
42 startWith(null as string), // FIXME: typings 56 startWith(null as string), // FIXME: typings
43 throttleTime(200, undefined, throttleOptions), 57 throttleTime(200, undefined, throttleOptions),
@@ -49,23 +63,34 @@ export class InfiniteScrollerDirective implements OnInit, OnDestroy {
49 // Scroll Down 63 // Scroll Down
50 this.scrollDownSub = scrollObservable 64 this.scrollDownSub = scrollObservable
51 .pipe( 65 .pipe(
52 // Check we scroll down 66 filter(({ current }) => this.isScrollingDown(current)),
53 filter(({ current }) => { 67 filter(({ current, maximumScroll }) => (current / maximumScroll) > this.decimalLimit)
54 const res = this.lastCurrentBottom < current
55
56 this.lastCurrentBottom = current
57 return res
58 }),
59 filter(({ current, maximumScroll }) => maximumScroll <= 0 || (current / maximumScroll) > this.decimalLimit)
60 ) 68 )
61 .subscribe(() => this.nearOfBottom.emit()) 69 .subscribe(() => this.nearOfBottom.emit())
70
71 if (this.dataObservable) {
72 this.dataObservable
73 .pipe(filter(d => d.length !== 0))
74 .subscribe(() => this.checkScroll = true)
75 }
62 } 76 }
63 77
64 private getScrollInfo () { 78 private getScrollInfo () {
65 if (this.container) { 79 return { current: this.container.scrollTop, maximumScroll: this.getMaximumScroll() }
66 return { current: this.container.scrollTop, maximumScroll: this.container.scrollHeight } 80 }
67 } 81
82 private getMaximumScroll () {
83 return this.container.scrollHeight - window.innerHeight
84 }
85
86 private hasScroll () {
87 return this.getMaximumScroll() > 0
88 }
89
90 private isScrollingDown (current: number) {
91 const result = this.lastCurrentBottom < current
68 92
69 return { current: window.scrollY, maximumScroll: document.body.clientHeight - window.innerHeight } 93 this.lastCurrentBottom = current
94 return result
70 } 95 }
71} 96}
diff --git a/client/src/app/shared/video/videos-selection.component.html b/client/src/app/shared/video/videos-selection.component.html
index 120c168cd..2b4b353cf 100644
--- a/client/src/app/shared/video/videos-selection.component.html
+++ b/client/src/app/shared/video/videos-selection.component.html
@@ -1,6 +1,6 @@
1<div class="no-results" i18n *ngIf="pagination.totalItems === 0">No results.</div> 1<div class="no-results" i18n *ngIf="pagination.totalItems === 0">No results.</div>
2 2
3<div myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" class="videos"> 3<div myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()" class="videos">
4 <div class="video" *ngFor="let video of videos; let i = index; trackBy: videoById"> 4 <div class="video" *ngFor="let video of videos; let i = index; trackBy: videoById">
5 5
6 <div class="checkbox-container"> 6 <div class="checkbox-container">