1 <ng-container [formGroup]=
"form">
2 <div class=
"form-row mt-5"> <!-- appearance grid -->
3 <div class=
"form-group col-12 col-lg-4 col-xl-3">
4 <div i18n
class=
"inner-form-title">APPEARANCE
</div>
5 <div i18n
class=
"inner-form-description">
6 Use
<a routerLink=
"/admin/plugins">plugins & themes
</a> for more involved changes, or
<a routerLink=
"/admin/config/edit-custom" fragment=
"advanced-configuration">add slight customizations
</a>.
10 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
12 <ng-container formGroupName=
"theme">
13 <div class=
"form-group">
14 <label i18n
for=
"themeDefault">Theme
</label>
16 <div class=
"peertube-select-container">
17 <select formControlName=
"default" id=
"themeDefault" class=
"form-control">
18 <option i18n
value=
"default">default
</option>
20 <option *
ngFor=
"let theme of getAvailableThemes()" [value]=
"theme">{{ theme }}
</option>
26 <div class=
"form-group" formGroupName=
"instance">
27 <label i18n
for=
"instanceDefaultClientRoute">Landing page
</label>
29 <my-select-custom-value
30 id=
"instanceDefaultClientRoute"
31 [items]=
"defaultLandingPageOptions"
32 formControlName=
"defaultClientRoute"
35 ></my-select-custom-value>
37 <div *
ngIf=
"formErrors.instance.defaultClientRoute" class=
"form-error">{{ formErrors.instance.defaultClientRoute }}
</div>
40 <div class=
"form-group" formGroupName=
"trending">
41 <ng-container formGroupName=
"videos">
42 <ng-container formGroupName=
"algorithms">
43 <label i18n
for=
"trendingVideosAlgorithmsDefault">Default trending page
</label>
45 <div class=
"peertube-select-container">
46 <select id=
"trendingVideosAlgorithmsDefault" formControlName=
"default" class=
"form-control">
47 <option i18n
value=
"best">Best videos
</option>
48 <option i18n
value=
"hot">Hot videos
</option>
49 <option i18n
value=
"most-viewed">Most viewed videos
</option>
50 <option i18n
value=
"most-liked">Most liked videos
</option>
54 <div *
ngIf=
"formErrors.trending.videos.algorithms.default" class=
"form-error">{{ formErrors.trending.videos.algorithms.default }}
</div>
59 <ng-container formGroupName=
"client">
61 <ng-container formGroupName=
"videos">
62 <ng-container formGroupName=
"miniature">
63 <div class=
"form-group">
65 inputName=
"clientVideosMiniaturePreferAuthorDisplayName" formControlName=
"preferAuthorDisplayName"
66 i18n-labelText
labelText=
"Prefer author display name in video miniature"
67 ></my-peertube-checkbox>
72 <ng-container formGroupName=
"menu">
73 <ng-container formGroupName=
"login">
74 <div class=
"form-group">
76 inputName=
"clientMenuLoginRedirectOnSingleExternalAuth" formControlName=
"redirectOnSingleExternalAuth"
77 i18n-labelText
labelText=
"Redirect users on single external auth when users click on the login button in menu"
79 <ng-container ngProjectAs=
"description">
80 <span *
ngIf=
"countExternalAuth() === 0" i18n
>⚠️ You don't have any external auth plugin enabled.
</span>
81 <span *
ngIf=
"countExternalAuth() > 1" i18n
>⚠️ You have multiple external auth plugins enabled.
</span>
83 </my-peertube-checkbox>
92 <div class=
"form-row mt-4"> <!-- broadcast grid -->
93 <div class=
"form-group col-12 col-lg-4 col-xl-3">
94 <div i18n
class=
"inner-form-title">BROADCAST MESSAGE
</div>
95 <div i18n
class=
"inner-for-description">
96 Display a message on your instance
100 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
102 <ng-container formGroupName=
"broadcastMessage">
104 <div class=
"form-group">
105 <my-peertube-checkbox
106 inputName=
"broadcastMessageEnabled" formControlName=
"enabled"
107 i18n-labelText
labelText=
"Enable broadcast message"
108 ></my-peertube-checkbox>
111 <div class=
"form-group">
112 <my-peertube-checkbox
113 inputName=
"broadcastMessageDismissable" formControlName=
"dismissable"
114 i18n-labelText
labelText=
"Allow users to dismiss the broadcast message "
115 ></my-peertube-checkbox>
118 <div class=
"form-group">
119 <label i18n
for=
"broadcastMessageLevel">Broadcast message level
</label>
121 <div class=
"peertube-select-container">
122 <select id=
"broadcastMessageLevel" formControlName=
"level" class=
"form-control">
123 <option value=
"info">info
</option>
124 <option value=
"warning">warning
</option>
125 <option value=
"error">error
</option>
129 <div *
ngIf=
"formErrors.broadcastMessage.level" class=
"form-error">{{ formErrors.broadcastMessage.level }}
</div>
132 <div class=
"form-group">
133 <label i18n
for=
"broadcastMessageMessage">Message
</label><my-help helpType=
"markdownText"></my-help>
135 <my-markdown-textarea
136 name=
"broadcastMessageMessage" formControlName=
"message" textareaMaxWidth=
"500px"
137 [classes]=
"{ 'input-error': formErrors['broadcastMessage.message'] }"
138 ></my-markdown-textarea>
140 <div *
ngIf=
"formErrors.broadcastMessage.message" class=
"form-error">{{ formErrors.broadcastMessage.message }}
</div>
148 <div class=
"form-row mt-4"> <!-- new users grid -->
149 <div class=
"form-group col-12 col-lg-4 col-xl-3">
150 <div i18n
class=
"inner-form-title">NEW USERS
</div>
151 <div i18n
class=
"inner-for-description">
152 Manage
<a routerLink=
"/admin/users">users
</a> to set their quota individually.
156 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
158 <ng-container formGroupName=
"signup">
159 <div class=
"form-group">
160 <my-peertube-checkbox
161 inputName=
"signupEnabled" formControlName=
"enabled"
162 i18n-labelText
labelText=
"Enable Signup"
164 <ng-container ngProjectAs=
"description">
165 <span i18n
>⚠️ This functionality requires a lot of attention and extra moderation.
</span>
167 <div class=
"alert alert-info alert-signup" *
ngIf=
"signupAlertMessage">{{ signupAlertMessage }}
</div>
170 <ng-container ngProjectAs=
"extra">
171 <my-peertube-checkbox [ngClass]=
"getDisabledSignupClass()"
172 inputName=
"signupRequiresEmailVerification" formControlName=
"requiresEmailVerification"
173 i18n-labelText
labelText=
"Signup requires email verification"
174 ></my-peertube-checkbox>
176 <div [ngClass]=
"getDisabledSignupClass()" class=
"mt-3">
177 <label i18n
for=
"signupLimit">Signup limit
</label>
179 <div class=
"number-with-unit">
181 type=
"number" min=
"-1" id=
"signupLimit" class=
"form-control"
182 formControlName=
"limit" [ngClass]=
"{ 'input-error': formErrors['signup.limit'] }"
184 <span i18n
>{form.value['signup']['limit'], plural, =
1 {user} other {users}}
</span>
187 <div *
ngIf=
"formErrors.signup.limit" class=
"form-error">{{ formErrors.signup.limit }}
</div>
189 <small i18n *
ngIf=
"hasUnlimitedSignup()" class=
"text-muted">Signup won't be limited to a fixed number of users.
</small>
192 <div [ngClass]=
"getDisabledSignupClass()" class=
"mt-3">
193 <label i18n
for=
"signupMinimumAge">Minimum required age to create an account
</label>
195 <div class=
"number-with-unit">
197 type=
"number" min=
"1" id=
"signupMinimumAge" class=
"form-control"
198 formControlName=
"minimumAge" [ngClass]=
"{ 'input-error': formErrors['signup.minimumAge'] }"
200 <span i18n
>{form.value['signup']['minimumAge'], plural, =
1 {year old} other {years old}}
</span>
203 <div *
ngIf=
"formErrors.signup.minimumAge" class=
"form-error">{{ formErrors.signup.minimumAge }}
</div>
206 </my-peertube-checkbox>
210 <ng-container formGroupName=
"user">
211 <div class=
"form-group">
212 <label i18n
for=
"userVideoQuota">Default video quota per user
</label>
214 <my-select-custom-value
216 [items]=
"getVideoQuotaOptions()"
217 formControlName=
"videoQuota"
218 i18n-inputSuffix
inputSuffix=
"bytes" inputType=
"number"
220 ></my-select-custom-value>
222 <div *
ngIf=
"formErrors.user.videoQuota" class=
"form-error">{{ formErrors.user.videoQuota }}
</div>
225 <div class=
"form-group">
226 <label i18n
for=
"userVideoQuotaDaily">Default daily upload limit per user
</label>
228 <my-select-custom-value
229 id=
"userVideoQuotaDaily"
230 [items]=
"getVideoQuotaDailyOptions()"
231 formControlName=
"videoQuotaDaily"
232 i18n-inputSuffix
inputSuffix=
"bytes" inputType=
"number"
234 ></my-select-custom-value>
236 <div *
ngIf=
"formErrors.user.videoQuotaDaily" class=
"form-error">{{ formErrors.user.videoQuotaDaily }}
</div>
243 <div class=
"form-row mt-4"> <!-- videos grid -->
244 <div class=
"form-group col-12 col-lg-4 col-xl-3">
245 <div i18n
class=
"inner-form-title">VIDEOS
</div>
248 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
250 <ng-container formGroupName=
"import">
252 <ng-container formGroupName=
"videos">
254 <div class=
"form-group mt-4">
255 <label i18n
for=
"importConcurrency">Import jobs concurrency
</label>
256 <span i18n
class=
"text-muted ml-1">allows to import multiple videos in parallel. ⚠️ Requires a PeerTube restart.
</span>
258 <div class=
"number-with-unit">
259 <input type=
"number" name=
"importConcurrency" formControlName=
"concurrency" />
260 <span i18n
>jobs in parallel
</span>
263 <div *
ngIf=
"formErrors.import.concurrency" class=
"form-error">{{ formErrors.import.concurrency }}
</div>
266 <div class=
"form-group" formGroupName=
"http">
267 <my-peertube-checkbox
268 inputName=
"importVideosHttpEnabled" formControlName=
"enabled"
269 i18n-labelText
labelText=
"Allow import with HTTP URL (e.g. YouTube)"
270 ></my-peertube-checkbox>
273 <div class=
"form-group" formGroupName=
"torrent">
274 <my-peertube-checkbox
275 inputName=
"importVideosTorrentEnabled" formControlName=
"enabled"
276 i18n-labelText
labelText=
"Allow import with a torrent file or a magnet URI"
277 ></my-peertube-checkbox>
283 <ng-container formGroupName=
"autoBlacklist">
284 <ng-container formGroupName=
"videos">
285 <ng-container formGroupName=
"ofUsers">
287 <div class=
"form-group">
288 <my-peertube-checkbox
289 inputName=
"autoBlacklistVideosOfUsersEnabled" formControlName=
"enabled"
290 i18n-labelText
labelText=
"Block new videos automatically"
292 <ng-container ngProjectAs=
"description">
293 <span i18n
>Unless a user is marked as trusted, their videos will stay private until a moderator reviews them.
</span>
295 </my-peertube-checkbox>
305 <div class=
"form-row mt-4"> <!-- video channels grid -->
306 <div class=
"form-group col-12 col-lg-4 col-xl-3">
307 <div i18n
class=
"inner-form-title">VIDEO CHANNELS
</div>
310 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
311 <div class=
"form-group" formGroupName=
"videoChannels">
312 <label i18n
for=
"videoChannelsMaxPerUser">Max video channels per user
</label>
314 <div class=
"number-with-unit">
316 type=
"number" min=
"1" id=
"videoChannelsMaxPerUser" class=
"form-control"
317 formControlName=
"maxPerUser" [ngClass]=
"{ 'input-error': formErrors['videoChannels.maxPerUser'] }"
319 <span i18n
>{form.value['videoChannels']['maxPerUser'], plural, =
1 {channel} other {channels}}
</span>
322 <div *
ngIf=
"formErrors.videoChannels.maxPerUser" class=
"form-error">{{ formErrors.videoChannels.maxPerUser }}
</div>
327 <div class=
"form-row mt-4"> <!-- search grid -->
328 <div class=
"form-group col-12 col-lg-4 col-xl-3">
329 <div i18n
class=
"inner-form-title">SEARCH
</div>
332 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
334 <ng-container formGroupName=
"search">
335 <ng-container formGroupName=
"remoteUri">
337 <div class=
"form-group">
338 <my-peertube-checkbox
339 inputName=
"searchRemoteUriUsers" formControlName=
"users"
340 i18n-labelText
labelText=
"Allow users to do remote URI/handle search"
342 <ng-container ngProjectAs=
"description">
343 <span i18n
>Allow
<strong>your users
</strong> to look up remote videos/actors that may not be federated with your instance
</span>
345 </my-peertube-checkbox>
348 <div class=
"form-group">
349 <my-peertube-checkbox
350 inputName=
"searchRemoteUriAnonymous" formControlName=
"anonymous"
351 i18n-labelText
labelText=
"Allow anonymous to do remote URI/handle search"
353 <ng-container ngProjectAs=
"description">
354 <span i18n
>Allow
<strong>anonymous users
</strong> to look up remote videos/actors that may not be federated with your instance
</span>
356 </my-peertube-checkbox>
361 <ng-container formGroupName=
"searchIndex">
362 <div class=
"form-group">
363 <my-peertube-checkbox
364 inputName=
"searchIndexEnabled" formControlName=
"enabled"
365 i18n-labelText
labelText=
"Enable global search"
367 <ng-container ngProjectAs=
"description">
368 <p i18n
>⚠️ This functionality depends heavily on the moderation of instances followed by the search index you select.
</p>
371 You should only use moderated search indexes in production, or
<a href=
"https://framagit.org/framasoft/peertube/search-index">host your own
</a>.
375 <ng-container ngProjectAs=
"extra">
376 <div [ngClass]=
"getDisabledSearchIndexClass()">
377 <label i18n
for=
"searchIndexUrl">Search index URL
</label>
380 type=
"text" id=
"searchIndexUrl" class=
"form-control"
381 formControlName=
"url" [ngClass]=
"{ 'input-error': formErrors['search.searchIndex.url'] }"
384 <div *
ngIf=
"formErrors.search.searchIndex.url" class=
"form-error">{{ formErrors.search.searchIndex.url }}
</div>
388 <my-peertube-checkbox [ngClass]=
"getDisabledSearchIndexClass()"
389 inputName=
"searchIndexDisableLocalSearch" formControlName=
"disableLocalSearch"
390 i18n-labelText
labelText=
"Disable local search in search bar"
391 ></my-peertube-checkbox>
395 <my-peertube-checkbox [ngClass]=
"getDisabledSearchIndexClass()"
396 inputName=
"searchIndexIsDefaultSearch" formControlName=
"isDefaultSearch"
397 i18n-labelText
labelText=
"Search bar uses the global search index by default"
399 <ng-container ngProjectAs=
"description">
400 <span i18n
>Otherwise the local search stays used by default
</span>
402 </my-peertube-checkbox>
406 </my-peertube-checkbox>
416 <div class=
"form-row mt-4"> <!-- federation grid -->
417 <div class=
"form-group col-12 col-lg-4 col-xl-3">
418 <div i18n
class=
"inner-form-title">FEDERATION
</div>
419 <div i18n
class=
"inner-form-description">
420 Manage
<a routerLink=
"/admin/follows">relations
</a> with other instances.
424 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
426 <ng-container formGroupName=
"followers">
427 <ng-container formGroupName=
"instance">
429 <div class=
"form-group">
430 <my-peertube-checkbox
431 inputName=
"followersInstanceEnabled" formControlName=
"enabled"
432 i18n-labelText
labelText=
"Other instances can follow yours"
433 ></my-peertube-checkbox>
436 <div class=
"form-group">
437 <my-peertube-checkbox
438 inputName=
"followersInstanceManualApproval" formControlName=
"manualApproval"
439 i18n-labelText
labelText=
"Manually approve new instance followers"
440 ></my-peertube-checkbox>
445 <ng-container formGroupName=
"followings">
446 <ng-container formGroupName=
"instance">
448 <ng-container formGroupName=
"autoFollowBack">
449 <div class=
"form-group">
450 <my-peertube-checkbox
451 inputName=
"followingsInstanceAutoFollowBackEnabled" formControlName=
"enabled"
452 i18n-labelText
labelText=
"Automatically follow back instances"
454 <ng-container ngProjectAs=
"description">
455 <span i18n
>⚠️ This functionality requires a lot of attention and extra moderation.
</span>
457 </my-peertube-checkbox>
461 <ng-container formGroupName=
"autoFollowIndex">
462 <div class=
"form-group">
463 <my-peertube-checkbox
464 inputName=
"followingsInstanceAutoFollowIndexEnabled" formControlName=
"enabled"
465 i18n-labelText
labelText=
"Automatically follow instances of a public index"
467 <ng-container ngProjectAs=
"description">
468 <p i18n
>⚠️ This functionality requires a lot of attention and extra moderation.
</p>
471 See
<a href=
"https://docs.joinpeertube.org/admin-following-instances?id=automatically-follow-other-instances" rel=
"noopener noreferrer" target=
"_blank">the documentation
</a> for more information about the expected URL
475 <ng-container ngProjectAs=
"extra">
476 <div [ngClass]=
"{ 'disabled-checkbox-extra': !isAutoFollowIndexEnabled() }">
477 <label i18n
for=
"followingsInstanceAutoFollowIndexUrl">Index URL
</label>
479 type=
"text" id=
"followingsInstanceAutoFollowIndexUrl" class=
"form-control"
480 formControlName=
"indexUrl" [ngClass]=
"{ 'input-error': formErrors['followings.instance.autoFollowIndex.indexUrl'] }"
482 <div *
ngIf=
"formErrors.followings.instance.autoFollowIndex.indexUrl" class=
"form-error">{{ formErrors.followings.instance.autoFollowIndex.indexUrl }}
</div>
485 </my-peertube-checkbox>
495 <div class=
"form-row mt-4"> <!-- administrators grid -->
496 <div class=
"form-group col-12 col-lg-4 col-xl-3">
497 <div i18n
class=
"inner-form-title">ADMINISTRATORS
</div>
500 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
502 <div class=
"form-group" formGroupName=
"admin">
503 <label i18n
for=
"adminEmail">Admin email
</label>
506 type=
"text" id=
"adminEmail" class=
"form-control"
507 formControlName=
"email" [ngClass]=
"{ 'input-error': formErrors['admin.email'] }"
510 <div *
ngIf=
"formErrors.admin.email" class=
"form-error">{{ formErrors.admin.email }}
</div>
513 <div class=
"form-group" formGroupName=
"contactForm">
514 <my-peertube-checkbox
515 inputName=
"enableContactForm" formControlName=
"enabled"
516 i18n-labelText
labelText=
"Enable contact form"
517 ></my-peertube-checkbox>
523 <div class=
"form-row mt-4"> <!-- Twitter grid -->
524 <div class=
"form-group col-12 col-lg-4 col-xl-3">
525 <div i18n
class=
"inner-form-title">TWITTER
</div>
526 <div i18n
class=
"inner-form-description">
527 Provide the Twitter account representing your instance to improve link previews.
528 If you don't have a Twitter account, just leave the default value.
532 <div class=
"form-group form-group-right col-12 col-lg-8 col-xl-9">
534 <ng-container formGroupName=
"services">
535 <ng-container formGroupName=
"twitter">
537 <div class=
"form-group">
538 <label for=
"servicesTwitterUsername" i18n
>Your Twitter username
</label>
541 type=
"text" id=
"servicesTwitterUsername" class=
"form-control"
542 formControlName=
"username" [ngClass]=
"{ 'input-error': formErrors['services.twitter.username'] }"
545 <div *
ngIf=
"formErrors.services.twitter.username" class=
"form-error">{{ formErrors.services.twitter.username }}
</div>
548 <div class=
"form-group">
549 <my-peertube-checkbox inputName=
"servicesTwitterWhitelisted" formControlName=
"whitelisted">
550 <ng-template ptTemplate=
"label">
551 <ng-container i18n
>Instance allowed by Twitter
</ng-container>
554 <ng-template ptTemplate=
"help">
556 If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.
<br />
557 If the instance is not, we use an image link card that will redirect to your PeerTube instance.
<br /><br />
558 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/w/blabla) on
559 <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'
>https://cards-dev.twitter.com/validator
</a>
560 to see if you instance is allowed.
563 </my-peertube-checkbox>