aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts8
-rw-r--r--client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts2
-rw-r--r--client/src/app/shared/shared-main/video/embed.component.ts8
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.html21
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.ts133
-rw-r--r--client/src/assets/player/shared/manager-options/manager-options-builder.ts2
-rw-r--r--client/src/root-helpers/video.ts7
-rw-r--r--shared/models/plugins/client/client-hook.model.ts17
-rw-r--r--shared/models/plugins/client/plugin-element-placeholder.type.ts5
9 files changed, 148 insertions, 55 deletions
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
index 033305a2b..8d67e9beb 100644
--- a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
@@ -145,15 +145,15 @@ export class VideoBlockListComponent extends RestTable implements OnInit {
145 } 145 }
146 146
147 getVideoEmbed (entry: VideoBlacklist) { 147 getVideoEmbed (entry: VideoBlacklist) {
148 return buildVideoOrPlaylistEmbed( 148 return buildVideoOrPlaylistEmbed({
149 decorateVideoLink({ 149 embedUrl: decorateVideoLink({
150 url: buildVideoEmbedLink(entry.video, environment.originServerUrl), 150 url: buildVideoEmbedLink(entry.video, environment.originServerUrl),
151 151
152 title: false, 152 title: false,
153 warningTitle: false 153 warningTitle: false
154 }), 154 }),
155 entry.video.name 155 embedTitle: entry.video.name
156 ) 156 })
157 } 157 }
158 158
159 protected reloadData () { 159 protected reloadData () {
diff --git a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts
index 955b0af18..0baf2428b 100644
--- a/client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts
+++ b/client/src/app/shared/shared-custom-markup/peertube-custom-tags/embed-markup.component.ts
@@ -21,6 +21,6 @@ export class EmbedMarkupComponent implements CustomMarkupComponent, OnInit {
21 ? buildVideoEmbedLink({ uuid: this.uuid }, environment.originServerUrl) 21 ? buildVideoEmbedLink({ uuid: this.uuid }, environment.originServerUrl)
22 : buildPlaylistEmbedLink({ uuid: this.uuid }, environment.originServerUrl) 22 : buildPlaylistEmbedLink({ uuid: this.uuid }, environment.originServerUrl)
23 23
24 this.el.nativeElement.innerHTML = buildVideoOrPlaylistEmbed(link, this.uuid) 24 this.el.nativeElement.innerHTML = buildVideoOrPlaylistEmbed({ embedUrl: link, embedTitle: this.uuid })
25 } 25 }
26} 26}
diff --git a/client/src/app/shared/shared-main/video/embed.component.ts b/client/src/app/shared/shared-main/video/embed.component.ts
index 123000834..43e350197 100644
--- a/client/src/app/shared/shared-main/video/embed.component.ts
+++ b/client/src/app/shared/shared-main/video/embed.component.ts
@@ -20,15 +20,15 @@ export class EmbedComponent implements OnInit {
20 } 20 }
21 21
22 ngOnInit () { 22 ngOnInit () {
23 const html = buildVideoOrPlaylistEmbed( 23 const html = buildVideoOrPlaylistEmbed({
24 decorateVideoLink({ 24 embedUrl: decorateVideoLink({
25 url: buildVideoEmbedLink(this.video, environment.originServerUrl), 25 url: buildVideoEmbedLink(this.video, environment.originServerUrl),
26 26
27 title: false, 27 title: false,
28 warningTitle: false 28 warningTitle: false
29 }), 29 }),
30 this.video.name 30 embedTitle: this.video.name
31 ) 31 })
32 32
33 this.embedHTML = this.sanitizer.bypassSecurityTrustHtml(html) 33 this.embedHTML = this.sanitizer.bypassSecurityTrustHtml(html)
34 } 34 }
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.html b/client/src/app/shared/shared-share-modal/video-share.component.html
index b163d3581..f4d249b41 100644
--- a/client/src/app/shared/shared-share-modal/video-share.component.html
+++ b/client/src/app/shared/shared-share-modal/video-share.component.html
@@ -25,7 +25,7 @@
25 25
26 <ng-template ngbNavContent> 26 <ng-template ngbNavContent>
27 <div class="nav-content"> 27 <div class="nav-content">
28 <my-input-text [value]="getPlaylistUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text> 28 <my-input-text [value]="playlistUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
29 </div> 29 </div>
30 </ng-template> 30 </ng-template>
31 </ng-container> 31 </ng-container>
@@ -35,7 +35,7 @@
35 35
36 <ng-template ngbNavContent> 36 <ng-template ngbNavContent>
37 <div class="nav-content"> 37 <div class="nav-content">
38 <qrcode [qrdata]="getPlaylistUrl()" [width]="256" level="Q"></qrcode> 38 <qrcode [qrdata]="playlistUrl" [width]="256" level="Q"></qrcode>
39 </div> 39 </div>
40 </ng-template> 40 </ng-template>
41 </ng-container> 41 </ng-container>
@@ -46,7 +46,7 @@
46 <ng-template ngbNavContent> 46 <ng-template ngbNavContent>
47 <div class="nav-content"> 47 <div class="nav-content">
48 <my-input-text 48 <my-input-text
49 [value]="customizations.onlyEmbedUrl ? getPlaylistEmbedUrl() : getPlaylistIframeCode()" (change)="updateEmbedCode()" 49 [value]="customizations.onlyEmbedUrl ? playlistEmbedUrl : playlistEmbedHTML" (change)="onUpdate()"
50 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true" 50 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
51 ></my-input-text> 51 ></my-input-text>
52 52
@@ -54,7 +54,7 @@
54 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). 54 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).
55 </div> 55 </div>
56 56
57 <div class="embed" [innerHTML]="playlistEmbedHTML"></div> 57 <div class="embed" [innerHTML]="playlistEmbedSafeHTML"></div>
58 </div> 58 </div>
59 </ng-template> 59 </ng-template>
60 </ng-container> 60 </ng-container>
@@ -67,7 +67,7 @@
67 67
68 <div class="form-group" *ngIf="video"> 68 <div class="form-group" *ngIf="video">
69 <my-peertube-checkbox 69 <my-peertube-checkbox
70 inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist" 70 inputName="includeVideoInPlaylist" [(ngModel)]="customizations.includeVideoInPlaylist"
71 i18n-labelText labelText="Share the playlist at this video position" 71 i18n-labelText labelText="Share the playlist at this video position"
72 ></my-peertube-checkbox> 72 ></my-peertube-checkbox>
73 </div> 73 </div>
@@ -80,6 +80,7 @@
80 ></my-peertube-checkbox> 80 ></my-peertube-checkbox>
81 </div> 81 </div>
82 82
83 <my-plugin-placeholder pluginId="share-modal-playlist-settings"></my-plugin-placeholder>
83 </div> 84 </div>
84 </div> 85 </div>
85 86
@@ -102,7 +103,7 @@
102 103
103 <ng-template ngbNavContent> 104 <ng-template ngbNavContent>
104 <div class="nav-content"> 105 <div class="nav-content">
105 <my-input-text [value]="getVideoUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text> 106 <my-input-text [value]="videoUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
106 </div> 107 </div>
107 </ng-template> 108 </ng-template>
108 </ng-container> 109 </ng-container>
@@ -112,7 +113,7 @@
112 113
113 <ng-template ngbNavContent> 114 <ng-template ngbNavContent>
114 <div class="nav-content"> 115 <div class="nav-content">
115 <qrcode [qrdata]="getVideoUrl()" [width]="256" level="Q"></qrcode> 116 <qrcode [qrdata]="videoUrl" [width]="256" level="Q"></qrcode>
116 </div> 117 </div>
117 </ng-template> 118 </ng-template>
118 </ng-container> 119 </ng-container>
@@ -123,7 +124,7 @@
123 <ng-template ngbNavContent> 124 <ng-template ngbNavContent>
124 <div class="nav-content"> 125 <div class="nav-content">
125 <my-input-text 126 <my-input-text
126 [value]="customizations.onlyEmbedUrl ? getVideoEmbedUrl() : getVideoIframeCode()" (ngModelChange)="updateEmbedCode()" 127 [value]="customizations.onlyEmbedUrl ? videoEmbedUrl : videoEmbedHTML" (ngModelChange)="onUpdate()"
127 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true" 128 [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
128 ></my-input-text> 129 ></my-input-text>
129 130
@@ -131,7 +132,7 @@
131 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). 132 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).
132 </div> 133 </div>
133 134
134 <div class="embed" [innerHTML]="videoEmbedHTML"></div> 135 <div class="embed" [innerHTML]="videoEmbedSafeHTML"></div>
135 </div> 136 </div>
136 </ng-template> 137 </ng-template>
137 </ng-container> 138 </ng-container>
@@ -176,6 +177,8 @@
176 i18n-labelText labelText="Only display embed URL" 177 i18n-labelText labelText="Only display embed URL"
177 ></my-peertube-checkbox> 178 ></my-peertube-checkbox>
178 </div> 179 </div>
180
181 <my-plugin-placeholder pluginId="share-modal-video-settings"></my-plugin-placeholder>
179 </div> 182 </div>
180 183
181 <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed"> 184 <div class="advanced-filters collapse-transition" [ngbCollapse]="isAdvancedCustomizationCollapsed">
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.ts b/client/src/app/shared/shared-share-modal/video-share.component.ts
index e0c98008c..e1db4a3b8 100644
--- a/client/src/app/shared/shared-share-modal/video-share.component.ts
+++ b/client/src/app/shared/shared-share-modal/video-share.component.ts
@@ -1,6 +1,6 @@
1import { Component, ElementRef, Input, ViewChild } from '@angular/core' 1import { Component, ElementRef, Input, ViewChild } from '@angular/core'
2import { DomSanitizer, SafeHtml } from '@angular/platform-browser' 2import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
3import { ServerService } from '@app/core' 3import { HooksService, ServerService } from '@app/core'
4import { VideoDetails } from '@app/shared/shared-main' 4import { VideoDetails } from '@app/shared/shared-main'
5import { VideoPlaylist } from '@app/shared/shared-video-playlist' 5import { VideoPlaylist } from '@app/shared/shared-video-playlist'
6import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 6import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
@@ -29,6 +29,8 @@ type Customizations = {
29 warningTitle: boolean 29 warningTitle: boolean
30 controlBar: boolean 30 controlBar: boolean
31 peertubeLink: boolean 31 peertubeLink: boolean
32
33 includeVideoInPlaylist: boolean
32} 34}
33 35
34type TabId = 'url' | 'qrcode' | 'embed' 36type TabId = 'url' | 'qrcode' | 'embed'
@@ -51,15 +53,23 @@ export class VideoShareComponent {
51 53
52 customizations: Customizations 54 customizations: Customizations
53 isAdvancedCustomizationCollapsed = true 55 isAdvancedCustomizationCollapsed = true
54 includeVideoInPlaylist = false
55 56
56 playlistEmbedHTML: SafeHtml 57 videoUrl: string
57 videoEmbedHTML: SafeHtml 58 playlistUrl: string
59
60 videoEmbedUrl: string
61 playlistEmbedUrl: string
62
63 videoEmbedHTML: string
64 videoEmbedSafeHTML: SafeHtml
65 playlistEmbedHTML: string
66 playlistEmbedSafeHTML: SafeHtml
58 67
59 constructor ( 68 constructor (
60 private modalService: NgbModal, 69 private modalService: NgbModal,
61 private sanitizer: DomSanitizer, 70 private sanitizer: DomSanitizer,
62 private server: ServerService 71 private server: ServerService,
72 private hooks: HooksService
63 ) { } 73 ) { }
64 74
65 show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) { 75 show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
@@ -89,7 +99,9 @@ export class VideoShareComponent {
89 title: true, 99 title: true,
90 warningTitle: true, 100 warningTitle: true,
91 controlBar: true, 101 controlBar: true,
92 peertubeLink: true 102 peertubeLink: true,
103
104 includeVideoInPlaylist: false
93 }, { 105 }, {
94 set: (target, prop, value) => { 106 set: (target, prop, value) => {
95 target[prop] = value 107 target[prop] = value
@@ -99,7 +111,7 @@ export class VideoShareComponent {
99 this.customizations.warningTitle = value 111 this.customizations.warningTitle = value
100 } 112 }
101 113
102 this.updateEmbedCode() 114 this.onUpdate()
103 115
104 return true 116 return true
105 } 117 }
@@ -107,50 +119,101 @@ export class VideoShareComponent {
107 119
108 this.playlistPosition = currentPlaylistPosition 120 this.playlistPosition = currentPlaylistPosition
109 121
110 this.updateEmbedCode() 122 this.onUpdate()
111
112 this.modalService.open(this.modal, { centered: true })
113 }
114
115 getVideoIframeCode () {
116 return buildVideoOrPlaylistEmbed(this.getVideoEmbedUrl(), this.video.name)
117 }
118 123
119 getVideoEmbedUrl () { 124 this.modalService.open(this.modal, { centered: true }).shown.subscribe(() => {
120 return decorateVideoLink({ url: this.video.embedUrl, ...this.getVideoOptions(true) }) 125 this.hooks.runAction('action:modal.share.shown', 'video-watch', { video: this.video, playlist: this.playlist })
121 } 126 })
122
123 getPlaylistEmbedUrl () {
124 return decoratePlaylistLink({ url: this.playlist.embedUrl, ...this.getPlaylistOptions() })
125 } 127 }
126 128
127 getPlaylistIframeCode () { 129 // ---------------------------------------------------------------------------
128 return buildVideoOrPlaylistEmbed(this.getPlaylistEmbedUrl(), this.playlist.displayName)
129 }
130 130
131 getVideoUrl () { 131 getVideoUrl () {
132 const url = this.customizations.originUrl 132 const url = this.customizations.originUrl
133 ? this.video.url 133 ? this.video.url
134 : buildVideoLink(this.video, window.location.origin) 134 : buildVideoLink(this.video, window.location.origin)
135 135
136 return decorateVideoLink({ 136 return this.hooks.wrapFun(
137 url, 137 decorateVideoLink,
138 { url, ...this.getVideoOptions(false) },
139 'video-watch',
140 'filter:share.video-url.build.params',
141 'filter:share.video-url.build.result'
142 )
143 }
138 144
139 ...this.getVideoOptions(false) 145 getVideoEmbedUrl () {
140 }) 146 return this.hooks.wrapFun(
147 decorateVideoLink,
148 { url: this.video.embedUrl, ...this.getVideoOptions(true) },
149 'video-watch',
150 'filter:share.video-embed-url.build.params',
151 'filter:share.video-embed-url.build.result'
152 )
153 }
154
155 async getVideoIframeCode () {
156 return this.hooks.wrapFun(
157 buildVideoOrPlaylistEmbed,
158 { embedUrl: await this.getVideoEmbedUrl(), embedTitle: this.video.name },
159 'video-watch',
160 'filter:share.video-embed-code.build.params',
161 'filter:share.video-embed-code.build.result'
162 )
141 } 163 }
142 164
165 // ---------------------------------------------------------------------------
166
143 getPlaylistUrl () { 167 getPlaylistUrl () {
144 const url = buildPlaylistLink(this.playlist) 168 const url = buildPlaylistLink(this.playlist)
145 if (!this.includeVideoInPlaylist) return url
146 169
147 return decoratePlaylistLink({ url, playlistPosition: this.playlistPosition }) 170 return this.hooks.wrapFun(
171 decoratePlaylistLink,
172 { url, ...this.getPlaylistOptions() },
173 'video-watch',
174 'filter:share.video-playlist-url.build.params',
175 'filter:share.video-playlist-url.build.result'
176 )
177 }
178
179 getPlaylistEmbedUrl () {
180 return this.hooks.wrapFun(
181 decoratePlaylistLink,
182 { url: this.playlist.embedUrl, ...this.getPlaylistOptions() },
183 'video-watch',
184 'filter:share.video-playlist-embed-url.build.params',
185 'filter:share.video-playlist-embed-url.build.result'
186 )
187 }
188
189 async getPlaylistEmbedCode () {
190 return this.hooks.wrapFun(
191 buildVideoOrPlaylistEmbed,
192 { embedUrl: await this.getPlaylistEmbedUrl(), embedTitle: this.playlist.displayName },
193 'video-watch',
194 'filter:share.video-playlist-embed-code.build.params',
195 'filter:share.video-playlist-embed-code.build.result'
196 )
148 } 197 }
149 198
150 updateEmbedCode () { 199 // ---------------------------------------------------------------------------
151 if (this.playlist) this.playlistEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getPlaylistIframeCode()) 200
201 async onUpdate () {
202 console.log('on update')
152 203
153 if (this.video) this.videoEmbedHTML = this.sanitizer.bypassSecurityTrustHtml(this.getVideoIframeCode()) 204 if (this.playlist) {
205 this.playlistUrl = await this.getPlaylistUrl()
206 this.playlistEmbedUrl = await this.getPlaylistEmbedUrl()
207 this.playlistEmbedHTML = await this.getPlaylistEmbedCode()
208 this.playlistEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.playlistEmbedHTML)
209 }
210
211 if (this.video) {
212 this.videoUrl = await this.getVideoUrl()
213 this.videoEmbedUrl = await this.getVideoEmbedUrl()
214 this.videoEmbedHTML = await this.getVideoIframeCode()
215 this.videoEmbedSafeHTML = this.sanitizer.bypassSecurityTrustHtml(this.videoEmbedHTML)
216 }
154 } 217 }
155 218
156 notSecure () { 219 notSecure () {
@@ -181,7 +244,9 @@ export class VideoShareComponent {
181 return { 244 return {
182 baseUrl, 245 baseUrl,
183 246
184 playlistPosition: this.playlistPosition || undefined 247 playlistPosition: this.playlistPosition && this.customizations.includeVideoInPlaylist
248 ? this.playlistPosition
249 : undefined
185 } 250 }
186 } 251 }
187 252
diff --git a/client/src/assets/player/shared/manager-options/manager-options-builder.ts b/client/src/assets/player/shared/manager-options/manager-options-builder.ts
index e454c719e..bc70bb12f 100644
--- a/client/src/assets/player/shared/manager-options/manager-options-builder.ts
+++ b/client/src/assets/player/shared/manager-options/manager-options-builder.ts
@@ -142,7 +142,7 @@ export class ManagerOptionsBuilder {
142 icon: 'code', 142 icon: 'code',
143 label: player.localize('Copy embed code'), 143 label: player.localize('Copy embed code'),
144 listener: () => { 144 listener: () => {
145 copyToClipboard(buildVideoOrPlaylistEmbed(commonOptions.embedUrl, commonOptions.embedTitle)) 145 copyToClipboard(buildVideoOrPlaylistEmbed({ embedUrl: commonOptions.embedUrl, embedTitle: commonOptions.embedTitle }))
146 } 146 }
147 } 147 }
148 ] 148 ]
diff --git a/client/src/root-helpers/video.ts b/client/src/root-helpers/video.ts
index 4290992aa..ba84e49ea 100644
--- a/client/src/root-helpers/video.ts
+++ b/client/src/root-helpers/video.ts
@@ -1,6 +1,11 @@
1import { HTMLServerConfig, Video } from '@shared/models' 1import { HTMLServerConfig, Video } from '@shared/models'
2 2
3function buildVideoOrPlaylistEmbed (embedUrl: string, embedTitle: string) { 3function buildVideoOrPlaylistEmbed (options: {
4 embedUrl: string
5 embedTitle: string
6}) {
7 const { embedUrl, embedTitle } = options
8
4 const iframe = document.createElement('iframe') 9 const iframe = document.createElement('iframe')
5 10
6 iframe.title = embedTitle 11 iframe.title = embedTitle
diff --git a/shared/models/plugins/client/client-hook.model.ts b/shared/models/plugins/client/client-hook.model.ts
index dda03124d..e6313b60e 100644
--- a/shared/models/plugins/client/client-hook.model.ts
+++ b/shared/models/plugins/client/client-hook.model.ts
@@ -72,6 +72,21 @@ export const clientFilterHookObject = {
72 'filter:login.instance-about-plugin-panels.create.result': true, 72 'filter:login.instance-about-plugin-panels.create.result': true,
73 'filter:signup.instance-about-plugin-panels.create.result': true, 73 'filter:signup.instance-about-plugin-panels.create.result': true,
74 74
75 'filter:share.video-embed-code.build.params': true,
76 'filter:share.video-embed-code.build.result': true,
77 'filter:share.video-playlist-embed-code.build.params': true,
78 'filter:share.video-playlist-embed-code.build.result': true,
79
80 'filter:share.video-embed-url.build.params': true,
81 'filter:share.video-embed-url.build.result': true,
82 'filter:share.video-playlist-embed-url.build.params': true,
83 'filter:share.video-playlist-embed-url.build.result': true,
84
85 'filter:share.video-url.build.params': true,
86 'filter:share.video-url.build.result': true,
87 'filter:share.video-playlist-url.build.params': true,
88 'filter:share.video-playlist-url.build.result': true,
89
75 // Filter videojs options built for PeerTube player 90 // Filter videojs options built for PeerTube player
76 'filter:internal.player.videojs.options.result': true 91 'filter:internal.player.videojs.options.result': true
77} 92}
@@ -146,6 +161,8 @@ export const clientActionHookObject = {
146 161
147 // Fired when the modal to download a video/caption is shown 162 // Fired when the modal to download a video/caption is shown
148 'action:modal.video-download.shown': true, 163 'action:modal.video-download.shown': true,
164 // Fired when the modal to share a video/playlist is shown
165 'action:modal.share.shown': true,
149 166
150 // ####### Embed hooks ####### 167 // ####### Embed hooks #######
151 // /!\ In embed scope, peertube helpers are not available 168 // /!\ In embed scope, peertube helpers are not available
diff --git a/shared/models/plugins/client/plugin-element-placeholder.type.ts b/shared/models/plugins/client/plugin-element-placeholder.type.ts
index 129099c62..7b8a2605b 100644
--- a/shared/models/plugins/client/plugin-element-placeholder.type.ts
+++ b/shared/models/plugins/client/plugin-element-placeholder.type.ts
@@ -1 +1,4 @@
1export type PluginElementPlaceholder = 'player-next' 1export type PluginElementPlaceholder =
2 'player-next' |
3 'share-modal-playlist-settings' |
4 'share-modal-video-settings'