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