diff options
Diffstat (limited to 'client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html')
-rw-r--r-- | client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html | 1192 |
1 files changed, 10 insertions, 1182 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html index 135276192..534b03517 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html | |||
@@ -7,231 +7,8 @@ | |||
7 | <a ngbNavLink i18n>Instance information</a> | 7 | <a ngbNavLink i18n>Instance information</a> |
8 | 8 | ||
9 | <ng-template ngbNavContent> | 9 | <ng-template ngbNavContent> |
10 | 10 | <my-edit-instance-information [form]="form" [formErrors]="formErrors" [languageItems]="languageItems" [categoryItems]="categoryItems"> | |
11 | <ng-container formGroupName="instance"> | 11 | </my-edit-instance-information> |
12 | |||
13 | <div class="form-row mt-5"> <!-- instance grid --> | ||
14 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
15 | <div i18n class="inner-form-title">INSTANCE</div> | ||
16 | </div> | ||
17 | |||
18 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
19 | |||
20 | <div class="form-group"> | ||
21 | <label i18n for="instanceName">Name</label> | ||
22 | <input | ||
23 | type="text" id="instanceName" class="form-control" | ||
24 | formControlName="name" [ngClass]="{ 'input-error': formErrors.instance.name }" | ||
25 | > | ||
26 | <div *ngIf="formErrors.instance.name" class="form-error">{{ formErrors.instance.name }}</div> | ||
27 | </div> | ||
28 | |||
29 | <div class="form-group"> | ||
30 | <label i18n for="instanceShortDescription">Short description</label> | ||
31 | <textarea | ||
32 | id="instanceShortDescription" formControlName="shortDescription" class="form-control small" | ||
33 | [ngClass]="{ 'input-error': formErrors['instance.shortDescription'] }" | ||
34 | ></textarea> | ||
35 | <div *ngIf="formErrors.instance.shortDescription" class="form-error">{{ formErrors.instance.shortDescription }}</div> | ||
36 | </div> | ||
37 | |||
38 | <div class="form-group"> | ||
39 | <label i18n for="instanceDescription">Description</label><my-help helpType="markdownText"></my-help> | ||
40 | <my-markdown-textarea | ||
41 | name="instanceDescription" formControlName="description" textareaMaxWidth="500px" | ||
42 | [classes]="{ 'input-error': formErrors['instance.description'] }" | ||
43 | ></my-markdown-textarea> | ||
44 | <div *ngIf="formErrors.instance.description" class="form-error">{{ formErrors.instance.description }}</div> | ||
45 | </div> | ||
46 | |||
47 | <div class="form-group"> | ||
48 | <label i18n for="instanceCategories">Main instance categories</label> | ||
49 | |||
50 | <div> | ||
51 | <my-select-checkbox | ||
52 | id="instanceCategories" | ||
53 | formControlName="categories" [availableItems]="categoryItems" | ||
54 | [selectableGroup]="false" | ||
55 | i18n-placeholder placeholder="Add a new category" | ||
56 | > | ||
57 | </my-select-checkbox> | ||
58 | </div> | ||
59 | </div> | ||
60 | |||
61 | <div class="form-group"> | ||
62 | <label i18n for="instanceLanguages">Main languages you/your moderators speak</label> | ||
63 | |||
64 | <div> | ||
65 | <my-select-checkbox | ||
66 | id="instanceLanguages" | ||
67 | formControlName="languages" [availableItems]="languageItems" | ||
68 | [selectableGroup]="false" | ||
69 | i18n-placeholder placeholder="Add a new language" | ||
70 | > | ||
71 | </my-select-checkbox> | ||
72 | </div> | ||
73 | </div> | ||
74 | |||
75 | </div> | ||
76 | </div> | ||
77 | |||
78 | <div class="form-row mt-4"> <!-- moderation & nsfw grid --> | ||
79 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
80 | <div i18n class="inner-form-title">MODERATION & NSFW</div> | ||
81 | <div i18n class="inner-for-description"> | ||
82 | Manage <a routerLink="/admin/users">users</a> to build a moderation team. | ||
83 | </div> | ||
84 | </div> | ||
85 | |||
86 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
87 | |||
88 | <div class="form-group"> | ||
89 | <my-peertube-checkbox inputName="instanceIsNSFW" formControlName="isNSFW"> | ||
90 | <ng-template ptTemplate="label"> | ||
91 | <ng-container i18n>This instance is dedicated to sensitive or NSFW content</ng-container> | ||
92 | </ng-template> | ||
93 | |||
94 | <ng-template ptTemplate="help"> | ||
95 | <ng-container i18n> | ||
96 | Enabling it will allow other administrators to know that you are mainly federating sensitive content.<br /><br /> | ||
97 | Moreover, the NSFW checkbox on video upload will be automatically checked by default. | ||
98 | </ng-container> | ||
99 | </ng-template> | ||
100 | </my-peertube-checkbox> | ||
101 | </div> | ||
102 | |||
103 | <div class="form-group"> | ||
104 | <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> | ||
105 | |||
106 | <my-help> | ||
107 | <ng-template ptTemplate="customHtml"> | ||
108 | <ng-container i18n> | ||
109 | With <strong>Do not list</strong> or <strong>Blur thumbnails</strong>, a confirmation will be requested to watch the video. | ||
110 | </ng-container> | ||
111 | </ng-template> | ||
112 | </my-help> | ||
113 | |||
114 | <div class="peertube-select-container"> | ||
115 | <select id="instanceDefaultNSFWPolicy" formControlName="defaultNSFWPolicy" class="form-control"> | ||
116 | <option i18n value="undefined" disabled>Policy for sensitive videos</option> | ||
117 | <option i18n value="do_not_list">Do not list</option> | ||
118 | <option i18n value="blur">Blur thumbnails</option> | ||
119 | <option i18n value="display">Display</option> | ||
120 | </select> | ||
121 | </div> | ||
122 | <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div> | ||
123 | </div> | ||
124 | |||
125 | <div class="form-group"> | ||
126 | <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> | ||
127 | <my-markdown-textarea | ||
128 | name="instanceTerms" formControlName="terms" textareaMaxWidth="500px" | ||
129 | [ngClass]="{ 'input-error': formErrors['instance.terms'] }" | ||
130 | ></my-markdown-textarea> | ||
131 | <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div> | ||
132 | </div> | ||
133 | |||
134 | <div class="form-group"> | ||
135 | <label i18n for="instanceCodeOfConduct">Code of conduct</label><my-help helpType="markdownText"></my-help> | ||
136 | <my-markdown-textarea | ||
137 | name="instanceCodeOfConduct" formControlName="codeOfConduct" textareaMaxWidth="500px" | ||
138 | [ngClass]="{ 'input-error': formErrors['instance.codeOfConduct'] }" | ||
139 | ></my-markdown-textarea> | ||
140 | <div *ngIf="formErrors.instance.codeOfConduct" class="form-error">{{ formErrors.instance.codeOfConduct }}</div> | ||
141 | </div> | ||
142 | |||
143 | <div class="form-group"> | ||
144 | <label i18n for="instanceModerationInformation">Moderation information</label><my-help helpType="markdownText"></my-help> | ||
145 | <div i18n class="label-small-info">Who moderates the instance? What is the policy regarding NSFW videos? Political videos? etc</div> | ||
146 | |||
147 | <my-markdown-textarea | ||
148 | name="instanceModerationInformation" formControlName="moderationInformation" textareaMaxWidth="500px" | ||
149 | [ngClass]="{ 'input-error': formErrors['instance.moderationInformation'] }" | ||
150 | ></my-markdown-textarea> | ||
151 | <div *ngIf="formErrors.instance.moderationInformation" class="form-error">{{ formErrors.instance.moderationInformation }}</div> | ||
152 | </div> | ||
153 | |||
154 | </div> | ||
155 | </div> | ||
156 | |||
157 | <div class="form-row mt-4"> <!-- you and your instance grid --> | ||
158 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
159 | <div i18n class="inner-form-title">YOU AND YOUR INSTANCE</div> | ||
160 | </div> | ||
161 | |||
162 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
163 | |||
164 | <div class="form-group"> | ||
165 | <label i18n for="instanceAdministrator">Who is behind the instance?</label><my-help helpType="markdownText"></my-help> | ||
166 | <div i18n class="label-small-info">A single person? A non-profit? A company?</div> | ||
167 | |||
168 | <my-markdown-textarea | ||
169 | name="instanceAdministrator" formControlName="administrator" textareaMaxWidth="500px" | ||
170 | [classes]="{ 'input-error': formErrors['instance.administrator'] }" | ||
171 | ></my-markdown-textarea> | ||
172 | |||
173 | <div *ngIf="formErrors.instance.administrator" class="form-error">{{ formErrors.instance.administrator }}</div> | ||
174 | </div> | ||
175 | |||
176 | <div class="form-group"> | ||
177 | <label i18n for="instanceCreationReason">Why did you create this instance?</label><my-help helpType="markdownText"></my-help> | ||
178 | <div i18n class="label-small-info">To share your personal videos? To open registrations and allow people to upload what they want?</div> | ||
179 | |||
180 | <my-markdown-textarea | ||
181 | name="instanceCreationReason" formControlName="creationReason" textareaMaxWidth="500px" | ||
182 | [ngClass]="{ 'input-error': formErrors['instance.creationReason'] }" | ||
183 | ></my-markdown-textarea> | ||
184 | <div *ngIf="formErrors.instance.creationReason" class="form-error">{{ formErrors.instance.creationReason }}</div> | ||
185 | </div> | ||
186 | |||
187 | <div class="form-group"> | ||
188 | <label i18n for="instanceMaintenanceLifetime">How long do you plan to maintain this instance?</label><my-help helpType="markdownText"></my-help> | ||
189 | <div i18n class="label-small-info">It's important to know for users who want to register on your instance</div> | ||
190 | |||
191 | <my-markdown-textarea | ||
192 | name="instanceMaintenanceLifetime" formControlName="maintenanceLifetime" textareaMaxWidth="500px" | ||
193 | [ngClass]="{ 'input-error': formErrors['instance.maintenanceLifetime'] }" | ||
194 | ></my-markdown-textarea> | ||
195 | <div *ngIf="formErrors.instance.maintenanceLifetime" class="form-error">{{ formErrors.instance.maintenanceLifetime }}</div> | ||
196 | </div> | ||
197 | |||
198 | <div class="form-group"> | ||
199 | <label i18n for="instanceBusinessModel">How will you finance the PeerTube server?</label><my-help helpType="markdownText"></my-help> | ||
200 | <div i18n class="label-small-info">With your own funds? With user donations? Advertising?</div> | ||
201 | |||
202 | <my-markdown-textarea | ||
203 | name="instanceBusinessModel" formControlName="businessModel" textareaMaxWidth="500px" | ||
204 | [ngClass]="{ 'input-error': formErrors['instance.businessModel'] }" | ||
205 | ></my-markdown-textarea> | ||
206 | <div *ngIf="formErrors.instance.businessModel" class="form-error">{{ formErrors.instance.businessModel }}</div> | ||
207 | </div> | ||
208 | |||
209 | </div> | ||
210 | </div> | ||
211 | |||
212 | <div class="form-row mt-4"> <!-- other information grid --> | ||
213 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
214 | <div i18n class="inner-form-title">OTHER INFORMATION</div> | ||
215 | </div> | ||
216 | |||
217 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
218 | |||
219 | <div class="form-group"> | ||
220 | <label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label> | ||
221 | <div i18n class="label-small-info">i.e. 2vCore 2GB RAM, a direct the link to the server you rent, etc.</div> | ||
222 | |||
223 | <my-markdown-textarea | ||
224 | name="instanceHardwareInformation" formControlName="hardwareInformation" textareaMaxWidth="500px" | ||
225 | [classes]="{ 'input-error': formErrors['instance.hardwareInformation'] }" | ||
226 | ></my-markdown-textarea> | ||
227 | |||
228 | <div *ngIf="formErrors.instance.hardwareInformation" class="form-error">{{ formErrors.instance.hardwareInformation }}</div> | ||
229 | </div> | ||
230 | |||
231 | </div> | ||
232 | </div> | ||
233 | |||
234 | </ng-container> | ||
235 | </ng-template> | 12 | </ng-template> |
236 | </ng-container> | 13 | </ng-container> |
237 | 14 | ||
@@ -239,502 +16,8 @@ | |||
239 | <a ngbNavLink i18n>Basic configuration</a> | 16 | <a ngbNavLink i18n>Basic configuration</a> |
240 | 17 | ||
241 | <ng-template ngbNavContent> | 18 | <ng-template ngbNavContent> |
242 | 19 | <my-edit-basic-configuration [form]="form" [formErrors]="formErrors" [serverConfig]="serverConfig"> | |
243 | <div class="form-row mt-5"> <!-- appearance grid --> | 20 | </my-edit-basic-configuration> |
244 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
245 | <div i18n class="inner-form-title">APPEARANCE</div> | ||
246 | <div i18n class="inner-form-description"> | ||
247 | Use <a routerLink="/admin/plugins">plugins & themes</a> for more involved changes, or <a routerLink="/admin/config/edit-custom" fragment="customizations" (click)="gotoAnchor()">add slight customizations</a>. | ||
248 | </div> | ||
249 | </div> | ||
250 | |||
251 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
252 | |||
253 | <ng-container formGroupName="theme"> | ||
254 | <div class="form-group"> | ||
255 | <label i18n for="themeDefault">Theme</label> | ||
256 | |||
257 | <div class="peertube-select-container"> | ||
258 | <select formControlName="default" id="themeDefault" class="form-control"> | ||
259 | <option i18n value="default">default</option> | ||
260 | |||
261 | <option *ngFor="let theme of availableThemes" [value]="theme">{{ theme }}</option> | ||
262 | </select> | ||
263 | </div> | ||
264 | </div> | ||
265 | </ng-container> | ||
266 | |||
267 | <div class="form-group" formGroupName="instance"> | ||
268 | <label i18n for="instanceDefaultClientRoute">Landing page</label> | ||
269 | <div class="peertube-select-container"> | ||
270 | <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute" class="form-control"> | ||
271 | <option i18n value="/videos/overview">Discover videos</option> | ||
272 | <optgroup i18n-label label="Trending pages"> | ||
273 | <option i18n value="/videos/trending">Default trending page</option> | ||
274 | <option i18n value="/videos/trending?alg=best" [disabled]="!trendingVideosAlgorithmsEnabledIncludes('best')">Best videos</option> | ||
275 | <option i18n value="/videos/trending?alg=hot" [disabled]="!trendingVideosAlgorithmsEnabledIncludes('hot')">Hot videos</option> | ||
276 | <option i18n value="/videos/trending?alg=most-viewed" [disabled]="!trendingVideosAlgorithmsEnabledIncludes('most-viewed')">Most viewed videos</option> | ||
277 | <option i18n value="/videos/trending?alg=most-liked" [disabled]="!trendingVideosAlgorithmsEnabledIncludes('most-liked')">Most liked videos</option> | ||
278 | </optgroup> | ||
279 | <option i18n value="/videos/recently-added">Recently added videos</option> | ||
280 | <option i18n value="/videos/local">Local videos</option> | ||
281 | </select> | ||
282 | </div> | ||
283 | <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div> | ||
284 | </div> | ||
285 | |||
286 | <div class="form-group" formGroupName="trending"> | ||
287 | <ng-container formGroupName="videos"> | ||
288 | <ng-container formGroupName="algorithms"> | ||
289 | <label i18n for="trendingVideosAlgorithmsDefault">Default trending page</label> | ||
290 | <div class="peertube-select-container"> | ||
291 | <select id="trendingVideosAlgorithmsDefault" formControlName="default" class="form-control"> | ||
292 | <option i18n value="best">Best videos</option> | ||
293 | <option i18n value="hot">Hot videos</option> | ||
294 | <option i18n value="most-viewed">Most viewed videos</option> | ||
295 | <option i18n value="most-liked">Most liked videos</option> | ||
296 | </select> | ||
297 | </div> | ||
298 | <div *ngIf="formErrors.trending.videos.algorithms.default" class="form-error">{{ formErrors.trending.videos.algorithms.default }}</div> | ||
299 | </ng-container> | ||
300 | </ng-container> | ||
301 | </div> | ||
302 | |||
303 | </div> | ||
304 | </div> | ||
305 | |||
306 | <div class="form-row mt-4"> <!-- broadcast grid --> | ||
307 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
308 | <div i18n class="inner-form-title">BROADCAST MESSAGE</div> | ||
309 | <div i18n class="inner-for-description"> | ||
310 | Display a message on your instance | ||
311 | </div> | ||
312 | </div> | ||
313 | |||
314 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
315 | |||
316 | <ng-container formGroupName="broadcastMessage"> | ||
317 | |||
318 | <div class="form-group"> | ||
319 | <my-peertube-checkbox | ||
320 | inputName="broadcastMessageEnabled" formControlName="enabled" | ||
321 | i18n-labelText labelText="Enable broadcast message" | ||
322 | ></my-peertube-checkbox> | ||
323 | </div> | ||
324 | |||
325 | <div class="form-group"> | ||
326 | <my-peertube-checkbox | ||
327 | inputName="broadcastMessageDismissable" formControlName="dismissable" | ||
328 | i18n-labelText labelText="Allow users to dismiss the broadcast message " | ||
329 | ></my-peertube-checkbox> | ||
330 | </div> | ||
331 | |||
332 | <div class="form-group"> | ||
333 | <label i18n for="broadcastMessageLevel">Broadcast message level</label> | ||
334 | <div class="peertube-select-container"> | ||
335 | <select id="broadcastMessageLevel" formControlName="level" class="form-control"> | ||
336 | <option value="info">info</option> | ||
337 | <option value="warning">warning</option> | ||
338 | <option value="error">error</option> | ||
339 | </select> | ||
340 | </div> | ||
341 | <div *ngIf="formErrors.broadcastMessage.level" class="form-error">{{ formErrors.broadcastMessage.level }}</div> | ||
342 | </div> | ||
343 | |||
344 | <div class="form-group"> | ||
345 | <label i18n for="broadcastMessageMessage">Message</label><my-help helpType="markdownText"></my-help> | ||
346 | <my-markdown-textarea | ||
347 | name="broadcastMessageMessage" formControlName="message" textareaMaxWidth="500px" | ||
348 | [classes]="{ 'input-error': formErrors['broadcastMessage.message'] }" | ||
349 | ></my-markdown-textarea> | ||
350 | <div *ngIf="formErrors.broadcastMessage.message" class="form-error">{{ formErrors.broadcastMessage.message }}</div> | ||
351 | </div> | ||
352 | |||
353 | </ng-container> | ||
354 | |||
355 | </div> | ||
356 | </div> | ||
357 | |||
358 | <div class="form-row mt-4"> <!-- new users grid --> | ||
359 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
360 | <div i18n class="inner-form-title">NEW USERS</div> | ||
361 | <div i18n class="inner-for-description"> | ||
362 | Manage <a routerLink="/admin/users">users</a> to set their quota individually. | ||
363 | </div> | ||
364 | </div> | ||
365 | |||
366 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
367 | |||
368 | <ng-container formGroupName="signup"> | ||
369 | <div class="form-group"> | ||
370 | <my-peertube-checkbox | ||
371 | inputName="signupEnabled" formControlName="enabled" | ||
372 | i18n-labelText labelText="Enable Signup" | ||
373 | > | ||
374 | <ng-container ngProjectAs="description"> | ||
375 | <span i18n>⚠️ This functionality requires a lot of attention and extra moderation.</span> | ||
376 | |||
377 | <div class="alert alert-info alert-signup" *ngIf="signupAlertMessage">{{ signupAlertMessage }}</div> | ||
378 | </ng-container> | ||
379 | <ng-container ngProjectAs="extra"> | ||
380 | <my-peertube-checkbox [ngClass]="{ 'disabled-checkbox-extra': !isSignupEnabled() }" | ||
381 | inputName="signupRequiresEmailVerification" formControlName="requiresEmailVerification" | ||
382 | i18n-labelText labelText="Signup requires email verification" | ||
383 | ></my-peertube-checkbox> | ||
384 | |||
385 | <div [ngClass]="{ 'disabled-checkbox-extra': !isSignupEnabled() }" class="mt-3"> | ||
386 | <label i18n for="signupLimit">Signup limit</label> | ||
387 | <div class="number-with-unit"> | ||
388 | <input | ||
389 | type="number" min="-1" id="signupLimit" class="form-control" | ||
390 | formControlName="limit" [ngClass]="{ 'input-error': formErrors['signup.limit'] }" | ||
391 | > | ||
392 | <span i18n>{form.value['signup']['limit'], plural, =1 {user} other {users}}</span> | ||
393 | </div> | ||
394 | <div *ngIf="formErrors.signup.limit" class="form-error">{{ formErrors.signup.limit }}</div> | ||
395 | <small *ngIf="form.value['signup']['limit'] === -1" class="text-muted">Signup won't be limited to a fixed number of users.</small> | ||
396 | </div> | ||
397 | </ng-container> | ||
398 | </my-peertube-checkbox> | ||
399 | </div> | ||
400 | </ng-container> | ||
401 | |||
402 | <ng-container formGroupName="user"> | ||
403 | <div class="form-group"> | ||
404 | <label i18n for="userVideoQuota">Default video quota per user</label> | ||
405 | |||
406 | <my-select-custom-value | ||
407 | id="userVideoQuota" | ||
408 | [items]="videoQuotaOptions" | ||
409 | formControlName="videoQuota" | ||
410 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
411 | [clearable]="false" | ||
412 | ></my-select-custom-value> | ||
413 | |||
414 | <div *ngIf="formErrors.user.videoQuota" class="form-error">{{ formErrors.user.videoQuota }}</div> | ||
415 | </div> | ||
416 | |||
417 | <div class="form-group"> | ||
418 | <label i18n for="userVideoQuotaDaily">Default daily upload limit per user</label> | ||
419 | |||
420 | <my-select-custom-value | ||
421 | id="userVideoQuotaDaily" | ||
422 | [items]="videoQuotaDailyOptions" | ||
423 | formControlName="videoQuotaDaily" | ||
424 | i18n-inputSuffix inputSuffix="bytes" inputType="number" | ||
425 | [clearable]="false" | ||
426 | ></my-select-custom-value> | ||
427 | |||
428 | <div *ngIf="formErrors.user.videoQuotaDaily" class="form-error">{{ formErrors.user.videoQuotaDaily }}</div> | ||
429 | </div> | ||
430 | </ng-container> | ||
431 | |||
432 | </div> | ||
433 | </div> | ||
434 | |||
435 | <div class="form-row mt-4"> <!-- videos grid --> | ||
436 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
437 | <div i18n class="inner-form-title">VIDEOS</div> | ||
438 | </div> | ||
439 | |||
440 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
441 | |||
442 | <ng-container formGroupName="import"> | ||
443 | |||
444 | <ng-container formGroupName="videos"> | ||
445 | |||
446 | <div class="form-group mt-4"> | ||
447 | <label i18n for="importConcurrency">Import jobs concurrency</label> | ||
448 | <span class="text-muted ml-1"> | ||
449 | <span i18n>allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.</span> | ||
450 | </span> | ||
451 | |||
452 | <div class="number-with-unit"> | ||
453 | <input type="number" name="importConcurrency" formControlName="concurrency" /> | ||
454 | <span i18n>jobs in parallel</span> | ||
455 | </div> | ||
456 | |||
457 | <div *ngIf="formErrors.import.concurrency" class="form-error">{{ formErrors.import.concurrency }}</div> | ||
458 | </div> | ||
459 | |||
460 | <div class="form-group" formGroupName="http"> | ||
461 | <my-peertube-checkbox | ||
462 | inputName="importVideosHttpEnabled" formControlName="enabled" | ||
463 | i18n-labelText labelText="Allow import with HTTP URL (e.g. YouTube)" | ||
464 | ></my-peertube-checkbox> | ||
465 | </div> | ||
466 | |||
467 | <div class="form-group" formGroupName="torrent"> | ||
468 | <my-peertube-checkbox | ||
469 | inputName="importVideosTorrentEnabled" formControlName="enabled" | ||
470 | i18n-labelText labelText="Allow import with a torrent file or a magnet URI" | ||
471 | ></my-peertube-checkbox> | ||
472 | </div> | ||
473 | |||
474 | </ng-container> | ||
475 | </ng-container> | ||
476 | |||
477 | <ng-container formGroupName="autoBlacklist"> | ||
478 | <ng-container formGroupName="videos"> | ||
479 | <ng-container formGroupName="ofUsers"> | ||
480 | |||
481 | <div class="form-group"> | ||
482 | <my-peertube-checkbox | ||
483 | inputName="autoBlacklistVideosOfUsersEnabled" formControlName="enabled" | ||
484 | i18n-labelText labelText="Block new videos automatically" | ||
485 | > | ||
486 | <ng-container ngProjectAs="description"> | ||
487 | <span i18n>Unless a user is marked as trusted, their videos will stay private until a moderator reviews them.</span> | ||
488 | </ng-container> | ||
489 | </my-peertube-checkbox> | ||
490 | </div> | ||
491 | |||
492 | </ng-container> | ||
493 | </ng-container> | ||
494 | </ng-container> | ||
495 | |||
496 | </div> | ||
497 | </div> | ||
498 | |||
499 | <div class="form-row mt-4"> <!-- search grid --> | ||
500 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
501 | <div i18n class="inner-form-title">SEARCH</div> | ||
502 | </div> | ||
503 | |||
504 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
505 | |||
506 | <ng-container formGroupName="search"> | ||
507 | <ng-container formGroupName="remoteUri"> | ||
508 | |||
509 | <div class="form-group"> | ||
510 | <my-peertube-checkbox | ||
511 | inputName="searchRemoteUriUsers" formControlName="users" | ||
512 | i18n-labelText labelText="Allow users to do remote URI/handle search" | ||
513 | > | ||
514 | <ng-container ngProjectAs="description"> | ||
515 | <span i18n>Allow <strong>your users</strong> to look up remote videos/actors that may not be federated with your instance</span> | ||
516 | </ng-container> | ||
517 | </my-peertube-checkbox> | ||
518 | </div> | ||
519 | |||
520 | <div class="form-group"> | ||
521 | <my-peertube-checkbox | ||
522 | inputName="searchRemoteUriAnonymous" formControlName="anonymous" | ||
523 | i18n-labelText labelText="Allow anonymous to do remote URI/handle search" | ||
524 | > | ||
525 | <ng-container ngProjectAs="description"> | ||
526 | <span i18n>Allow <strong>anonymous users</strong> to look up remote videos/actors that may not be federated with your instance</span> | ||
527 | </ng-container> | ||
528 | </my-peertube-checkbox> | ||
529 | </div> | ||
530 | |||
531 | </ng-container> | ||
532 | |||
533 | <ng-container formGroupName="searchIndex"> | ||
534 | <div class="form-group"> | ||
535 | <my-peertube-checkbox | ||
536 | inputName="searchIndexEnabled" formControlName="enabled" | ||
537 | i18n-labelText labelText="Enable global search" | ||
538 | > | ||
539 | <ng-container ngProjectAs="description"> | ||
540 | <p i18n>⚠️ This functionality depends heavily on the moderation of instances followed by the search index you select.</p> | ||
541 | |||
542 | <span i18n> | ||
543 | You should only use moderated search indexes in production, or <a href="https://framagit.org/framasoft/peertube/search-index">host your own</a>. | ||
544 | </span> | ||
545 | </ng-container> | ||
546 | |||
547 | <ng-container ngProjectAs="extra"> | ||
548 | <div [ngClass]="{ 'disabled-checkbox-extra': !isSearchIndexEnabled() }"> | ||
549 | <label i18n for="searchIndexUrl">Search index URL</label> | ||
550 | <input | ||
551 | type="text" id="searchIndexUrl" class="form-control" | ||
552 | formControlName="url" [ngClass]="{ 'input-error': formErrors['search.searchIndex.url'] }" | ||
553 | > | ||
554 | <div *ngIf="formErrors.search.searchIndex.url" class="form-error">{{ formErrors.search.searchIndex.url }}</div> | ||
555 | </div> | ||
556 | |||
557 | <div class="mt-3"> | ||
558 | <my-peertube-checkbox [ngClass]="{ 'disabled-checkbox-extra': !isSearchIndexEnabled() }" | ||
559 | inputName="searchIndexDisableLocalSearch" formControlName="disableLocalSearch" | ||
560 | i18n-labelText labelText="Disable local search in search bar" | ||
561 | ></my-peertube-checkbox> | ||
562 | </div> | ||
563 | |||
564 | <div class="mt-3"> | ||
565 | <my-peertube-checkbox [ngClass]="{ 'disabled-checkbox-extra': !isSearchIndexEnabled() }" | ||
566 | inputName="searchIndexIsDefaultSearch" formControlName="isDefaultSearch" | ||
567 | i18n-labelText labelText="Search bar uses the global search index by default" | ||
568 | > | ||
569 | <ng-container ngProjectAs="description"> | ||
570 | <span i18n>Otherwise the local search stays used by default</span> | ||
571 | </ng-container> | ||
572 | </my-peertube-checkbox> | ||
573 | </div> | ||
574 | |||
575 | </ng-container> | ||
576 | </my-peertube-checkbox> | ||
577 | </div> | ||
578 | |||
579 | </ng-container> | ||
580 | |||
581 | </ng-container> | ||
582 | |||
583 | </div> | ||
584 | </div> | ||
585 | |||
586 | <div class="form-row mt-4"> <!-- federation grid --> | ||
587 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
588 | <div i18n class="inner-form-title">FEDERATION</div> | ||
589 | <div i18n class="inner-form-description"> | ||
590 | Manage <a routerLink="/admin/follows">relations</a> with other instances. | ||
591 | </div> | ||
592 | </div> | ||
593 | |||
594 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
595 | |||
596 | <ng-container formGroupName="followers"> | ||
597 | <ng-container formGroupName="instance"> | ||
598 | |||
599 | <div class="form-group"> | ||
600 | <my-peertube-checkbox | ||
601 | inputName="followersInstanceEnabled" formControlName="enabled" | ||
602 | i18n-labelText labelText="Other instances can follow yours" | ||
603 | ></my-peertube-checkbox> | ||
604 | </div> | ||
605 | |||
606 | <div class="form-group"> | ||
607 | <my-peertube-checkbox | ||
608 | inputName="followersInstanceManualApproval" formControlName="manualApproval" | ||
609 | i18n-labelText labelText="Manually approve new instance followers" | ||
610 | ></my-peertube-checkbox> | ||
611 | </div> | ||
612 | </ng-container> | ||
613 | </ng-container> | ||
614 | |||
615 | <ng-container formGroupName="followings"> | ||
616 | <ng-container formGroupName="instance"> | ||
617 | |||
618 | <ng-container formGroupName="autoFollowBack"> | ||
619 | <div class="form-group"> | ||
620 | <my-peertube-checkbox | ||
621 | inputName="followingsInstanceAutoFollowBackEnabled" formControlName="enabled" | ||
622 | i18n-labelText labelText="Automatically follow back instances" | ||
623 | > | ||
624 | <ng-container ngProjectAs="description"> | ||
625 | <span i18n>⚠️ This functionality requires a lot of attention and extra moderation.</span> | ||
626 | </ng-container> | ||
627 | </my-peertube-checkbox> | ||
628 | </div> | ||
629 | </ng-container> | ||
630 | |||
631 | <ng-container formGroupName="autoFollowIndex"> | ||
632 | <div class="form-group"> | ||
633 | <my-peertube-checkbox | ||
634 | inputName="followingsInstanceAutoFollowIndexEnabled" formControlName="enabled" | ||
635 | i18n-labelText labelText="Automatically follow instances of a public index" | ||
636 | > | ||
637 | <ng-container ngProjectAs="description"> | ||
638 | <p i18n>⚠️ This functionality requires a lot of attention and extra moderation.</p> | ||
639 | |||
640 | <span i18n> | ||
641 | You should only follow moderated indexes in production, or <a href="https://framagit.org/framasoft/peertube/instances-peertube#peertube-auto-follow">host your own</a>. | ||
642 | </span> | ||
643 | </ng-container> | ||
644 | |||
645 | <ng-container ngProjectAs="extra"> | ||
646 | <div [ngClass]="{ 'disabled-checkbox-extra': !isAutoFollowIndexEnabled() }"> | ||
647 | <label i18n for="followingsInstanceAutoFollowIndexUrl">Index URL</label> | ||
648 | <input | ||
649 | type="text" id="followingsInstanceAutoFollowIndexUrl" class="form-control" | ||
650 | formControlName="indexUrl" [ngClass]="{ 'input-error': formErrors['followings.instance.autoFollowIndex.indexUrl'] }" | ||
651 | > | ||
652 | <div *ngIf="formErrors.followings.instance.autoFollowIndex.indexUrl" class="form-error">{{ formErrors.followings.instance.autoFollowIndex.indexUrl }}</div> | ||
653 | </div> | ||
654 | </ng-container> | ||
655 | </my-peertube-checkbox> | ||
656 | </div> | ||
657 | |||
658 | </ng-container> | ||
659 | </ng-container> | ||
660 | </ng-container> | ||
661 | |||
662 | </div> | ||
663 | </div> | ||
664 | |||
665 | <div class="form-row mt-4"> <!-- administrators grid --> | ||
666 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
667 | <div i18n class="inner-form-title">ADMINISTRATORS</div> | ||
668 | </div> | ||
669 | |||
670 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
671 | |||
672 | <div class="form-group" formGroupName="admin"> | ||
673 | <label i18n for="adminEmail">Admin email</label> | ||
674 | <input | ||
675 | type="text" id="adminEmail" class="form-control" | ||
676 | formControlName="email" [ngClass]="{ 'input-error': formErrors['admin.email'] }" | ||
677 | > | ||
678 | <div *ngIf="formErrors.admin.email" class="form-error">{{ formErrors.admin.email }}</div> | ||
679 | </div> | ||
680 | |||
681 | <div class="form-group" formGroupName="contactForm"> | ||
682 | <my-peertube-checkbox | ||
683 | inputName="enableContactForm" formControlName="enabled" | ||
684 | i18n-labelText labelText="Enable contact form" | ||
685 | ></my-peertube-checkbox> | ||
686 | </div> | ||
687 | |||
688 | </div> | ||
689 | </div> | ||
690 | |||
691 | <div class="form-row mt-4"> <!-- Twitter grid --> | ||
692 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
693 | <div i18n class="inner-form-title">TWITTER</div> | ||
694 | <div i18n class="inner-form-description"> | ||
695 | Provide the Twitter account representing your instance to improve link previews. | ||
696 | If you don't have a Twitter account, just leave the default value. | ||
697 | </div> | ||
698 | </div> | ||
699 | |||
700 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
701 | |||
702 | <ng-container formGroupName="services"> | ||
703 | <ng-container formGroupName="twitter"> | ||
704 | |||
705 | <div class="form-group"> | ||
706 | <label i18n for="signupLimit">Your Twitter username</label> | ||
707 | |||
708 | <input | ||
709 | type="text" id="servicesTwitterUsername" class="form-control" | ||
710 | formControlName="username" [ngClass]="{ 'input-error': formErrors['services.twitter.username'] }" | ||
711 | > | ||
712 | <div *ngIf="formErrors.services.twitter.username" class="form-error">{{ formErrors.services.twitter.username }}</div> | ||
713 | </div> | ||
714 | |||
715 | <div class="form-group"> | ||
716 | <my-peertube-checkbox inputName="servicesTwitterWhitelisted" formControlName="whitelisted"> | ||
717 | <ng-template ptTemplate="label"> | ||
718 | <ng-container i18n>Instance allowed by Twitter</ng-container> | ||
719 | </ng-template> | ||
720 | |||
721 | <ng-template ptTemplate="help"> | ||
722 | <ng-container i18n> | ||
723 | If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | ||
724 | If the instance is not, we use an image link card that will redirect to your PeerTube instance.<br /><br /> | ||
725 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on | ||
726 | <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> | ||
727 | to see if you instance is allowed. | ||
728 | </ng-container> | ||
729 | </ng-template> | ||
730 | </my-peertube-checkbox> | ||
731 | </div> | ||
732 | |||
733 | </ng-container> | ||
734 | </ng-container> | ||
735 | |||
736 | </div> | ||
737 | </div> | ||
738 | </ng-template> | 21 | </ng-template> |
739 | </ng-container> | 22 | </ng-container> |
740 | 23 | ||
@@ -742,208 +25,8 @@ | |||
742 | <a ngbNavLink i18n>VOD Transcoding</a> | 25 | <a ngbNavLink i18n>VOD Transcoding</a> |
743 | 26 | ||
744 | <ng-template ngbNavContent> | 27 | <ng-template ngbNavContent> |
745 | 28 | <my-edit-vod-transcoding [form]="form" [formErrors]="formErrors" [serverConfig]="serverConfig"> | |
746 | <div class="form-row mt-4"> <!-- transcoding grid --> | 29 | </my-edit-vod-transcoding> |
747 | <div class="form-group col-12 col-lg-4 col-xl-3"></div> | ||
748 | <div class="form-group form-group-right col-12 col-lg-8"> | ||
749 | |||
750 | <div class="callout callout-info"> | ||
751 | <span i18n> | ||
752 | Estimating a server's capacity to transcode and stream videos isn't easy and we can't tune PeerTube automatically. | ||
753 | </span> | ||
754 | <span i18n> | ||
755 | However, you may want to read our guidelines before tweaking the following values. | ||
756 | </span> | ||
757 | |||
758 | <div class="callout-container"> | ||
759 | <a class="callout-link" target="_blank" rel="noopener noreferrer" href="https://docs.joinpeertube.org/#/admin-configuration?id=transcoding" i18n>Read guidelines</a> | ||
760 | </div> | ||
761 | </div> | ||
762 | |||
763 | |||
764 | </div> | ||
765 | </div> | ||
766 | |||
767 | <div class="form-row mt-2"> <!-- transcoding grid --> | ||
768 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
769 | <div i18n class="inner-form-title">TRANSCODING</div> | ||
770 | <div i18n class="inner-form-description"> | ||
771 | Process uploaded videos so that they are in a streamable form that any device can play. Though costly in | ||
772 | resources, this is a critical part of PeerTube, so tread carefully. | ||
773 | </div> | ||
774 | </div> | ||
775 | |||
776 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
777 | |||
778 | <ng-container formGroupName="transcoding"> | ||
779 | |||
780 | <div class="form-group mb-0 col-12 col-xl-11"> | ||
781 | <my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true"> | ||
782 | <ng-template ptTemplate="label"> | ||
783 | <ng-container i18n>Transcoding enabled</ng-container> | ||
784 | </ng-template> | ||
785 | |||
786 | <ng-container ngProjectAs="extra"> | ||
787 | |||
788 | <div class="callout callout-light pt-2 pb-0"> | ||
789 | <label i18n>Input formats</label> | ||
790 | |||
791 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
792 | <my-peertube-checkbox | ||
793 | inputName="transcodingAllowAdditionalExtensions" formControlName="allowAdditionalExtensions" | ||
794 | i18n-labelText labelText="Allow additional extensions" | ||
795 | > | ||
796 | <ng-container ngProjectAs="description"> | ||
797 | <span i18n>Allows users to upload .mkv, .mov, .avi, .wmv, .flv, .f4v, .3g2, .3gp, .mts, .m2ts, .mxf, or .nut videos.</span> | ||
798 | </ng-container> | ||
799 | </my-peertube-checkbox> | ||
800 | </div> | ||
801 | |||
802 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
803 | <my-peertube-checkbox | ||
804 | inputName="transcodingAllowAudioFiles" formControlName="allowAudioFiles" | ||
805 | i18n-labelText labelText="Allow audio files upload" | ||
806 | > | ||
807 | <ng-container ngProjectAs="description"> | ||
808 | <div i18n>Allows users to upload .mp3, .ogg, .wma, .flac, .aac, or .ac3 audio files.</div> | ||
809 | <div i18n>The file will be merged in a still image video with the preview file on upload.</div> | ||
810 | </ng-container> | ||
811 | </my-peertube-checkbox> | ||
812 | </div> | ||
813 | </div> | ||
814 | |||
815 | <div class="callout callout-light pt-2 mt-2 pb-0"> | ||
816 | <label i18n>Output formats</label> | ||
817 | |||
818 | <ng-container formGroupName="webtorrent"> | ||
819 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
820 | <my-peertube-checkbox | ||
821 | inputName="transcodingWebTorrentEnabled" formControlName="enabled" | ||
822 | i18n-labelText labelText="WebTorrent enabled" | ||
823 | > | ||
824 | <ng-template ptTemplate="help"> | ||
825 | <ng-container i18n> | ||
826 | <p>If you also enabled HLS support, it will multiply videos storage by 2</p> | ||
827 | |||
828 | <br /> | ||
829 | |||
830 | <strong>If disabled, breaks federation with PeerTube instances < 2.1</strong> | ||
831 | </ng-container> | ||
832 | </ng-template> | ||
833 | </my-peertube-checkbox> | ||
834 | </div> | ||
835 | </ng-container> | ||
836 | |||
837 | <ng-container formGroupName="hls"> | ||
838 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
839 | <my-peertube-checkbox | ||
840 | inputName="transcodingHlsEnabled" formControlName="enabled" | ||
841 | i18n-labelText labelText="HLS with P2P support enabled" | ||
842 | [recommended]="true" | ||
843 | > | ||
844 | <ng-template ptTemplate="help"> | ||
845 | <ng-container i18n> | ||
846 | <strong>Requires ffmpeg >= 4.1</strong> | ||
847 | |||
848 | <p>Generate HLS playlists and fragmented MP4 files resulting in a better playback than with plain WebTorrent:</p> | ||
849 | <ul> | ||
850 | <li>Resolution change is smoother</li> | ||
851 | <li>Faster playback especially with long videos</li> | ||
852 | <li>More stable playback (less bugs/infinite loading)</li> | ||
853 | </ul> | ||
854 | |||
855 | <p>If you also enabled WebTorrent support, it will multiply videos storage by 2</p> | ||
856 | </ng-container> | ||
857 | </ng-template> | ||
858 | </my-peertube-checkbox> | ||
859 | </div> | ||
860 | </ng-container> | ||
861 | |||
862 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
863 | <label i18n>Resolutions to generate per enabled format</label> | ||
864 | |||
865 | <div class="ml-2 mt-2 d-flex flex-column"> | ||
866 | <ng-container formGroupName="resolutions"> | ||
867 | <div class="form-group" *ngFor="let resolution of resolutions"> | ||
868 | <my-peertube-checkbox | ||
869 | [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id" | ||
870 | labelText="{{ resolution.label }}" | ||
871 | > | ||
872 | <ng-template *ngIf="resolution.description" ptTemplate="help"> | ||
873 | <div [innerHTML]="resolution.description"></div> | ||
874 | </ng-template> | ||
875 | </my-peertube-checkbox> | ||
876 | </div> | ||
877 | |||
878 | <span class="mb-2 text-muted" i18n> | ||
879 | The original file resolution will be the default target if no option is selected. | ||
880 | </span> | ||
881 | </ng-container> | ||
882 | </div> | ||
883 | </div> | ||
884 | </div> | ||
885 | |||
886 | </ng-container> | ||
887 | </my-peertube-checkbox> | ||
888 | </div> | ||
889 | |||
890 | <div class="form-group mt-4" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
891 | <label i18n for="transcodingThreads">Transcoding threads</label> | ||
892 | <span class="text-muted ml-1"> | ||
893 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n>will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding</ng-container> | ||
894 | <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with live transcoding</ng-container> | ||
895 | </span> | ||
896 | |||
897 | <my-select-custom-value | ||
898 | id="transcodingThreads" | ||
899 | [items]="transcodingThreadOptions" | ||
900 | formControlName="threads" | ||
901 | [clearable]="false" | ||
902 | ></my-select-custom-value> | ||
903 | |||
904 | <div *ngIf="formErrors.transcoding.threads" class="form-error">{{ formErrors.transcoding.threads }}</div> | ||
905 | </div> | ||
906 | |||
907 | <div class="form-group mt-4" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
908 | <label i18n for="transcodingConcurrency">Transcoding jobs concurrency</label> | ||
909 | <span class="text-muted ml-1"> | ||
910 | <span i18n>allows to transcode multiple files in parallel. ⚠️ Requires a PeerTube restart.</span> | ||
911 | </span> | ||
912 | |||
913 | <div class="number-with-unit"> | ||
914 | <input type="number" name="transcodingConcurrency" formControlName="concurrency" /> | ||
915 | <span i18n>jobs in parallel</span> | ||
916 | </div> | ||
917 | |||
918 | <div *ngIf="formErrors.transcoding.concurrency" class="form-error">{{ formErrors.transcoding.concurrency }}</div> | ||
919 | </div> | ||
920 | |||
921 | <div class="form-group mt-4" [ngClass]="{ 'disabled-checkbox-extra': !isTranscodingEnabled() }"> | ||
922 | <label i18n for="transcodingProfile">Transcoding profile</label> | ||
923 | <span class="text-muted ml-1" i18n>new transcoding profiles can be added by PeerTube plugins</span> | ||
924 | |||
925 | <my-select-options | ||
926 | id="transcodingProfile" | ||
927 | formControlName="profile" | ||
928 | [items]="getAvailableTranscodingProfile('vod')" | ||
929 | [clearable]="false" | ||
930 | > | ||
931 | <ng-template ng-option-tmp let-item="item" let-index="index"> | ||
932 | {{ item }} | ||
933 | <ng-container *ngIf="item === 'default'"> | ||
934 | <br> | ||
935 | <span class="text-muted" i18n>x264, targeting maximum device compatibility</span> | ||
936 | </ng-container> | ||
937 | </ng-template> | ||
938 | </my-select-options> | ||
939 | <div *ngIf="formErrors.transcoding.profile" class="form-error">{{ formErrors.transcoding.profile }}</div> | ||
940 | </div> | ||
941 | |||
942 | </ng-container> | ||
943 | |||
944 | </div> | ||
945 | </div> | ||
946 | |||
947 | </ng-template> | 30 | </ng-template> |
948 | </ng-container> | 31 | </ng-container> |
949 | 32 | ||
@@ -951,160 +34,8 @@ | |||
951 | <a ngbNavLink i18n>Live streaming</a> | 34 | <a ngbNavLink i18n>Live streaming</a> |
952 | 35 | ||
953 | <ng-template ngbNavContent> | 36 | <ng-template ngbNavContent> |
954 | 37 | <my-edit-live-configuration [form]="form" [formErrors]="formErrors" [serverConfig]="serverConfig"> | |
955 | <div class="form-row mt-5"> | 38 | </my-edit-live-configuration> |
956 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
957 | <div i18n class="inner-form-title">LIVE</div> | ||
958 | <div i18n class="inner-form-description"> | ||
959 | Enable users of your instance to stream live. | ||
960 | </div> | ||
961 | </div> | ||
962 | |||
963 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
964 | |||
965 | <ng-container formGroupName="live"> | ||
966 | |||
967 | <div class="form-group"> | ||
968 | <my-peertube-checkbox inputName="liveEnabled" formControlName="enabled"> | ||
969 | <ng-template ptTemplate="label"> | ||
970 | <ng-container i18n>Allow live streaming</ng-container> | ||
971 | </ng-template> | ||
972 | |||
973 | <ng-container ngProjectAs="description"> | ||
974 | <div i18n>⚠️ Enabling live streaming requires trust in your users and extra moderation work</div> | ||
975 | <div i18n>If enabled, your server needs to accept incoming TCP traffic on port {{ liveRTMPPort }}</div> | ||
976 | </ng-container> | ||
977 | |||
978 | <ng-container ngProjectAs="extra"> | ||
979 | |||
980 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> | ||
981 | <my-peertube-checkbox | ||
982 | inputName="liveAllowReplay" formControlName="allowReplay" | ||
983 | i18n-labelText labelText="Allow your users to automatically publish a replay of their live" | ||
984 | > | ||
985 | <ng-container ngProjectAs="description" i18n> | ||
986 | If the user quota is reached, PeerTube will automatically terminate the live streaming | ||
987 | </ng-container> | ||
988 | </my-peertube-checkbox> | ||
989 | </div> | ||
990 | |||
991 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> | ||
992 | <label i18n for="liveMaxInstanceLives">Max simultaneous lives created on your instance <span class="text-muted">(-1 for "unlimited")</span></label> | ||
993 | <div class="number-with-unit"> | ||
994 | <input type="number" name="liveMaxInstanceLives" formControlName="maxInstanceLives" /> | ||
995 | <span i18n>{form.value['live']['maxInstanceLives'], plural, =1 {live} other {lives}}</span> | ||
996 | </div> | ||
997 | </div> | ||
998 | |||
999 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> | ||
1000 | <label i18n for="liveMaxUserLives">Max simultaneous lives created per user <span class="text-muted">(-1 for "unlimited")</span></label> | ||
1001 | <div class="number-with-unit"> | ||
1002 | <input type="number" name="liveMaxUserLives" formControlName="maxUserLives" /> | ||
1003 | <span i18n>{form.value['live']['maxUserLives'], plural, =1 {live} other {lives}}</span> | ||
1004 | </div> | ||
1005 | </div> | ||
1006 | |||
1007 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> | ||
1008 | <label i18n for="liveMaxDuration">Max live duration</label> | ||
1009 | |||
1010 | <my-select-options | ||
1011 | labelForId="liveMaxDuration" [items]="liveMaxDurationOptions" formControlName="maxDuration" | ||
1012 | bindLabel="label" bindValue="value" [clearable]="false" [searchable]="true" | ||
1013 | ></my-select-options> | ||
1014 | </div> | ||
1015 | |||
1016 | </ng-container> | ||
1017 | </my-peertube-checkbox> | ||
1018 | </div> | ||
1019 | </ng-container> | ||
1020 | </div> | ||
1021 | </div> | ||
1022 | |||
1023 | <div class="form-row"> <!-- transcoding live streams grid --> | ||
1024 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
1025 | <div i18n class="inner-form-title">TRANSCODING</div> | ||
1026 | <div i18n class="inner-form-description"> | ||
1027 | Same as VOD transcoding, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some. | ||
1028 | </div> | ||
1029 | </div> | ||
1030 | |||
1031 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
1032 | |||
1033 | <ng-container formGroupName="live"> | ||
1034 | <ng-container formGroupName="transcoding"> | ||
1035 | |||
1036 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() }"> | ||
1037 | <my-peertube-checkbox | ||
1038 | inputName="liveTranscodingEnabled" formControlName="enabled" | ||
1039 | > | ||
1040 | <ng-template ptTemplate="label"> | ||
1041 | <ng-container i18n>Transcoding enabled for live streams</ng-container> | ||
1042 | </ng-template> | ||
1043 | </my-peertube-checkbox> | ||
1044 | </div> | ||
1045 | |||
1046 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }"> | ||
1047 | <label i18n for="liveTranscodingThreads">Live resolutions to generate</label> | ||
1048 | |||
1049 | <div class="ml-2 mt-2 d-flex flex-column"> | ||
1050 | <ng-container formGroupName="resolutions"> | ||
1051 | <div class="form-group" *ngFor="let resolution of liveResolutions"> | ||
1052 | <my-peertube-checkbox | ||
1053 | [inputName]="getResolutionKey(resolution.id)" [formControlName]="resolution.id" | ||
1054 | labelText="{{resolution.label}}" | ||
1055 | > | ||
1056 | <ng-template *ngIf="resolution.description" ptTemplate="help"> | ||
1057 | <div [innerHTML]="resolution.description"></div> | ||
1058 | </ng-template> | ||
1059 | </my-peertube-checkbox> | ||
1060 | </div> | ||
1061 | </ng-container> | ||
1062 | </div> | ||
1063 | </div> | ||
1064 | |||
1065 | <div class="form-group" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }"> | ||
1066 | <label i18n for="liveTranscodingThreads">Live transcoding threads</label> | ||
1067 | <span class="text-muted ml-1"> | ||
1068 | <ng-container *ngIf="getTotalTranscodingThreads().atMost" i18n>will claim at most {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding</ng-container> | ||
1069 | <ng-container *ngIf="!getTotalTranscodingThreads().atMost" i18n>will claim at least {{ getTotalTranscodingThreads().value }} {{ getTotalTranscodingThreads().unit }} with VOD transcoding</ng-container> | ||
1070 | </span> | ||
1071 | |||
1072 | <my-select-custom-value | ||
1073 | id="liveTranscodingThreads" | ||
1074 | [items]="transcodingThreadOptions" | ||
1075 | formControlName="threads" | ||
1076 | [clearable]="false" | ||
1077 | ></my-select-custom-value> | ||
1078 | <div *ngIf="formErrors.live.transcoding.threads" class="form-error">{{ formErrors.live.transcoding.threads }}</div> | ||
1079 | </div> | ||
1080 | |||
1081 | <div class="form-group mt-4" [ngClass]="{ 'disabled-checkbox-extra': !isLiveEnabled() || !isLiveTranscodingEnabled() }"> | ||
1082 | <label i18n for="liveTranscodingProfile">Live transcoding profile</label> | ||
1083 | <span class="text-muted ml-1" i18n>new live transcoding profiles can be added by PeerTube plugins</span> | ||
1084 | |||
1085 | <my-select-options | ||
1086 | id="liveTranscodingProfile" | ||
1087 | formControlName="profile" | ||
1088 | [items]="getAvailableTranscodingProfile('live')" | ||
1089 | [clearable]="false" | ||
1090 | > | ||
1091 | <ng-template ng-option-tmp let-item="item" let-index="index"> | ||
1092 | {{ item }} | ||
1093 | <ng-container *ngIf="item === 'default'"> | ||
1094 | <br> | ||
1095 | <span class="text-muted" i18n>x264, targeting maximum device compatibility</span> | ||
1096 | </ng-container> | ||
1097 | </ng-template> | ||
1098 | </my-select-options> | ||
1099 | <div *ngIf="formErrors.live.transcoding.profile" class="form-error">{{ formErrors.live.transcoding.profile }}</div> | ||
1100 | </div> | ||
1101 | |||
1102 | </ng-container> | ||
1103 | </ng-container> | ||
1104 | |||
1105 | </div> | ||
1106 | </div> | ||
1107 | |||
1108 | </ng-template> | 39 | </ng-template> |
1109 | </ng-container> | 40 | </ng-container> |
1110 | 41 | ||
@@ -1112,111 +43,8 @@ | |||
1112 | <a ngbNavLink i18n>Advanced configuration</a> | 43 | <a ngbNavLink i18n>Advanced configuration</a> |
1113 | 44 | ||
1114 | <ng-template ngbNavContent> | 45 | <ng-template ngbNavContent> |
1115 | 46 | <my-edit-advanced-configuration [form]="form" [formErrors]="formErrors"> | |
1116 | <div class="form-row mt-5"> <!-- cache grid --> | 47 | </my-edit-advanced-configuration> |
1117 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
1118 | <div i18n class="inner-form-title">CACHE</div> | ||
1119 | <div i18n class="inner-form-description"> | ||
1120 | Some files are not federated, and fetched when necessary. Define their caching policies. | ||
1121 | </div> | ||
1122 | </div> | ||
1123 | |||
1124 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
1125 | |||
1126 | <ng-container formGroupName="cache"> | ||
1127 | <div class="form-group" formGroupName="previews"> | ||
1128 | <label i18n for="cachePreviewsSize">Number of previews to keep in cache</label> | ||
1129 | <div class="number-with-unit"> | ||
1130 | <input | ||
1131 | type="number" min="0" id="cachePreviewsSize" class="form-control" | ||
1132 | formControlName="size" [ngClass]="{ 'input-error': formErrors['cache.previews.size'] }" | ||
1133 | > | ||
1134 | <span i18n>{form.value['cache']['previews']['size'], plural, =1 {cached image} other {cached images}}</span> | ||
1135 | </div> | ||
1136 | <div *ngIf="formErrors.cache.previews.size" class="form-error">{{ formErrors.cache.previews.size }}</div> | ||
1137 | </div> | ||
1138 | |||
1139 | <div class="form-group" formGroupName="captions"> | ||
1140 | <label i18n for="cacheCaptionsSize">Number of video captions to keep in cache</label> | ||
1141 | <div class="number-with-unit"> | ||
1142 | <input | ||
1143 | type="number" min="0" id="cacheCaptionsSize" class="form-control" | ||
1144 | formControlName="size" [ngClass]="{ 'input-error': formErrors['cache.captions.size'] }" | ||
1145 | > | ||
1146 | <span i18n>{form.value['cache']['captions']['size'], plural, =1 {cached image} other {cached images}}</span> | ||
1147 | </div> | ||
1148 | <div *ngIf="formErrors.cache.captions.size" class="form-error">{{ formErrors.cache.captions.size }}</div> | ||
1149 | </div> | ||
1150 | </ng-container> | ||
1151 | |||
1152 | </div> | ||
1153 | </div> | ||
1154 | |||
1155 | <div class="form-row mt-4"> <!-- cache grid --> | ||
1156 | <div class="form-group col-12 col-lg-4 col-xl-3"> | ||
1157 | <div class="anchor" id="customizations"></div> <!-- customizations anchor --> | ||
1158 | <div i18n class="inner-form-title">CUSTOMIZATIONS</div> | ||
1159 | <div i18n class="inner-form-description"> | ||
1160 | Slight modifications to your PeerTube instance for when creating a plugin or theme is overkill. | ||
1161 | </div> | ||
1162 | </div> | ||
1163 | |||
1164 | <div class="form-group form-group-right col-12 col-lg-8 col-xl-9"> | ||
1165 | |||
1166 | <ng-container formGroupName="instance"> | ||
1167 | <ng-container formGroupName="customizations"> | ||
1168 | <div class="form-group"> | ||
1169 | <label i18n for="customizationJavascript">JavaScript</label> | ||
1170 | <my-help> | ||
1171 | <ng-template ptTemplate="customHtml"> | ||
1172 | <ng-container i18n> | ||
1173 | Write JavaScript code directly.<br />Example: <pre>console.log('my instance is amazing');</pre> | ||
1174 | </ng-container> | ||
1175 | </ng-template> | ||
1176 | </my-help> | ||
1177 | |||
1178 | <textarea | ||
1179 | id="customizationJavascript" formControlName="javascript" class="form-control" | ||
1180 | [ngClass]="{ 'input-error': formErrors['instance.customizations.javascript'] }" | ||
1181 | ></textarea> | ||
1182 | |||
1183 | <div *ngIf="formErrors.instance.customizations.javascript" class="form-error">{{ formErrors.instance.customizations.javascript }}</div> | ||
1184 | </div> | ||
1185 | |||
1186 | <div class="form-group"> | ||
1187 | <label for="customizationCSS">CSS</label> | ||
1188 | |||
1189 | <my-help> | ||
1190 | <ng-template ptTemplate="customHtml"> | ||
1191 | <ng-container i18n> | ||
1192 | Write CSS code directly. Example:<br /><br /> | ||
1193 | <pre> | ||
1194 | #custom-css {{ '{' }} | ||
1195 | color: red; | ||
1196 | {{ '}' }} | ||
1197 | </pre> | ||
1198 | Prepend with <em>#custom-css</em> to override styles. Example:<br /><br /> | ||
1199 | <pre> | ||
1200 | #custom-css .logged-in-email {{ '{' }} | ||
1201 | color: red; | ||
1202 | {{ '}' }} | ||
1203 | </pre> | ||
1204 | </ng-container> | ||
1205 | </ng-template> | ||
1206 | </my-help> | ||
1207 | |||
1208 | <textarea | ||
1209 | id="customizationCSS" formControlName="css" class="form-control" | ||
1210 | [ngClass]="{ 'input-error': formErrors['instance.customizations.css'] }" | ||
1211 | ></textarea> | ||
1212 | <div *ngIf="formErrors.instance.customizations.css" class="form-error">{{ formErrors.instance.customizations.css }}</div> | ||
1213 | </div> | ||
1214 | </ng-container> | ||
1215 | </ng-container> | ||
1216 | |||
1217 | </div> | ||
1218 | </div> | ||
1219 | |||
1220 | </ng-template> | 48 | </ng-template> |
1221 | </ng-container> | 49 | </ng-container> |
1222 | </div> | 50 | </div> |