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