]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+videos/+video-edit/shared/video-edit.component.html
Revert matrix for docker build
[github/Chocobozzz/PeerTube.git] / client / src / app / +videos / +video-edit / shared / video-edit.component.html
1 <div class="video-edit" [formGroup]="form">
2 <div ngbNav #nav="ngbNav" class="nav-tabs">
3
4 <ng-template #pluginSettingTemplate let-pluginSetting>
5 <div class="form-group" [hidden]="isPluginFieldHidden(pluginSetting)">
6 <my-dynamic-form-field [form]="pluginDataFormGroup" [formErrors]="formErrors['pluginData']" [setting]="pluginSetting.commonOptions"></my-dynamic-form-field>
7 </div>
8 </ng-template>
9
10 <ng-container ngbNavItem>
11 <a ngbNavLink i18n>Basic info</a>
12
13 <ng-template ngbNavContent>
14 <div class="form-columns">
15 <div class="col-video-edit">
16 <div class="form-group">
17 <label i18n for="name">Title</label>
18 <input type="text" id="name" class="form-control" formControlName="name" />
19 <div *ngIf="formErrors.name" class="form-error">
20 {{ formErrors.name }}
21 </div>
22 </div>
23
24 <div class="form-group">
25 <label i18n class="label-tags">Tags</label>
26
27 <my-help>
28 <ng-template ptTemplate="customHtml">
29 <ng-container i18n>
30 Tags could be used to suggest relevant recommendations. <br />
31 There is a maximum of 5 tags. <br />
32 Press <kbd>Enter</kbd> to add a new tag.
33 </ng-container>
34 </ng-template>
35 </my-help>
36
37 <my-select-tags labelForId="label-tags" formControlName="tags"></my-select-tags>
38 <div *ngIf="formErrors.tags" class="form-error">
39 {{ formErrors.tags }}
40 </div>
41 </div>
42
43 <div class="form-group">
44 <label i18n for="description">Description</label>
45
46 <my-help helpType="markdownText">
47 <ng-template ptTemplate="preHtml">
48 <ng-container i18n>Video descriptions are truncated by default and require manual action to expand them.</ng-container>
49
50 <br />
51
52 <ng-container i18n>A timestamp (<i>00:05</i> for example) is automatically converted into a link to a part of the video.</ng-container>
53 </ng-template>
54 </my-help>
55
56 <my-markdown-textarea
57 formControlName="description" [markdownVideo]="videoToUpdate"
58 [formError]="formErrors.description" [truncate]="250"
59 ></my-markdown-textarea>
60 </div>
61 </div>
62
63 <div class="col-video-edit">
64 <div class="form-group">
65 <label i18n for="channel">Channel</label>
66 <my-select-channel labelForId="channel" [items]="userVideoChannels" formControlName="channelId"></my-select-channel>
67 </div>
68
69 <div class="form-group">
70 <label i18n for="category">Category</label>
71 <my-select-options
72 labelForId="category" [items]="videoCategories" formControlName="category" [clearable]="true"
73 ></my-select-options>
74
75 <div *ngIf="formErrors.category" class="form-error">
76 {{ formErrors.category }}
77 </div>
78 </div>
79
80 <div class="form-group">
81 <label i18n for="licence">Licence</label>
82
83 <my-help>
84 <ng-template ptTemplate="customHtml">
85 <ng-container i18n>
86 <a href="https://chooser-beta.creativecommons.org/" target="_blank" rel="noopener noreferrer">Choose</a> the appropriate licence for your work.
87 </ng-container>
88 </ng-template>
89 </my-help>
90
91 <my-select-options
92 labelForId="licence" [items]="videoLicences" formControlName="licence" [clearable]="true"
93 ></my-select-options>
94
95 <div *ngIf="formErrors.licence" class="form-error">
96 {{ formErrors.licence }}
97 </div>
98 </div>
99
100 <div class="form-group">
101 <label i18n for="language">Language</label>
102 <my-select-options
103 labelForId="language" [items]="videoLanguages" formControlName="language"
104 [clearable]="true" [searchable]="true" [groupBy]="'group'"
105 ></my-select-options>
106
107 <div *ngIf="formErrors.language" class="form-error">
108 {{ formErrors.language }}
109 </div>
110 </div>
111
112 <div class="form-group">
113 <label i18n for="privacy">Privacy</label>
114 <my-select-options
115 labelForId="privacy" [items]="videoPrivacies" formControlName="privacy" [clearable]="false"
116 ></my-select-options>
117
118 <div *ngIf="formErrors.privacy" class="form-error">
119 {{ formErrors.privacy }}
120 </div>
121 </div>
122
123 <div *ngIf="schedulePublicationEnabled" class="form-group">
124 <label i18n for="schedulePublicationAt">Schedule publication ({{ calendarTimezone }})</label>
125 <p-calendar
126 id="schedulePublicationAt" formControlName="schedulePublicationAt" [dateFormat]="calendarDateFormat"
127 [firstDayOfWeek]="0" [minDate]="minScheduledDate" [showTime]="true" [hideOnDateTimeSelect]="true"
128 >
129 </p-calendar>
130
131 <div *ngIf="formErrors.schedulePublicationAt" class="form-error">
132 {{ formErrors.schedulePublicationAt }}
133 </div>
134 </div>
135
136 <my-peertube-checkbox inputName="nsfw" formControlName="nsfw" helpPlacement="bottom-right">
137 <ng-template ptTemplate="label">
138 <ng-container i18n>Contains sensitive content</ng-container>
139 </ng-template>
140
141 <ng-template ptTemplate="help">
142 <ng-container i18n>Some instances hide videos containing mature or explicit content by default.</ng-container>
143 </ng-template>
144 </my-peertube-checkbox>
145
146 <my-peertube-checkbox *ngIf="!hideWaitTranscoding" inputName="waitTranscoding" formControlName="waitTranscoding" helpPlacement="bottom-right">
147 <ng-template ptTemplate="label">
148 <ng-container i18n>Publish after transcoding</ng-container>
149 </ng-template>
150
151 <ng-template ptTemplate="help">
152 <ng-container i18n>The video may be unplayable during the transcoding process. It's the reason why we prefer to publish publicly the video after transcoding.</ng-container>
153 </ng-template>
154 </my-peertube-checkbox>
155
156 <ng-container
157 *ngFor="let pluginSetting of getPluginsFields('main')"
158 [ngTemplateOutlet]="pluginSettingTemplate" [ngTemplateOutletContext]="{ $implicit: pluginSetting }"
159 >
160 </ng-container>
161 </div>
162 </div>
163 </ng-template>
164 </ng-container>
165
166 <ng-container ngbNavItem *ngIf="!liveVideo">
167 <a ngbNavLink i18n>Captions</a>
168
169 <ng-template ngbNavContent>
170 <div class="captions">
171
172 <div class="captions-header">
173 <a (click)="openAddCaptionModal()" class="create-caption">
174 <my-global-icon iconName="add" aria-hidden="true"></my-global-icon>
175 <ng-container i18n>Add another caption</ng-container>
176 </a>
177 </div>
178
179 <div class="form-group" *ngFor="let videoCaption of videoCaptions">
180
181 <div class="caption-entry">
182 <ng-container *ngIf="!videoCaption.action">
183 <a
184 i18n-title title="See the subtitle file" class="caption-entry-label" target="_blank" rel="noopener noreferrer"
185 [href]="videoCaption.captionPath"
186 >{{ videoCaption.language.label }}</a>
187
188 <div i18n class="caption-entry-state">Already uploaded on {{ videoCaption.updatedAt | date }} &#10004;</div>
189
190 <span i18n class="caption-entry-edit" (click)="openEditCaptionModal(videoCaption)">Edit</span>
191 <span i18n class="caption-entry-delete" (click)="deleteCaption(videoCaption)">Delete</span>
192 </ng-container>
193
194 <ng-container *ngIf="videoCaption.action === 'CREATE'">
195 <span class="caption-entry-label">{{ videoCaption.language.label }}</span>
196
197 <div i18n class="caption-entry-state caption-entry-state-create">Will be created on update</div>
198
199 <span i18n class="caption-entry-delete" (click)="deleteCaption(videoCaption)">Cancel create</span>
200 </ng-container>
201
202 <ng-container *ngIf="videoCaption.action === 'UPDATE'">
203 <span class="caption-entry-label">{{ videoCaption.language.label }}</span>
204
205 <div i18n class="caption-entry-state caption-entry-state-create">Will be edited on update</div>
206
207 <span i18n class="caption-entry-delete" (click)="deleteCaption(videoCaption)">Cancel edition</span>
208 </ng-container>
209
210 <ng-container *ngIf="videoCaption.action === 'REMOVE'">
211 <span class="caption-entry-label">{{ videoCaption.language.label }}</span>
212
213 <div i18n class="caption-entry-state caption-entry-state-delete">Will be deleted on update</div>
214
215 <span i18n class="caption-entry-delete" (click)="deleteCaption(videoCaption)">Cancel deletion</span>
216 </ng-container>
217 </div>
218 </div>
219
220 <div i18n class="no-caption" *ngIf="videoCaptions?.length === 0">
221 No captions for now.
222 </div>
223
224 </div>
225 </ng-template>
226 </ng-container>
227
228 <ng-container ngbNavItem *ngIf="liveVideo">
229 <a ngbNavLink i18n>Live settings</a>
230
231 <ng-template ngbNavContent>
232 <div class="row live-settings">
233 <div class="col-md-12">
234 <div class="alert pt-alert-primary">
235 <my-live-documentation-link></my-live-documentation-link>
236 </div>
237
238 <div *ngIf="liveVideo.rtmpUrl" class="form-group">
239 <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label>
240 <my-input-text inputId="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
241 </div>
242
243 <div *ngIf="liveVideo.rtmpsUrl" class="form-group">
244 <label for="liveVideoRTMPSUrl" i18n>Live RTMPS Url</label>
245 <my-input-text inputId="liveVideoRTMPSUrl" [value]="liveVideo.rtmpsUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-text>
246 </div>
247
248 <div class="form-group">
249 <label for="liveVideoStreamKey" i18n>Live stream key</label>
250 <my-input-text inputId="liveVideoStreamKey" [value]="liveVideo.streamKey" [withCopy]="true" [readonly]="true"></my-input-text>
251
252 <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div>
253 </div>
254
255 <div class="form-group">
256 <div class="peertube-radio-container">
257 <input type="radio" formControlName="permanentLive" id="permanentLiveFalse" [value]="false">
258 <label i18n for="permanentLiveFalse" class="radio">This is a normal live</label>
259
260 <span class="form-group-description" i18n>
261 You can stream only once in a normal live. If you enable replay, it will be saved under the same URL as your live
262 </span>
263 </div>
264
265 <div class="peertube-radio-container">
266 <input type="radio" formControlName="permanentLive" id="permanentLiveTrue" [value]="true">
267 <label i18n for="permanentLiveTrue" class="radio">This is a permanent/recurring live</label>
268
269 <span class="form-group-description" i18n>
270 You can stream multiple times in a permanent/recurring live. If you enable replays, they will be saved as separate videos
271 </span>
272 </div>
273 </div>
274
275 <div class="form-group" *ngIf="isSaveReplayEnabled()">
276 <my-peertube-checkbox inputName="liveVideoSaveReplay" formControlName="saveReplay">
277 <ng-template ptTemplate="label">
278 <ng-container i18n>Automatically publish a replay when your live ends</ng-container>
279 </ng-template>
280
281 <ng-container ngProjectAs="description">
282 <span i18n>⚠️ If you enable this option, your live will be terminated if you exceed your video quota</span>
283 </ng-container>
284 </my-peertube-checkbox>
285 </div>
286
287 <div class="form-group" *ngIf="isLatencyModeEnabled()">
288 <label i18n for="latencyMode">Latency mode</label>
289 <my-select-options
290 labelForId="latencyMode" [items]="latencyModes" formControlName="latencyMode" [clearable]="true"
291 ></my-select-options>
292
293 <div *ngIf="formErrors.latencyMode" class="form-error">
294 {{ formErrors.latencyMode }}
295 </div>
296 </div>
297 </div>
298 </div>
299 </ng-template>
300
301 </ng-container>
302
303
304 <ng-container ngbNavItem>
305 <a ngbNavLink i18n>Advanced settings</a>
306
307 <ng-template ngbNavContent>
308 <div class="row advanced-settings">
309 <div class="col-md-12 col-xl-8">
310
311 <div class="form-group">
312 <label i18n for="previewfile">Video thumbnail</label>
313
314 <my-preview-upload
315 i18n-inputLabel inputLabel="Edit" inputName="previewfile" formControlName="previewfile"
316 previewWidth="360px" previewHeight="200px"
317 ></my-preview-upload>
318 </div>
319
320 <div class="form-group">
321 <label i18n for="support">Support</label>
322 <my-help helpType="markdownEnhanced">
323 <ng-template ptTemplate="preHtml">
324 <ng-container i18n>
325 Short text to tell people how they can support you (membership platform...).
326 </ng-container>
327 </ng-template>
328 </my-help>
329
330 <my-markdown-textarea
331 id="support" formControlName="support" markdownType="enhanced"
332 [formError]="formErrors['support']"
333 ></my-markdown-textarea>
334 </div>
335 </div>
336
337 <div class="col-md-12 col-xl-4">
338
339 <div *ngIf="videoSource" class="form-group">
340 <label i18n for="filename">Filename</label>
341
342 <my-help>
343 <ng-template ptTemplate="preHtml">
344 <ng-container i18n>
345 Name of the uploaded file
346 </ng-container>
347 </ng-template>
348 </my-help>
349
350 <input type="text" [disabled]="true" id="filename" class="form-control" [value]="videoSource.filename" />
351 </div>
352
353 <div class="form-group originally-published-at">
354 <label i18n for="originallyPublishedAt">Original publication date</label>
355 <my-help>
356 <ng-template ptTemplate="preHtml">
357 <ng-container i18n>
358 This is the date when the content was originally published (e.g. the release date for a film)
359 </ng-container>
360 </ng-template>
361 </my-help>
362 <p-calendar
363 id="originallyPublishedAt" formControlName="originallyPublishedAt" [dateFormat]="calendarDateFormat" [firstDayOfWeek]="0"
364 [showTime]="true" [hideOnDateTimeSelect]="true" [monthNavigator]="true" [yearNavigator]="true" [yearRange]="myYearRange"
365 >
366 </p-calendar>
367
368 <div *ngIf="formErrors.originallyPublishedAt" class="form-error">
369 {{ formErrors.originallyPublishedAt }}
370 </div>
371 </div>
372
373 <my-peertube-checkbox
374 inputName="commentsEnabled" formControlName="commentsEnabled"
375 i18n-labelText labelText="Enable video comments"
376 ></my-peertube-checkbox>
377
378 <my-peertube-checkbox
379 inputName="downloadEnabled" formControlName="downloadEnabled"
380 i18n-labelText labelText="Enable download"
381 ></my-peertube-checkbox>
382 </div>
383 </div>
384 </ng-template>
385 </ng-container>
386
387 <ng-container ngbNavItem *ngIf="getPluginsFields('plugin-settings').length !== 0">
388 <a ngbNavLink i18n>Plugin settings</a>
389
390 <ng-template ngbNavContent>
391 <div class="row plugin-settings">
392
393 <div class="col-md-12 col-xl-8">
394 <ng-container
395 *ngFor="let pluginSetting of getPluginsFields('plugin-settings')"
396 [ngTemplateOutlet]="pluginSettingTemplate" [ngTemplateOutletContext]="{ $implicit: pluginSetting }"
397 >
398 </ng-container>
399 </div>
400
401 </div>
402 </ng-template>
403 </ng-container>
404 </div>
405
406 <div [ngbNavOutlet]="nav"></div>
407 </div>
408
409 <my-video-caption-add-modal
410 #videoCaptionAddModal [existingCaptions]="getExistingCaptions()" [serverConfig]="serverConfig" (captionAdded)="onCaptionEdited($event)"
411 ></my-video-caption-add-modal>