Add plugin hooks/placeholder to share modal

This commit is contained in:
Chocobozzz 2022-08-11 15:28:11 +02:00
parent 2a95b88477
commit de61544582
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
9 changed files with 149 additions and 56 deletions

View 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 () {

View 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 })
}
}

View 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)
}

View 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>
@ -102,7 +103,7 @@
<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>
@ -112,7 +113,7 @@
<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>
@ -123,7 +124,7 @@
<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>
@ -131,7 +132,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]="videoEmbedHTML"></div>
<div class="embed" [innerHTML]="videoEmbedSafeHTML"></div>
</div>
</ng-template>
</ng-container>
@ -176,6 +177,8 @@
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">

View 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.onUpdate()
this.modalService.open(this.modal, { centered: true })
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 () {
return buildVideoOrPlaylistEmbed(this.getVideoEmbedUrl(), this.video.name)
}
getVideoEmbedUrl () {
return decorateVideoLink({ url: this.video.embedUrl, ...this.getVideoOptions(true) })
}
getPlaylistEmbedUrl () {
return decoratePlaylistLink({ url: this.playlist.embedUrl, ...this.getPlaylistOptions() })
}
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,
...this.getVideoOptions(false)
})
return this.hooks.wrapFun(
decorateVideoLink,
{ url, ...this.getVideoOptions(false) },
'video-watch',
'filter:share.video-url.build.params',
'filter:share.video-url.build.result'
)
}
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'
)
}
updateEmbedCode () {
if (this.playlist) this.playlistEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getPlaylistIframeCode())
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'
)
}
if (this.video) this.videoEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getVideoIframeCode())
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'
)
}
// ---------------------------------------------------------------------------
async onUpdate () {
console.log('on update')
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
}
}

View 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 }))
}
}
]

View 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

View 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

View File

@ -1 +1,4 @@
export type PluginElementPlaceholder = 'player-next'
export type PluginElementPlaceholder =
'player-next' |
'share-modal-playlist-settings' |
'share-modal-video-settings'