]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add plugin hooks/placeholder to share modal
authorChocobozzz <me@florianbigard.com>
Thu, 11 Aug 2022 13:28:11 +0000 (15:28 +0200)
committerChocobozzz <me@florianbigard.com>
Thu, 11 Aug 2022 13:28:11 +0000 (15:28 +0200)
client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts
client/src/app/shared/shared-main/video/embed.component.ts
client/src/app/shared/shared-share-modal/video-share.component.html
client/src/app/shared/shared-share-modal/video-share.component.ts
client/src/assets/player/shared/manager-options/manager-options-builder.ts
client/src/root-helpers/video.ts
shared/models/plugins/client/client-hook.model.ts
shared/models/plugins/client/plugin-element-placeholder.type.ts

index 033305a2b7cf0b0f3c5d4864daf13d5af5cc45dd..8d67e9beb42b8c08b91f3e8ef506b2fe86dd1dad 100644 (file)
@@ -145,15 +145,15 @@ export class VideoBlockListComponent extends RestTable implements OnInit {
   }
 
   getVideoEmbed (entry: VideoBlacklist) {
-    return buildVideoOrPlaylistEmbed(
-      decorateVideoLink({
+    return buildVideoOrPlaylistEmbed({
+      embedUrl: decorateVideoLink({
         url: buildVideoEmbedLink(entry.video, environment.originServerUrl),
 
         title: false,
         warningTitle: false
       }),
-      entry.video.name
-    )
+      embedTitle: entry.video.name
+    })
   }
 
   protected reloadData () {
index 955b0af18485921a7b96b53cb6d5a55c622026b7..0baf2428b27f947fb2830c217bf07cab7fa95b8f 100644 (file)
@@ -21,6 +21,6 @@ export class EmbedMarkupComponent implements CustomMarkupComponent, OnInit {
       ? buildVideoEmbedLink({ uuid: this.uuid }, environment.originServerUrl)
       : buildPlaylistEmbedLink({ uuid: this.uuid }, environment.originServerUrl)
 
-    this.el.nativeElement.innerHTML = buildVideoOrPlaylistEmbed(link, this.uuid)
+    this.el.nativeElement.innerHTML = buildVideoOrPlaylistEmbed({ embedUrl: link, embedTitle: this.uuid })
   }
 }
index 1230008346233aa5b610fc6b0cefbade7a33365f..43e3501978c18576c5bb4f3614763a334bec0be2 100644 (file)
@@ -20,15 +20,15 @@ export class EmbedComponent implements OnInit {
   }
 
   ngOnInit () {
-    const html = buildVideoOrPlaylistEmbed(
-      decorateVideoLink({
+    const html = buildVideoOrPlaylistEmbed({
+      embedUrl: decorateVideoLink({
         url: buildVideoEmbedLink(this.video, environment.originServerUrl),
 
         title: false,
         warningTitle: false
       }),
-      this.video.name
-    )
+      embedTitle: this.video.name
+    })
 
     this.embedHTML = this.sanitizer.bypassSecurityTrustHtml(html)
   }
index b163d358110deb2d55ba41614a8e546c4944bd0f..f4d249b4193f5c39bffb8e2876b3534e7404ceff 100644 (file)
@@ -25,7 +25,7 @@
 
           <ng-template ngbNavContent>
             <div class="nav-content">
-              <my-input-text [value]="getPlaylistUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
+              <my-input-text [value]="playlistUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
             </div>
           </ng-template>
         </ng-container>
@@ -35,7 +35,7 @@
 
           <ng-template ngbNavContent>
             <div class="nav-content">
-              <qrcode [qrdata]="getPlaylistUrl()" [width]="256" level="Q"></qrcode>
+              <qrcode [qrdata]="playlistUrl" [width]="256" level="Q"></qrcode>
             </div>
           </ng-template>
         </ng-container>
@@ -46,7 +46,7 @@
           <ng-template ngbNavContent>
             <div class="nav-content">
               <my-input-text
-                [value]="customizations.onlyEmbedUrl ? getPlaylistEmbedUrl() : getPlaylistIframeCode()" (change)="updateEmbedCode()"
+                [value]="customizations.onlyEmbedUrl ? playlistEmbedUrl : playlistEmbedHTML" (change)="onUpdate()"
                 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
               ></my-input-text>
 
@@ -54,7 +54,7 @@
                 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
               </div>
 
-              <div class="embed" [innerHTML]="playlistEmbedHTML"></div>
+              <div class="embed" [innerHTML]="playlistEmbedSafeHTML"></div>
             </div>
           </ng-template>
         </ng-container>
@@ -67,7 +67,7 @@
 
         <div class="form-group" *ngIf="video">
           <my-peertube-checkbox
-            inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist"
+            inputName="includeVideoInPlaylist" [(ngModel)]="customizations.includeVideoInPlaylist"
             i18n-labelText labelText="Share the playlist at this video position"
           ></my-peertube-checkbox>
         </div>
@@ -80,6 +80,7 @@
           ></my-peertube-checkbox>
         </div>
 
+        <my-plugin-placeholder pluginId="share-modal-playlist-settings"></my-plugin-placeholder>
       </div>
     </div>
 
 
           <ng-template ngbNavContent>
             <div class="nav-content">
-              <my-input-text [value]="getVideoUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
+              <my-input-text [value]="videoUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
             </div>
           </ng-template>
         </ng-container>
 
           <ng-template ngbNavContent>
             <div class="nav-content">
-              <qrcode [qrdata]="getVideoUrl()" [width]="256" level="Q"></qrcode>
+              <qrcode [qrdata]="videoUrl" [width]="256" level="Q"></qrcode>
             </div>
           </ng-template>
         </ng-container>
           <ng-template ngbNavContent>
             <div class="nav-content">
               <my-input-text
-                [value]="customizations.onlyEmbedUrl ? getVideoEmbedUrl() : getVideoIframeCode()" (ngModelChange)="updateEmbedCode()"
+                [value]="customizations.onlyEmbedUrl ? videoEmbedUrl : videoEmbedHTML" (ngModelChange)="onUpdate()"
                 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
               ></my-input-text>
 
                 The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
               </div>
 
-              <div class="embed" [innerHTML]="videoEmbedHTML"></div>
+              <div class="embed" [innerHTML]="videoEmbedSafeHTML"></div>
             </div>
           </ng-template>
         </ng-container>
               i18n-labelText labelText="Only display embed URL"
             ></my-peertube-checkbox>
           </div>
+
+          <my-plugin-placeholder pluginId="share-modal-video-settings"></my-plugin-placeholder>
         </div>
 
         <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed">
index e0c98008cb79f4d1304602807b9e1ed5c2c6ce8d..e1db4a3b81f29738876b60c747022d28a34df54d 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, ElementRef, Input, ViewChild } from '@angular/core'
 import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
-import { ServerService } from '@app/core'
+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'
@@ -29,6 +29,8 @@ type Customizations = {
   warningTitle: boolean
   controlBar: boolean
   peertubeLink: boolean
+
+  includeVideoInPlaylist: boolean
 }
 
 type TabId = 'url' | 'qrcode' | 'embed'
@@ -51,15 +53,23 @@ export class VideoShareComponent {
 
   customizations: Customizations
   isAdvancedCustomizationCollapsed = true
-  includeVideoInPlaylist = false
 
-  playlistEmbedHTML: SafeHtml
-  videoEmbedHTML: SafeHtml
+  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 server: ServerService,
+    private hooks: HooksService
   ) { }
 
   show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
@@ -89,7 +99,9 @@ export class VideoShareComponent {
       title: true,
       warningTitle: true,
       controlBar: true,
-      peertubeLink: true
+      peertubeLink: true,
+
+      includeVideoInPlaylist: false
     }, {
       set: (target, prop, value) => {
         target[prop] = value
@@ -99,7 +111,7 @@ export class VideoShareComponent {
           this.customizations.warningTitle = value
         }
 
-        this.updateEmbedCode()
+        this.onUpdate()
 
         return true
       }
@@ -107,50 +119,101 @@ export class VideoShareComponent {
 
     this.playlistPosition = currentPlaylistPosition
 
-    this.updateEmbedCode()
-
-    this.modalService.open(this.modal, { centered: true })
-  }
-
-  getVideoIframeCode () {
-    return buildVideoOrPlaylistEmbed(this.getVideoEmbedUrl(), this.video.name)
-  }
+    this.onUpdate()
 
-  getVideoEmbedUrl () {
-    return decorateVideoLink({ url: this.video.embedUrl, ...this.getVideoOptions(true) })
-  }
-
-  getPlaylistEmbedUrl () {
-    return decoratePlaylistLink({ url: this.playlist.embedUrl, ...this.getPlaylistOptions() })
+    this.modalService.open(this.modal, { centered: true }).shown.subscribe(() => {
+      this.hooks.runAction('action:modal.share.shown', 'video-watch', { video: this.video, playlist: this.playlist })
+    })
   }
 
-  getPlaylistIframeCode () {
-    return buildVideoOrPlaylistEmbed(this.getPlaylistEmbedUrl(), this.playlist.displayName)
-  }
+  // ---------------------------------------------------------------------------
 
   getVideoUrl () {
     const url = this.customizations.originUrl
       ? this.video.url
       : buildVideoLink(this.video, window.location.origin)
 
-    return decorateVideoLink({
-      url,
+    return this.hooks.wrapFun(
+      decorateVideoLink,
+      { url, ...this.getVideoOptions(false) },
+      'video-watch',
+      'filter:share.video-url.build.params',
+      'filter:share.video-url.build.result'
+    )
+  }
 
-      ...this.getVideoOptions(false)
-    })
+  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'
+    )
+  }
+
+  async getVideoIframeCode () {
+    return this.hooks.wrapFun(
+      buildVideoOrPlaylistEmbed,
+      { embedUrl: await this.getVideoEmbedUrl(), embedTitle: this.video.name },
+      'video-watch',
+      'filter:share.video-embed-code.build.params',
+      'filter:share.video-embed-code.build.result'
+    )
   }
 
+  // ---------------------------------------------------------------------------
+
   getPlaylistUrl () {
     const url = buildPlaylistLink(this.playlist)
-    if (!this.includeVideoInPlaylist) return url
 
-    return decoratePlaylistLink({ url, playlistPosition: this.playlistPosition })
+    return this.hooks.wrapFun(
+      decoratePlaylistLink,
+      { url, ...this.getPlaylistOptions() },
+      'video-watch',
+      'filter:share.video-playlist-url.build.params',
+      'filter:share.video-playlist-url.build.result'
+    )
+  }
+
+  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 () {
+    return this.hooks.wrapFun(
+      buildVideoOrPlaylistEmbed,
+      { embedUrl: await this.getPlaylistEmbedUrl(), embedTitle: this.playlist.displayName },
+      'video-watch',
+      'filter:share.video-playlist-embed-code.build.params',
+      'filter:share.video-playlist-embed-code.build.result'
+    )
   }
 
-  updateEmbedCode () {
-    if (this.playlist) this.playlistEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getPlaylistIframeCode())
+  // ---------------------------------------------------------------------------
+
+  async onUpdate () {
+    console.log('on update')
 
-    if (this.video) this.videoEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getVideoIframeCode())
+    if (this.playlist) {
+      this.playlistUrl = await this.getPlaylistUrl()
+      this.playlistEmbedUrl = await this.getPlaylistEmbedUrl()
+      this.playlistEmbedHTML = await this.getPlaylistEmbedCode()
+      this.playlistEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.playlistEmbedHTML)
+    }
+
+    if (this.video) {
+      this.videoUrl = await this.getVideoUrl()
+      this.videoEmbedUrl = await this.getVideoEmbedUrl()
+      this.videoEmbedHTML = await this.getVideoIframeCode()
+      this.videoEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.videoEmbedHTML)
+    }
   }
 
   notSecure () {
@@ -181,7 +244,9 @@ export class VideoShareComponent {
     return {
       baseUrl,
 
-      playlistPosition: this.playlistPosition || undefined
+      playlistPosition: this.playlistPosition && this.customizations.includeVideoInPlaylist
+        ? this.playlistPosition
+        : undefined
     }
   }
 
index e454c719e399aff7f2762b8013b77106d3aa7e72..bc70bb12fc1cec28333a5c27bb3ad04efb8b0d27 100644 (file)
@@ -142,7 +142,7 @@ export class ManagerOptionsBuilder {
           icon: 'code',
           label: player.localize('Copy embed code'),
           listener: () => {
-            copyToClipboard(buildVideoOrPlaylistEmbed(commonOptions.embedUrl, commonOptions.embedTitle))
+            copyToClipboard(buildVideoOrPlaylistEmbed({ embedUrl: commonOptions.embedUrl, embedTitle: commonOptions.embedTitle }))
           }
         }
       ]
index 4290992aab93964f12ace229b17a2f951f23c97f..ba84e49ea2cd862081414f5be233df691a25a99b 100644 (file)
@@ -1,6 +1,11 @@
 import { HTMLServerConfig, Video } from '@shared/models'
 
-function buildVideoOrPlaylistEmbed (embedUrl: string, embedTitle: string) {
+function buildVideoOrPlaylistEmbed (options: {
+  embedUrl: string
+  embedTitle: string
+}) {
+  const { embedUrl, embedTitle } = options
+
   const iframe = document.createElement('iframe')
 
   iframe.title = embedTitle
index dda03124d0e68984bfecdd2938892213f3533b8b..e6313b60eff4a6b4c22c8a63dd63cf537077f7e0 100644 (file)
@@ -72,6 +72,21 @@ export const clientFilterHookObject = {
   'filter:login.instance-about-plugin-panels.create.result': true,
   'filter:signup.instance-about-plugin-panels.create.result': true,
 
+  'filter:share.video-embed-code.build.params': true,
+  'filter:share.video-embed-code.build.result': true,
+  'filter:share.video-playlist-embed-code.build.params': true,
+  'filter:share.video-playlist-embed-code.build.result': true,
+
+  'filter:share.video-embed-url.build.params': true,
+  'filter:share.video-embed-url.build.result': true,
+  'filter:share.video-playlist-embed-url.build.params': true,
+  'filter:share.video-playlist-embed-url.build.result': true,
+
+  'filter:share.video-url.build.params': true,
+  'filter:share.video-url.build.result': true,
+  'filter:share.video-playlist-url.build.params': true,
+  'filter:share.video-playlist-url.build.result': true,
+
   // Filter videojs options built for PeerTube player
   'filter:internal.player.videojs.options.result': true
 }
@@ -146,6 +161,8 @@ export const clientActionHookObject = {
 
   // Fired when the modal to download a video/caption is shown
   'action:modal.video-download.shown': true,
+  // Fired when the modal to share a video/playlist is shown
+  'action:modal.share.shown': true,
 
   // ####### Embed hooks #######
   // /!\ In embed scope, peertube helpers are not available
index 129099c624c342878f337ec44a06637c7ac670ca..7b8a2605b56123c548d18de878bdd307d4524744 100644 (file)
@@ -1 +1,4 @@
-export type PluginElementPlaceholder = 'player-next'
+export type PluginElementPlaceholder =
+  'player-next' |
+  'share-modal-playlist-settings' |
+  'share-modal-video-settings'