diff options
author | Chocobozzz <me@florianbigard.com> | 2019-08-02 14:49:25 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-08-02 14:49:25 +0200 |
commit | ad453580b20056fd80b3245d4db554f5ca1a5e29 (patch) | |
tree | ed07a6dbd8bc8cd27b22cd33dabcbd3d31deea07 | |
parent | dd570a34ff731a6cd98ef8f8bf83f234e804f6c1 (diff) | |
download | PeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.tar.gz PeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.tar.zst PeerTube-ad453580b20056fd80b3245d4db554f5ca1a5e29.zip |
Fix infinite scroll on big screens
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 | |||
4 | import { Notifier } from '@app/core' | 4 | import { Notifier } from '@app/core' |
5 | import { RestService } from '@app/shared' | 5 | import { RestService } from '@app/shared' |
6 | import { SortMeta } from 'primeng/api' | 6 | import { SortMeta } from 'primeng/api' |
7 | import { 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' | |||
4 | import { AccountService } from '@app/shared/account/account.service' | 4 | import { AccountService } from '@app/shared/account/account.service' |
5 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 5 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
6 | import { concatMap, map, switchMap, tap } from 'rxjs/operators' | 6 | import { concatMap, map, switchMap, tap } from 'rxjs/operators' |
7 | import { from, Subscription } from 'rxjs' | 7 | import { from, Subject, Subscription } from 'rxjs' |
8 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 8 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
9 | import { Video } from '@app/shared/video/video.model' | 9 | import { Video } from '@app/shared/video/video.model' |
10 | import { AuthService } from '@app/core' | 10 | import { 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' | |||
8 | import { ActivatedRoute, Router } from '@angular/router' | 8 | import { ActivatedRoute, Router } from '@angular/router' |
9 | import { compareSemVer } from '@shared/core-utils/miscs/miscs' | 9 | import { compareSemVer } from '@shared/core-utils/miscs/miscs' |
10 | import { PluginService } from '@app/core/plugins/plugin.service' | 10 | import { PluginService } from '@app/core/plugins/plugin.service' |
11 | import { 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' | |||
3 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 3 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
4 | import { UserSubscriptionService } from '@app/shared/user-subscription' | 4 | import { UserSubscriptionService } from '@app/shared/user-subscription' |
5 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 5 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
6 | import { 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' | |||
3 | import { AuthService } from '../../core/auth' | 3 | import { AuthService } from '../../core/auth' |
4 | import { ConfirmService } from '../../core/confirm' | 4 | import { ConfirmService } from '../../core/confirm' |
5 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 5 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
6 | import { Subscription } from 'rxjs' | 6 | import { Subject, Subscription } from 'rxjs' |
7 | import { ActivatedRoute } from '@angular/router' | 7 | import { ActivatedRoute } from '@angular/router' |
8 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | 8 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' |
9 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | 9 | import { 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' | |||
9 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' | 9 | import { ComponentPagination } from '@app/shared/rest/component-pagination.model' |
10 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | 10 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' |
11 | import { VideoPlaylistType } from '@shared/models' | 11 | import { VideoPlaylistType } from '@shared/models' |
12 | import { 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' | |||
2 | import { ConfirmService } from '../../core/confirm' | 2 | import { ConfirmService } from '../../core/confirm' |
3 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' | 3 | import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' |
4 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' | 4 | import { VideoChannel } from '@app/shared/video-channel/video-channel.model' |
5 | import { Subscription } from 'rxjs' | 5 | import { Subject, Subscription } from 'rxjs' |
6 | import { Notifier } from '@app/core' | 6 | import { Notifier } from '@app/core' |
7 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | 7 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' |
8 | import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' | 8 | import { 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' | |||
4 | import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' | 4 | import { ComponentPagination, hasMoreItems } from '@app/shared/rest/component-pagination.model' |
5 | import { Notifier } from '@app/core' | 5 | import { Notifier } from '@app/core' |
6 | import { UserNotification } from '@app/shared/users/user-notification.model' | 6 | import { UserNotification } from '@app/shared/users/user-notification.model' |
7 | import { 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 @@ | |||
1 | import { debounceTime, first, tap } from 'rxjs/operators' | 1 | import { debounceTime, first, tap } from 'rxjs/operators' |
2 | import { OnDestroy, OnInit } from '@angular/core' | 2 | import { OnDestroy, OnInit } from '@angular/core' |
3 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
4 | import { fromEvent, Observable, of, Subscription } from 'rxjs' | 4 | import { fromEvent, Observable, of, Subject, Subscription } from 'rxjs' |
5 | import { AuthService } from '../../core/auth' | 5 | import { AuthService } from '../../core/auth' |
6 | import { ComponentPagination } from '../rest/component-pagination.model' | 6 | import { ComponentPagination } from '../rest/component-pagination.model' |
7 | import { VideoSortField } from './sort-field.type' | 7 | import { 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 @@ | |||
1 | import { distinct, distinctUntilChanged, filter, map, share, startWith, throttleTime } from 'rxjs/operators' | 1 | import { distinctUntilChanged, filter, map, share, startWith, tap, throttleTime } from 'rxjs/operators' |
2 | import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' | 2 | import { AfterContentChecked, Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' |
3 | import { fromEvent, Subscription } from 'rxjs' | 3 | import { fromEvent, Observable, Subscription } from 'rxjs' |
4 | 4 | ||
5 | @Directive({ | 5 | @Directive({ |
6 | selector: '[myInfiniteScroller]' | 6 | selector: '[myInfiniteScroller]' |
7 | }) | 7 | }) |
8 | export class InfiniteScrollerDirective implements OnInit, OnDestroy { | 8 | export 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 @@ | |||
1 | import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core' |
2 | import { ActivatedRoute } from '@angular/router' | 2 | import { ActivatedRoute } from '@angular/router' |
3 | import { ConfirmService, Notifier } from '@app/core' | 3 | import { ConfirmService, Notifier } from '@app/core' |
4 | import { Subscription } from 'rxjs' | 4 | import { Subject, Subscription } from 'rxjs' |
5 | import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' | 5 | import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' |
6 | import { AuthService } from '../../../core/auth' | 6 | import { AuthService } from '../../../core/auth' |
7 | import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model' | 7 | import { 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) |