]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/shared/shared-share-modal/video-share.component.ts
Prevent edition with 0 task
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-share-modal / video-share.component.ts
1 import { Component, ElementRef, Input, ViewChild } from '@angular/core'
2 import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
3 import { HooksService, ServerService } from '@app/core'
4 import { VideoDetails } from '@app/shared/shared-main'
5 import { VideoPlaylist } from '@app/shared/shared-video-playlist'
6 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
7 import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
8 import { buildPlaylistLink, buildVideoLink, decoratePlaylistLink, decorateVideoLink } from '@shared/core-utils'
9 import { VideoCaption, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
10
11 type Customizations = {
12 startAtCheckbox: boolean
13 startAt: number
14
15 stopAtCheckbox: boolean
16 stopAt: number
17
18 subtitleCheckbox: boolean
19 subtitle: string
20
21 loop: boolean
22 originUrl: boolean
23 autoplay: boolean
24 muted: boolean
25
26 embedP2P: boolean
27 onlyEmbedUrl: boolean
28 title: boolean
29 warningTitle: boolean
30 controlBar: boolean
31 peertubeLink: boolean
32
33 includeVideoInPlaylist: boolean
34 }
35
36 type TabId = 'url' | 'qrcode' | 'embed'
37
38 @Component({
39 selector: 'my-video-share',
40 templateUrl: './video-share.component.html',
41 styleUrls: [ './video-share.component.scss' ]
42 })
43 export class VideoShareComponent {
44 @ViewChild('modal', { static: true }) modal: ElementRef
45
46 @Input() video: VideoDetails = null
47 @Input() videoCaptions: VideoCaption[] = []
48 @Input() playlist: VideoPlaylist = null
49 @Input() playlistPosition: number = null
50
51 activeVideoId: TabId = 'url'
52 activePlaylistId: TabId = 'url'
53
54 customizations: Customizations
55 isAdvancedCustomizationCollapsed = true
56
57 videoUrl: string
58 playlistUrl: string
59
60 videoEmbedUrl: string
61 playlistEmbedUrl: string
62
63 videoEmbedHTML: string
64 videoEmbedSafeHTML: SafeHtml
65 playlistEmbedHTML: string
66 playlistEmbedSafeHTML: SafeHtml
67
68 constructor (
69 private modalService: NgbModal,
70 private sanitizer: DomSanitizer,
71 private server: ServerService,
72 private hooks: HooksService
73 ) { }
74
75 show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
76 let subtitle: string
77 if (this.videoCaptions && this.videoCaptions.length !== 0) {
78 subtitle = this.videoCaptions[0].language.id
79 }
80
81 this.customizations = new Proxy({
82 startAtCheckbox: false,
83 startAt: currentVideoTimestamp ? Math.floor(currentVideoTimestamp) : 0,
84
85 stopAtCheckbox: false,
86 stopAt: this.video?.duration,
87
88 subtitleCheckbox: false,
89 subtitle,
90
91 loop: false,
92 originUrl: false,
93 autoplay: false,
94 muted: false,
95
96 // Embed options
97 embedP2P: this.server.getHTMLConfig().defaults.p2p.embed.enabled,
98 onlyEmbedUrl: false,
99 title: true,
100 warningTitle: true,
101 controlBar: true,
102 peertubeLink: true,
103
104 includeVideoInPlaylist: false
105 }, {
106 set: (target, prop, value) => {
107 target[prop] = value
108
109 if (prop === 'embedP2P') {
110 // Auto enabled warning title if P2P is enabled
111 this.customizations.warningTitle = value
112 }
113
114 this.onUpdate()
115
116 return true
117 }
118 })
119
120 this.playlistPosition = currentPlaylistPosition
121
122 this.onUpdate()
123
124 this.modalService.open(this.modal, { centered: true }).shown.subscribe(() => {
125 this.hooks.runAction('action:modal.share.shown', 'video-watch', { video: this.video, playlist: this.playlist })
126 })
127 }
128
129 // ---------------------------------------------------------------------------
130
131 getVideoUrl () {
132 const url = this.customizations.originUrl
133 ? this.video.url
134 : buildVideoLink(this.video, window.location.origin)
135
136 return this.hooks.wrapFun(
137 decorateVideoLink,
138 { url, ...this.getVideoOptions(false) },
139 'video-watch',
140 'filter:share.video-url.build.params',
141 'filter:share.video-url.build.result'
142 )
143 }
144
145 getVideoEmbedUrl () {
146 return this.hooks.wrapFun(
147 decorateVideoLink,
148 { url: this.video.embedUrl, ...this.getVideoOptions(true) },
149 'video-watch',
150 'filter:share.video-embed-url.build.params',
151 'filter:share.video-embed-url.build.result'
152 )
153 }
154
155 async getVideoIframeCode () {
156 return this.hooks.wrapFun(
157 buildVideoOrPlaylistEmbed,
158 { embedUrl: await this.getVideoEmbedUrl(), embedTitle: this.video.name },
159 'video-watch',
160 'filter:share.video-embed-code.build.params',
161 'filter:share.video-embed-code.build.result'
162 )
163 }
164
165 // ---------------------------------------------------------------------------
166
167 getPlaylistUrl () {
168 const url = buildPlaylistLink(this.playlist)
169
170 return this.hooks.wrapFun(
171 decoratePlaylistLink,
172 { url, ...this.getPlaylistOptions() },
173 'video-watch',
174 'filter:share.video-playlist-url.build.params',
175 'filter:share.video-playlist-url.build.result'
176 )
177 }
178
179 getPlaylistEmbedUrl () {
180 return this.hooks.wrapFun(
181 decoratePlaylistLink,
182 { url: this.playlist.embedUrl, ...this.getPlaylistOptions() },
183 'video-watch',
184 'filter:share.video-playlist-embed-url.build.params',
185 'filter:share.video-playlist-embed-url.build.result'
186 )
187 }
188
189 async getPlaylistEmbedCode () {
190 return this.hooks.wrapFun(
191 buildVideoOrPlaylistEmbed,
192 { embedUrl: await this.getPlaylistEmbedUrl(), embedTitle: this.playlist.displayName },
193 'video-watch',
194 'filter:share.video-playlist-embed-code.build.params',
195 'filter:share.video-playlist-embed-code.build.result'
196 )
197 }
198
199 // ---------------------------------------------------------------------------
200
201 async onUpdate () {
202 console.log('on update')
203
204 if (this.playlist) {
205 this.playlistUrl = await this.getPlaylistUrl()
206 this.playlistEmbedUrl = await this.getPlaylistEmbedUrl()
207 this.playlistEmbedHTML = await this.getPlaylistEmbedCode()
208 this.playlistEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.playlistEmbedHTML)
209 }
210
211 if (this.video) {
212 this.videoUrl = await this.getVideoUrl()
213 this.videoEmbedUrl = await this.getVideoEmbedUrl()
214 this.videoEmbedHTML = await this.getVideoIframeCode()
215 this.videoEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.videoEmbedHTML)
216 }
217 }
218
219 notSecure () {
220 return window.location.protocol === 'http:'
221 }
222
223 isInVideoEmbedTab () {
224 return this.activeVideoId === 'embed'
225 }
226
227 isInPlaylistEmbedTab () {
228 return this.activePlaylistId === 'embed'
229 }
230
231 isLocalVideo () {
232 return this.video.isLocal
233 }
234
235 isPrivateVideo () {
236 return this.video.privacy.id === VideoPrivacy.PRIVATE
237 }
238
239 isPrivatePlaylist () {
240 return this.playlist.privacy.id === VideoPlaylistPrivacy.PRIVATE
241 }
242
243 private getPlaylistOptions (baseUrl?: string) {
244 return {
245 baseUrl,
246
247 playlistPosition: this.playlistPosition && this.customizations.includeVideoInPlaylist
248 ? this.playlistPosition
249 : undefined
250 }
251 }
252
253 private getVideoOptions (forEmbed: boolean) {
254 const embedOptions = forEmbed
255 ? {
256 title: this.customizations.title,
257 warningTitle: this.customizations.warningTitle,
258 controlBar: this.customizations.controlBar,
259 peertubeLink: this.customizations.peertubeLink,
260
261 // If using default value, we don't need to specify it
262 p2p: this.customizations.embedP2P === this.server.getHTMLConfig().defaults.p2p.embed.enabled
263 ? undefined
264 : this.customizations.embedP2P
265 }
266 : {}
267
268 return {
269 startTime: this.customizations.startAtCheckbox ? this.customizations.startAt : undefined,
270 stopTime: this.customizations.stopAtCheckbox ? this.customizations.stopAt : undefined,
271
272 subtitle: this.customizations.subtitleCheckbox ? this.customizations.subtitle : undefined,
273
274 loop: this.customizations.loop,
275 autoplay: this.customizations.autoplay,
276 muted: this.customizations.muted,
277
278 ...embedOptions
279 }
280 }
281 }