]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/video/abstract-video-list.ts
Update CONTRIBUTING.md
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / video / abstract-video-list.ts
CommitLineData
db400f44 1import { debounceTime } from 'rxjs/operators'
489290b8 2import { OnDestroy, OnInit } from '@angular/core'
fd45e8f4 3import { ActivatedRoute, Router } from '@angular/router'
db400f44 4import { fromEvent, Observable, Subscription } from 'rxjs'
b2731bff 5import { AuthService } from '../../core/auth'
4635f59d 6import { ComponentPagination } from '../rest/component-pagination.model'
7b87d2d5 7import { VideoSortField } from './sort-field.type'
202f6b6c 8import { Video } from './video.model'
bbe0f064 9import { ScreenService } from '@app/shared/misc/screen.service'
22a16e36 10import { OwnerDisplayType } from '@app/shared/video/video-miniature.component'
c199c427 11import { Syndication } from '@app/shared/video/syndication.model'
489290b8
C
12import { Notifier, ServerService } from '@app/core'
13import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
0cd4344f 14
489290b8 15export abstract class AbstractVideoList implements OnInit, OnDestroy, DisableForReuseHook {
4635f59d 16 pagination: ComponentPagination = {
fd45e8f4 17 currentPage: 1,
489290b8 18 itemsPerPage: 25,
fd45e8f4
C
19 totalItems: null
20 }
136cce4d 21 sort: VideoSortField = '-publishedAt'
489290b8 22
d59cba29 23 categoryOneOf?: number
136cce4d 24 defaultSort: VideoSortField = '-publishedAt'
489290b8 25
c199c427 26 syndicationItems: Syndication[] = []
244e76a5 27
f3aaa9a9 28 loadOnInit = true
0626e7af 29 marginContent = true
489290b8 30 videos: Video[] = []
22a16e36 31 ownerDisplayType: OwnerDisplayType = 'account'
017c3dca 32 displayModerationBlock = false
9b4b15f9 33 titleTooltip: string
fd45e8f4 34
489290b8 35 disabled = false
9af61e84 36
f8b2c1b4 37 protected abstract notifier: Notifier
b2731bff 38 protected abstract authService: AuthService
b2731bff 39 protected abstract route: ActivatedRoute
489290b8 40 protected abstract serverService: ServerService
bbe0f064 41 protected abstract screenService: ScreenService
489290b8 42 protected abstract router: Router
9bf9d2a5 43 abstract titlePage: string
c88593f7 44
9af61e84 45 private resizeSubscription: Subscription
489290b8
C
46 private angularState: number
47
48 abstract getVideosObservable (page: number): Observable<{ videos: Video[], totalVideos: number }>
9af61e84 49
c199c427 50 abstract generateSyndicationList (): void
fd45e8f4 51
b2731bff
C
52 get user () {
53 return this.authService.getUser()
54 }
55
fd45e8f4
C
56 ngOnInit () {
57 // Subscribe to route changes
5b5e333f 58 const routeParams = this.route.snapshot.queryParams
2bbb3412 59 this.loadRouteParams(routeParams)
a2b817d3 60
9af61e84 61 this.resizeSubscription = fromEvent(window, 'resize')
db400f44 62 .pipe(debounceTime(500))
6194c1b4 63 .subscribe(() => this.calcPageSizes())
3290f37c 64
6194c1b4 65 this.calcPageSizes()
489290b8 66 if (this.loadOnInit === true) this.loadMoreVideos()
fd45e8f4
C
67 }
68
9af61e84
C
69 ngOnDestroy () {
70 if (this.resizeSubscription) this.resizeSubscription.unsubscribe()
71 }
72
489290b8
C
73 disableForReuse () {
74 this.disabled = true
89724816
C
75 }
76
489290b8
C
77 enabledForReuse () {
78 this.disabled = false
89724816
C
79 }
80
489290b8
C
81 videoById (index: number, video: Video) {
82 return video.id
2bbb3412
C
83 }
84
85 onNearOfBottom () {
489290b8 86 if (this.disabled) return
2bbb3412 87
489290b8
C
88 // Last page
89 if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
0cd4344f 90
489290b8 91 this.pagination.currentPage += 1
a8ecc6f6 92
489290b8 93 this.setScrollRouteParams()
a8ecc6f6 94
489290b8
C
95 this.loadMoreVideos()
96 }
fd45e8f4 97
489290b8
C
98 loadMoreVideos () {
99 const observable = this.getVideosObservable(this.pagination.currentPage)
fd45e8f4
C
100
101 observable.subscribe(
102 ({ videos, totalVideos }) => {
fd45e8f4 103 this.pagination.totalItems = totalVideos
489290b8 104 this.videos = this.videos.concat(videos)
fd45e8f4 105 },
017c3dca 106
489290b8
C
107 error => this.notifier.error(error.message)
108 )
2bbb3412
C
109 }
110
489290b8
C
111 reloadVideos () {
112 this.pagination.currentPage = 1
113 this.videos = []
114 this.loadMoreVideos()
fd45e8f4
C
115 }
116
489290b8
C
117 toggleModerationDisplay () {
118 throw new Error('toggleModerationDisplay is not implemented')
fd45e8f4
C
119 }
120
121 protected loadRouteParams (routeParams: { [ key: string ]: any }) {
489290b8
C
122 this.sort = routeParams[ 'sort' ] as VideoSortField || this.defaultSort
123 this.categoryOneOf = routeParams[ 'categoryOneOf' ]
124 this.angularState = routeParams[ 'a-state' ]
0cd4344f 125 }
6194c1b4
C
126
127 private calcPageSizes () {
489290b8 128 if (this.screenService.isInMobileView()) {
6194c1b4 129 this.pagination.itemsPerPage = 5
6194c1b4 130 }
489290b8 131 }
6194c1b4 132
489290b8
C
133 private setScrollRouteParams () {
134 // Already set
135 if (this.angularState) return
6194c1b4 136
489290b8 137 this.angularState = 42
6194c1b4 138
489290b8
C
139 const queryParams = {
140 'a-state': this.angularState,
141 categoryOneOf: this.categoryOneOf
9af61e84 142 }
6194c1b4 143
489290b8
C
144 let path = this.router.url
145 if (!path || path === '/') path = this.serverService.getConfig().instance.defaultClientRoute
146
147 this.router.navigate([ path ], { queryParams, replaceUrl: true, queryParamsHandling: 'merge' })
6194c1b4 148 }
fd45e8f4 149}