diff options
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.ts | 147 |
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 @@ | |||
1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core' | 1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core' |
2 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | 2 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' |
3 | import { AuthService, Notifier } from '@app/core' | 3 | import { AuthService, Notifier } from '@app/core' |
4 | import { forkJoin, Subject } from 'rxjs' | 4 | import { Subject, Subscription } from 'rxjs' |
5 | import { debounceTime } from 'rxjs/operators' | 5 | import { debounceTime, filter } from 'rxjs/operators' |
6 | import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' | 6 | import { Video, VideoPlaylistCreate, VideoPlaylistElementCreate, VideoPlaylistPrivacy } from '@shared/models' |
7 | import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms' | 7 | import { FormReactive, FormValidatorService, VideoPlaylistValidatorsService } from '@app/shared/forms' |
8 | import { I18n } from '@ngx-translate/i18n-polyfill' | 8 | import { I18n } from '@ngx-translate/i18n-polyfill' |
9 | import { secondsToTime } from '../../../assets/player/utils' | 9 | import { secondsToTime } from '../../../assets/player/utils' |
10 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | ||
11 | import * as debug from 'debug' | ||
12 | import { DisableForReuseHook } from '@app/core/routing/disable-for-reuse-hook' | ||
13 | import { VideoExistInPlaylist } from '@shared/models/videos/playlist/video-exist-in-playlist.model' | ||
14 | |||
15 | const logger = debug('peertube:playlists:VideoAddToPlaylistComponent') | ||
10 | 16 | ||
11 | type PlaylistSummary = { | 17 | type 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 | }) |
27 | export class VideoAddToPlaylistComponent extends FormReactive implements OnInit, OnChanges { | 33 | export 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() |