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