Playlist videos component
[oweals/peertube.git] / client / src / app / +my-account / my-account-video-playlists / my-account-video-playlist-elements.component.ts
1 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
2 import { Notifier, ServerService } from '@app/core'
3 import { AuthService } from '../../core/auth'
4 import { ConfirmService } from '../../core/confirm'
5 import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
6 import { Video } from '@app/shared/video/video.model'
7 import { Subscription } from 'rxjs'
8 import { ActivatedRoute } from '@angular/router'
9 import { VideoService } from '@app/shared/video/video.service'
10 import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
11 import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
12 import { I18n } from '@ngx-translate/i18n-polyfill'
13 import { secondsToTime } from '../../../assets/player/utils'
14 import { VideoPlaylistElementUpdate } from '@shared/models'
15 import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
16
17 @Component({
18   selector: 'my-account-video-playlist-elements',
19   templateUrl: './my-account-video-playlist-elements.component.html',
20   styleUrls: [ './my-account-video-playlist-elements.component.scss' ]
21 })
22 export class MyAccountVideoPlaylistElementsComponent implements OnInit, OnDestroy {
23   @ViewChild('moreDropdown') moreDropdown: NgbDropdown
24
25   videos: Video[] = []
26   playlist: VideoPlaylist
27
28   pagination: ComponentPagination = {
29     currentPage: 1,
30     itemsPerPage: 10,
31     totalItems: null
32   }
33
34   displayTimestampOptions = false
35
36   timestampOptions: {
37     startTimestampEnabled: boolean
38     startTimestamp: number
39     stopTimestampEnabled: boolean
40     stopTimestamp: number
41   } = {} as any
42
43   private videoPlaylistId: string | number
44   private paramsSub: Subscription
45
46   constructor (
47     private authService: AuthService,
48     private serverService: ServerService,
49     private notifier: Notifier,
50     private confirmService: ConfirmService,
51     private route: ActivatedRoute,
52     private i18n: I18n,
53     private videoService: VideoService,
54     private videoPlaylistService: VideoPlaylistService
55   ) {}
56
57   ngOnInit () {
58     this.paramsSub = this.route.params.subscribe(routeParams => {
59       this.videoPlaylistId = routeParams[ 'videoPlaylistId' ]
60       this.loadElements()
61
62       this.loadPlaylistInfo()
63     })
64   }
65
66   ngOnDestroy () {
67     if (this.paramsSub) this.paramsSub.unsubscribe()
68   }
69
70   isVideoBlur (video: Video) {
71     return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig())
72   }
73
74   removeFromPlaylist (video: Video) {
75     this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, video.id)
76         .subscribe(
77           () => {
78             this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName }))
79
80             this.videos = this.videos.filter(v => v.id !== video.id)
81           },
82
83           err => this.notifier.error(err.message)
84         )
85
86     this.moreDropdown.close()
87   }
88
89   updateTimestamps (video: Video) {
90     const body: VideoPlaylistElementUpdate = {}
91
92     body.startTimestamp = this.timestampOptions.startTimestampEnabled ? this.timestampOptions.startTimestamp : null
93     body.stopTimestamp = this.timestampOptions.stopTimestampEnabled ? this.timestampOptions.stopTimestamp : null
94
95     this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, video.id, body)
96         .subscribe(
97           () => {
98             this.notifier.success(this.i18n('Timestamps updated'))
99
100             video.playlistElement.startTimestamp = body.startTimestamp
101             video.playlistElement.stopTimestamp = body.stopTimestamp
102           },
103
104           err => this.notifier.error(err.message)
105         )
106
107     this.moreDropdown.close()
108   }
109
110   onNearOfBottom () {
111     // Last page
112     if (this.pagination.totalItems <= (this.pagination.currentPage * this.pagination.itemsPerPage)) return
113
114     this.pagination.currentPage += 1
115     this.loadElements()
116   }
117
118   formatTimestamp (video: Video) {
119     const start = video.playlistElement.startTimestamp
120     const stop = video.playlistElement.stopTimestamp
121
122     const startFormatted = secondsToTime(start, true, ':')
123     const stopFormatted = secondsToTime(stop, true, ':')
124
125     if (start === null && stop === null) return ''
126
127     if (start !== null && stop === null) return this.i18n('Starts at ') + startFormatted
128     if (start === null && stop !== null) return this.i18n('Stops at ') + stopFormatted
129
130     return this.i18n('Starts at ') + startFormatted + this.i18n(' and stops at ') + stopFormatted
131   }
132
133   onDropdownOpenChange () {
134     this.displayTimestampOptions = false
135   }
136
137   toggleDisplayTimestampsOptions (event: Event, video: Video) {
138     event.preventDefault()
139
140     this.displayTimestampOptions = !this.displayTimestampOptions
141
142     if (this.displayTimestampOptions === true) {
143       this.timestampOptions = {
144         startTimestampEnabled: false,
145         stopTimestampEnabled: false,
146         startTimestamp: 0,
147         stopTimestamp: video.duration
148       }
149
150       if (video.playlistElement.startTimestamp) {
151         this.timestampOptions.startTimestampEnabled = true
152         this.timestampOptions.startTimestamp = video.playlistElement.startTimestamp
153       }
154
155       if (video.playlistElement.stopTimestamp) {
156         this.timestampOptions.stopTimestampEnabled = true
157         this.timestampOptions.stopTimestamp = video.playlistElement.stopTimestamp
158       }
159     }
160   }
161
162   private loadElements () {
163     this.videoService.getPlaylistVideos(this.videoPlaylistId, this.pagination)
164         .subscribe(({ totalVideos, videos }) => {
165           this.videos = this.videos.concat(videos)
166           this.pagination.totalItems = totalVideos
167         })
168   }
169
170   private loadPlaylistInfo () {
171     this.videoPlaylistService.getVideoPlaylist(this.videoPlaylistId)
172       .subscribe(playlist => {
173         this.playlist = playlist
174       })
175   }
176 }