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