]>
Commit | Line | Data |
---|---|---|
3143ae17 | 1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core' |
e2f01c47 | 2 | import { Video } from '@app/shared/video/video.model' |
bfbd9128 | 3 | import { VideoPlaylistElementType, VideoPlaylistElementUpdate } from '@shared/models' |
e2f01c47 C |
4 | import { AuthService, ConfirmService, Notifier, ServerService } from '@app/core' |
5 | import { ActivatedRoute } from '@angular/router' | |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | |
7 | import { VideoService } from '@app/shared/video/video.service' | |
8 | import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' | |
9 | import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' | |
10 | import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model' | |
11 | import { secondsToTime } from '../../../assets/player/utils' | |
bfbd9128 | 12 | import { VideoPlaylistElement } from '@app/shared/video-playlist/video-playlist-element.model' |
e2f01c47 C |
13 | |
14 | @Component({ | |
15 | selector: 'my-video-playlist-element-miniature', | |
16 | styleUrls: [ './video-playlist-element-miniature.component.scss' ], | |
bce47964 C |
17 | templateUrl: './video-playlist-element-miniature.component.html', |
18 | changeDetection: ChangeDetectionStrategy.OnPush | |
e2f01c47 C |
19 | }) |
20 | export class VideoPlaylistElementMiniatureComponent { | |
f36da21e | 21 | @ViewChild('moreDropdown', { static: false }) moreDropdown: NgbDropdown |
e2f01c47 C |
22 | |
23 | @Input() playlist: VideoPlaylist | |
bfbd9128 | 24 | @Input() playlistElement: VideoPlaylistElement |
e2f01c47 C |
25 | @Input() owned = false |
26 | @Input() playing = false | |
27 | @Input() rowLink = false | |
28 | @Input() accountLink = true | |
bfbd9128 | 29 | @Input() position: number // Keep this property because we're in the OnPush change detection strategy |
e2f01c47 | 30 | |
bfbd9128 | 31 | @Output() elementRemoved = new EventEmitter<VideoPlaylistElement>() |
e2f01c47 C |
32 | |
33 | displayTimestampOptions = false | |
34 | ||
35 | timestampOptions: { | |
36 | startTimestampEnabled: boolean | |
37 | startTimestamp: number | |
38 | stopTimestampEnabled: boolean | |
39 | stopTimestamp: number | |
40 | } = {} as any | |
41 | ||
42 | constructor ( | |
43 | private authService: AuthService, | |
44 | private serverService: ServerService, | |
45 | private notifier: Notifier, | |
46 | private confirmService: ConfirmService, | |
47 | private route: ActivatedRoute, | |
48 | private i18n: I18n, | |
49 | private videoService: VideoService, | |
bce47964 C |
50 | private videoPlaylistService: VideoPlaylistService, |
51 | private cdr: ChangeDetectorRef | |
e2f01c47 C |
52 | ) {} |
53 | ||
bfbd9128 C |
54 | isUnavailable (e: VideoPlaylistElement) { |
55 | return e.type === VideoPlaylistElementType.UNAVAILABLE | |
56 | } | |
57 | ||
58 | isPrivate (e: VideoPlaylistElement) { | |
59 | return e.type === VideoPlaylistElementType.PRIVATE | |
60 | } | |
61 | ||
62 | isDeleted (e: VideoPlaylistElement) { | |
63 | return e.type === VideoPlaylistElementType.DELETED | |
64 | } | |
65 | ||
e2f01c47 C |
66 | buildRouterLink () { |
67 | if (!this.playlist) return null | |
68 | ||
69 | return [ '/videos/watch/playlist', this.playlist.uuid ] | |
70 | } | |
71 | ||
72 | buildRouterQuery () { | |
bfbd9128 | 73 | if (!this.playlistElement || !this.playlistElement.video) return {} |
e2f01c47 C |
74 | |
75 | return { | |
bfbd9128 C |
76 | videoId: this.playlistElement.video.uuid, |
77 | start: this.playlistElement.startTimestamp, | |
78 | stop: this.playlistElement.stopTimestamp | |
e2f01c47 C |
79 | } |
80 | } | |
81 | ||
82 | isVideoBlur (video: Video) { | |
83 | return video.isVideoNSFWForUser(this.authService.getUser(), this.serverService.getConfig()) | |
84 | } | |
85 | ||
bfbd9128 C |
86 | removeFromPlaylist (playlistElement: VideoPlaylistElement) { |
87 | this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id) | |
e2f01c47 C |
88 | .subscribe( |
89 | () => { | |
90 | this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName })) | |
91 | ||
bfbd9128 | 92 | this.elementRemoved.emit(playlistElement) |
e2f01c47 C |
93 | }, |
94 | ||
95 | err => this.notifier.error(err.message) | |
96 | ) | |
97 | ||
98 | this.moreDropdown.close() | |
99 | } | |
100 | ||
bfbd9128 | 101 | updateTimestamps (playlistElement: VideoPlaylistElement) { |
e2f01c47 C |
102 | const body: VideoPlaylistElementUpdate = {} |
103 | ||
104 | body.startTimestamp = this.timestampOptions.startTimestampEnabled ? this.timestampOptions.startTimestamp : null | |
105 | body.stopTimestamp = this.timestampOptions.stopTimestampEnabled ? this.timestampOptions.stopTimestamp : null | |
106 | ||
bfbd9128 | 107 | this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body) |
e2f01c47 C |
108 | .subscribe( |
109 | () => { | |
110 | this.notifier.success(this.i18n('Timestamps updated')) | |
111 | ||
bfbd9128 C |
112 | playlistElement.startTimestamp = body.startTimestamp |
113 | playlistElement.stopTimestamp = body.stopTimestamp | |
bce47964 C |
114 | |
115 | this.cdr.detectChanges() | |
e2f01c47 C |
116 | }, |
117 | ||
118 | err => this.notifier.error(err.message) | |
119 | ) | |
120 | ||
121 | this.moreDropdown.close() | |
122 | } | |
123 | ||
bfbd9128 C |
124 | formatTimestamp (playlistElement: VideoPlaylistElement) { |
125 | const start = playlistElement.startTimestamp | |
126 | const stop = playlistElement.stopTimestamp | |
e2f01c47 C |
127 | |
128 | const startFormatted = secondsToTime(start, true, ':') | |
129 | const stopFormatted = secondsToTime(stop, true, ':') | |
130 | ||
131 | if (start === null && stop === null) return '' | |
132 | ||
133 | if (start !== null && stop === null) return this.i18n('Starts at ') + startFormatted | |
134 | if (start === null && stop !== null) return this.i18n('Stops at ') + stopFormatted | |
135 | ||
136 | return this.i18n('Starts at ') + startFormatted + this.i18n(' and stops at ') + stopFormatted | |
137 | } | |
138 | ||
139 | onDropdownOpenChange () { | |
140 | this.displayTimestampOptions = false | |
141 | } | |
142 | ||
bfbd9128 | 143 | toggleDisplayTimestampsOptions (event: Event, playlistElement: VideoPlaylistElement) { |
e2f01c47 C |
144 | event.preventDefault() |
145 | ||
146 | this.displayTimestampOptions = !this.displayTimestampOptions | |
147 | ||
148 | if (this.displayTimestampOptions === true) { | |
149 | this.timestampOptions = { | |
150 | startTimestampEnabled: false, | |
151 | stopTimestampEnabled: false, | |
152 | startTimestamp: 0, | |
bfbd9128 | 153 | stopTimestamp: playlistElement.video.duration |
e2f01c47 C |
154 | } |
155 | ||
bfbd9128 | 156 | if (playlistElement.startTimestamp) { |
e2f01c47 | 157 | this.timestampOptions.startTimestampEnabled = true |
bfbd9128 | 158 | this.timestampOptions.startTimestamp = playlistElement.startTimestamp |
e2f01c47 C |
159 | } |
160 | ||
bfbd9128 | 161 | if (playlistElement.stopTimestamp) { |
e2f01c47 | 162 | this.timestampOptions.stopTimestampEnabled = true |
bfbd9128 | 163 | this.timestampOptions.stopTimestamp = playlistElement.stopTimestamp |
e2f01c47 C |
164 | } |
165 | } | |
bce47964 C |
166 | |
167 | // FIXME: why do we have to use setTimeout here? | |
168 | setTimeout(() => { | |
169 | this.cdr.detectChanges() | |
170 | }) | |
e2f01c47 C |
171 | } |
172 | } |