]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/video/abstract-video-list.ts
Fix search pagination
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / video / abstract-video-list.ts
CommitLineData
f3aaa9a9 1import { OnInit } from '@angular/core'
fd45e8f4 2import { ActivatedRoute, Router } from '@angular/router'
fd45e8f4 3import { NotificationsService } from 'angular2-notifications'
9bf9d2a5 4import { Observable } from 'rxjs/Observable'
b2731bff 5import { AuthService } from '../../core/auth'
4635f59d 6import { ComponentPagination } from '../rest/component-pagination.model'
202f6b6c 7import { SortField } from './sort-field.type'
202f6b6c 8import { Video } from './video.model'
fd45e8f4 9
f3aaa9a9 10export abstract class AbstractVideoList implements OnInit {
4635f59d 11 pagination: ComponentPagination = {
fd45e8f4 12 currentPage: 1,
c88593f7 13 itemsPerPage: 10,
fd45e8f4
C
14 totalItems: null
15 }
9bf9d2a5 16 sort: SortField = '-createdAt'
f3aaa9a9 17 defaultSort: SortField = '-createdAt'
fd45e8f4 18 videos: Video[] = []
f3aaa9a9 19 loadOnInit = true
fd45e8f4 20
b2731bff
C
21 protected abstract notificationsService: NotificationsService
22 protected abstract authService: AuthService
23 protected abstract router: Router
24 protected abstract route: ActivatedRoute
fd45e8f4 25
2bbb3412
C
26 protected abstract currentRoute: string
27
9bf9d2a5 28 abstract titlePage: string
c88593f7
C
29
30 protected otherParams = {}
31
2bbb3412
C
32 private loadedPages: { [ id: number ]: boolean } = {}
33
fd45e8f4
C
34 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}>
35
b2731bff
C
36 get user () {
37 return this.authService.getUser()
38 }
39
fd45e8f4
C
40 ngOnInit () {
41 // Subscribe to route changes
2bbb3412
C
42 const routeParams = this.route.snapshot.params
43 this.loadRouteParams(routeParams)
a2b817d3 44
f3aaa9a9 45 if (this.loadOnInit === true) this.loadMoreVideos('after')
fd45e8f4
C
46 }
47
2bbb3412
C
48 onNearOfTop () {
49 if (this.pagination.currentPage > 1) {
50 this.previousPage()
51 }
52 }
53
54 onNearOfBottom () {
55 if (this.hasMoreVideos()) {
56 this.nextPage()
57 }
58 }
59
f3aaa9a9
C
60 reloadVideos () {
61 this.videos = []
62 this.loadedPages = {}
63 this.loadMoreVideos('before')
64 }
65
2bbb3412
C
66 loadMoreVideos (where: 'before' | 'after') {
67 if (this.loadedPages[this.pagination.currentPage] === true) return
fd45e8f4
C
68
69 const observable = this.getVideosObservable()
70
71 observable.subscribe(
72 ({ videos, totalVideos }) => {
a2b817d3 73 // Paging is too high, return to the first one
f595d394 74 if (this.pagination.currentPage > 1 && totalVideos <= ((this.pagination.currentPage - 1) * this.pagination.itemsPerPage)) {
a2b817d3
C
75 this.pagination.currentPage = 1
76 this.setNewRouteParams()
77 return this.reloadVideos()
78 }
79
2bbb3412 80 this.loadedPages[this.pagination.currentPage] = true
fd45e8f4 81 this.pagination.totalItems = totalVideos
2bbb3412
C
82
83 if (where === 'before') {
84 this.videos = videos.concat(this.videos)
85 } else {
86 this.videos = this.videos.concat(videos)
87 }
fd45e8f4 88 },
c5911fd3 89 error => this.notificationsService.error('Error', error.message)
fd45e8f4
C
90 )
91 }
92
2bbb3412 93 protected hasMoreVideos () {
f595d394
C
94 // No results
95 if (this.pagination.totalItems === 0) return false
96
97 // Not loaded yet
2bbb3412
C
98 if (!this.pagination.totalItems) return true
99
202f6b6c 100 const maxPage = this.pagination.totalItems / this.pagination.itemsPerPage
2bbb3412
C
101 return maxPage > this.pagination.currentPage
102 }
103
104 protected previousPage () {
105 this.pagination.currentPage--
106
107 this.setNewRouteParams()
108 this.loadMoreVideos('before')
109 }
110
111 protected nextPage () {
112 this.pagination.currentPage++
fd45e8f4 113
2bbb3412
C
114 this.setNewRouteParams()
115 this.loadMoreVideos('after')
fd45e8f4
C
116 }
117
fd45e8f4
C
118 protected buildRouteParams () {
119 // There is always a sort and a current page
120 const params = {
121 sort: this.sort,
122 page: this.pagination.currentPage
123 }
124
c88593f7 125 return Object.assign(params, this.otherParams)
fd45e8f4
C
126 }
127
128 protected loadRouteParams (routeParams: { [ key: string ]: any }) {
f3aaa9a9 129 this.sort = routeParams['sort'] as SortField || this.defaultSort
fd45e8f4
C
130
131 if (routeParams['page'] !== undefined) {
132 this.pagination.currentPage = parseInt(routeParams['page'], 10)
133 } else {
134 this.pagination.currentPage = 1
135 }
136 }
137
2bbb3412 138 protected setNewRouteParams () {
fd45e8f4 139 const routeParams = this.buildRouteParams()
2bbb3412 140 this.router.navigate([ this.currentRoute, routeParams ])
fd45e8f4
C
141 }
142}