diff options
author | Chocobozzz <me@florianbigard.com> | 2022-08-11 15:28:11 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2022-08-11 15:28:11 +0200 |
commit | de61544582726713c965d3369902f4a464f72e20 (patch) | |
tree | d66d87bb7d633906e1a36c4e72ee7109316db713 /client/src/app | |
parent | 2a95b88477a547c319108c0bab8692624df6804c (diff) | |
download | PeerTube-de61544582726713c965d3369902f4a464f72e20.tar.gz PeerTube-de61544582726713c965d3369902f4a464f72e20.tar.zst PeerTube-de61544582726713c965d3369902f4a464f72e20.zip |
Add plugin hooks/placeholder to share modal
Diffstat (limited to 'client/src/app')
5 files changed, 120 insertions, 52 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 @@ | |||
1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core' |
2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' | 2 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser' |
3 | import { ServerService } from '@app/core' | 3 | import { HooksService, ServerService } from '@app/core' |
4 | import { VideoDetails } from '@app/shared/shared-main' | 4 | import { VideoDetails } from '@app/shared/shared-main' |
5 | import { VideoPlaylist } from '@app/shared/shared-video-playlist' | 5 | import { VideoPlaylist } from '@app/shared/shared-video-playlist' |
6 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 6 | import { 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 | ||
34 | type TabId = 'url' | 'qrcode' | 'embed' | 36 | type 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 | ||