diff options
author | Chocobozzz <me@florianbigard.com> | 2018-03-19 18:00:31 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-03-19 18:00:31 +0100 |
commit | 9af61e84309c23ffbfd7562435a5fadd86cdf20c (patch) | |
tree | eb367495b082a776c21b603c40bbe2ad0a8ebc6d /client/src/app/shared | |
parent | 606ca5bccf55e75a20a70d41a4d1f2cbf12d2563 (diff) | |
download | PeerTube-9af61e84309c23ffbfd7562435a5fadd86cdf20c.tar.gz PeerTube-9af61e84309c23ffbfd7562435a5fadd86cdf20c.tar.zst PeerTube-9af61e84309c23ffbfd7562435a5fadd86cdf20c.zip |
Don't forget to clean up subscriptions
Diffstat (limited to 'client/src/app/shared')
-rw-r--r-- | client/src/app/shared/video/abstract-video-list.ts | 29 | ||||
-rw-r--r-- | client/src/app/shared/video/infinite-scroller.directive.ts | 22 |
2 files changed, 38 insertions, 13 deletions
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts index 570aaae9d..4a220c93d 100644 --- a/client/src/app/shared/video/abstract-video-list.ts +++ b/client/src/app/shared/video/abstract-video-list.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { ElementRef, OnInit, ViewChild } from '@angular/core' | 1 | import { ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core' |
2 | import { ActivatedRoute, Router } from '@angular/router' | 2 | import { ActivatedRoute, Router } from '@angular/router' |
3 | import { isInMobileView } from '@app/shared/misc/utils' | 3 | import { isInMobileView } from '@app/shared/misc/utils' |
4 | import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' | 4 | import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' |
@@ -6,12 +6,13 @@ import { NotificationsService } from 'angular2-notifications' | |||
6 | import 'rxjs/add/operator/debounceTime' | 6 | import 'rxjs/add/operator/debounceTime' |
7 | import { Observable } from 'rxjs/Observable' | 7 | import { Observable } from 'rxjs/Observable' |
8 | import { fromEvent } from 'rxjs/observable/fromEvent' | 8 | import { fromEvent } from 'rxjs/observable/fromEvent' |
9 | import { Subscription } from 'rxjs/Subscription' | ||
9 | import { AuthService } from '../../core/auth' | 10 | import { AuthService } from '../../core/auth' |
10 | import { ComponentPagination } from '../rest/component-pagination.model' | 11 | import { ComponentPagination } from '../rest/component-pagination.model' |
11 | import { SortField } from './sort-field.type' | 12 | import { SortField } from './sort-field.type' |
12 | import { Video } from './video.model' | 13 | import { Video } from './video.model' |
13 | 14 | ||
14 | export abstract class AbstractVideoList implements OnInit { | 15 | export abstract class AbstractVideoList implements OnInit, OnDestroy { |
15 | private static LINES_PER_PAGE = 3 | 16 | private static LINES_PER_PAGE = 3 |
16 | 17 | ||
17 | @ViewChild('videoElement') videosElement: ElementRef | 18 | @ViewChild('videoElement') videosElement: ElementRef |
@@ -30,6 +31,9 @@ export abstract class AbstractVideoList implements OnInit { | |||
30 | videoHeight: number | 31 | videoHeight: number |
31 | videoPages: Video[][] = [] | 32 | videoPages: Video[][] = [] |
32 | 33 | ||
34 | protected baseVideoWidth = 215 | ||
35 | protected baseVideoHeight = 230 | ||
36 | |||
33 | protected abstract notificationsService: NotificationsService | 37 | protected abstract notificationsService: NotificationsService |
34 | protected abstract authService: AuthService | 38 | protected abstract authService: AuthService |
35 | protected abstract router: Router | 39 | protected abstract router: Router |
@@ -40,6 +44,8 @@ export abstract class AbstractVideoList implements OnInit { | |||
40 | protected loadedPages: { [ id: number ]: Video[] } = {} | 44 | protected loadedPages: { [ id: number ]: Video[] } = {} |
41 | protected otherRouteParams = {} | 45 | protected otherRouteParams = {} |
42 | 46 | ||
47 | private resizeSubscription: Subscription | ||
48 | |||
43 | abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number}> | 49 | abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number}> |
44 | 50 | ||
45 | get user () { | 51 | get user () { |
@@ -51,7 +57,7 @@ export abstract class AbstractVideoList implements OnInit { | |||
51 | const routeParams = this.route.snapshot.params | 57 | const routeParams = this.route.snapshot.params |
52 | this.loadRouteParams(routeParams) | 58 | this.loadRouteParams(routeParams) |
53 | 59 | ||
54 | fromEvent(window, 'resize') | 60 | this.resizeSubscription = fromEvent(window, 'resize') |
55 | .debounceTime(500) | 61 | .debounceTime(500) |
56 | .subscribe(() => this.calcPageSizes()) | 62 | .subscribe(() => this.calcPageSizes()) |
57 | 63 | ||
@@ -59,6 +65,10 @@ export abstract class AbstractVideoList implements OnInit { | |||
59 | if (this.loadOnInit === true) this.loadMoreVideos(this.pagination.currentPage) | 65 | if (this.loadOnInit === true) this.loadMoreVideos(this.pagination.currentPage) |
60 | } | 66 | } |
61 | 67 | ||
68 | ngOnDestroy () { | ||
69 | if (this.resizeSubscription) this.resizeSubscription.unsubscribe() | ||
70 | } | ||
71 | |||
62 | onNearOfTop () { | 72 | onNearOfTop () { |
63 | this.previousPage() | 73 | this.previousPage() |
64 | } | 74 | } |
@@ -168,15 +178,15 @@ export abstract class AbstractVideoList implements OnInit { | |||
168 | } | 178 | } |
169 | 179 | ||
170 | private calcPageSizes () { | 180 | private calcPageSizes () { |
171 | if (isInMobileView()) { | 181 | if (isInMobileView() || this.baseVideoWidth === -1) { |
172 | this.pagination.itemsPerPage = 5 | 182 | this.pagination.itemsPerPage = 5 |
173 | 183 | ||
174 | // Video takes all the width | 184 | // Video takes all the width |
175 | this.videoWidth = -1 | 185 | this.videoWidth = -1 |
176 | this.pageHeight = this.pagination.itemsPerPage * this.videoHeight | 186 | this.pageHeight = this.pagination.itemsPerPage * this.videoHeight |
177 | } else { | 187 | } else { |
178 | this.videoWidth = 215 | 188 | this.videoWidth = this.baseVideoWidth |
179 | this.videoHeight = 230 | 189 | this.videoHeight = this.baseVideoHeight |
180 | 190 | ||
181 | const videosWidth = this.videosElement.nativeElement.offsetWidth | 191 | const videosWidth = this.videosElement.nativeElement.offsetWidth |
182 | this.pagination.itemsPerPage = Math.floor(videosWidth / this.videoWidth) * AbstractVideoList.LINES_PER_PAGE | 192 | this.pagination.itemsPerPage = Math.floor(videosWidth / this.videoWidth) * AbstractVideoList.LINES_PER_PAGE |
@@ -194,7 +204,12 @@ export abstract class AbstractVideoList implements OnInit { | |||
194 | i++ | 204 | i++ |
195 | } | 205 | } |
196 | 206 | ||
197 | this.buildVideoPages() | 207 | // Re fetch the last page |
208 | if (videos.length !== 0) { | ||
209 | this.loadMoreVideos(i) | ||
210 | } else { | ||
211 | this.buildVideoPages() | ||
212 | } | ||
198 | 213 | ||
199 | console.log('Rebuilt pages with %s elements per page.', this.pagination.itemsPerPage) | 214 | console.log('Rebuilt pages with %s elements per page.', this.pagination.itemsPerPage) |
200 | } | 215 | } |
diff --git a/client/src/app/shared/video/infinite-scroller.directive.ts b/client/src/app/shared/video/infinite-scroller.directive.ts index e0f9f4f83..e2730423f 100644 --- a/client/src/app/shared/video/infinite-scroller.directive.ts +++ b/client/src/app/shared/video/infinite-scroller.directive.ts | |||
@@ -1,18 +1,19 @@ | |||
1 | import { Directive, EventEmitter, Input, OnInit, Output } from '@angular/core' | 1 | import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core' |
2 | import 'rxjs/add/operator/debounceTime' | 2 | import 'rxjs/add/operator/debounceTime' |
3 | import 'rxjs/add/operator/distinct' | 3 | import 'rxjs/add/operator/distinct' |
4 | import 'rxjs/add/operator/distinctUntilChanged' | 4 | import 'rxjs/add/operator/distinctUntilChanged' |
5 | import 'rxjs/add/operator/filter' | 5 | import 'rxjs/add/operator/filter' |
6 | import 'rxjs/add/operator/map' | 6 | import 'rxjs/add/operator/map' |
7 | import 'rxjs/add/operator/share' | ||
7 | import 'rxjs/add/operator/startWith' | 8 | import 'rxjs/add/operator/startWith' |
8 | import 'rxjs/add/operator/throttleTime' | 9 | import 'rxjs/add/operator/throttleTime' |
9 | import { fromEvent } from 'rxjs/observable/fromEvent' | 10 | import { fromEvent } from 'rxjs/observable/fromEvent' |
10 | import 'rxjs/add/operator/share' | 11 | import { Subscription } from 'rxjs/Subscription' |
11 | 12 | ||
12 | @Directive({ | 13 | @Directive({ |
13 | selector: '[myInfiniteScroller]' | 14 | selector: '[myInfiniteScroller]' |
14 | }) | 15 | }) |
15 | export class InfiniteScrollerDirective implements OnInit { | 16 | export class InfiniteScrollerDirective implements OnInit, OnDestroy { |
16 | private static PAGE_VIEW_TOP_MARGIN = 500 | 17 | private static PAGE_VIEW_TOP_MARGIN = 500 |
17 | 18 | ||
18 | @Input() containerHeight: number | 19 | @Input() containerHeight: number |
@@ -27,6 +28,9 @@ export class InfiniteScrollerDirective implements OnInit { | |||
27 | private decimalLimit = 0 | 28 | private decimalLimit = 0 |
28 | private lastCurrentBottom = -1 | 29 | private lastCurrentBottom = -1 |
29 | private lastCurrentTop = 0 | 30 | private lastCurrentTop = 0 |
31 | private scrollDownSub: Subscription | ||
32 | private scrollUpSub: Subscription | ||
33 | private pageChangeSub: Subscription | ||
30 | 34 | ||
31 | constructor () { | 35 | constructor () { |
32 | this.decimalLimit = this.percentLimit / 100 | 36 | this.decimalLimit = this.percentLimit / 100 |
@@ -36,6 +40,12 @@ export class InfiniteScrollerDirective implements OnInit { | |||
36 | if (this.autoLoading === true) return this.initialize() | 40 | if (this.autoLoading === true) return this.initialize() |
37 | } | 41 | } |
38 | 42 | ||
43 | ngOnDestroy () { | ||
44 | if (this.scrollDownSub) this.scrollDownSub.unsubscribe() | ||
45 | if (this.scrollUpSub) this.scrollUpSub.unsubscribe() | ||
46 | if (this.pageChangeSub) this.pageChangeSub.unsubscribe() | ||
47 | } | ||
48 | |||
39 | initialize () { | 49 | initialize () { |
40 | // Emit the last value | 50 | // Emit the last value |
41 | const throttleOptions = { leading: true, trailing: true } | 51 | const throttleOptions = { leading: true, trailing: true } |
@@ -48,7 +58,7 @@ export class InfiniteScrollerDirective implements OnInit { | |||
48 | .share() | 58 | .share() |
49 | 59 | ||
50 | // Scroll Down | 60 | // Scroll Down |
51 | scrollObservable | 61 | this.scrollDownSub = scrollObservable |
52 | // Check we scroll down | 62 | // Check we scroll down |
53 | .filter(({ current }) => { | 63 | .filter(({ current }) => { |
54 | const res = this.lastCurrentBottom < current | 64 | const res = this.lastCurrentBottom < current |
@@ -60,7 +70,7 @@ export class InfiniteScrollerDirective implements OnInit { | |||
60 | .subscribe(() => this.nearOfBottom.emit()) | 70 | .subscribe(() => this.nearOfBottom.emit()) |
61 | 71 | ||
62 | // Scroll up | 72 | // Scroll up |
63 | scrollObservable | 73 | this.scrollUpSub = scrollObservable |
64 | // Check we scroll up | 74 | // Check we scroll up |
65 | .filter(({ current }) => { | 75 | .filter(({ current }) => { |
66 | const res = this.lastCurrentTop > current | 76 | const res = this.lastCurrentTop > current |
@@ -74,7 +84,7 @@ export class InfiniteScrollerDirective implements OnInit { | |||
74 | .subscribe(() => this.nearOfTop.emit()) | 84 | .subscribe(() => this.nearOfTop.emit()) |
75 | 85 | ||
76 | // Page change | 86 | // Page change |
77 | scrollObservable | 87 | this.pageChangeSub = scrollObservable |
78 | .distinct() | 88 | .distinct() |
79 | .map(({ current }) => this.calculateCurrentPage(current)) | 89 | .map(({ current }) => this.calculateCurrentPage(current)) |
80 | .distinctUntilChanged() | 90 | .distinctUntilChanged() |