1 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'
2 import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
3 import { AuthService, Notifier } from '@app/core'
4 import { forkJoin, Subject } from 'rxjs'
5 import { debounceTime } from 'rxjs/operators'
6 import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models'
7 import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms'
8 import { I18n } from '@ngx-translate/i18n-polyfill'
9 import { secondsToTime } from '../../../assets/player/utils'
11 type PlaylistSummary = {
16 playlistElementId?: number
17 startTimestamp?: number
18 stopTimestamp?: number
22 selector: 'my-video-add-to-playlist',
23 styleUrls: [ './video-add-to-playlist.component.scss' ],
24 templateUrl: './video-add-to-playlist.component.html',
25 changeDetection: ChangeDetectionStrategy.OnPush
27 export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, OnChanges {
29 @Input() currentVideoTimestamp: number
30 @Input() lazyLoad = false
32 isNewPlaylistBlockOpened = false
33 videoPlaylistSearch: string
34 videoPlaylistSearchChanged = new Subject<string>()
35 videoPlaylists: PlaylistSummary[] = []
37 startTimestampEnabled: boolean
38 startTimestamp: number
39 stopTimestampEnabled: boolean
42 displayOptions = false
45 protected formValidatorService: FormValidatorService,
46 private authService: AuthService,
47 private notifier: Notifier,
49 private videoPlaylistService: VideoPlaylistService,
50 private videoPlaylistValidatorsService: VideoPlaylistValidatorsService,
51 private cd: ChangeDetectorRef
57 return this.authService.getUser()
62 displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME
65 this.videoPlaylistSearchChanged
73 ngOnChanges (simpleChanges: SimpleChanges) {
74 if (simpleChanges['video']) {
80 this.resetOptions(true)
82 if (this.lazyLoad !== true) this.load()
86 this.videoPlaylists = []
87 this.videoPlaylistSearch = undefined
91 this.cd.markForCheck()
96 this.videoPlaylistService.listAccountPlaylists(this.user.account, undefined, '-updatedAt', this.videoPlaylistSearch),
97 this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id)
100 ([ playlistsResult, existResult ]) => {
101 this.videoPlaylists = []
102 for (const playlist of playlistsResult.data) {
103 const existingPlaylist = existResult[ this.video.id ].find(p => p.playlistId === playlist.id)
105 this.videoPlaylists.push({
107 displayName: playlist.displayName,
108 inPlaylist: !!existingPlaylist,
109 playlistElementId: existingPlaylist ? existingPlaylist.playlistElementId : undefined,
110 startTimestamp: existingPlaylist ? existingPlaylist.startTimestamp : undefined,
111 stopTimestamp: existingPlaylist ? existingPlaylist.stopTimestamp : undefined
115 this.cd.markForCheck()
120 openChange (opened: boolean) {
121 if (opened === false) {
122 this.isNewPlaylistBlockOpened = false
123 this.displayOptions = false
127 openCreateBlock (event: Event) {
128 event.preventDefault()
130 this.isNewPlaylistBlockOpened = true
133 togglePlaylist (event: Event, playlist: PlaylistSummary) {
134 event.preventDefault()
136 if (playlist.inPlaylist === true) {
137 this.removeVideoFromPlaylist(playlist)
139 this.addVideoInPlaylist(playlist)
142 playlist.inPlaylist = !playlist.inPlaylist
145 this.cd.markForCheck()
149 const displayName = this.form.value[ 'displayName' ]
151 const videoPlaylistCreate: VideoPlaylistCreate = {
153 privacy: VideoPlaylistPrivacy.PRIVATE
156 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe(
158 this.videoPlaylists.push({
159 id: res.videoPlaylist.id,
164 this.isNewPlaylistBlockOpened = false
166 this.cd.markForCheck()
169 err => this.notifier.error(err.message)
173 resetOptions (resetTimestamp = false) {
174 this.displayOptions = false
176 this.timestampOptions = {} as any
177 this.timestampOptions.startTimestampEnabled = false
178 this.timestampOptions.stopTimestampEnabled = false
180 if (resetTimestamp) {
181 this.timestampOptions.startTimestamp = 0
182 this.timestampOptions.stopTimestamp = this.video.duration
186 formatTimestamp (playlist: PlaylistSummary) {
187 const start = playlist.startTimestamp ? secondsToTime(playlist.startTimestamp) : ''
188 const stop = playlist.stopTimestamp ? secondsToTime(playlist.stopTimestamp) : ''
190 return `(${start}-${stop})`
193 onVideoPlaylistSearchChanged () {
194 this.videoPlaylistSearchChanged.next()
197 private removeVideoFromPlaylist (playlist: PlaylistSummary) {
198 if (!playlist.playlistElementId) return
200 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, playlist.playlistElementId)
203 this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName }))
205 playlist.inPlaylist = false
206 playlist.playlistElementId = undefined
210 this.notifier.error(err.message)
212 playlist.inPlaylist = true
215 () => this.cd.markForCheck()
219 private addVideoInPlaylist (playlist: PlaylistSummary) {
220 const body: VideoPlaylistElementCreate = { videoId: this.video.id }
222 if (this.timestampOptions.startTimestampEnabled) body.startTimestamp = this.timestampOptions.startTimestamp
223 if (this.timestampOptions.stopTimestampEnabled) body.stopTimestamp = this.timestampOptions.stopTimestamp
225 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
228 playlist.inPlaylist = true
229 playlist.playlistElementId = res.videoPlaylistElement.id
231 playlist.startTimestamp = body.startTimestamp
232 playlist.stopTimestamp = body.stopTimestamp
234 const message = body.startTimestamp || body.stopTimestamp
235 ? this.i18n('Video added in {{n}} at timestamps {{t}}', { n: playlist.displayName, t: this.formatTimestamp(playlist) })
236 : this.i18n('Video added in {{n}}', { n: playlist.displayName })
238 this.notifier.success(message)
242 this.notifier.error(err.message)
244 playlist.inPlaylist = false
247 () => this.cd.markForCheck()