aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-08-02 14:49:25 +0200
committerChocobozzz <me@florianbigard.com>2019-08-02 14:49:25 +0200
commitad453580b20056fd80b3245d4db554f5ca1a5e29 (patch)
treeed07a6dbd8bc8cd27b22cd33dabcbd3d31deea07 /client/src/app
parentdd570a34ff731a6cd98ef8f8bf83f234e804f6c1 (diff)
downloadPeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.tar.gz
PeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.tar.zst
PeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.zip
Fix infinite scroll on big screens
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+about/about-follows/about-follows.component.html2
-rw-r--r--client/src/app/+about/about-follows/about-follows.component.ts11
-rw-r--r--client/src/app/+accounts/account-video-channels/account-video-channels.component.html2
-rw-r--r--client/src/app/+accounts/account-video-channels/account-video-channels.component.ts6
-rw-r--r--client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html2
-rw-r--r--client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts5
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.html2
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts4
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.html2
-rw-r--r--client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html2
-rw-r--r--client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts5
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html2
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss2
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts8
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html2
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts11
-rw-r--r--client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html2
-rw-r--r--client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts8
-rw-r--r--client/src/app/shared/users/user-notifications.component.html2
-rw-r--r--client/src/app/shared/users/user-notifications.component.ts5
-rw-r--r--client/src/app/shared/video-playlist/video-add-to-playlist.component.ts2
-rw-r--r--client/src/app/shared/video-playlist/video-playlist.service.ts15
-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
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comments.component.html1
-rw-r--r--client/src/app/videos/+video-watch/comment/video-comments.component.ts6
28 files changed, 135 insertions, 49 deletions
diff --git a/client/src/app/+about/about-follows/about-follows.component.html b/client/src/app/+about/about-follows/about-follows.component.html
index 18689bbf7..5d7a50c74 100644
--- a/client/src/app/+about/about-follows/about-follows.component.html
+++ b/client/src/app/+about/about-follows/about-follows.component.html
@@ -1,4 +1,4 @@
1<div class="row" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"> 1<div class="row" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
2 <div class="col-xl-6 col-md-12"> 2 <div class="col-xl-6 col-md-12">
3 <div i18n class="subtitle">Followers</div> 3 <div i18n class="subtitle">Followers</div>
4 4
diff --git a/client/src/app/+about/about-follows/about-follows.component.ts b/client/src/app/+about/about-follows/about-follows.component.ts
index f0e1375d6..d60307928 100644
--- a/client/src/app/+about/about-follows/about-follows.component.ts
+++ b/client/src/app/+about/about-follows/about-follows.component.ts
@@ -4,6 +4,7 @@ import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pa
4import { Notifier } from '@app/core' 4import { Notifier } from '@app/core'
5import { RestService } from '@app/shared' 5import { RestService } from '@app/shared'
6import { SortMeta } from 'primeng/api' 6import { SortMeta } from 'primeng/api'
7import { Subject } from 'rxjs'
7 8
8@Component({ 9@Component({
9 selector: 'my-about-follows', 10 selector: 'my-about-follows',
@@ -17,13 +18,13 @@ export class AboutFollowsComponent implements OnInit {
17 18
18 followersPagination: ComponentPagination = { 19 followersPagination: ComponentPagination = {
19 currentPage: 1, 20 currentPage: 1,
20 itemsPerPage: 40, 21 itemsPerPage: 20,
21 totalItems: null 22 totalItems: null
22 } 23 }
23 24
24 followingsPagination: ComponentPagination = { 25 followingsPagination: ComponentPagination = {
25 currentPage: 1, 26 currentPage: 1,
26 itemsPerPage: 40, 27 itemsPerPage: 20,
27 totalItems: null 28 totalItems: null
28 } 29 }
29 30
@@ -32,6 +33,8 @@ export class AboutFollowsComponent implements OnInit {
32 order: -1 33 order: -1
33 } 34 }
34 35
36 onDataSubject = new Subject<any[]>()
37
35 constructor ( 38 constructor (
36 private restService: RestService, 39 private restService: RestService,
37 private notifier: Notifier, 40 private notifier: Notifier,
@@ -78,6 +81,8 @@ export class AboutFollowsComponent implements OnInit {
78 this.followers = this.followers.concat(newFollowers) 81 this.followers = this.followers.concat(newFollowers)
79 82
80 this.followersPagination.totalItems = resultList.total 83 this.followersPagination.totalItems = resultList.total
84
85 this.onDataSubject.next(newFollowers)
81 }, 86 },
82 87
83 err => this.notifier.error(err.message) 88 err => this.notifier.error(err.message)
@@ -94,6 +99,8 @@ export class AboutFollowsComponent implements OnInit {
94 this.followings = this.followings.concat(newFollowings) 99 this.followings = this.followings.concat(newFollowings)
95 100
96 this.followingsPagination.totalItems = resultList.total 101 this.followingsPagination.totalItems = resultList.total
102
103 this.onDataSubject.next(newFollowings)
97 }, 104 },
98 105
99 err => this.notifier.error(err.message) 106 err => this.notifier.error(err.message)
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html
index ea5f61b18..4ebad514c 100644
--- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.html
+++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.html
@@ -2,7 +2,7 @@
2 2
3 <div class="no-results" i18n *ngIf="channelPagination.totalItems === 0">This account does not have channels.</div> 3 <div class="no-results" i18n *ngIf="channelPagination.totalItems === 0">This account does not have channels.</div>
4 4
5 <div class="channels" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true"> 5 <div class="channels" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onChannelDataSubject.asObservable()">
6 <div class="section channel" *ngFor="let videoChannel of videoChannels"> 6 <div class="section channel" *ngFor="let videoChannel of videoChannels">
7 <div class="section-title"> 7 <div class="section-title">
8 <a [routerLink]="getVideoChannelLink(videoChannel)" i18n-title title="See this video channel"> 8 <a [routerLink]="getVideoChannelLink(videoChannel)" i18n-title title="See this video channel">
diff --git a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
index 7144f4b5f..85dedd7de 100644
--- a/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
+++ b/client/src/app/+accounts/account-video-channels/account-video-channels.component.ts
@@ -4,7 +4,7 @@ import { Account } from '@app/shared/account/account.model'
4import { AccountService } from '@app/shared/account/account.service' 4import { AccountService } from '@app/shared/account/account.service'
5import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 5import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
6import { concatMap, map, switchMap, tap } from 'rxjs/operators' 6import { concatMap, map, switchMap, tap } from 'rxjs/operators'
7import { from, Subscription } from 'rxjs' 7import { from, Subject, Subscription } from 'rxjs'
8import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 8import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
9import { Video } from '@app/shared/video/video.model' 9import { Video } from '@app/shared/video/video.model'
10import { AuthService } from '@app/core' 10import { AuthService } from '@app/core'
@@ -33,6 +33,8 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy {
33 } 33 }
34 videosSort: VideoSortField = '-publishedAt' 34 videosSort: VideoSortField = '-publishedAt'
35 35
36 onChannelDataSubject = new Subject<any>()
37
36 private accountSub: Subscription 38 private accountSub: Subscription
37 39
38 constructor ( 40 constructor (
@@ -75,6 +77,8 @@ export class AccountVideoChannelsComponent implements OnInit, OnDestroy {
75 this.videoChannels.push(videoChannel) 77 this.videoChannels.push(videoChannel)
76 78
77 this.videos[videoChannel.id] = videos 79 this.videos[videoChannel.id] = videos
80
81 this.onChannelDataSubject.next([ videoChannel ])
78 }) 82 })
79 } 83 }
80 84
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
index 6d2155332..4526aaf66 100644
--- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
+++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.html
@@ -6,7 +6,7 @@
6 {{ getNoResultMessage() }} 6 {{ getNoResultMessage() }}
7</div> 7</div>
8 8
9<div class="plugins" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true"> 9<div class="plugins" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()">
10 <div class="card plugin" *ngFor="let plugin of plugins"> 10 <div class="card plugin" *ngFor="let plugin of plugins">
11 <div class="card-body"> 11 <div class="card-body">
12 <div class="first-row"> 12 <div class="first-row">
diff --git a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts
index dced14dee..b30b136bd 100644
--- a/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts
+++ b/client/src/app/+admin/plugins/plugin-list-installed/plugin-list-installed.component.ts
@@ -8,6 +8,7 @@ import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model'
8import { ActivatedRoute, Router } from '@angular/router' 8import { ActivatedRoute, Router } from '@angular/router'
9import { compareSemVer } from '@shared/core-utils/miscs/miscs' 9import { compareSemVer } from '@shared/core-utils/miscs/miscs'
10import { PluginService } from '@app/core/plugins/plugin.service' 10import { PluginService } from '@app/core/plugins/plugin.service'
11import { Subject } from 'rxjs'
11 12
12@Component({ 13@Component({
13 selector: 'my-plugin-list-installed', 14 selector: 'my-plugin-list-installed',
@@ -33,6 +34,8 @@ export class PluginListInstalledComponent implements OnInit {
33 34
34 PluginType = PluginType 35 PluginType = PluginType
35 36
37 onDataSubject = new Subject<any[]>()
38
36 constructor ( 39 constructor (
37 private i18n: I18n, 40 private i18n: I18n,
38 private pluginService: PluginService, 41 private pluginService: PluginService,
@@ -67,6 +70,8 @@ export class PluginListInstalledComponent implements OnInit {
67 res => { 70 res => {
68 this.plugins = this.plugins.concat(res.data) 71 this.plugins = this.plugins.concat(res.data)
69 this.pagination.totalItems = res.total 72 this.pagination.totalItems = res.total
73
74 this.onDataSubject.next(res.data)
70 }, 75 },
71 76
72 err => this.notifier.error(err.message) 77 err => this.notifier.error(err.message)
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
index 87f1c86ee..6ec6301b1 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.html
@@ -29,7 +29,7 @@
29 No results. 29 No results.
30</div> 30</div>
31 31
32<div class="plugins" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true"> 32<div class="plugins" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()">
33 <div class="card plugin" *ngFor="let plugin of plugins"> 33 <div class="card plugin" *ngFor="let plugin of plugins">
34 <div class="card-body"> 34 <div class="card-body">
35 <div class="first-row"> 35 <div class="first-row">
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
index a6fbeed84..65566ab79 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
@@ -36,6 +36,8 @@ export class PluginSearchComponent implements OnInit {
36 installing: { [name: string]: boolean } = {} 36 installing: { [name: string]: boolean } = {}
37 pluginInstalled = false 37 pluginInstalled = false
38 38
39 onDataSubject = new Subject<any[]>()
40
39 private searchSubject = new Subject<string>() 41 private searchSubject = new Subject<string>()
40 42
41 constructor ( 43 constructor (
@@ -90,6 +92,8 @@ export class PluginSearchComponent implements OnInit {
90 92
91 this.plugins = this.plugins.concat(res.data) 93 this.plugins = this.plugins.concat(res.data)
92 this.pagination.totalItems = res.total 94 this.pagination.totalItems = res.total
95
96 this.onDataSubject.next(res.data)
93 }, 97 },
94 98
95 err => { 99 err => {
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html
index 6e274f689..7258fcc1f 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.html
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html
@@ -13,7 +13,7 @@
13 13
14<div class="no-history" i18n *ngIf="pagination.totalItems === 0">You don't have videos history yet.</div> 14<div class="no-history" i18n *ngIf="pagination.totalItems === 0">You don't have videos history yet.</div>
15 15
16<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" class="videos"> 16<div myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [autoInit]="true" [dataObservable]="onDataSubject.asObservable()" class="videos">
17 <div class="video" *ngFor="let video of videos"> 17 <div class="video" *ngFor="let video of videos">
18 <my-video-miniature 18 <my-video-miniature
19 [video]="video" [displayAsRow]="true" 19 [video]="video" [displayAsRow]="true"
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html
index fc23053c8..ce43ed6dd 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html
+++ b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.html
@@ -1,6 +1,6 @@
1<div class="no-results" i18n *ngIf="pagination.totalItems === 0">You don't have any subscriptions yet.</div> 1<div class="no-results" i18n *ngIf="pagination.totalItems === 0">You don't have any subscriptions yet.</div>
2 2
3<div class="video-channels" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"> 3<div class="video-channels" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
4 <div *ngFor="let videoChannel of videoChannels" class="video-channel"> 4 <div *ngFor="let videoChannel of videoChannels" class="video-channel">
5 <a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]"> 5 <a [routerLink]="[ '/video-channels', videoChannel.nameWithHost ]">
6 <img [src]="videoChannel.avatarUrl" alt="Avatar" /> 6 <img [src]="videoChannel.avatarUrl" alt="Avatar" />
diff --git a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
index 6ce22989b..b347fc3fe 100644
--- a/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
+++ b/client/src/app/+my-account/my-account-subscriptions/my-account-subscriptions.component.ts
@@ -3,6 +3,7 @@ import { Notifier } from '@app/core'
3import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
4import { UserSubscriptionService } from '@app/shared/user-subscription' 4import { UserSubscriptionService } from '@app/shared/user-subscription'
5import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 5import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
6import { Subject } from 'rxjs'
6 7
7@Component({ 8@Component({
8 selector: 'my-account-subscriptions', 9 selector: 'my-account-subscriptions',
@@ -18,6 +19,8 @@ export class MyAccountSubscriptionsComponent implements OnInit {
18 totalItems: null 19 totalItems: null
19 } 20 }
20 21
22 onDataSubject = new Subject<any[]>()
23
21 constructor ( 24 constructor (
22 private userSubscriptionService: UserSubscriptionService, 25 private userSubscriptionService: UserSubscriptionService,
23 private notifier: Notifier 26 private notifier: Notifier
@@ -33,6 +36,8 @@ export class MyAccountSubscriptionsComponent implements OnInit {
33 res => { 36 res => {
34 this.videoChannels = this.videoChannels.concat(res.data) 37 this.videoChannels = this.videoChannels.concat(res.data)
35 this.pagination.totalItems = res.total 38 this.pagination.totalItems = res.total
39
40 this.onDataSubject.next(res.data)
36 }, 41 },
37 42
38 error => this.notifier.error(error.message) 43 error => this.notifier.error(error.message)
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html
index 4de4e69da..a3de3da4a 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.html
@@ -12,7 +12,7 @@
12 12
13 <div 13 <div
14 class="videos" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" 14 class="videos" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"
15 cdkDropList (cdkDropListDropped)="drop($event)" 15 cdkDropList (cdkDropListDropped)="drop($event)" [dataObservable]="onDataSubject.asObservable()"
16 > 16 >
17 <div class="video" *ngFor="let playlistElement of playlistElements; trackBy: trackByFn" cdkDrag> 17 <div class="video" *ngFor="let playlistElement of playlistElements; trackBy: trackByFn" cdkDrag>
18 <my-video-playlist-element-miniature 18 <my-video-playlist-element-miniature
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss
index 900669827..9657ac11d 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.scss
@@ -7,7 +7,7 @@
7 margin-left: -15px; 7 margin-left: -15px;
8 margin-top: -$sub-menu-margin-bottom; 8 margin-top: -$sub-menu-margin-bottom;
9 9
10 padding: $sub-menu-margin-bottom 0; 10 padding: $sub-menu-margin-bottom 0 -15px 0;
11 11
12 display: flex; 12 display: flex;
13 justify-content: center; 13 justify-content: center;
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts
index 6f307a058..22c9af566 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component.ts
@@ -3,7 +3,7 @@ import { Notifier, ServerService } from '@app/core'
3import { AuthService } from '../../core/auth' 3import { AuthService } from '../../core/auth'
4import { ConfirmService } from '../../core/confirm' 4import { ConfirmService } from '../../core/confirm'
5import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 5import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
6import { Subscription } from 'rxjs' 6import { Subject, Subscription } from 'rxjs'
7import { ActivatedRoute } from '@angular/router' 7import { ActivatedRoute } from '@angular/router'
8import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' 8import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
9import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' 9import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
@@ -22,10 +22,12 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
22 22
23 pagination: ComponentPagination = { 23 pagination: ComponentPagination = {
24 currentPage: 1, 24 currentPage: 1,
25 itemsPerPage: 30, 25 itemsPerPage: 10,
26 totalItems: null 26 totalItems: null
27 } 27 }
28 28
29 onDataSubject = new Subject<any[]>()
30
29 private videoPlaylistId: string | number 31 private videoPlaylistId: string | number
30 private paramsSub: Subscription 32 private paramsSub: Subscription
31 33
@@ -102,6 +104,8 @@ export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestro
102 .subscribe(({ total, data }) => { 104 .subscribe(({ total, data }) => {
103 this.playlistElements = this.playlistElements.concat(data) 105 this.playlistElements = this.playlistElements.concat(data)
104 this.pagination.totalItems = total 106 this.pagination.totalItems = total
107
108 this.onDataSubject.next(data)
105 }) 109 })
106 } 110 }
107 111
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html
index 322560673..307884c70 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.html
@@ -5,7 +5,7 @@
5 </a> 5 </a>
6</div> 6</div>
7 7
8<div class="video-playlists" myInfiniteScroller (nearOfBottom)="onNearOfBottom()"> 8<div class="video-playlists" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
9 <div *ngFor="let playlist of videoPlaylists" class="video-playlist"> 9 <div *ngFor="let playlist of videoPlaylists" class="video-playlist">
10 <div class="miniature-wrapper"> 10 <div class="miniature-wrapper">
11 <my-video-playlist-miniature [playlist]="playlist" [toManage]="true" [displayChannel]="true" [displayDescription]="true" [displayPrivacy]="true" 11 <my-video-playlist-miniature [playlist]="playlist" [toManage]="true" [displayChannel]="true" [displayDescription]="true" [displayPrivacy]="true"
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts
index e30656b92..0c4e4b0d6 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlists.component.ts
@@ -9,6 +9,7 @@ import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
9import { ComponentPagination } from '@app/shared/rest/component-pagination.model' 9import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
10import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' 10import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
11import { VideoPlaylistType } from '@shared/models' 11import { VideoPlaylistType } from '@shared/models'
12import { Subject } from 'rxjs'
12 13
13@Component({ 14@Component({
14 selector: 'my-account-video-playlists', 15 selector: 'my-account-video-playlists',
@@ -20,10 +21,12 @@ export class MyAccountVideoPlaylistsComponent implements OnInit {
20 21
21 pagination: ComponentPagination = { 22 pagination: ComponentPagination = {
22 currentPage: 1, 23 currentPage: 1,
23 itemsPerPage: 10, 24 itemsPerPage: 5,
24 totalItems: null 25 totalItems: null
25 } 26 }
26 27
28 onDataSubject = new Subject<any[]>()
29
27 private user: User 30 private user: User
28 31
29 constructor ( 32 constructor (
@@ -78,11 +81,15 @@ export class MyAccountVideoPlaylistsComponent implements OnInit {
78 } 81 }
79 82
80 private loadVideoPlaylists () { 83 private loadVideoPlaylists () {
84 const playlistsObservable = this.videoPlaylistService.listAccountPlaylists(this.user.account, this.pagination, '-updatedAt')
85
81 this.authService.userInformationLoaded 86 this.authService.userInformationLoaded
82 .pipe(flatMap(() => this.videoPlaylistService.listAccountPlaylists(this.user.account, '-updatedAt'))) 87 .pipe(flatMap(() => playlistsObservable))
83 .subscribe(res => { 88 .subscribe(res => {
84 this.videoPlaylists = this.videoPlaylists.concat(res.data) 89 this.videoPlaylists = this.videoPlaylists.concat(res.data)
85 this.pagination.totalItems = res.total 90 this.pagination.totalItems = res.total
91
92 this.onDataSubject.next(res.data)
86 }) 93 })
87 } 94 }
88} 95}
diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html
index befc7143c..1adc50180 100644
--- a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html
+++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.html
@@ -4,7 +4,7 @@
4 4
5<div i18n class="no-results" *ngIf="pagination.totalItems === 0">This channel does not have playlists.</div> 5<div i18n class="no-results" *ngIf="pagination.totalItems === 0">This channel does not have playlists.</div>
6 6
7<div class="video-playlist" myInfiniteScroller (nearOfBottom)="onNearOfBottom()"> 7<div class="video-playlist" myInfiniteScroller (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
8 <div *ngFor="let playlist of videoPlaylists"> 8 <div *ngFor="let playlist of videoPlaylists">
9 <my-video-playlist-miniature [playlist]="playlist" [toManage]="false"></my-video-playlist-miniature> 9 <my-video-playlist-miniature [playlist]="playlist" [toManage]="false"></my-video-playlist-miniature>
10 </div> 10 </div>
diff --git a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts
index 7990044a2..0b0033082 100644
--- a/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts
+++ b/client/src/app/+video-channels/video-channel-playlists/video-channel-playlists.component.ts
@@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ConfirmService } from '../../core/confirm' 2import { ConfirmService } from '../../core/confirm'
3import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 3import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
4import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 4import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
5import { Subscription } from 'rxjs' 5import { Subject, Subscription } from 'rxjs'
6import { Notifier } from '@app/core' 6import { Notifier } from '@app/core'
7import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' 7import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
8import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' 8import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model'
@@ -22,6 +22,8 @@ export class VideoChannelPlaylistsComponent implements OnInit, OnDestroy {
22 totalItems: null 22 totalItems: null
23 } 23 }
24 24
25 onDataSubject = new Subject<any[]>()
26
25 private videoChannelSub: Subscription 27 private videoChannelSub: Subscription
26 private videoChannel: VideoChannel 28 private videoChannel: VideoChannel
27 29
@@ -53,10 +55,12 @@ export class VideoChannelPlaylistsComponent implements OnInit, OnDestroy {
53 } 55 }
54 56
55 private loadVideoPlaylists () { 57 private loadVideoPlaylists () {
56 this.videoPlaylistService.listChannelPlaylists(this.videoChannel) 58 this.videoPlaylistService.listChannelPlaylists(this.videoChannel, this.pagination)
57 .subscribe(res => { 59 .subscribe(res => {
58 this.videoPlaylists = this.videoPlaylists.concat(res.data) 60 this.videoPlaylists = this.videoPlaylists.concat(res.data)
59 this.pagination.totalItems = res.total 61 this.pagination.totalItems = res.total
62
63 this.onDataSubject.next(res.data)
60 }) 64 })
61 } 65 }
62} 66}
diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html
index d0d9d9f35..292813426 100644
--- a/client/src/app/shared/users/user-notifications.component.html
+++ b/client/src/app/shared/users/user-notifications.component.html
@@ -1,6 +1,6 @@
1<div *ngIf="componentPagination.totalItems === 0" class="no-notification" i18n>You don't have notifications.</div> 1<div *ngIf="componentPagination.totalItems === 0" class="no-notification" i18n>You don't have notifications.</div>
2 2
3<div class="notifications" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()"> 3<div class="notifications" myInfiniteScroller [autoInit]="true" (nearOfBottom)="onNearOfBottom()" [dataObservable]="onDataSubject.asObservable()">
4 <div *ngFor="let notification of notifications" class="notification" [ngClass]="{ unread: !notification.read }" (click)="markAsRead(notification)"> 4 <div *ngFor="let notification of notifications" class="notification" [ngClass]="{ unread: !notification.read }" (click)="markAsRead(notification)">
5 5
6 <ng-container [ngSwitch]="notification.type"> 6 <ng-container [ngSwitch]="notification.type">
diff --git a/client/src/app/shared/users/user-notifications.component.ts b/client/src/app/shared/users/user-notifications.component.ts
index ce43b604a..3c9eb369d 100644
--- a/client/src/app/shared/users/user-notifications.component.ts
+++ b/client/src/app/shared/users/user-notifications.component.ts
@@ -4,6 +4,7 @@ import { UserNotificationType } from '../../../../../shared'
4import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' 4import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model'
5import { Notifier } from '@app/core' 5import { Notifier } from '@app/core'
6import { UserNotification } from '@app/shared/users/user-notification.model' 6import { UserNotification } from '@app/shared/users/user-notification.model'
7import { Subject } from 'rxjs'
7 8
8@Component({ 9@Component({
9 selector: 'my-user-notifications', 10 selector: 'my-user-notifications',
@@ -24,6 +25,8 @@ export class UserNotificationsComponent implements OnInit {
24 25
25 componentPagination: ComponentPagination 26 componentPagination: ComponentPagination
26 27
28 onDataSubject = new Subject<any[]>()
29
27 constructor ( 30 constructor (
28 private userNotificationService: UserNotificationService, 31 private userNotificationService: UserNotificationService,
29 private notifier: Notifier 32 private notifier: Notifier
@@ -47,6 +50,8 @@ export class UserNotificationsComponent implements OnInit {
47 this.componentPagination.totalItems = result.total 50 this.componentPagination.totalItems = result.total
48 51
49 this.notificationsLoaded.emit() 52 this.notificationsLoaded.emit()
53
54 this.onDataSubject.next(result.data)
50 }, 55 },
51 56
52 err => this.notifier.error(err.message) 57 err => this.notifier.error(err.message)
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
index 08ceb21bc..72de84703 100644
--- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
+++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
@@ -83,7 +83,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
83 83
84 load () { 84 load () {
85 forkJoin([ 85 forkJoin([
86 this.videoPlaylistService.listAccountPlaylists(this.user.account, '-updatedAt'), 86 this.videoPlaylistService.listAccountPlaylists(this.user.account, undefined,'-updatedAt'),
87 this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id) 87 this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id)
88 ]) 88 ])
89 .subscribe( 89 .subscribe(
diff --git a/client/src/app/shared/video-playlist/video-playlist.service.ts b/client/src/app/shared/video-playlist/video-playlist.service.ts
index b93a19356..376387082 100644
--- a/client/src/app/shared/video-playlist/video-playlist.service.ts
+++ b/client/src/app/shared/video-playlist/video-playlist.service.ts
@@ -45,21 +45,28 @@ export class VideoPlaylistService {
45 ) 45 )
46 } 46 }
47 47
48 listChannelPlaylists (videoChannel: VideoChannel): Observable<ResultList<VideoPlaylist>> { 48 listChannelPlaylists (videoChannel: VideoChannel, componentPagination: ComponentPagination): Observable<ResultList<VideoPlaylist>> {
49 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/video-playlists' 49 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.nameWithHost + '/video-playlists'
50 const pagination = this.restService.componentPaginationToRestPagination(componentPagination)
50 51
51 return this.authHttp.get<ResultList<VideoPlaylist>>(url) 52 let params = new HttpParams()
53 params = this.restService.addRestGetParams(params, pagination)
54
55 return this.authHttp.get<ResultList<VideoPlaylist>>(url, { params })
52 .pipe( 56 .pipe(
53 switchMap(res => this.extractPlaylists(res)), 57 switchMap(res => this.extractPlaylists(res)),
54 catchError(err => this.restExtractor.handleError(err)) 58 catchError(err => this.restExtractor.handleError(err))
55 ) 59 )
56 } 60 }
57 61
58 listAccountPlaylists (account: Account, sort: string): Observable<ResultList<VideoPlaylist>> { 62 listAccountPlaylists (account: Account, componentPagination: ComponentPagination, sort: string): Observable<ResultList<VideoPlaylist>> {
59 const url = AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-playlists' 63 const url = AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-playlists'
64 const pagination = componentPagination
65 ? this.restService.componentPaginationToRestPagination(componentPagination)
66 : undefined
60 67
61 let params = new HttpParams() 68 let params = new HttpParams()
62 params = this.restService.addRestGetParams(params, undefined, sort) 69 params = this.restService.addRestGetParams(params, pagination, sort)
63 70
64 return this.authHttp.get<ResultList<VideoPlaylist>>(url, { params }) 71 return this.authHttp.get<ResultList<VideoPlaylist>>(url, { params })
65 .pipe( 72 .pipe(
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">
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.html b/client/src/app/videos/+video-watch/comment/video-comments.component.html
index 7b941454a..be20a8490 100644
--- a/client/src/app/videos/+video-watch/comment/video-comments.component.html
+++ b/client/src/app/videos/+video-watch/comment/video-comments.component.html
@@ -21,6 +21,7 @@
21 myInfiniteScroller 21 myInfiniteScroller
22 [autoInit]="true" 22 [autoInit]="true"
23 (nearOfBottom)="onNearOfBottom()" 23 (nearOfBottom)="onNearOfBottom()"
24 [dataObservable]="onDataSubject.asObservable()"
24 > 25 >
25 <div #commentHighlightBlock id="highlighted-comment"> 26 <div #commentHighlightBlock id="highlighted-comment">
26 <my-video-comment 27 <my-video-comment
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.ts b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
index 64bd18072..a3e5ed880 100644
--- a/client/src/app/videos/+video-watch/comment/video-comments.component.ts
+++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts
@@ -1,7 +1,7 @@
1import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core' 1import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core'
2import { ActivatedRoute } from '@angular/router' 2import { ActivatedRoute } from '@angular/router'
3import { ConfirmService, Notifier } from '@app/core' 3import { ConfirmService, Notifier } from '@app/core'
4import { Subscription } from 'rxjs' 4import { Subject, Subscription } from 'rxjs'
5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' 5import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model'
6import { AuthService } from '../../../core/auth' 6import { AuthService } from '../../../core/auth'
7import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model' 7import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model'
@@ -38,6 +38,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
38 38
39 syndicationItems: Syndication[] = [] 39 syndicationItems: Syndication[] = []
40 40
41 onDataSubject = new Subject<any[]>()
42
41 private sub: Subscription 43 private sub: Subscription
42 44
43 constructor ( 45 constructor (
@@ -124,6 +126,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
124 res => { 126 res => {
125 this.comments = this.comments.concat(res.data) 127 this.comments = this.comments.concat(res.data)
126 this.componentPagination.totalItems = res.total 128 this.componentPagination.totalItems = res.total
129
130 this.onDataSubject.next(res.data)
127 }, 131 },
128 132
129 err => this.notifier.error(err.message) 133 err => this.notifier.error(err.message)