diff options
author | Chocobozzz <me@florianbigard.com> | 2020-06-23 14:10:17 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-06-23 16:00:49 +0200 |
commit | 67ed6552b831df66713bac9e672738796128d33f (patch) | |
tree | 59c97d41e0b49d75a90aa3de987968ab9b1ff447 /client/src/app/shared/shared-video-miniature/video-miniature.component.ts | |
parent | 0c4bacbff53bc732f5a2677d62a6ead7752e2405 (diff) | |
download | PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.gz PeerTube-67ed6552b831df66713bac9e672738796128d33f.tar.zst PeerTube-67ed6552b831df66713bac9e672738796128d33f.zip |
Reorganize client shared modules
Diffstat (limited to 'client/src/app/shared/shared-video-miniature/video-miniature.component.ts')
-rw-r--r-- | client/src/app/shared/shared-video-miniature/video-miniature.component.ts | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.ts b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts new file mode 100644 index 000000000..6f32977b3 --- /dev/null +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.ts | |||
@@ -0,0 +1,283 @@ | |||
1 | import { switchMap } from 'rxjs/operators' | ||
2 | import { | ||
3 | ChangeDetectionStrategy, | ||
4 | ChangeDetectorRef, | ||
5 | Component, | ||
6 | EventEmitter, | ||
7 | Inject, | ||
8 | Input, | ||
9 | LOCALE_ID, | ||
10 | OnInit, | ||
11 | Output | ||
12 | } from '@angular/core' | ||
13 | import { AuthService, ScreenService, ServerService, User } from '@app/core' | ||
14 | import { I18n } from '@ngx-translate/i18n-polyfill' | ||
15 | import { ServerConfig, VideoPlaylistType, VideoPrivacy, VideoState } from '../../../../../shared' | ||
16 | import { Video } from '../shared-main' | ||
17 | import { VideoPlaylistService } from '../shared-video-playlist' | ||
18 | import { VideoActionsDisplayType } from './video-actions-dropdown.component' | ||
19 | |||
20 | export type OwnerDisplayType = 'account' | 'videoChannel' | 'auto' | ||
21 | export type MiniatureDisplayOptions = { | ||
22 | date?: boolean | ||
23 | views?: boolean | ||
24 | by?: boolean | ||
25 | avatar?: boolean | ||
26 | privacyLabel?: boolean | ||
27 | privacyText?: boolean | ||
28 | state?: boolean | ||
29 | blacklistInfo?: boolean | ||
30 | nsfw?: boolean | ||
31 | } | ||
32 | |||
33 | @Component({ | ||
34 | selector: 'my-video-miniature', | ||
35 | styleUrls: [ './video-miniature.component.scss' ], | ||
36 | templateUrl: './video-miniature.component.html', | ||
37 | changeDetection: ChangeDetectionStrategy.OnPush | ||
38 | }) | ||
39 | export class VideoMiniatureComponent implements OnInit { | ||
40 | @Input() user: User | ||
41 | @Input() video: Video | ||
42 | |||
43 | @Input() ownerDisplayType: OwnerDisplayType = 'account' | ||
44 | @Input() displayOptions: MiniatureDisplayOptions = { | ||
45 | date: true, | ||
46 | views: true, | ||
47 | by: true, | ||
48 | avatar: false, | ||
49 | privacyLabel: false, | ||
50 | privacyText: false, | ||
51 | state: false, | ||
52 | blacklistInfo: false | ||
53 | } | ||
54 | @Input() displayAsRow = false | ||
55 | @Input() displayVideoActions = true | ||
56 | @Input() fitWidth = false | ||
57 | |||
58 | @Input() useLazyLoadUrl = false | ||
59 | |||
60 | @Output() videoBlocked = new EventEmitter() | ||
61 | @Output() videoUnblocked = new EventEmitter() | ||
62 | @Output() videoRemoved = new EventEmitter() | ||
63 | |||
64 | videoActionsDisplayOptions: VideoActionsDisplayType = { | ||
65 | playlist: true, | ||
66 | download: false, | ||
67 | update: true, | ||
68 | blacklist: true, | ||
69 | delete: true, | ||
70 | report: true, | ||
71 | duplicate: true | ||
72 | } | ||
73 | showActions = false | ||
74 | serverConfig: ServerConfig | ||
75 | |||
76 | addToWatchLaterText: string | ||
77 | addedToWatchLaterText: string | ||
78 | inWatchLaterPlaylist: boolean | ||
79 | channelLinkTitle = '' | ||
80 | |||
81 | watchLaterPlaylist: { | ||
82 | id: number | ||
83 | playlistElementId?: number | ||
84 | } | ||
85 | |||
86 | videoLink: any[] = [] | ||
87 | |||
88 | private ownerDisplayTypeChosen: 'account' | 'videoChannel' | ||
89 | |||
90 | constructor ( | ||
91 | private screenService: ScreenService, | ||
92 | private serverService: ServerService, | ||
93 | private i18n: I18n, | ||
94 | private authService: AuthService, | ||
95 | private videoPlaylistService: VideoPlaylistService, | ||
96 | private cd: ChangeDetectorRef, | ||
97 | @Inject(LOCALE_ID) private localeId: string | ||
98 | ) {} | ||
99 | |||
100 | get isVideoBlur () { | ||
101 | return this.video.isVideoNSFWForUser(this.user, this.serverConfig) | ||
102 | } | ||
103 | |||
104 | ngOnInit () { | ||
105 | this.serverConfig = this.serverService.getTmpConfig() | ||
106 | this.serverService.getConfig() | ||
107 | .subscribe(config => { | ||
108 | this.serverConfig = config | ||
109 | this.buildVideoLink() | ||
110 | }) | ||
111 | |||
112 | this.setUpBy() | ||
113 | |||
114 | this.channelLinkTitle = this.i18n( | ||
115 | '{{name}} (channel page)', | ||
116 | { name: this.video.channel.name, handle: this.video.byVideoChannel } | ||
117 | ) | ||
118 | |||
119 | // We rely on mouseenter to lazy load actions | ||
120 | if (this.screenService.isInTouchScreen()) { | ||
121 | this.loadActions() | ||
122 | } | ||
123 | } | ||
124 | |||
125 | buildVideoLink () { | ||
126 | if (this.useLazyLoadUrl && this.video.url) { | ||
127 | const remoteUriConfig = this.serverConfig.search.remoteUri | ||
128 | |||
129 | // Redirect on the external instance if not allowed to fetch remote data | ||
130 | const externalRedirect = (!this.authService.isLoggedIn() && !remoteUriConfig.anonymous) || !remoteUriConfig.users | ||
131 | const fromPath = window.location.pathname + window.location.search | ||
132 | |||
133 | this.videoLink = [ '/search/lazy-load-video', { url: this.video.url, externalRedirect, fromPath } ] | ||
134 | return | ||
135 | } | ||
136 | |||
137 | this.videoLink = [ '/videos/watch', this.video.uuid ] | ||
138 | } | ||
139 | |||
140 | displayOwnerAccount () { | ||
141 | return this.ownerDisplayTypeChosen === 'account' | ||
142 | } | ||
143 | |||
144 | displayOwnerVideoChannel () { | ||
145 | return this.ownerDisplayTypeChosen === 'videoChannel' | ||
146 | } | ||
147 | |||
148 | isUnlistedVideo () { | ||
149 | return this.video.privacy.id === VideoPrivacy.UNLISTED | ||
150 | } | ||
151 | |||
152 | isPrivateVideo () { | ||
153 | return this.video.privacy.id === VideoPrivacy.PRIVATE | ||
154 | } | ||
155 | |||
156 | getStateLabel (video: Video) { | ||
157 | if (!video.state) return '' | ||
158 | |||
159 | if (video.privacy.id !== VideoPrivacy.PRIVATE && video.state.id === VideoState.PUBLISHED) { | ||
160 | return this.i18n('Published') | ||
161 | } | ||
162 | |||
163 | if (video.scheduledUpdate) { | ||
164 | const updateAt = new Date(video.scheduledUpdate.updateAt.toString()).toLocaleString(this.localeId) | ||
165 | return this.i18n('Publication scheduled on ') + updateAt | ||
166 | } | ||
167 | |||
168 | if (video.state.id === VideoState.TO_TRANSCODE && video.waitTranscoding === true) { | ||
169 | return this.i18n('Waiting transcoding') | ||
170 | } | ||
171 | |||
172 | if (video.state.id === VideoState.TO_TRANSCODE) { | ||
173 | return this.i18n('To transcode') | ||
174 | } | ||
175 | |||
176 | if (video.state.id === VideoState.TO_IMPORT) { | ||
177 | return this.i18n('To import') | ||
178 | } | ||
179 | |||
180 | return '' | ||
181 | } | ||
182 | |||
183 | getAvatarUrl () { | ||
184 | if (this.ownerDisplayTypeChosen === 'account') { | ||
185 | return this.video.accountAvatarUrl | ||
186 | } | ||
187 | |||
188 | return this.video.videoChannelAvatarUrl | ||
189 | } | ||
190 | |||
191 | loadActions () { | ||
192 | if (this.displayVideoActions) this.showActions = true | ||
193 | |||
194 | this.loadWatchLater() | ||
195 | } | ||
196 | |||
197 | onVideoBlocked () { | ||
198 | this.videoBlocked.emit() | ||
199 | } | ||
200 | |||
201 | onVideoUnblocked () { | ||
202 | this.videoUnblocked.emit() | ||
203 | } | ||
204 | |||
205 | onVideoRemoved () { | ||
206 | this.videoRemoved.emit() | ||
207 | } | ||
208 | |||
209 | isUserLoggedIn () { | ||
210 | return this.authService.isLoggedIn() | ||
211 | } | ||
212 | |||
213 | onWatchLaterClick (currentState: boolean) { | ||
214 | if (currentState === true) this.removeFromWatchLater() | ||
215 | else this.addToWatchLater() | ||
216 | |||
217 | this.inWatchLaterPlaylist = !currentState | ||
218 | } | ||
219 | |||
220 | addToWatchLater () { | ||
221 | const body = { videoId: this.video.id } | ||
222 | |||
223 | this.videoPlaylistService.addVideoInPlaylist(this.watchLaterPlaylist.id, body).subscribe( | ||
224 | res => { | ||
225 | this.watchLaterPlaylist.playlistElementId = res.videoPlaylistElement.id | ||
226 | } | ||
227 | ) | ||
228 | } | ||
229 | |||
230 | removeFromWatchLater () { | ||
231 | this.videoPlaylistService.removeVideoFromPlaylist(this.watchLaterPlaylist.id, this.watchLaterPlaylist.playlistElementId, this.video.id) | ||
232 | .subscribe( | ||
233 | _ => { /* empty */ } | ||
234 | ) | ||
235 | } | ||
236 | |||
237 | isWatchLaterPlaylistDisplayed () { | ||
238 | return this.displayVideoActions && this.isUserLoggedIn() && this.inWatchLaterPlaylist !== undefined | ||
239 | } | ||
240 | |||
241 | private setUpBy () { | ||
242 | if (this.ownerDisplayType === 'account' || this.ownerDisplayType === 'videoChannel') { | ||
243 | this.ownerDisplayTypeChosen = this.ownerDisplayType | ||
244 | return | ||
245 | } | ||
246 | |||
247 | // If the video channel name an UUID (not really displayable, we changed this behaviour in v1.0.0-beta.12) | ||
248 | // -> Use the account name | ||
249 | if ( | ||
250 | this.video.channel.name === `${this.video.account.name}_channel` || | ||
251 | this.video.channel.name.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) | ||
252 | ) { | ||
253 | this.ownerDisplayTypeChosen = 'account' | ||
254 | } else { | ||
255 | this.ownerDisplayTypeChosen = 'videoChannel' | ||
256 | } | ||
257 | } | ||
258 | |||
259 | private loadWatchLater () { | ||
260 | if (!this.isUserLoggedIn() || this.inWatchLaterPlaylist !== undefined) return | ||
261 | |||
262 | this.authService.userInformationLoaded | ||
263 | .pipe(switchMap(() => this.videoPlaylistService.listenToVideoPlaylistChange(this.video.id))) | ||
264 | .subscribe(existResult => { | ||
265 | const watchLaterPlaylist = this.authService.getUser().specialPlaylists.find(p => p.type === VideoPlaylistType.WATCH_LATER) | ||
266 | const existsInWatchLater = existResult.find(r => r.playlistId === watchLaterPlaylist.id) | ||
267 | this.inWatchLaterPlaylist = false | ||
268 | |||
269 | this.watchLaterPlaylist = { | ||
270 | id: watchLaterPlaylist.id | ||
271 | } | ||
272 | |||
273 | if (existsInWatchLater) { | ||
274 | this.inWatchLaterPlaylist = true | ||
275 | this.watchLaterPlaylist.playlistElementId = existsInWatchLater.playlistElementId | ||
276 | } | ||
277 | |||
278 | this.cd.markForCheck() | ||
279 | }) | ||
280 | |||
281 | this.videoPlaylistService.runPlaylistCheck(this.video.id) | ||
282 | } | ||
283 | } | ||