]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - client/src/app/shared/shared-share-modal/video-share.component.ts
Prevent invalid end watch section warnings
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-share-modal / video-share.component.ts
index 2a73e6166dd028fd532b744947024e288eda9589..1b69aa2d05e5ad6e56b51281506e86d51738697b 100644 (file)
@@ -1,9 +1,12 @@
 import { Component, ElementRef, Input, ViewChild } from '@angular/core'
+import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
+import { HooksService, ServerService } from '@app/core'
 import { VideoDetails } from '@app/shared/shared-main'
 import { VideoPlaylist } from '@app/shared/shared-video-playlist'
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
-import { VideoCaption } from '@shared/models'
-import { buildPlaylistLink, buildVideoLink, buildVideoOrPlaylistEmbed } from '../../../assets/player/utils'
+import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
+import { buildPlaylistLink, buildVideoLink, decoratePlaylistLink, decorateVideoLink } from '@shared/core-utils'
+import { VideoCaption, VideoPlaylistPrivacy, VideoPrivacy } from '@shared/models'
 
 type Customizations = {
   startAtCheckbox: boolean
@@ -19,10 +22,16 @@ type Customizations = {
   originUrl: boolean
   autoplay: boolean
   muted: boolean
+
+  embedP2P: boolean
+  onlyEmbedUrl: boolean
   title: boolean
   warningTitle: boolean
-  controls: boolean
+  controlBar: boolean
   peertubeLink: boolean
+  responsive: boolean
+
+  includeVideoInPlaylist: boolean
 }
 
 type TabId = 'url' | 'qrcode' | 'embed'
@@ -45,9 +54,24 @@ export class VideoShareComponent {
 
   customizations: Customizations
   isAdvancedCustomizationCollapsed = true
-  includeVideoInPlaylist = false
 
-  constructor (private modalService: NgbModal) { }
+  videoUrl: string
+  playlistUrl: string
+
+  videoEmbedUrl: string
+  playlistEmbedUrl: string
+
+  videoEmbedHTML: string
+  videoEmbedSafeHTML: SafeHtml
+  playlistEmbedHTML: string
+  playlistEmbedSafeHTML: SafeHtml
+
+  constructor (
+    private modalService: NgbModal,
+    private sanitizer: DomSanitizer,
+    private server: ServerService,
+    private hooks: HooksService
+  ) { }
 
   show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
     let subtitle: string
@@ -55,7 +79,7 @@ export class VideoShareComponent {
       subtitle = this.videoCaptions[0].language.id
     }
 
-    this.customizations = {
+    this.customizations = new Proxy({
       startAtCheckbox: false,
       startAt: currentVideoTimestamp ? Math.floor(currentVideoTimestamp) : 0,
 
@@ -71,71 +95,179 @@ export class VideoShareComponent {
       muted: false,
 
       // Embed options
+      embedP2P: this.server.getHTMLConfig().defaults.p2p.embed.enabled,
+      onlyEmbedUrl: false,
       title: true,
       warningTitle: true,
-      controls: true,
-      peertubeLink: true
-    }
+      controlBar: true,
+      peertubeLink: true,
+      responsive: false,
+
+      includeVideoInPlaylist: false
+    }, {
+      set: (target, prop, value) => {
+        target[prop] = value
+
+        if (prop === 'embedP2P') {
+          // Auto enabled warning title if P2P is enabled
+          this.customizations.warningTitle = value
+        }
+
+        this.onUpdate()
+
+        return true
+      }
+    })
 
     this.playlistPosition = currentPlaylistPosition
 
-    this.modalService.open(this.modal, { centered: true })
+    this.onUpdate()
+
+    this.modalService.open(this.modal, { centered: true }).shown.subscribe(() => {
+      this.hooks.runAction('action:modal.share.shown', 'video-watch', { video: this.video, playlist: this.playlist })
+    })
   }
 
-  getVideoIframeCode () {
-    const options = this.getVideoOptions(this.video.embedUrl)
+  // ---------------------------------------------------------------------------
 
-    const embedUrl = buildVideoLink(options)
-    return buildVideoOrPlaylistEmbed(embedUrl, this.video.name)
+  getVideoUrl () {
+    const url = this.customizations.originUrl
+      ? this.video.url
+      : buildVideoLink(this.video, window.location.origin)
+
+    return this.hooks.wrapFun(
+      decorateVideoLink,
+      { url, ...this.getVideoOptions(false) },
+      'video-watch',
+      'filter:share.video-url.build.params',
+      'filter:share.video-url.build.result'
+    )
   }
 
-  getPlaylistIframeCode () {
-    const options = this.getPlaylistOptions(this.playlist.embedUrl)
+  getVideoEmbedUrl () {
+    return this.hooks.wrapFun(
+      decorateVideoLink,
+      { url: this.video.embedUrl, ...this.getVideoOptions(true) },
+      'video-watch',
+      'filter:share.video-embed-url.build.params',
+      'filter:share.video-embed-url.build.result'
+    )
+  }
 
-    const embedUrl = buildPlaylistLink(options)
-    return buildVideoOrPlaylistEmbed(embedUrl, this.playlist.displayName)
+  async getVideoEmbedCode (options: { responsive: boolean }) {
+    const { responsive } = options
+    return this.hooks.wrapFun(
+      buildVideoOrPlaylistEmbed,
+      { embedUrl: await this.getVideoEmbedUrl(), embedTitle: this.video.name, responsive },
+      'video-watch',
+      'filter:share.video-embed-code.build.params',
+      'filter:share.video-embed-code.build.result'
+    )
   }
 
-  getVideoUrl () {
-    let baseUrl = this.customizations.originUrl ? this.video.originInstanceUrl : window.location.origin
-    baseUrl += '/w/' + this.video.uuid
-    const options = this.getVideoOptions(baseUrl)
+  // ---------------------------------------------------------------------------
 
-    return buildVideoLink(options)
+  getPlaylistUrl () {
+    const url = buildPlaylistLink(this.playlist)
+
+    return this.hooks.wrapFun(
+      decoratePlaylistLink,
+      { url, ...this.getPlaylistOptions() },
+      'video-watch',
+      'filter:share.video-playlist-url.build.params',
+      'filter:share.video-playlist-url.build.result'
+    )
   }
 
-  getPlaylistUrl () {
-    const base = window.location.origin + '/w/p/' + this.playlist.uuid
+  getPlaylistEmbedUrl () {
+    return this.hooks.wrapFun(
+      decoratePlaylistLink,
+      { url: this.playlist.embedUrl, ...this.getPlaylistOptions() },
+      'video-watch',
+      'filter:share.video-playlist-embed-url.build.params',
+      'filter:share.video-playlist-embed-url.build.result'
+    )
+  }
+
+  async getPlaylistEmbedCode (options: { responsive: boolean }) {
+    const { responsive } = options
+    return this.hooks.wrapFun(
+      buildVideoOrPlaylistEmbed,
+      { embedUrl: await this.getPlaylistEmbedUrl(), embedTitle: this.playlist.displayName, responsive },
+      'video-watch',
+      'filter:share.video-playlist-embed-code.build.params',
+      'filter:share.video-playlist-embed-code.build.result'
+    )
+  }
+
+  // ---------------------------------------------------------------------------
 
-    if (!this.includeVideoInPlaylist) return base
+  async onUpdate () {
+    if (this.playlist) {
+      this.playlistUrl = await this.getPlaylistUrl()
+      this.playlistEmbedUrl = await this.getPlaylistEmbedUrl()
+      this.playlistEmbedHTML = await this.getPlaylistEmbedCode({ responsive: this.customizations.responsive })
+      this.playlistEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(await this.getPlaylistEmbedCode({ responsive: false }))
+    }
 
-    return base + '?playlistPosition=' + this.playlistPosition
+    if (this.video) {
+      this.videoUrl = await this.getVideoUrl()
+      this.videoEmbedUrl = await this.getVideoEmbedUrl()
+      this.videoEmbedHTML = await this.getVideoEmbedCode({ responsive: this.customizations.responsive })
+      this.videoEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(await this.getVideoEmbedCode({ responsive: false }))
+    }
   }
 
   notSecure () {
     return window.location.protocol === 'http:'
   }
 
-  isVideoInEmbedTab () {
+  isInVideoEmbedTab () {
     return this.activeVideoId === 'embed'
   }
 
+  isInPlaylistEmbedTab () {
+    return this.activePlaylistId === 'embed'
+  }
+
   isLocalVideo () {
     return this.video.isLocal
   }
 
+  isPrivateVideo () {
+    return this.video.privacy.id === VideoPrivacy.PRIVATE
+  }
+
+  isPrivatePlaylist () {
+    return this.playlist.privacy.id === VideoPlaylistPrivacy.PRIVATE
+  }
+
   private getPlaylistOptions (baseUrl?: string) {
     return {
       baseUrl,
 
-      playlistPosition: this.playlistPosition || undefined
+      playlistPosition: this.playlistPosition && this.customizations.includeVideoInPlaylist
+        ? this.playlistPosition
+        : undefined
     }
   }
 
-  private getVideoOptions (baseUrl?: string) {
-    return {
-      baseUrl,
+  private getVideoOptions (forEmbed: boolean) {
+    const embedOptions = forEmbed
+      ? {
+        title: this.customizations.title,
+        warningTitle: this.customizations.warningTitle,
+        controlBar: this.customizations.controlBar,
+        peertubeLink: this.customizations.peertubeLink,
+
+        // If using default value, we don't need to specify it
+        p2p: this.customizations.embedP2P === this.server.getHTMLConfig().defaults.p2p.embed.enabled
+          ? undefined
+          : this.customizations.embedP2P
+      }
+      : {}
 
+    return {
       startTime: this.customizations.startAtCheckbox ? this.customizations.startAt : undefined,
       stopTime: this.customizations.stopAtCheckbox ? this.customizations.stopAt : undefined,
 
@@ -145,10 +277,7 @@ export class VideoShareComponent {
       autoplay: this.customizations.autoplay,
       muted: this.customizations.muted,
 
-      title: this.customizations.title,
-      warningTitle: this.customizations.warningTitle,
-      controls: this.customizations.controls,
-      peertubeLink: this.customizations.peertubeLink
+      ...embedOptions
     }
   }
 }