aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/video-playlist/video-add-to-playlist.component.ts')
-rw-r--r--client/src/app/shared/video-playlist/video-add-to-playlist.component.ts147
1 files changed, 89 insertions, 58 deletions
diff --git a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
index 25ba8cbca..e60a8381d 100644
--- a/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
+++ b/client/src/app/shared/video-playlist/video-add-to-playlist.component.ts
@@ -1,12 +1,18 @@
1import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core' 1import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'
2import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' 2import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
3import { AuthService, Notifier } from '@app/core' 3import { AuthService, Notifier } from '@app/core'
4import { forkJoin, Subject } from 'rxjs' 4import { Subject, Subscription } from 'rxjs'
5import { debounceTime } from 'rxjs/operators' 5import { debounceTime, filter } from 'rxjs/operators'
6import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' 6import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models'
7import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms' 7import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms'
8import { I18n } from '@ngx-translate/i18n-polyfill' 8import { I18n } from '@ngx-translate/i18n-polyfill'
9import { secondsToTime } from '../../../assets/player/utils' 9import { secondsToTime } from '../../../assets/player/utils'
10import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
11import * as debug from 'debug'
12import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook'
13import { VideoExistInPlaylist } from '@shared/models/videos/playlist/video-exist-in-playlist.model'
14
15const logger = debug('peertube:playlists:VideoAddToPlaylistComponent')
10 16
11type PlaylistSummary = { 17type PlaylistSummary = {
12 id: number 18 id: number
@@ -24,7 +30,7 @@ type PlaylistSummary = {
24 templateUrl: './video-add-to-playlist.component.html', 30 templateUrl: './video-add-to-playlist.component.html',
25 changeDetection: ChangeDetectionStrategy.OnPush 31 changeDetection: ChangeDetectionStrategy.OnPush
26}) 32})
27export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, OnChanges { 33export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, OnChanges, OnDestroy, DisableForReuseHook {
28 @Input() video: Video 34 @Input() video: Video
29 @Input() currentVideoTimestamp: number 35 @Input() currentVideoTimestamp: number
30 @Input() lazyLoad = false 36 @Input() lazyLoad = false
@@ -41,6 +47,11 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
41 } 47 }
42 displayOptions = false 48 displayOptions = false
43 49
50 private disabled = false
51
52 private listenToPlaylistChangeSub: Subscription
53 private playlistsData: VideoPlaylist[] = []
54
44 constructor ( 55 constructor (
45 protected formValidatorService: FormValidatorService, 56 protected formValidatorService: FormValidatorService,
46 private authService: AuthService, 57 private authService: AuthService,
@@ -62,12 +73,18 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
62 displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME 73 displayName: this.videoPlaylistValidatorsService.VIDEO_PLAYLIST_DISPLAY_NAME
63 }) 74 })
64 75
76 this.videoPlaylistService.listenToMyAccountPlaylistsChange()
77 .subscribe(result => {
78 this.playlistsData = result.data
79
80 this.videoPlaylistService.runPlaylistCheck(this.video.id)
81 })
82
65 this.videoPlaylistSearchChanged 83 this.videoPlaylistSearchChanged
66 .pipe( 84 .pipe(debounceTime(500))
67 debounceTime(500)) 85 .subscribe(() => this.load())
68 .subscribe(() => { 86
69 this.load() 87 if (this.lazyLoad === false) this.load()
70 })
71 } 88 }
72 89
73 ngOnChanges (simpleChanges: SimpleChanges) { 90 ngOnChanges (simpleChanges: SimpleChanges) {
@@ -76,45 +93,41 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
76 } 93 }
77 } 94 }
78 95
79 init () { 96 ngOnDestroy () {
80 this.resetOptions(true) 97 this.unsubscribePlaylistChanges()
98 }
81 99
82 if (this.lazyLoad !== true) this.load() 100 disableForReuse () {
101 this.disabled = true
102 }
103
104 enabledForReuse () {
105 this.disabled = false
83 } 106 }
84 107
85 reload () { 108 reload () {
109 logger('Reloading component')
110
86 this.videoPlaylists = [] 111 this.videoPlaylists = []
87 this.videoPlaylistSearch = undefined 112 this.videoPlaylistSearch = undefined
88 113
89 this.init() 114 this.resetOptions(true)
115 this.load()
90 116
91 this.cd.markForCheck() 117 this.cd.markForCheck()
92 } 118 }
93 119
94 load () { 120 load () {
95 forkJoin([ 121 logger('Loading component')
96 this.videoPlaylistService.listAccountPlaylists(this.user.account, undefined, '-updatedAt', this.videoPlaylistSearch), 122
97 this.videoPlaylistService.doesVideoExistInPlaylist(this.video.id) 123 this.listenToPlaylistChanges()
98 ]) 124
99 .subscribe( 125 this.videoPlaylistService.listMyPlaylistWithCache(this.user, this.videoPlaylistSearch)
100 ([ playlistsResult, existResult ]) => { 126 .subscribe(playlistsResult => {
101 this.videoPlaylists = [] 127 this.playlistsData = playlistsResult.data
102 for (const playlist of playlistsResult.data) { 128
103 const existingPlaylist = existResult[ this.video.id ].find(p => p.playlistId === playlist.id) 129 this.videoPlaylistService.runPlaylistCheck(this.video.id)
104 130 })
105 this.videoPlaylists.push({
106 id: playlist.id,
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
112 })
113 }
114
115 this.cd.markForCheck()
116 }
117 )
118 } 131 }
119 132
120 openChange (opened: boolean) { 133 openChange (opened: boolean) {
@@ -154,13 +167,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
154 } 167 }
155 168
156 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe( 169 this.videoPlaylistService.createVideoPlaylist(videoPlaylistCreate).subscribe(
157 res => { 170 () => {
158 this.videoPlaylists.push({
159 id: res.videoPlaylist.id,
160 displayName,
161 inPlaylist: false
162 })
163
164 this.isNewPlaylistBlockOpened = false 171 this.isNewPlaylistBlockOpened = false
165 172
166 this.cd.markForCheck() 173 this.cd.markForCheck()
@@ -197,25 +204,57 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
197 private removeVideoFromPlaylist (playlist: PlaylistSummary) { 204 private removeVideoFromPlaylist (playlist: PlaylistSummary) {
198 if (!playlist.playlistElementId) return 205 if (!playlist.playlistElementId) return
199 206
200 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, playlist.playlistElementId) 207 this.videoPlaylistService.removeVideoFromPlaylist(playlist.id, playlist.playlistElementId, this.video.id)
201 .subscribe( 208 .subscribe(
202 () => { 209 () => {
203 this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName })) 210 this.notifier.success(this.i18n('Video removed from {{name}}', { name: playlist.displayName }))
204
205 playlist.inPlaylist = false
206 playlist.playlistElementId = undefined
207 }, 211 },
208 212
209 err => { 213 err => {
210 this.notifier.error(err.message) 214 this.notifier.error(err.message)
211
212 playlist.inPlaylist = true
213 }, 215 },
214 216
215 () => this.cd.markForCheck() 217 () => this.cd.markForCheck()
216 ) 218 )
217 } 219 }
218 220
221 private listenToPlaylistChanges () {
222 this.unsubscribePlaylistChanges()
223
224 this.listenToPlaylistChangeSub = this.videoPlaylistService.listenToVideoPlaylistChange(this.video.id)
225 .pipe(filter(() => this.disabled === false))
226 .subscribe(existResult => this.rebuildPlaylists(existResult))
227 }
228
229 private unsubscribePlaylistChanges () {
230 if (this.listenToPlaylistChangeSub) {
231 this.listenToPlaylistChangeSub.unsubscribe()
232 this.listenToPlaylistChangeSub = undefined
233 }
234 }
235
236 private rebuildPlaylists (existResult: VideoExistInPlaylist[]) {
237 logger('Got existing results for %d.', this.video.id, existResult)
238
239 this.videoPlaylists = []
240 for (const playlist of this.playlistsData) {
241 const existingPlaylist = existResult.find(p => p.playlistId === playlist.id)
242
243 this.videoPlaylists.push({
244 id: playlist.id,
245 displayName: playlist.displayName,
246 inPlaylist: !!existingPlaylist,
247 playlistElementId: existingPlaylist ? existingPlaylist.playlistElementId : undefined,
248 startTimestamp: existingPlaylist ? existingPlaylist.startTimestamp : undefined,
249 stopTimestamp: existingPlaylist ? existingPlaylist.stopTimestamp : undefined
250 })
251 }
252
253 logger('Rebuilt playlist state for video %d.', this.video.id, this.videoPlaylists)
254
255 this.cd.markForCheck()
256 }
257
219 private addVideoInPlaylist (playlist: PlaylistSummary) { 258 private addVideoInPlaylist (playlist: PlaylistSummary) {
220 const body: VideoPlaylistElementCreate = { videoId: this.video.id } 259 const body: VideoPlaylistElementCreate = { videoId: this.video.id }
221 260
@@ -224,13 +263,7 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
224 263
225 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body) 264 this.videoPlaylistService.addVideoInPlaylist(playlist.id, body)
226 .subscribe( 265 .subscribe(
227 res => { 266 () => {
228 playlist.inPlaylist = true
229 playlist.playlistElementId = res.videoPlaylistElement.id
230
231 playlist.startTimestamp = body.startTimestamp
232 playlist.stopTimestamp = body.stopTimestamp
233
234 const message = body.startTimestamp || body.stopTimestamp 267 const message = body.startTimestamp || body.stopTimestamp
235 ? this.i18n('Video added in {{n}} at timestamps {{t}}', { n: playlist.displayName, t: this.formatTimestamp(playlist) }) 268 ? 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 }) 269 : this.i18n('Video added in {{n}}', { n: playlist.displayName })
@@ -240,8 +273,6 @@ export class VideoAddToPlaylistComponent extends FormReactive implements OnInit,
240 273
241 err => { 274 err => {
242 this.notifier.error(err.message) 275 this.notifier.error(err.message)
243
244 playlist.inPlaylist = false
245 }, 276 },
246 277
247 () => this.cd.markForCheck() 278 () => this.cd.markForCheck()