1 import { Component, ElementRef, Input, ViewChild } from '@angular/core'
2 import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
3 import { VideoDetails } from '@app/shared/shared-main'
4 import { VideoPlaylist } from '@app/shared/shared-video-playlist'
5 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
6 import { buildPlaylistLink, buildVideoLink, decoratePlaylistLink, decorateVideoLink } from '@shared/core-utils'
7 import { VideoCaption, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
8 import { buildVideoOrPlaylistEmbed } from '../../../assets/player/utils'
10 type Customizations = {
11 startAtCheckbox: boolean
14 stopAtCheckbox: boolean
17 subtitleCheckbox: boolean
30 type TabId = 'url' | 'qrcode' | 'embed'
33 selector: 'my-video-share',
34 templateUrl: './video-share.component.html',
35 styleUrls: [ './video-share.component.scss' ]
37 export class VideoShareComponent {
38 @ViewChild('modal', { static: true }) modal: ElementRef
40 @Input() video: VideoDetails = null
41 @Input() videoCaptions: VideoCaption[] = []
42 @Input() playlist: VideoPlaylist = null
43 @Input() playlistPosition: number = null
45 activeVideoId: TabId = 'url'
46 activePlaylistId: TabId = 'url'
48 customizations: Customizations
49 isAdvancedCustomizationCollapsed = true
50 includeVideoInPlaylist = false
52 playlistEmbedHTML: SafeHtml
53 videoEmbedHTML: SafeHtml
56 private modalService: NgbModal,
57 private sanitizer: DomSanitizer
60 show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
62 if (this.videoCaptions && this.videoCaptions.length !== 0) {
63 subtitle = this.videoCaptions[0].language.id
66 this.customizations = new Proxy({
67 startAtCheckbox: false,
68 startAt: currentVideoTimestamp ? Math.floor(currentVideoTimestamp) : 0,
70 stopAtCheckbox: false,
71 stopAt: this.video?.duration,
73 subtitleCheckbox: false,
87 set: (target, prop, value) => {
90 this.updateEmbedCode()
96 this.playlistPosition = currentPlaylistPosition
98 this.updateEmbedCode()
100 this.modalService.open(this.modal, { centered: true })
103 getVideoIframeCode () {
104 const embedUrl = decorateVideoLink({ url: this.video.embedUrl, ...this.getVideoOptions() })
106 return buildVideoOrPlaylistEmbed(embedUrl, this.video.name)
109 getPlaylistIframeCode () {
110 const embedUrl = decoratePlaylistLink({ url: this.playlist.embedUrl, ...this.getPlaylistOptions() })
112 return buildVideoOrPlaylistEmbed(embedUrl, this.playlist.displayName)
116 const url = this.customizations.originUrl
118 : buildVideoLink(this.video, window.location.origin)
120 return decorateVideoLink({
123 ...this.getVideoOptions()
128 const url = buildPlaylistLink(this.playlist)
129 if (!this.includeVideoInPlaylist) return url
131 return decoratePlaylistLink({ url, playlistPosition: this.playlistPosition })
135 if (this.playlist) this.playlistEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getPlaylistIframeCode())
137 if (this.video) this.videoEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getVideoIframeCode())
141 return window.location.protocol === 'http:'
144 isVideoInEmbedTab () {
145 return this.activeVideoId === 'embed'
149 return this.video.isLocal
153 return this.video.privacy.id === VideoPrivacy.PRIVATE
156 isPrivatePlaylist () {
157 return this.playlist.privacy.id === VideoPlaylistPrivacy.PRIVATE
160 private getPlaylistOptions (baseUrl?: string) {
164 playlistPosition: this.playlistPosition || undefined
168 private getVideoOptions () {
170 startTime: this.customizations.startAtCheckbox ? this.customizations.startAt : undefined,
171 stopTime: this.customizations.stopAtCheckbox ? this.customizations.stopAt : undefined,
173 subtitle: this.customizations.subtitleCheckbox ? this.customizations.subtitle : undefined,
175 loop: this.customizations.loop,
176 autoplay: this.customizations.autoplay,
177 muted: this.customizations.muted,
179 title: this.customizations.title,
180 warningTitle: this.customizations.warningTitle,
181 controls: this.customizations.controls,
182 peertubeLink: this.customizations.peertubeLink