aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/video/abstract-video-list.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/video/abstract-video-list.ts')
-rw-r--r--client/src/app/shared/video/abstract-video-list.ts96
1 files changed, 64 insertions, 32 deletions
diff --git a/client/src/app/shared/video/abstract-video-list.ts b/client/src/app/shared/video/abstract-video-list.ts
index a25fc532c..034d0d879 100644
--- a/client/src/app/shared/video/abstract-video-list.ts
+++ b/client/src/app/shared/video/abstract-video-list.ts
@@ -1,6 +1,7 @@
1import { OnInit } from '@angular/core' 1import { ElementRef, OnInit, ViewChild, ViewChildren } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { isInMobileView, isInSmallView } from '@app/shared/misc/utils' 3import { isInMobileView } from '@app/shared/misc/utils'
4import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
4import { NotificationsService } from 'angular2-notifications' 5import { NotificationsService } from 'angular2-notifications'
5import { Observable } from 'rxjs/Observable' 6import { Observable } from 'rxjs/Observable'
6import { AuthService } from '../../core/auth' 7import { AuthService } from '../../core/auth'
@@ -9,30 +10,35 @@ import { SortField } from './sort-field.type'
9import { Video } from './video.model' 10import { Video } from './video.model'
10 11
11export abstract class AbstractVideoList implements OnInit { 12export abstract class AbstractVideoList implements OnInit {
13 private static LINES_PER_PAGE = 3
14
15 @ViewChild('videoElement') videosElement: ElementRef
16 @ViewChild(InfiniteScrollerDirective) infiniteScroller: InfiniteScrollerDirective
17
12 pagination: ComponentPagination = { 18 pagination: ComponentPagination = {
13 currentPage: 1, 19 currentPage: 1,
14 itemsPerPage: 25, 20 itemsPerPage: 10,
15 totalItems: null 21 totalItems: null
16 } 22 }
17 sort: SortField = '-createdAt' 23 sort: SortField = '-createdAt'
18 defaultSort: SortField = '-createdAt' 24 defaultSort: SortField = '-createdAt'
19 videos: Video[] = []
20 loadOnInit = true 25 loadOnInit = true
26 pageHeight: number
27 videoWidth = 215
28 videoHeight = 230
29 videoPages: Video[][]
21 30
22 protected abstract notificationsService: NotificationsService 31 protected abstract notificationsService: NotificationsService
23 protected abstract authService: AuthService 32 protected abstract authService: AuthService
24 protected abstract router: Router 33 protected abstract router: Router
25 protected abstract route: ActivatedRoute 34 protected abstract route: ActivatedRoute
26
27 protected abstract currentRoute: string 35 protected abstract currentRoute: string
28
29 abstract titlePage: string 36 abstract titlePage: string
30 37
31 protected otherParams = {} 38 protected loadedPages: { [ id: number ]: Video[] } = {}
32 39 protected otherRouteParams = {}
33 private loadedPages: { [ id: number ]: boolean } = {}
34 40
35 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}> 41 abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number}>
36 42
37 get user () { 43 get user () {
38 return this.authService.getUser() 44 return this.authService.getUser()
@@ -45,15 +51,26 @@ export abstract class AbstractVideoList implements OnInit {
45 51
46 if (isInMobileView()) { 52 if (isInMobileView()) {
47 this.pagination.itemsPerPage = 5 53 this.pagination.itemsPerPage = 5
54 this.videoWidth = -1
55 }
56
57 if (this.videoWidth !== -1) {
58 const videosWidth = this.videosElement.nativeElement.offsetWidth
59 this.pagination.itemsPerPage = Math.floor(videosWidth / this.videoWidth) * AbstractVideoList.LINES_PER_PAGE
60 }
61
62 // Video takes all the width
63 if (this.videoWidth === -1) {
64 this.pageHeight = this.pagination.itemsPerPage * this.videoHeight
65 } else {
66 this.pageHeight = this.videoHeight * AbstractVideoList.LINES_PER_PAGE
48 } 67 }
49 68
50 if (this.loadOnInit === true) this.loadMoreVideos('after') 69 if (this.loadOnInit === true) this.loadMoreVideos(this.pagination.currentPage)
51 } 70 }
52 71
53 onNearOfTop () { 72 onNearOfTop () {
54 if (this.pagination.currentPage > 1) { 73 this.previousPage()
55 this.previousPage()
56 }
57 } 74 }
58 75
59 onNearOfBottom () { 76 onNearOfBottom () {
@@ -62,16 +79,20 @@ export abstract class AbstractVideoList implements OnInit {
62 } 79 }
63 } 80 }
64 81
82 onPageChanged (page: number) {
83 this.pagination.currentPage = page
84 this.setNewRouteParams()
85 }
86
65 reloadVideos () { 87 reloadVideos () {
66 this.videos = []
67 this.loadedPages = {} 88 this.loadedPages = {}
68 this.loadMoreVideos('before') 89 this.loadMoreVideos(this.pagination.currentPage)
69 } 90 }
70 91
71 loadMoreVideos (where: 'before' | 'after') { 92 loadMoreVideos (page: number) {
72 if (this.loadedPages[this.pagination.currentPage] === true) return 93 if (this.loadedPages[page] !== undefined) return
73 94
74 const observable = this.getVideosObservable() 95 const observable = this.getVideosObservable(page)
75 96
76 observable.subscribe( 97 observable.subscribe(
77 ({ videos, totalVideos }) => { 98 ({ videos, totalVideos }) => {
@@ -82,13 +103,14 @@ export abstract class AbstractVideoList implements OnInit {
82 return this.reloadVideos() 103 return this.reloadVideos()
83 } 104 }
84 105
85 this.loadedPages[this.pagination.currentPage] = true 106 this.loadedPages[page] = videos
107 this.buildVideoPages()
86 this.pagination.totalItems = totalVideos 108 this.pagination.totalItems = totalVideos
87 109
88 if (where === 'before') { 110 // Initialize infinite scroller now we loaded the first page
89 this.videos = videos.concat(this.videos) 111 if (Object.keys(this.loadedPages).length === 1) {
90 } else { 112 // Wait elements creation
91 this.videos = this.videos.concat(videos) 113 setTimeout(() => this.infiniteScroller.initialize(), 500)
92 } 114 }
93 }, 115 },
94 error => this.notificationsService.error('Error', error.message) 116 error => this.notificationsService.error('Error', error.message)
@@ -107,17 +129,15 @@ export abstract class AbstractVideoList implements OnInit {
107 } 129 }
108 130
109 protected previousPage () { 131 protected previousPage () {
110 this.pagination.currentPage-- 132 const min = this.minPageLoaded()
111 133
112 this.setNewRouteParams() 134 if (min > 1) {
113 this.loadMoreVideos('before') 135 this.loadMoreVideos(min - 1)
136 }
114 } 137 }
115 138
116 protected nextPage () { 139 protected nextPage () {
117 this.pagination.currentPage++ 140 this.loadMoreVideos(this.maxPageLoaded() + 1)
118
119 this.setNewRouteParams()
120 this.loadMoreVideos('after')
121 } 141 }
122 142
123 protected buildRouteParams () { 143 protected buildRouteParams () {
@@ -127,7 +147,7 @@ export abstract class AbstractVideoList implements OnInit {
127 page: this.pagination.currentPage 147 page: this.pagination.currentPage
128 } 148 }
129 149
130 return Object.assign(params, this.otherParams) 150 return Object.assign(params, this.otherRouteParams)
131 } 151 }
132 152
133 protected loadRouteParams (routeParams: { [ key: string ]: any }) { 153 protected loadRouteParams (routeParams: { [ key: string ]: any }) {
@@ -144,4 +164,16 @@ export abstract class AbstractVideoList implements OnInit {
144 const routeParams = this.buildRouteParams() 164 const routeParams = this.buildRouteParams()
145 this.router.navigate([ this.currentRoute, routeParams ]) 165 this.router.navigate([ this.currentRoute, routeParams ])
146 } 166 }
167
168 protected buildVideoPages () {
169 this.videoPages = Object.values(this.loadedPages)
170 }
171
172 private minPageLoaded () {
173 return Math.min(...Object.keys(this.loadedPages).map(e => parseInt(e, 10)))
174 }
175
176 private maxPageLoaded () {
177 return Math.max(...Object.keys(this.loadedPages).map(e => parseInt(e, 10)))
178 }
147} 179}