]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
a5eddf6c2b49a7dbf5400874febe5c5a15cb00cd
[github/Chocobozzz/PeerTube.git] / client / src / app / +admin / config / edit-custom-config / edit-custom-config.component.ts
1
2 import { Component, OnInit } from '@angular/core'
3 import { ActivatedRoute, Router } from '@angular/router'
4 import { ConfigService } from '@app/+admin/config/shared/config.service'
5 import { Notifier } from '@app/core'
6 import { ServerService } from '@app/core/server/server.service'
7 import {
8 ADMIN_EMAIL_VALIDATOR,
9 CACHE_CAPTIONS_SIZE_VALIDATOR,
10 CACHE_PREVIEWS_SIZE_VALIDATOR,
11 CONCURRENCY_VALIDATOR,
12 INDEX_URL_VALIDATOR,
13 INSTANCE_NAME_VALIDATOR,
14 INSTANCE_SHORT_DESCRIPTION_VALIDATOR,
15 SEARCH_INDEX_URL_VALIDATOR,
16 SERVICES_TWITTER_USERNAME_VALIDATOR,
17 SIGNUP_LIMIT_VALIDATOR,
18 TRANSCODING_THREADS_VALIDATOR
19 } from '@app/shared/form-validators/custom-config-validators'
20 import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators'
21 import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
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'
26
27 @Component({
28 selector: 'my-edit-custom-config',
29 templateUrl: './edit-custom-config.component.html',
30 styleUrls: [ './edit-custom-config.component.scss' ]
31 })
32 export class EditCustomConfigComponent extends FormReactive implements OnInit {
33 activeNav: string
34
35 customConfig: CustomConfig
36 serverConfig: ServerConfig
37
38 languageItems: SelectOptionsItem[] = []
39 categoryItems: SelectOptionsItem[] = []
40
41 constructor (
42 private router: Router,
43 private route: ActivatedRoute,
44 protected formValidatorService: FormValidatorService,
45 private notifier: Notifier,
46 private configService: ConfigService,
47 private serverService: ServerService,
48 private editConfigurationService: EditConfigurationService
49 ) {
50 super()
51 }
52
53 ngOnInit () {
54 this.serverConfig = this.serverService.getTmpConfig()
55 this.serverService.getConfig()
56 .subscribe(config => {
57 this.serverConfig = config
58 })
59
60 const formGroupData: { [key in keyof CustomConfig ]: any } = {
61 instance: {
62 name: INSTANCE_NAME_VALIDATOR,
63 shortDescription: INSTANCE_SHORT_DESCRIPTION_VALIDATOR,
64 description: null,
65
66 isNSFW: false,
67 defaultNSFWPolicy: null,
68
69 terms: null,
70 codeOfConduct: null,
71
72 creationReason: null,
73 moderationInformation: null,
74 administrator: null,
75 maintenanceLifetime: null,
76 businessModel: null,
77
78 hardwareInformation: null,
79
80 categories: null,
81 languages: null,
82
83 defaultClientRoute: null,
84
85 customizations: {
86 javascript: null,
87 css: null
88 }
89 },
90 theme: {
91 default: null
92 },
93 services: {
94 twitter: {
95 username: SERVICES_TWITTER_USERNAME_VALIDATOR,
96 whitelisted: null
97 }
98 },
99 cache: {
100 previews: {
101 size: CACHE_PREVIEWS_SIZE_VALIDATOR
102 },
103 captions: {
104 size: CACHE_CAPTIONS_SIZE_VALIDATOR
105 }
106 },
107 signup: {
108 enabled: null,
109 limit: SIGNUP_LIMIT_VALIDATOR,
110 requiresEmailVerification: null
111 },
112 import: {
113 videos: {
114 concurrency: CONCURRENCY_VALIDATOR,
115 http: {
116 enabled: null
117 },
118 torrent: {
119 enabled: null
120 }
121 }
122 },
123 trending: {
124 videos: {
125 algorithms: {
126 enabled: null,
127 default: null
128 }
129 }
130 },
131 admin: {
132 email: ADMIN_EMAIL_VALIDATOR
133 },
134 contactForm: {
135 enabled: null
136 },
137 user: {
138 videoQuota: USER_VIDEO_QUOTA_VALIDATOR,
139 videoQuotaDaily: USER_VIDEO_QUOTA_DAILY_VALIDATOR
140 },
141 transcoding: {
142 enabled: null,
143 threads: TRANSCODING_THREADS_VALIDATOR,
144 allowAdditionalExtensions: null,
145 allowAudioFiles: null,
146 profile: null,
147 concurrency: CONCURRENCY_VALIDATOR,
148 resolutions: {},
149 hls: {
150 enabled: null
151 },
152 webtorrent: {
153 enabled: null
154 }
155 },
156 live: {
157 enabled: null,
158
159 maxDuration: null,
160 maxInstanceLives: null,
161 maxUserLives: null,
162 allowReplay: null,
163
164 transcoding: {
165 enabled: null,
166 threads: TRANSCODING_THREADS_VALIDATOR,
167 profile: null,
168 resolutions: {}
169 }
170 },
171 autoBlacklist: {
172 videos: {
173 ofUsers: {
174 enabled: null
175 }
176 }
177 },
178 followers: {
179 instance: {
180 enabled: null,
181 manualApproval: null
182 }
183 },
184 followings: {
185 instance: {
186 autoFollowBack: {
187 enabled: null
188 },
189 autoFollowIndex: {
190 enabled: null,
191 indexUrl: INDEX_URL_VALIDATOR
192 }
193 }
194 },
195 broadcastMessage: {
196 enabled: null,
197 level: null,
198 dismissable: null,
199 message: null
200 },
201 search: {
202 remoteUri: {
203 users: null,
204 anonymous: null
205 },
206 searchIndex: {
207 enabled: null,
208 url: SEARCH_INDEX_URL_VALIDATOR,
209 disableLocalSearch: null,
210 isDefaultSearch: null
211 }
212 }
213 }
214
215 const defaultValues = {
216 transcoding: {
217 resolutions: {}
218 },
219 live: {
220 transcoding: {
221 resolutions: {}
222 }
223 }
224 }
225
226 for (const resolution of this.editConfigurationService.getVODResolutions()) {
227 defaultValues.transcoding.resolutions[resolution.id] = 'false'
228 formGroupData.transcoding.resolutions[resolution.id] = null
229 }
230
231 for (const resolution of this.editConfigurationService.getLiveResolutions()) {
232 defaultValues.live.transcoding.resolutions[resolution.id] = 'false'
233 formGroupData.live.transcoding.resolutions[resolution.id] = null
234 }
235
236 this.buildForm(formGroupData)
237
238 if (this.route.snapshot.fragment) {
239 this.onNavChange(this.route.snapshot.fragment)
240 }
241
242 this.loadConfigAndUpdateForm()
243 this.loadCategoriesAndLanguages()
244 }
245
246 async formValidated () {
247 const value: CustomConfig = this.form.getRawValue()
248
249 this.configService.updateCustomConfig(value)
250 .subscribe(
251 res => {
252 this.customConfig = res
253
254 // Reload general configuration
255 this.serverService.resetConfig()
256
257 this.updateForm()
258
259 this.notifier.success($localize`Configuration updated.`)
260 },
261
262 err => this.notifier.error(err.message)
263 )
264 }
265
266 hasConsistentOptions () {
267 if (this.hasLiveAllowReplayConsistentOptions()) return true
268
269 return false
270 }
271
272 hasLiveAllowReplayConsistentOptions () {
273 if (
274 this.editConfigurationService.isTranscodingEnabled(this.form) === false &&
275 this.editConfigurationService.isLiveEnabled(this.form) &&
276 this.form.value['live']['allowReplay'] === true
277 ) {
278 return false
279 }
280
281 return true
282 }
283
284 onNavChange (newActiveNav: string) {
285 this.activeNav = newActiveNav
286
287 this.router.navigate([], { fragment: this.activeNav })
288 }
289
290 private updateForm () {
291 this.form.patchValue(this.customConfig)
292 }
293
294 private loadConfigAndUpdateForm () {
295 this.configService.getCustomConfig()
296 .subscribe(config => {
297 this.customConfig = config
298
299 this.updateForm()
300 // Force form validation
301 this.forceCheck()
302 },
303
304 err => this.notifier.error(err.message)
305 )
306 }
307
308 private loadCategoriesAndLanguages () {
309 forkJoin([
310 this.serverService.getVideoLanguages(),
311 this.serverService.getVideoCategories()
312 ]).subscribe(
313 ([ languages, categories ]) => {
314 this.languageItems = languages.map(l => ({ label: l.label, id: l.id }))
315 this.categoryItems = categories.map(l => ({ label: l.label, id: l.id + '' }))
316 },
317
318 err => this.notifier.error(err.message)
319 )
320 }
321 }