diff options
Diffstat (limited to 'client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts')
-rw-r--r-- | client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts new file mode 100644 index 000000000..57a5fbe61 --- /dev/null +++ b/client/src/app/shared/shared-video-playlist/video-playlist-element-miniature.component.ts | |||
@@ -0,0 +1,182 @@ | |||
1 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' | ||
2 | import { AuthService, Notifier, ServerService } from '@app/core' | ||
3 | import { Video } from '@app/shared/shared-main' | ||
4 | import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap' | ||
5 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
6 | import { ServerConfig, VideoPlaylistElementType, VideoPlaylistElementUpdate } from '@shared/models' | ||
7 | import { secondsToTime } from '../../../assets/player/utils' | ||
8 | import { VideoPlaylistElement } from './video-playlist-element.model' | ||
9 | import { VideoPlaylist } from './video-playlist.model' | ||
10 | import { VideoPlaylistService } from './video-playlist.service' | ||
11 | |||
12 | @Component({ | ||
13 | selector: 'my-video-playlist-element-miniature', | ||
14 | styleUrls: [ './video-playlist-element-miniature.component.scss' ], | ||
15 | templateUrl: './video-playlist-element-miniature.component.html', | ||
16 | changeDetection: ChangeDetectionStrategy.OnPush | ||
17 | }) | ||
18 | export class VideoPlaylistElementMiniatureComponent implements OnInit { | ||
19 | @ViewChild('moreDropdown') moreDropdown: NgbDropdown | ||
20 | |||
21 | @Input() playlist: VideoPlaylist | ||
22 | @Input() playlistElement: VideoPlaylistElement | ||
23 | @Input() owned = false | ||
24 | @Input() playing = false | ||
25 | @Input() rowLink = false | ||
26 | @Input() accountLink = true | ||
27 | @Input() position: number // Keep this property because we're in the OnPush change detection strategy | ||
28 | @Input() touchScreenEditButton = false | ||
29 | |||
30 | @Output() elementRemoved = new EventEmitter<VideoPlaylistElement>() | ||
31 | |||
32 | displayTimestampOptions = false | ||
33 | |||
34 | timestampOptions: { | ||
35 | startTimestampEnabled: boolean | ||
36 | startTimestamp: number | ||
37 | stopTimestampEnabled: boolean | ||
38 | stopTimestamp: number | ||
39 | } = {} as any | ||
40 | |||
41 | private serverConfig: ServerConfig | ||
42 | |||
43 | constructor ( | ||
44 | private authService: AuthService, | ||
45 | private serverService: ServerService, | ||
46 | private notifier: Notifier, | ||
47 | private i18n: I18n, | ||
48 | private videoPlaylistService: VideoPlaylistService, | ||
49 | private cdr: ChangeDetectorRef | ||
50 | ) {} | ||
51 | |||
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 | |||
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 | |||
73 | buildRouterLink () { | ||
74 | if (!this.playlist) return null | ||
75 | |||
76 | return [ '/videos/watch/playlist', this.playlist.uuid ] | ||
77 | } | ||
78 | |||
79 | buildRouterQuery () { | ||
80 | if (!this.playlistElement || !this.playlistElement.video) return {} | ||
81 | |||
82 | return { | ||
83 | videoId: this.playlistElement.video.uuid, | ||
84 | start: this.playlistElement.startTimestamp, | ||
85 | stop: this.playlistElement.stopTimestamp, | ||
86 | resume: true | ||
87 | } | ||
88 | } | ||
89 | |||
90 | isVideoBlur (video: Video) { | ||
91 | return video.isVideoNSFWForUser(this.authService.getUser(), this.serverConfig) | ||
92 | } | ||
93 | |||
94 | removeFromPlaylist (playlistElement: VideoPlaylistElement) { | ||
95 | const videoId = this.playlistElement.video ? this.playlistElement.video.id : undefined | ||
96 | |||
97 | this.videoPlaylistService.removeVideoFromPlaylist(this.playlist.id, playlistElement.id, videoId) | ||
98 | .subscribe( | ||
99 | () => { | ||
100 | this.notifier.success(this.i18n('Video removed from {{name}}', { name: this.playlist.displayName })) | ||
101 | |||
102 | this.elementRemoved.emit(playlistElement) | ||
103 | }, | ||
104 | |||
105 | err => this.notifier.error(err.message) | ||
106 | ) | ||
107 | |||
108 | this.moreDropdown.close() | ||
109 | } | ||
110 | |||
111 | updateTimestamps (playlistElement: VideoPlaylistElement) { | ||
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 | |||
117 | this.videoPlaylistService.updateVideoOfPlaylist(this.playlist.id, playlistElement.id, body, this.playlistElement.video.id) | ||
118 | .subscribe( | ||
119 | () => { | ||
120 | this.notifier.success(this.i18n('Timestamps updated')) | ||
121 | |||
122 | playlistElement.startTimestamp = body.startTimestamp | ||
123 | playlistElement.stopTimestamp = body.stopTimestamp | ||
124 | |||
125 | this.cdr.detectChanges() | ||
126 | }, | ||
127 | |||
128 | err => this.notifier.error(err.message) | ||
129 | ) | ||
130 | |||
131 | this.moreDropdown.close() | ||
132 | } | ||
133 | |||
134 | formatTimestamp (playlistElement: VideoPlaylistElement) { | ||
135 | const start = playlistElement.startTimestamp | ||
136 | const stop = playlistElement.stopTimestamp | ||
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 | |||
153 | toggleDisplayTimestampsOptions (event: Event, playlistElement: VideoPlaylistElement) { | ||
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, | ||
163 | stopTimestamp: playlistElement.video.duration | ||
164 | } | ||
165 | |||
166 | if (playlistElement.startTimestamp) { | ||
167 | this.timestampOptions.startTimestampEnabled = true | ||
168 | this.timestampOptions.startTimestamp = playlistElement.startTimestamp | ||
169 | } | ||
170 | |||
171 | if (playlistElement.stopTimestamp) { | ||
172 | this.timestampOptions.stopTimestampEnabled = true | ||
173 | this.timestampOptions.stopTimestamp = playlistElement.stopTimestamp | ||
174 | } | ||
175 | } | ||
176 | |||
177 | // FIXME: why do we have to use setTimeout here? | ||
178 | setTimeout(() => { | ||
179 | this.cdr.detectChanges() | ||
180 | }) | ||
181 | } | ||
182 | } | ||