]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
Fix component reuse on channel/account videos
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / video-playlist / video-add-to-playlist.component.ts
1 import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'
2 import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
3 import { AuthService, Notifier } from '@app/core'
4 import { forkJoin } from 'rxjs'
5 import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models'
6 import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms'
7 import { I18n } from '@ngx-translate/i18n-polyfill'
8 import { secondsToTime } from '../../../assets/player/utils'
9
10 type PlaylistSummary = {
11 id: number
12 inPlaylist: boolean
13 displayName: string
14
15 startTimestamp?: number
16 stopTimestamp?: number
17 }
18
19 @Component({
20 selector: 'my-video-add-to-playlist',
21 styleUrls: [ './video-add-to-playlist.component.scss' ],
22 templateUrl: './video-add-to-playlist.component.html',
23 changeDetection: ChangeDetectionStrategy.OnPush
24 })
25 export class VideoAddToPlaylistComponent extends FormReactive implements OnInit {
26 @Input() video: Video
27 @Input() currentVideoTimestamp: number
28 @Input() lazyLoad = false
29
30 isNewPlaylistBlockOpened = false
31 videoPlaylists: PlaylistSummary[] = []
32 timestampOptions: {
33 startTimestampEnabled: boolean
34 startTimestamp: number
35 stopTimestampEnabled: boolean
36 stopTimestamp: number
37 }
38 displayOptions = false
39
40 constructor (
41 protected formValidatorService: FormValidatorService,
42 private authService: AuthService,
43 private notifier: Notifier,
44 private i18n: I18n,
45 private videoPlaylistService: VideoPlaylistService,
46 private videoPlaylistValidatorsService: VideoPlaylistValidatorsService,
47 private cd: ChangeDetectorRef
48 ) {
49 super()
50 }
51
52 get user () {
53 return this.authService.getUser()
54 }
55
56 ngOnInit () {
57 this.resetOptions(true)
58
59 this.buildForm({
60 displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME
61 })
62
63 if (this.lazyLoad !== true) this.load()
64 }
65
66 load () {
67 forkJoin([
68 this.videoPlaylistService.listAccountPlaylists(this.user.account, '-updatedAt'),
69 this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id)
70 ])
71 .subscribe(
72 ([ playlistsResult, existResult ]) => {
73 for (const playlist of playlistsResult.data) {
74 const existingPlaylist = existResult[ this.video.id ].find(p => p.playlistId === playlist.id)
75
76 this.videoPlaylists.push({
77 id: playlist.id,
78 displayName: playlist.displayName,
79 inPlaylist: !!existingPlaylist,
80 startTimestamp: existingPlaylist ? existingPlaylist.startTimestamp : undefined,
81 stopTimestamp: existingPlaylist ? existingPlaylist.stopTimestamp : undefined
82 })
83 }
84
85 this.cd.markForCheck()
86 }
87 )
88 }
89
90 openChange (opened: boolean) {
91 if (opened === false) {
92 this.isNewPlaylistBlockOpened = false
93 this.displayOptions = false
94 }
95 }
96
97 openCreateBlock (event: Event) {
98 event.preventDefault()
99
100 this.isNewPlaylistBlockOpened = true
101 }
102
103 togglePlaylist (event: Event, playlist: PlaylistSummary) {
104 event.preventDefault()
105
106 if (playlist.inPlaylist === true) {
107 this.removeVideoFromPlaylist(playlist)
108 } else {
109 this.addVideoInPlaylist(playlist)
110 }
111
112 playlist.inPlaylist = !playlist.inPlaylist
113 this.resetOptions()
114
115 this.cd.markForCheck()
116 }
117
118 createPlaylist () {
119 const displayName = this.form.value[ 'displayName' ]
120
121 const videoPlaylistCreate: VideoPlaylistCreate = {
122 displayName,
123 privacy: VideoPlaylistPrivacy.PRIVATE
124 }
125
126 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe(
127 res => {
128 this.videoPlaylists.push({
129 id: res.videoPlaylist.id,
130 displayName,
131 inPlaylist: false
132 })
133
134 this.isNewPlaylistBlockOpened = false
135
136 this.cd.markForCheck()
137 },
138
139 err => this.notifier.error(err.message)
140 )
141 }
142
143 resetOptions (resetTimestamp = false) {
144 this.displayOptions = false
145
146 this.timestampOptions = {} as any
147 this.timestampOptions.startTimestampEnabled = false
148 this.timestampOptions.stopTimestampEnabled = false
149
150 if (resetTimestamp) {
151 this.timestampOptions.startTimestamp = 0
152 this.timestampOptions.stopTimestamp = this.video.duration
153 }
154 }
155
156 formatTimestamp (playlist: PlaylistSummary) {
157 const start = playlist.startTimestamp ? secondsToTime(playlist.startTimestamp) : ''
158 const stop = playlist.stopTimestamp ? secondsToTime(playlist.stopTimestamp) : ''
159
160 return `(${start}-${stop})`
161 }
162
163 private removeVideoFromPlaylist (playlist: PlaylistSummary) {
164 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, this.video.id)
165 .subscribe(
166 () => {
167 this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName }))
168
169 playlist.inPlaylist = false
170 },
171
172 err => {
173 this.notifier.error(err.message)
174
175 playlist.inPlaylist = true
176 },
177
178 () => this.cd.markForCheck()
179 )
180 }
181
182 private addVideoInPlaylist (playlist: PlaylistSummary) {
183 const body: VideoPlaylistElementCreate = { videoId: this.video.id }
184
185 if (this.timestampOptions.startTimestampEnabled) body.startTimestamp = this.timestampOptions.startTimestamp
186 if (this.timestampOptions.stopTimestampEnabled) body.stopTimestamp = this.timestampOptions.stopTimestamp
187
188 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
189 .subscribe(
190 () => {
191 playlist.inPlaylist = true
192
193 playlist.startTimestamp = body.startTimestamp
194 playlist.stopTimestamp = body.stopTimestamp
195
196 const message = body.startTimestamp || body.stopTimestamp
197 ? this.i18n('Video added in {{n}} at timestamps {{t}}', { n: playlist.displayName, t: this.formatTimestamp(playlist) })
198 : this.i18n('Video added in {{n}}', { n: playlist.displayName })
199
200 this.notifier.success(message)
201 },
202
203 err => {
204 this.notifier.error(err.message)
205
206 playlist.inPlaylist = false
207 },
208
209 () => this.cd.markForCheck()
210 )
211 }
212 }