]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
Merge branch 'blacklist' into 'develop'
[github/Chocobozzz/PeerTube.git] / client / src / app / +admin / config / edit-custom-config / edit-custom-config.component.ts
CommitLineData
45c6bcf3 1import { AfterViewChecked, Component, OnInit, ViewChild } from '@angular/core'
fd206f0b
C
2import { ConfigService } from '@app/+admin/config/shared/config.service'
3import { ServerService } from '@app/core/server/server.service'
e309822b 4import { CustomConfigValidatorsService, FormReactive, UserValidatorsService } from '@app/shared'
f8b2c1b4 5import { Notifier } from '@app/core'
09cababd 6import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model'
b1d40cff 7import { I18n } from '@ngx-translate/i18n-polyfill'
0dc64777 8import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
ccc00cb2
C
9import { SelectItem } from 'primeng/api'
10import { forkJoin } from 'rxjs'
ba430d75 11import { ServerConfig } from '@shared/models'
45e0d669 12import { ViewportScroller } from '@angular/common'
45c6bcf3 13import { NgbNav } from '@ng-bootstrap/ng-bootstrap'
fd206f0b
C
14
15@Component({
16 selector: 'my-edit-custom-config',
17 templateUrl: './edit-custom-config.component.html',
18 styleUrls: [ './edit-custom-config.component.scss' ]
19})
45e0d669 20export class EditCustomConfigComponent extends FormReactive implements OnInit, AfterViewChecked {
45c6bcf3
C
21 // FIXME: use built-in router
22 @ViewChild('nav') nav: NgbNav
45e0d669
RK
23
24 initDone = false
bee0abff 25 customConfig: CustomConfig
bee0abff 26
46db9430 27 resolutions: { id: string, label: string, description?: string }[] = []
3827c3b3 28 transcodingThreadOptions: { label: string, value: number }[] = []
fd206f0b 29
ccc00cb2
C
30 languageItems: SelectItem[] = []
31 categoryItems: SelectItem[] = []
32
ba430d75
C
33 private serverConfig: ServerConfig
34
fd206f0b 35 constructor (
45e0d669 36 private viewportScroller: ViewportScroller,
d18d6478 37 protected formValidatorService: FormValidatorService,
e309822b
C
38 private customConfigValidatorsService: CustomConfigValidatorsService,
39 private userValidatorsService: UserValidatorsService,
f8b2c1b4 40 private notifier: Notifier,
fd206f0b 41 private configService: ConfigService,
1f30a185 42 private serverService: ServerService,
b1d40cff 43 private i18n: I18n
fd206f0b
C
44 ) {
45 super()
3827c3b3
C
46
47 this.resolutions = [
2fa9c40e 48 {
5c7d6508 49 id: '0p',
46db9430 50 label: this.i18n('Audio-only'),
6a07a058 51 description: this.i18n('A <code>.mp4</code> that keeps the original audio track, with no video')
5c7d6508 52 },
00aa1f0d
C
53 {
54 id: '240p',
55 label: this.i18n('240p')
56 },
57 {
58 id: '360p',
59 label: this.i18n('360p')
60 },
61 {
62 id: '480p',
63 label: this.i18n('480p')
64 },
65 {
66 id: '720p',
67 label: this.i18n('720p')
68 },
69 {
70 id: '1080p',
71 label: this.i18n('1080p')
72 },
73 {
74 id: '2160p',
75 label: this.i18n('2160p')
76 }
3827c3b3
C
77 ]
78
79 this.transcodingThreadOptions = [
80 { value: 0, label: this.i18n('Auto (via ffmpeg)') },
81 { value: 1, label: '1' },
82 { value: 2, label: '2' },
83 { value: 4, label: '4' },
84 { value: 8, label: '8' }
85 ]
fd206f0b
C
86 }
87
41a676db 88 get videoQuotaOptions () {
3827c3b3 89 return this.configService.videoQuotaOptions
41a676db
C
90 }
91
92 get videoQuotaDailyOptions () {
3827c3b3 93 return this.configService.videoQuotaDailyOptions
41a676db
C
94 }
95
7cd4d2ba 96 get availableThemes () {
ba430d75 97 return this.serverConfig.theme.registered
ffb321be 98 .map(t => t.name)
7cd4d2ba
C
99 }
100
fd206f0b 101 getResolutionKey (resolution: string) {
3866f1a0 102 return 'transcoding.resolutions.' + resolution
fd206f0b
C
103 }
104
d18d6478 105 ngOnInit () {
ba430d75
C
106 this.serverConfig = this.serverService.getTmpConfig()
107 this.serverService.getConfig()
108 .subscribe(config => this.serverConfig = config)
109
3866f1a0
C
110 const formGroupData: { [key in keyof CustomConfig ]: any } = {
111 instance: {
112 name: this.customConfigValidatorsService.INSTANCE_NAME,
113 shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION,
114 description: null,
ccc00cb2 115
f8802489 116 isNSFW: false,
3866f1a0 117 defaultNSFWPolicy: null,
ccc00cb2
C
118
119 terms: null,
120 codeOfConduct: null,
8ae03c37
C
121
122 creationReason: null,
ccc00cb2
C
123 moderationInformation: null,
124 administrator: null,
125 maintenanceLifetime: null,
126 businessModel: null,
127
be04c6fd
C
128 hardwareInformation: null,
129
ccc00cb2
C
130 categories: null,
131 languages: null,
132
133 defaultClientRoute: null,
134
3866f1a0
C
135 customizations: {
136 javascript: null,
137 css: null
138 }
139 },
7cd4d2ba
C
140 theme: {
141 default: null
142 },
3866f1a0
C
143 services: {
144 twitter: {
145 username: this.customConfigValidatorsService.SERVICES_TWITTER_USERNAME,
146 whitelisted: null
147 }
148 },
149 cache: {
150 previews: {
151 size: this.customConfigValidatorsService.CACHE_PREVIEWS_SIZE
152 },
153 captions: {
154 size: this.customConfigValidatorsService.CACHE_CAPTIONS_SIZE
155 }
156 },
157 signup: {
158 enabled: null,
159 limit: this.customConfigValidatorsService.SIGNUP_LIMIT,
160 requiresEmailVerification: null
161 },
162 import: {
163 videos: {
164 http: {
165 enabled: null
166 },
167 torrent: {
168 enabled: null
169 }
170 }
171 },
172 admin: {
173 email: this.customConfigValidatorsService.ADMIN_EMAIL
174 },
175 contactForm: {
176 enabled: null
177 },
178 user: {
179 videoQuota: this.userValidatorsService.USER_VIDEO_QUOTA,
180 videoQuotaDaily: this.userValidatorsService.USER_VIDEO_QUOTA_DAILY
181 },
182 transcoding: {
183 enabled: null,
184 threads: this.customConfigValidatorsService.TRANSCODING_THREADS,
185 allowAdditionalExtensions: null,
536598cf 186 allowAudioFiles: null,
5d9e4eaa
C
187 resolutions: {},
188 hls: {
189 enabled: null
5a71acd2
C
190 },
191 webtorrent: {
192 enabled: null
5d9e4eaa 193 }
7ccddd7b
JM
194 },
195 autoBlacklist: {
196 videos: {
197 ofUsers: {
198 enabled: null
199 }
200 }
0dc64777
C
201 },
202 followers: {
203 instance: {
204 enabled: null,
205 manualApproval: null
206 }
e1b49ee5
C
207 },
208 followings: {
209 instance: {
210 autoFollowBack: {
211 enabled: null
212 },
213 autoFollowIndex: {
214 enabled: null,
215 indexUrl: this.customConfigValidatorsService.INDEX_URL
216 }
217 }
72c33e71
C
218 },
219 broadcastMessage: {
220 enabled: null,
221 level: null,
222 dismissable: null,
223 message: null
5fb2e288
C
224 },
225 search: {
226 remoteUri: {
227 users: null,
228 anonymous: null
229 },
230 searchIndex: {
231 enabled: null,
232 url: this.customConfigValidatorsService.SEARCH_INDEX_URL,
233 disableLocalSearch: null,
234 isDefaultSearch: null
235 }
3866f1a0 236 }
fd206f0b
C
237 }
238
3866f1a0
C
239 const defaultValues = {
240 transcoding: {
241 resolutions: {}
242 }
243 }
fd206f0b 244 for (const resolution of this.resolutions) {
00aa1f0d
C
245 defaultValues.transcoding.resolutions[resolution.id] = 'false'
246 formGroupData.transcoding.resolutions[resolution.id] = null
fd206f0b
C
247 }
248
d18d6478 249 this.buildForm(formGroupData)
04cda1d7
C
250 this.loadForm()
251 this.checkTranscodingFields()
fd206f0b
C
252 }
253
45e0d669
RK
254 ngAfterViewChecked () {
255 if (!this.initDone) {
256 this.initDone = true
257 this.gotoAnchor()
258 }
259 }
260
fd206f0b 261 isTranscodingEnabled () {
3866f1a0 262 return this.form.value['transcoding']['enabled'] === true
fd206f0b
C
263 }
264
265 isSignupEnabled () {
3866f1a0 266 return this.form.value['signup']['enabled'] === true
fd206f0b
C
267 }
268
5fb2e288
C
269 isSearchIndexEnabled () {
270 return this.form.value['search']['searchIndex']['enabled'] === true
271 }
272
4ee6a8b1
C
273 isAutoFollowIndexEnabled () {
274 return this.form.value['followings']['instance']['autoFollowIndex']['enabled'] === true
275 }
276
1f30a185 277 async formValidated () {
04cda1d7 278 this.configService.updateCustomConfig(this.form.getRawValue())
fd206f0b
C
279 .subscribe(
280 res => {
281 this.customConfig = res
282
283 // Reload general configuration
ba430d75 284 this.serverService.resetConfig()
fd206f0b
C
285
286 this.updateForm()
66b16caf 287
f8b2c1b4 288 this.notifier.success(this.i18n('Configuration updated.'))
fd206f0b
C
289 },
290
f8b2c1b4 291 err => this.notifier.error(err.message)
fd206f0b
C
292 )
293 }
294
ccc00cb2
C
295 getSelectedLanguageLabel () {
296 return this.i18n('{{\'{0} languages selected')
297 }
298
299 getDefaultLanguageLabel () {
300 return this.i18n('No language')
301 }
302
303 getSelectedCategoryLabel () {
304 return this.i18n('{{\'{0} categories selected')
305 }
306
307 getDefaultCategoryLabel () {
308 return this.i18n('No category')
309 }
310
45e0d669 311 gotoAnchor () {
45c6bcf3 312 const hashToNav = {
45e0d669
RK
313 'customizations': 'advanced-configuration'
314 }
315 const hash = window.location.hash.replace('#', '')
316
45c6bcf3
C
317 if (hash && Object.keys(hashToNav).includes(hash)) {
318 this.nav.select(hashToNav[hash])
45e0d669
RK
319 setTimeout(() => this.viewportScroller.scrollToAnchor(hash), 100)
320 }
321 }
322
fd206f0b 323 private updateForm () {
3866f1a0 324 this.form.patchValue(this.customConfig)
fd206f0b 325 }
04cda1d7
C
326
327 private loadForm () {
328 forkJoin([
329 this.configService.getCustomConfig(),
330 this.serverService.getVideoLanguages(),
331 this.serverService.getVideoCategories()
332 ]).subscribe(
333 ([ config, languages, categories ]) => {
334 this.customConfig = config
335
336 this.languageItems = languages.map(l => ({ label: l.label, value: l.id }))
337 this.categoryItems = categories.map(l => ({ label: l.label, value: l.id }))
338
339 this.updateForm()
340 // Force form validation
341 this.forceCheck()
342 },
343
344 err => this.notifier.error(err.message)
345 )
346 }
347
348 private checkTranscodingFields () {
349 const hlsControl = this.form.get('transcoding.hls.enabled')
350 const webtorrentControl = this.form.get('transcoding.webtorrent.enabled')
351
352 webtorrentControl.valueChanges
353 .subscribe(newValue => {
354 if (newValue === false && !hlsControl.disabled) {
355 hlsControl.disable()
356 }
357
358 if (newValue === true && !hlsControl.enabled) {
359 hlsControl.enable()
360 }
361 })
362
363 hlsControl.valueChanges
364 .subscribe(newValue => {
365 if (newValue === false && !webtorrentControl.disabled) {
366 webtorrentControl.disable()
367 }
368
369 if (newValue === true && !webtorrentControl.enabled) {
370 webtorrentControl.enable()
371 }
372 })
373 }
fd206f0b 374}