diff options
author | Chocobozzz <me@florianbigard.com> | 2021-02-10 11:06:32 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-02-10 11:36:40 +0100 |
commit | 5f46d28ccac4a20fcbb12c96a047a84a08e485ae (patch) | |
tree | 6529920195176736d187b93bcac8f3ad6920853d /client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts | |
parent | 53e4e201797aa1b581209ffd775bf05197efa78f (diff) | |
download | PeerTube-5f46d28ccac4a20fcbb12c96a047a84a08e485ae.tar.gz PeerTube-5f46d28ccac4a20fcbb12c96a047a84a08e485ae.tar.zst PeerTube-5f46d28ccac4a20fcbb12c96a047a84a08e485ae.zip |
Split admin conf page
Diffstat (limited to 'client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts')
-rw-r--r-- | client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts | 280 |
1 files changed, 35 insertions, 245 deletions
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts index 29524fdd8..a5eddf6c2 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts | |||
@@ -1,8 +1,5 @@ | |||
1 | import { forkJoin } from 'rxjs' | 1 | |
2 | import { pairwise } from 'rxjs/operators' | 2 | import { Component, OnInit } from '@angular/core' |
3 | import { SelectOptionsItem } from 'src/types/select-options-item.model' | ||
4 | import { ViewportScroller } from '@angular/common' | ||
5 | import { AfterViewChecked, Component, OnInit, ViewChild } from '@angular/core' | ||
6 | import { ActivatedRoute, Router } from '@angular/router' | 3 | import { ActivatedRoute, Router } from '@angular/router' |
7 | import { ConfigService } from '@app/+admin/config/shared/config.service' | 4 | import { ConfigService } from '@app/+admin/config/shared/config.service' |
8 | import { Notifier } from '@app/core' | 5 | import { Notifier } from '@app/core' |
@@ -22,155 +19,35 @@ import { | |||
22 | } from '@app/shared/form-validators/custom-config-validators' | 19 | } from '@app/shared/form-validators/custom-config-validators' |
23 | import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators' | 20 | import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators' |
24 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 21 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
25 | import { NgbNav } from '@ng-bootstrap/ng-bootstrap' | ||
26 | import { CustomConfig, ServerConfig } from '@shared/models' | 22 | import { CustomConfig, ServerConfig } from '@shared/models' |
23 | import { forkJoin } from 'rxjs' | ||
24 | import { SelectOptionsItem } from 'src/types/select-options-item.model' | ||
25 | import { EditConfigurationService } from './edit-configuration.service' | ||
27 | 26 | ||
28 | @Component({ | 27 | @Component({ |
29 | selector: 'my-edit-custom-config', | 28 | selector: 'my-edit-custom-config', |
30 | templateUrl: './edit-custom-config.component.html', | 29 | templateUrl: './edit-custom-config.component.html', |
31 | styleUrls: [ './edit-custom-config.component.scss' ] | 30 | styleUrls: [ './edit-custom-config.component.scss' ] |
32 | }) | 31 | }) |
33 | export class EditCustomConfigComponent extends FormReactive implements OnInit, AfterViewChecked { | 32 | export class EditCustomConfigComponent extends FormReactive implements OnInit { |
34 | @ViewChild('nav') nav: NgbNav | 33 | activeNav: string |
35 | 34 | ||
36 | initDone = false | ||
37 | customConfig: CustomConfig | 35 | customConfig: CustomConfig |
38 | 36 | serverConfig: ServerConfig | |
39 | resolutions: { id: string, label: string, description?: string }[] = [] | ||
40 | liveResolutions: { id: string, label: string, description?: string }[] = [] | ||
41 | |||
42 | transcodingThreadOptions: SelectOptionsItem[] = [] | ||
43 | liveMaxDurationOptions: SelectOptionsItem[] = [] | ||
44 | 37 | ||
45 | languageItems: SelectOptionsItem[] = [] | 38 | languageItems: SelectOptionsItem[] = [] |
46 | categoryItems: SelectOptionsItem[] = [] | 39 | categoryItems: SelectOptionsItem[] = [] |
47 | 40 | ||
48 | signupAlertMessage: string | ||
49 | |||
50 | activeNav: string | ||
51 | |||
52 | private serverConfig: ServerConfig | ||
53 | |||
54 | constructor ( | 41 | constructor ( |
55 | private router: Router, | 42 | private router: Router, |
56 | private route: ActivatedRoute, | 43 | private route: ActivatedRoute, |
57 | private viewportScroller: ViewportScroller, | ||
58 | protected formValidatorService: FormValidatorService, | 44 | protected formValidatorService: FormValidatorService, |
59 | private notifier: Notifier, | 45 | private notifier: Notifier, |
60 | private configService: ConfigService, | 46 | private configService: ConfigService, |
61 | private serverService: ServerService | 47 | private serverService: ServerService, |
48 | private editConfigurationService: EditConfigurationService | ||
62 | ) { | 49 | ) { |
63 | super() | 50 | super() |
64 | |||
65 | this.resolutions = [ | ||
66 | { | ||
67 | id: '0p', | ||
68 | label: $localize`Audio-only`, | ||
69 | description: $localize`A <code>.mp4</code> that keeps the original audio track, with no video` | ||
70 | }, | ||
71 | { | ||
72 | id: '240p', | ||
73 | label: $localize`240p` | ||
74 | }, | ||
75 | { | ||
76 | id: '360p', | ||
77 | label: $localize`360p` | ||
78 | }, | ||
79 | { | ||
80 | id: '480p', | ||
81 | label: $localize`480p` | ||
82 | }, | ||
83 | { | ||
84 | id: '720p', | ||
85 | label: $localize`720p` | ||
86 | }, | ||
87 | { | ||
88 | id: '1080p', | ||
89 | label: $localize`1080p` | ||
90 | }, | ||
91 | { | ||
92 | id: '1440p', | ||
93 | label: $localize`1440p` | ||
94 | }, | ||
95 | { | ||
96 | id: '2160p', | ||
97 | label: $localize`2160p` | ||
98 | } | ||
99 | ] | ||
100 | |||
101 | this.liveResolutions = this.resolutions.filter(r => r.id !== '0p') | ||
102 | |||
103 | this.transcodingThreadOptions = [ | ||
104 | { id: 0, label: $localize`Auto (via ffmpeg)` }, | ||
105 | { id: 1, label: '1' }, | ||
106 | { id: 2, label: '2' }, | ||
107 | { id: 4, label: '4' }, | ||
108 | { id: 8, label: '8' }, | ||
109 | { id: 12, label: '12' }, | ||
110 | { id: 16, label: '16' }, | ||
111 | { id: 32, label: '32' } | ||
112 | ] | ||
113 | |||
114 | this.liveMaxDurationOptions = [ | ||
115 | { id: -1, label: $localize`No limit` }, | ||
116 | { id: 1000 * 3600, label: $localize`1 hour` }, | ||
117 | { id: 1000 * 3600 * 3, label: $localize`3 hours` }, | ||
118 | { id: 1000 * 3600 * 5, label: $localize`5 hours` }, | ||
119 | { id: 1000 * 3600 * 10, label: $localize`10 hours` } | ||
120 | ] | ||
121 | } | ||
122 | |||
123 | get videoQuotaOptions () { | ||
124 | return this.configService.videoQuotaOptions | ||
125 | } | ||
126 | |||
127 | get videoQuotaDailyOptions () { | ||
128 | return this.configService.videoQuotaDailyOptions | ||
129 | } | ||
130 | |||
131 | get availableThemes () { | ||
132 | return this.serverConfig.theme.registered | ||
133 | .map(t => t.name) | ||
134 | } | ||
135 | |||
136 | get liveRTMPPort () { | ||
137 | return this.serverConfig.live.rtmp.port | ||
138 | } | ||
139 | |||
140 | getAvailableTranscodingProfile (type: 'live' | 'vod') { | ||
141 | const profiles = type === 'live' | ||
142 | ? this.serverConfig.live.transcoding.availableProfiles | ||
143 | : this.serverConfig.transcoding.availableProfiles | ||
144 | |||
145 | return profiles.map(p => ({ id: p, label: p })) | ||
146 | } | ||
147 | |||
148 | getTotalTranscodingThreads () { | ||
149 | const transcodingEnabled = this.form.value['transcoding']['enabled'] | ||
150 | const transcodingThreads = this.form.value['transcoding']['threads'] | ||
151 | const liveTranscodingEnabled = this.form.value['live']['transcoding']['enabled'] | ||
152 | const liveTranscodingThreads = this.form.value['live']['transcoding']['threads'] | ||
153 | |||
154 | // checks whether all enabled method are on fixed values and not on auto (= 0) | ||
155 | let noneOnAuto = !transcodingEnabled || +transcodingThreads > 0 | ||
156 | noneOnAuto &&= !liveTranscodingEnabled || +liveTranscodingThreads > 0 | ||
157 | |||
158 | // count total of fixed value, repalcing auto by a single thread (knowing it will display "at least") | ||
159 | let value = 0 | ||
160 | if (transcodingEnabled) value += +transcodingThreads || 1 | ||
161 | if (liveTranscodingEnabled) value += +liveTranscodingThreads || 1 | ||
162 | |||
163 | return { | ||
164 | value, | ||
165 | atMost: noneOnAuto, // auto switches everything to a least estimation since ffmpeg will take as many threads as possible | ||
166 | unit: value > 1 | ||
167 | ? $localize`threads` | ||
168 | : $localize`thread` | ||
169 | } | ||
170 | } | ||
171 | |||
172 | getResolutionKey (resolution: string) { | ||
173 | return 'transcoding.resolutions.' + resolution | ||
174 | } | 51 | } |
175 | 52 | ||
176 | ngOnInit () { | 53 | ngOnInit () { |
@@ -346,60 +223,24 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
346 | } | 223 | } |
347 | } | 224 | } |
348 | 225 | ||
349 | for (const resolution of this.resolutions) { | 226 | for (const resolution of this.editConfigurationService.getVODResolutions()) { |
350 | defaultValues.transcoding.resolutions[resolution.id] = 'false' | 227 | defaultValues.transcoding.resolutions[resolution.id] = 'false' |
351 | formGroupData.transcoding.resolutions[resolution.id] = null | 228 | formGroupData.transcoding.resolutions[resolution.id] = null |
352 | } | 229 | } |
353 | 230 | ||
354 | for (const resolution of this.liveResolutions) { | 231 | for (const resolution of this.editConfigurationService.getLiveResolutions()) { |
355 | defaultValues.live.transcoding.resolutions[resolution.id] = 'false' | 232 | defaultValues.live.transcoding.resolutions[resolution.id] = 'false' |
356 | formGroupData.live.transcoding.resolutions[resolution.id] = null | 233 | formGroupData.live.transcoding.resolutions[resolution.id] = null |
357 | } | 234 | } |
358 | 235 | ||
359 | if (this.route.snapshot.fragment) { | ||
360 | this.onNavChange(this.route.snapshot.fragment) | ||
361 | } | ||
362 | |||
363 | this.buildForm(formGroupData) | 236 | this.buildForm(formGroupData) |
364 | this.loadForm() | ||
365 | 237 | ||
366 | this.checkTranscodingFields() | 238 | if (this.route.snapshot.fragment) { |
367 | this.checkSignupField() | 239 | this.onNavChange(this.route.snapshot.fragment) |
368 | } | ||
369 | |||
370 | ngAfterViewChecked () { | ||
371 | if (!this.initDone) { | ||
372 | this.initDone = true | ||
373 | this.gotoAnchor() | ||
374 | } | 240 | } |
375 | } | ||
376 | |||
377 | isTranscodingEnabled () { | ||
378 | return this.form.value['transcoding']['enabled'] === true | ||
379 | } | ||
380 | |||
381 | isLiveEnabled () { | ||
382 | return this.form.value['live']['enabled'] === true | ||
383 | } | ||
384 | |||
385 | isLiveTranscodingEnabled () { | ||
386 | return this.form.value['live']['transcoding']['enabled'] === true | ||
387 | } | ||
388 | |||
389 | isSignupEnabled () { | ||
390 | return this.form.value['signup']['enabled'] === true | ||
391 | } | ||
392 | |||
393 | isSearchIndexEnabled () { | ||
394 | return this.form.value['search']['searchIndex']['enabled'] === true | ||
395 | } | ||
396 | 241 | ||
397 | isAutoFollowIndexEnabled () { | 242 | this.loadConfigAndUpdateForm() |
398 | return this.form.value['followings']['instance']['autoFollowIndex']['enabled'] === true | 243 | this.loadCategoriesAndLanguages() |
399 | } | ||
400 | |||
401 | trendingVideosAlgorithmsEnabledIncludes (algorithm: string) { | ||
402 | return this.form.value['trending']['videos']['algorithms']['enabled'].find((e: string) => e === algorithm) | ||
403 | } | 244 | } |
404 | 245 | ||
405 | async formValidated () { | 246 | async formValidated () { |
@@ -422,18 +263,6 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
422 | ) | 263 | ) |
423 | } | 264 | } |
424 | 265 | ||
425 | gotoAnchor () { | ||
426 | const hashToNav = { | ||
427 | 'customizations': 'advanced-configuration' | ||
428 | } | ||
429 | const hash = window.location.hash.replace('#', '') | ||
430 | |||
431 | if (hash && Object.keys(hashToNav).includes(hash)) { | ||
432 | this.nav.select(hashToNav[hash]) | ||
433 | setTimeout(() => this.viewportScroller.scrollToAnchor(hash), 100) | ||
434 | } | ||
435 | } | ||
436 | |||
437 | hasConsistentOptions () { | 266 | hasConsistentOptions () { |
438 | if (this.hasLiveAllowReplayConsistentOptions()) return true | 267 | if (this.hasLiveAllowReplayConsistentOptions()) return true |
439 | 268 | ||
@@ -441,7 +270,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
441 | } | 270 | } |
442 | 271 | ||
443 | hasLiveAllowReplayConsistentOptions () { | 272 | hasLiveAllowReplayConsistentOptions () { |
444 | if (this.isTranscodingEnabled() === false && this.isLiveEnabled() && this.form.value['live']['allowReplay'] === true) { | 273 | if ( |
274 | this.editConfigurationService.isTranscodingEnabled(this.form) === false && | ||
275 | this.editConfigurationService.isLiveEnabled(this.form) && | ||
276 | this.form.value['live']['allowReplay'] === true | ||
277 | ) { | ||
445 | return false | 278 | return false |
446 | } | 279 | } |
447 | 280 | ||
@@ -458,18 +291,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
458 | this.form.patchValue(this.customConfig) | 291 | this.form.patchValue(this.customConfig) |
459 | } | 292 | } |
460 | 293 | ||
461 | private loadForm () { | 294 | private loadConfigAndUpdateForm () { |
462 | forkJoin([ | 295 | this.configService.getCustomConfig() |
463 | this.configService.getCustomConfig(), | 296 | .subscribe(config => { |
464 | this.serverService.getVideoLanguages(), | ||
465 | this.serverService.getVideoCategories() | ||
466 | ]).subscribe( | ||
467 | ([ config, languages, categories ]) => { | ||
468 | this.customConfig = config | 297 | this.customConfig = config |
469 | 298 | ||
470 | this.languageItems = languages.map(l => ({ label: l.label, id: l.id })) | ||
471 | this.categoryItems = categories.map(l => ({ label: l.label, id: l.id + '' })) | ||
472 | |||
473 | this.updateForm() | 299 | this.updateForm() |
474 | // Force form validation | 300 | // Force form validation |
475 | this.forceCheck() | 301 | this.forceCheck() |
@@ -479,53 +305,17 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit, A | |||
479 | ) | 305 | ) |
480 | } | 306 | } |
481 | 307 | ||
482 | private checkTranscodingFields () { | 308 | private loadCategoriesAndLanguages () { |
483 | const hlsControl = this.form.get('transcoding.hls.enabled') | 309 | forkJoin([ |
484 | const webtorrentControl = this.form.get('transcoding.webtorrent.enabled') | 310 | this.serverService.getVideoLanguages(), |
485 | 311 | this.serverService.getVideoCategories() | |
486 | webtorrentControl.valueChanges | 312 | ]).subscribe( |
487 | .subscribe(newValue => { | 313 | ([ languages, categories ]) => { |
488 | if (newValue === false && !hlsControl.disabled) { | 314 | this.languageItems = languages.map(l => ({ label: l.label, id: l.id })) |
489 | hlsControl.disable() | 315 | this.categoryItems = categories.map(l => ({ label: l.label, id: l.id + '' })) |
490 | } | 316 | }, |
491 | |||
492 | if (newValue === true && !hlsControl.enabled) { | ||
493 | hlsControl.enable() | ||
494 | } | ||
495 | }) | ||
496 | |||
497 | hlsControl.valueChanges | ||
498 | .subscribe(newValue => { | ||
499 | if (newValue === false && !webtorrentControl.disabled) { | ||
500 | webtorrentControl.disable() | ||
501 | } | ||
502 | |||
503 | if (newValue === true && !webtorrentControl.enabled) { | ||
504 | webtorrentControl.enable() | ||
505 | } | ||
506 | }) | ||
507 | } | ||
508 | 317 | ||
509 | private checkSignupField () { | 318 | err => this.notifier.error(err.message) |
510 | const signupControl = this.form.get('signup.enabled') | 319 | ) |
511 | |||
512 | signupControl.valueChanges | ||
513 | .pipe(pairwise()) | ||
514 | .subscribe(([ oldValue, newValue ]) => { | ||
515 | if (oldValue !== true && newValue === true) { | ||
516 | // tslint:disable:max-line-length | ||
517 | this.signupAlertMessage = $localize`You enabled signup: we automatically enabled the "Block new videos automatically" checkbox of the "Videos" section just below.` | ||
518 | |||
519 | this.form.patchValue({ | ||
520 | autoBlacklist: { | ||
521 | videos: { | ||
522 | ofUsers: { | ||
523 | enabled: true | ||
524 | } | ||
525 | } | ||
526 | } | ||
527 | }) | ||
528 | } | ||
529 | }) | ||
530 | } | 320 | } |
531 | } | 321 | } |