]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/videos/video-list/shared/abstract-video-list.ts
44cdc1d9fce1809bd2810132ccdd00c91f48c3aa
[github/Chocobozzz/PeerTube.git] / client / src / app / videos / video-list / shared / abstract-video-list.ts
1 import { OnDestroy, OnInit } from '@angular/core'
2 import { ActivatedRoute, Router } from '@angular/router'
3
4 import { NotificationsService } from 'angular2-notifications'
5 import { Observable } from 'rxjs/Observable'
6 import { Subscription } from 'rxjs/Subscription'
7
8 import { SortField, Video, VideoPagination } from '../../shared'
9
10 export abstract class AbstractVideoList implements OnInit, OnDestroy {
11 pagination: VideoPagination = {
12 currentPage: 1,
13 itemsPerPage: 25,
14 totalItems: null
15 }
16 sort: SortField = '-createdAt'
17 videos: Video[] = []
18
19 protected notificationsService: NotificationsService
20 protected router: Router
21 protected route: ActivatedRoute
22 protected subActivatedRoute: Subscription
23
24 protected abstract currentRoute: string
25
26 abstract titlePage: string
27 private loadedPages: { [ id: number ]: boolean } = {}
28
29 abstract getVideosObservable (): Observable<{ videos: Video[], totalVideos: number}>
30
31 ngOnInit () {
32 // Subscribe to route changes
33 const routeParams = this.route.snapshot.params
34 this.loadRouteParams(routeParams)
35 this.loadMoreVideos('after')
36 }
37
38 ngOnDestroy () {
39 this.subActivatedRoute.unsubscribe()
40 }
41
42 onNearOfTop () {
43 if (this.pagination.currentPage > 1) {
44 this.previousPage()
45 }
46 }
47
48 onNearOfBottom () {
49 if (this.hasMoreVideos()) {
50 this.nextPage()
51 }
52 }
53
54 loadMoreVideos (where: 'before' | 'after') {
55 if (this.loadedPages[this.pagination.currentPage] === true) return
56
57 const observable = this.getVideosObservable()
58
59 observable.subscribe(
60 ({ videos, totalVideos }) => {
61 this.loadedPages[this.pagination.currentPage] = true
62 this.pagination.totalItems = totalVideos
63
64 if (where === 'before') {
65 this.videos = videos.concat(this.videos)
66 } else {
67 this.videos = this.videos.concat(videos)
68 }
69 },
70 error => this.notificationsService.error('Error', error.text)
71 )
72 }
73
74 protected hasMoreVideos () {
75 if (!this.pagination.totalItems) return true
76
77 const maxPage = this.pagination.totalItems/this.pagination.itemsPerPage
78 return maxPage > this.pagination.currentPage
79 }
80
81 protected previousPage () {
82 this.pagination.currentPage--
83
84 this.setNewRouteParams()
85 this.loadMoreVideos('before')
86 }
87
88 protected nextPage () {
89 this.pagination.currentPage++
90
91 this.setNewRouteParams()
92 this.loadMoreVideos('after')
93 }
94
95 protected buildRouteParams () {
96 // There is always a sort and a current page
97 const params = {
98 sort: this.sort,
99 page: this.pagination.currentPage
100 }
101
102 return params
103 }
104
105 protected loadRouteParams (routeParams: { [ key: string ]: any }) {
106 this.sort = routeParams['sort'] as SortField || '-createdAt'
107
108 if (routeParams['page'] !== undefined) {
109 this.pagination.currentPage = parseInt(routeParams['page'], 10)
110 } else {
111 this.pagination.currentPage = 1
112 }
113 }
114
115 protected setNewRouteParams () {
116 const routeParams = this.buildRouteParams()
117 this.router.navigate([ this.currentRoute, routeParams ])
118 }
119 }