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