diff options
18 files changed, 437 insertions, 82 deletions
diff --git a/client/src/app/+about/about-instance/about-instance.component.html b/client/src/app/+about/about-instance/about-instance.component.html index 7c27ec760..0fd3626b7 100644 --- a/client/src/app/+about/about-instance/about-instance.component.html +++ b/client/src/app/+about/about-instance/about-instance.component.html | |||
@@ -1,7 +1,8 @@ | |||
1 | <div class="row"> | 1 | <div class="row"> |
2 | <div class="col-md-12 col-xl-6"> | 2 | <div class="col-md-12 col-xl-6"> |
3 | |||
3 | <div class="about-instance-title"> | 4 | <div class="about-instance-title"> |
4 | <div i18n>About {{ instanceName }} instance</div> | 5 | <div i18n class="title">About {{ instanceName }} instance</div> |
5 | 6 | ||
6 | <div *ngIf="isContactFormEnabled" (click)="openContactModal()" i18n role="button" class="contact-admin">Contact administrator</div> | 7 | <div *ngIf="isContactFormEnabled" (click)="openContactModal()" i18n role="button" class="contact-admin">Contact administrator</div> |
7 | </div> | 8 | </div> |
@@ -12,16 +13,58 @@ | |||
12 | <div *ngIf="isNSFW" class="dedicated-to-nsfw">This instance is dedicated to sensitive/NSFW content.</div> | 13 | <div *ngIf="isNSFW" class="dedicated-to-nsfw">This instance is dedicated to sensitive/NSFW content.</div> |
13 | </div> | 14 | </div> |
14 | 15 | ||
15 | <div class="description"> | 16 | <div class="middle-title" *ngIf="html.administrator || maintenanceLifetime || businessModel"> |
17 | Administrators & sustainability | ||
18 | </div> | ||
19 | |||
20 | <div class="block administrator" *ngIf="html.administrator"> | ||
21 | <div i18n class="section-title">Instance administrators</div> | ||
22 | |||
23 | <div [innerHTML]="html.administrator"></div> | ||
24 | </div> | ||
25 | |||
26 | <div class="block maintenance-lifetime" *ngIf="maintenanceLifetime"> | ||
27 | <div i18n class="section-title">Maintenance lifetime</div> | ||
28 | |||
29 | <p>{{ maintenanceLifetime }}</p> | ||
30 | </div> | ||
31 | |||
32 | <div class="block business-model" *ngIf="businessModel"> | ||
33 | <div i18n class="section-title">Business model</div> | ||
34 | |||
35 | <p>{{ businessModel }}</p> | ||
36 | </div> | ||
37 | |||
38 | <div class="middle-title" *ngIf="html.description"> | ||
39 | Information | ||
40 | </div> | ||
41 | |||
42 | <div class="block description"> | ||
16 | <div i18n class="section-title">Description</div> | 43 | <div i18n class="section-title">Description</div> |
17 | 44 | ||
18 | <div [innerHTML]="descriptionHTML"></div> | 45 | <div [innerHTML]="html.description"></div> |
46 | </div> | ||
47 | |||
48 | <div class="middle-title" *ngIf="html.moderationInformation || html.codeOfConduct || html.terms"> | ||
49 | Moderation | ||
50 | </div> | ||
51 | |||
52 | <div class="block moderation-information" *ngIf="html.moderationInformation"> | ||
53 | <div i18n class="section-title">Moderation information</div> | ||
54 | |||
55 | <div [innerHTML]="html.moderationInformation"></div> | ||
56 | </div> | ||
57 | |||
58 | <div class="block code-of-conduct" *ngIf="html.codeOfConduct"> | ||
59 | <div i18n class="section-title">Code of conduct</div> | ||
60 | |||
61 | <div [innerHTML]="html.codeOfConduct"></div> | ||
19 | </div> | 62 | </div> |
20 | 63 | ||
21 | <div class="terms" id="terms-section"> | 64 | <div class="block terms" id="terms-section"> |
22 | <div i18n class="section-title">Terms</div> | 65 | <div i18n class="section-title">Terms</div> |
23 | 66 | ||
24 | <div [innerHTML]="termsHTML"></div> | 67 | <div [innerHTML]="html.terms"></div> |
25 | </div> | 68 | </div> |
26 | </div> | 69 | </div> |
27 | 70 | ||
diff --git a/client/src/app/+about/about-instance/about-instance.component.scss b/client/src/app/+about/about-instance/about-instance.component.scss index 0296ae8e9..0585ad5f3 100644 --- a/client/src/app/+about/about-instance/about-instance.component.scss +++ b/client/src/app/+about/about-instance/about-instance.component.scss | |||
@@ -5,13 +5,13 @@ | |||
5 | display: flex; | 5 | display: flex; |
6 | justify-content: space-between; | 6 | justify-content: space-between; |
7 | 7 | ||
8 | & > div { | 8 | .title { |
9 | font-size: 20px; | 9 | font-size: 20px; |
10 | font-weight: bold; | ||
11 | margin-bottom: 15px; | 10 | margin-bottom: 15px; |
11 | font-weight: $font-semibold; | ||
12 | } | 12 | } |
13 | 13 | ||
14 | & > .contact-admin { | 14 | .contact-admin { |
15 | @include peertube-button; | 15 | @include peertube-button; |
16 | @include orange-button; | 16 | @include orange-button; |
17 | 17 | ||
@@ -21,11 +21,20 @@ | |||
21 | 21 | ||
22 | .section-title { | 22 | .section-title { |
23 | font-weight: $font-semibold; | 23 | font-weight: $font-semibold; |
24 | font-size: 20px; | 24 | font-size: 16px; |
25 | margin-bottom: 5px; | 25 | margin-bottom: 5px; |
26 | display: flex; | ||
27 | align-items: center; | ||
28 | } | ||
29 | |||
30 | .middle-title { | ||
31 | @include in-content-small-title; | ||
32 | |||
33 | margin-top: 45px; | ||
34 | margin-bottom: 25px; | ||
26 | } | 35 | } |
27 | 36 | ||
28 | .short-description, .description, .terms, .signup { | 37 | .block { |
29 | margin-bottom: 30px; | 38 | margin-bottom: 30px; |
30 | } | 39 | } |
31 | 40 | ||
diff --git a/client/src/app/+about/about-instance/about-instance.component.ts b/client/src/app/+about/about-instance/about-instance.component.ts index a5204de27..b85a6be94 100644 --- a/client/src/app/+about/about-instance/about-instance.component.ts +++ b/client/src/app/+about/about-instance/about-instance.component.ts | |||
@@ -14,8 +14,20 @@ export class AboutInstanceComponent implements OnInit { | |||
14 | @ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent | 14 | @ViewChild('contactAdminModal', { static: true }) contactAdminModal: ContactAdminModalComponent |
15 | 15 | ||
16 | shortDescription = '' | 16 | shortDescription = '' |
17 | descriptionHTML = '' | 17 | |
18 | termsHTML = '' | 18 | html = { |
19 | description: '', | ||
20 | terms: '', | ||
21 | codeOfConduct: '', | ||
22 | moderationInformation: '', | ||
23 | administrator: '' | ||
24 | } | ||
25 | |||
26 | maintenanceLifetime = '' | ||
27 | businessModel = '' | ||
28 | |||
29 | languages: string[] = [] | ||
30 | categories: number[] = [] | ||
19 | 31 | ||
20 | constructor ( | 32 | constructor ( |
21 | private notifier: Notifier, | 33 | private notifier: Notifier, |
@@ -43,8 +55,15 @@ export class AboutInstanceComponent implements OnInit { | |||
43 | async res => { | 55 | async res => { |
44 | this.shortDescription = res.instance.shortDescription | 56 | this.shortDescription = res.instance.shortDescription |
45 | 57 | ||
46 | this.descriptionHTML = await this.markdownService.textMarkdownToHTML(res.instance.description) | 58 | this.maintenanceLifetime = res.instance.maintenanceLifetime |
47 | this.termsHTML = await this.markdownService.textMarkdownToHTML(res.instance.terms) | 59 | this.businessModel = res.instance.businessModel |
60 | |||
61 | for (const key of [ 'description', 'terms', 'codeOfConduct', 'moderationInformation', 'administrator' ]) { | ||
62 | this.html[key] = await this.markdownService.textMarkdownToHTML(res.instance[key]) | ||
63 | } | ||
64 | |||
65 | this.languages = res.instance.languages | ||
66 | this.categories = res.instance.categories | ||
48 | }, | 67 | }, |
49 | 68 | ||
50 | () => this.notifier.error(this.i18n('Cannot get about information from server')) | 69 | () => this.notifier.error(this.i18n('Cannot get about information from server')) |
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 ec6f879d7..50df8a8ac 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 | |||
@@ -2,12 +2,13 @@ | |||
2 | 2 | ||
3 | <ngb-tabset class="root-tabset bootstrap"> | 3 | <ngb-tabset class="root-tabset bootstrap"> |
4 | 4 | ||
5 | <ngb-tab i18n-title title="Basic configuration"> | 5 | <ngb-tab i18n-title title="Instance information"> |
6 | <ng-template ngbTabContent> | 6 | <ng-template ngbTabContent> |
7 | 7 | ||
8 | <div i18n class="inner-form-title">Instance</div> | ||
9 | |||
10 | <ng-container formGroupName="instance"> | 8 | <ng-container formGroupName="instance"> |
9 | |||
10 | <div i18n class="inner-form-title">Instance</div> | ||
11 | |||
11 | <div class="form-group"> | 12 | <div class="form-group"> |
12 | <label i18n for="instanceName">Name</label> | 13 | <label i18n for="instanceName">Name</label> |
13 | <input | 14 | <input |
@@ -36,37 +37,41 @@ | |||
36 | </div> | 37 | </div> |
37 | 38 | ||
38 | <div class="form-group"> | 39 | <div class="form-group"> |
39 | <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> | 40 | <label i18n for="instanceCategories">Main instance categories</label> |
40 | <my-markdown-textarea | 41 | |
41 | id="instanceTerms" formControlName="terms" textareaWidth="500px" [previewColumn]="true" | 42 | <div> |
42 | [ngClass]="{ 'input-error': formErrors['instance.terms'] }" | 43 | <p-multiSelect |
43 | ></my-markdown-textarea> | 44 | inputId="instanceCategories" [options]="categoryItems" formControlName="categories" showToggleAll="false" |
44 | <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div> | 45 | [defaultLabel]="getDefaultCategoryLabel()" [selectedItemsLabel]="getSelectedCategoryLabel()" |
46 | emptyFilterMessage="No results found" i18n-emptyFilterMessage | ||
47 | ></p-multiSelect> | ||
48 | </div> | ||
45 | </div> | 49 | </div> |
46 | 50 | ||
47 | <div class="form-group"> | 51 | <div class="form-group"> |
52 | <label i18n for="instanceLanguages">Main languages you/your moderators speak</label> | ||
53 | |||
54 | <div> | ||
55 | <p-multiSelect | ||
56 | inputId="instanceLanguages" [options]="languageItems" formControlName="languages" showToggleAll="false" | ||
57 | [defaultLabel]="getDefaultLanguageLabel()" [selectedItemsLabel]="getSelectedLanguageLabel()" | ||
58 | emptyFilterMessage="No results found" i18n-emptyFilterMessage | ||
59 | ></p-multiSelect> | ||
60 | </div> | ||
61 | </div> | ||
62 | |||
63 | <div i18n class="inner-form-title">Moderation & NSFW</div> | ||
64 | |||
65 | <div class="form-group"> | ||
48 | <my-peertube-checkbox | 66 | <my-peertube-checkbox |
49 | inputName="instanceIsNSFW" formControlName="isNSFW" | 67 | inputName="instanceIsNSFW" formControlName="isNSFW" |
50 | i18n-labelText labelText="Dedicated to sensitive or NSFW content" | 68 | i18n-labelText labelText="This instance is dedicated to sensitive or NSFW content" |
51 | i18n-helpHtml helpHtml="Enabling it will allow other administrators to know that you are mainly federating sensitive content.<br /><br /> | 69 | i18n-helpHtml helpHtml="Enabling it will allow other administrators to know that you are mainly federating sensitive content.<br /><br /> |
52 | Moreover, the NSFW checkbox on video upload will be automatically checked by default." | 70 | Moreover, the NSFW checkbox on video upload will be automatically checked by default." |
53 | ></my-peertube-checkbox> | 71 | ></my-peertube-checkbox> |
54 | </div> | 72 | </div> |
55 | 73 | ||
56 | <div class="form-group"> | 74 | <div class="form-group"> |
57 | <label i18n for="instanceDefaultClientRoute">Default client route</label> | ||
58 | <div class="peertube-select-container"> | ||
59 | <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute"> | ||
60 | <option i18n value="/videos/overview">Videos Overview</option> | ||
61 | <option i18n value="/videos/trending">Videos Trending</option> | ||
62 | <option i18n value="/videos/recently-added">Videos Recently Added</option> | ||
63 | <option i18n value="/videos/local">Local videos</option> | ||
64 | </select> | ||
65 | </div> | ||
66 | <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div> | ||
67 | </div> | ||
68 | |||
69 | <div class="form-group"> | ||
70 | <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> | 75 | <label i18n for="instanceDefaultNSFWPolicy">Policy on videos containing sensitive content</label> |
71 | <my-help | 76 | <my-help |
72 | helpType="custom" i18n-customHtml | 77 | helpType="custom" i18n-customHtml |
@@ -82,10 +87,79 @@ | |||
82 | </div> | 87 | </div> |
83 | <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div> | 88 | <div *ngIf="formErrors.instance.defaultNSFWPolicy" class="form-error">{{ formErrors.instance.defaultNSFWPolicy }}</div> |
84 | </div> | 89 | </div> |
90 | |||
91 | <div class="form-group"> | ||
92 | <label i18n for="instanceTerms">Terms</label><my-help helpType="markdownText"></my-help> | ||
93 | <my-markdown-textarea | ||
94 | id="instanceTerms" formControlName="terms" textareaWidth="500px" [previewColumn]="true" | ||
95 | [ngClass]="{ 'input-error': formErrors['instance.terms'] }" | ||
96 | ></my-markdown-textarea> | ||
97 | <div *ngIf="formErrors.instance.terms" class="form-error">{{ formErrors.instance.terms }}</div> | ||
98 | </div> | ||
99 | |||
100 | <div class="form-group"> | ||
101 | <label i18n for="instanceCodeOfConduct">Code of conduct</label><my-help helpType="markdownText"></my-help> | ||
102 | <my-markdown-textarea | ||
103 | id="instanceCodeOfConduct" formControlName="codeOfConduct" textareaWidth="500px" [previewColumn]="true" | ||
104 | [ngClass]="{ 'input-error': formErrors['instance.codeOfConduct'] }" | ||
105 | ></my-markdown-textarea> | ||
106 | <div *ngIf="formErrors.instance.codeOfConduct" class="form-error">{{ formErrors.instance.codeOfConduct }}</div> | ||
107 | </div> | ||
108 | |||
109 | <div class="form-group"> | ||
110 | <label i18n for="instanceModerationInformation">Moderation information</label><my-help helpType="markdownText"></my-help> | ||
111 | <div class="label-small-info">Who moderates the instance? What is the policy regarding NSFW videos? Political videos? etc</div> | ||
112 | |||
113 | <my-markdown-textarea | ||
114 | id="instanceModerationInformation" formControlName="moderationInformation" textareaWidth="500px" [previewColumn]="true" | ||
115 | [ngClass]="{ 'input-error': formErrors['instance.moderationInformation'] }" | ||
116 | ></my-markdown-textarea> | ||
117 | <div *ngIf="formErrors.instance.moderationInformation" class="form-error">{{ formErrors.instance.moderationInformation }}</div> | ||
118 | </div> | ||
119 | |||
120 | <div i18n class="inner-form-title">You and your instance</div> | ||
121 | |||
122 | <div class="form-group"> | ||
123 | <label i18n for="instanceAdministrator">Who is behind the instance? </label> | ||
124 | <div class="label-small-info">A single person? A non profit? A company?</div> | ||
125 | |||
126 | <textarea | ||
127 | id="instanceAdministrator" formControlName="administrator" | ||
128 | [ngClass]="{ 'input-error': formErrors['instance.administrator'] }" | ||
129 | ></textarea> | ||
130 | <div *ngIf="formErrors.instance.administrator" class="form-error">{{ formErrors.instance.administrator }}</div> | ||
131 | </div> | ||
132 | |||
133 | <div class="form-group"> | ||
134 | <label i18n for="instanceMaintenanceLifetime">How long do you plan to maintain this instance?</label> | ||
135 | <div class="label-small-info">It's important to know for users who want to register on your instance</div> | ||
136 | |||
137 | <textarea | ||
138 | id="instanceMaintenanceLifetime" formControlName="maintenanceLifetime" | ||
139 | [ngClass]="{ 'input-error': formErrors['instance.maintenanceLifetime'] }" | ||
140 | ></textarea> | ||
141 | <div *ngIf="formErrors.instance.maintenanceLifetime" class="form-error">{{ formErrors.instance.maintenanceLifetime }}</div> | ||
142 | </div> | ||
143 | |||
144 | <div class="form-group"> | ||
145 | <label i18n for="instanceBusinessModel">How will you pay the PeerTube instance server?</label> | ||
146 | <div class="label-small-info">With you own funds? With users donations? Advertising?</div> | ||
147 | |||
148 | <textarea | ||
149 | id="instanceBusinessModel" formControlName="businessModel" | ||
150 | [ngClass]="{ 'input-error': formErrors['instance.businessModel'] }" | ||
151 | ></textarea> | ||
152 | <div *ngIf="formErrors.instance.businessModel" class="form-error">{{ formErrors.instance.businessModel }}</div> | ||
153 | </div> | ||
154 | |||
85 | </ng-container> | 155 | </ng-container> |
156 | </ng-template> | ||
157 | </ngb-tab> | ||
86 | 158 | ||
159 | <ngb-tab i18n-title title="Basic configuration"> | ||
160 | <ng-template ngbTabContent> | ||
87 | 161 | ||
88 | <div i18n class="inner-form-title">Theme</div> | 162 | <div i18n class="inner-form-title">Theme & Default route</div> |
89 | 163 | ||
90 | <ng-container formGroupName="theme"> | 164 | <ng-container formGroupName="theme"> |
91 | <div class="form-group"> | 165 | <div class="form-group"> |
@@ -102,6 +176,19 @@ | |||
102 | </ng-container> | 176 | </ng-container> |
103 | 177 | ||
104 | 178 | ||
179 | <div class="form-group" formGroupName="instance"> | ||
180 | <label i18n for="instanceDefaultClientRoute">Default client route</label> | ||
181 | <div class="peertube-select-container"> | ||
182 | <select id="instanceDefaultClientRoute" formControlName="defaultClientRoute"> | ||
183 | <option i18n value="/videos/overview">Videos Discover</option> | ||
184 | <option i18n value="/videos/trending">Videos Trending</option> | ||
185 | <option i18n value="/videos/recently-added">Videos Recently Added</option> | ||
186 | <option i18n value="/videos/local">Local videos</option> | ||
187 | </select> | ||
188 | </div> | ||
189 | <div *ngIf="formErrors.instance.defaultClientRoute" class="form-error">{{ formErrors.instance.defaultClientRoute }}</div> | ||
190 | </div> | ||
191 | |||
105 | <div i18n class="inner-form-title">Signup</div> | 192 | <div i18n class="inner-form-title">Signup</div> |
106 | 193 | ||
107 | <ng-container formGroupName="signup"> | 194 | <ng-container formGroupName="signup"> |
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss index c90bd5141..68f1b01b7 100644 --- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss +++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.scss | |||
@@ -1,6 +1,10 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | .form-group { | ||
5 | margin-bottom: 25px; | ||
6 | } | ||
7 | |||
4 | input[type=text] { | 8 | input[type=text] { |
5 | @include peertube-input-text(340px); | 9 | @include peertube-input-text(340px); |
6 | display: block; | 10 | display: block; |
@@ -44,3 +48,8 @@ textarea { | |||
44 | height: 100px; | 48 | height: 100px; |
45 | } | 49 | } |
46 | } | 50 | } |
51 | |||
52 | .label-small-info { | ||
53 | font-style: italic; | ||
54 | margin-bottom: 10px; | ||
55 | } | ||
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 d51104569..3119ab040 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 | |||
@@ -6,6 +6,9 @@ import { Notifier } from '@app/core' | |||
6 | import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' | 6 | import { CustomConfig } from '../../../../../../shared/models/server/custom-config.model' |
7 | import { I18n } from '@ngx-translate/i18n-polyfill' | 7 | import { I18n } from '@ngx-translate/i18n-polyfill' |
8 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' | 8 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' |
9 | import { SelectItem } from 'primeng/api' | ||
10 | import { forkJoin } from 'rxjs' | ||
11 | import { first } from 'rxjs/operators' | ||
9 | 12 | ||
10 | @Component({ | 13 | @Component({ |
11 | selector: 'my-edit-custom-config', | 14 | selector: 'my-edit-custom-config', |
@@ -18,6 +21,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
18 | resolutions: { id: string, label: string }[] = [] | 21 | resolutions: { id: string, label: string }[] = [] |
19 | transcodingThreadOptions: { label: string, value: number }[] = [] | 22 | transcodingThreadOptions: { label: string, value: number }[] = [] |
20 | 23 | ||
24 | languageItems: SelectItem[] = [] | ||
25 | categoryItems: SelectItem[] = [] | ||
26 | |||
21 | constructor ( | 27 | constructor ( |
22 | protected formValidatorService: FormValidatorService, | 28 | protected formValidatorService: FormValidatorService, |
23 | private customConfigValidatorsService: CustomConfigValidatorsService, | 29 | private customConfigValidatorsService: CustomConfigValidatorsService, |
@@ -88,10 +94,22 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
88 | name: this.customConfigValidatorsService.INSTANCE_NAME, | 94 | name: this.customConfigValidatorsService.INSTANCE_NAME, |
89 | shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION, | 95 | shortDescription: this.customConfigValidatorsService.INSTANCE_SHORT_DESCRIPTION, |
90 | description: null, | 96 | description: null, |
91 | terms: null, | 97 | |
92 | defaultClientRoute: null, | ||
93 | isNSFW: false, | 98 | isNSFW: false, |
94 | defaultNSFWPolicy: null, | 99 | defaultNSFWPolicy: null, |
100 | |||
101 | terms: null, | ||
102 | codeOfConduct: null, | ||
103 | moderationInformation: null, | ||
104 | administrator: null, | ||
105 | maintenanceLifetime: null, | ||
106 | businessModel: null, | ||
107 | |||
108 | categories: null, | ||
109 | languages: null, | ||
110 | |||
111 | defaultClientRoute: null, | ||
112 | |||
95 | customizations: { | 113 | customizations: { |
96 | javascript: null, | 114 | javascript: null, |
97 | css: null | 115 | css: null |
@@ -184,18 +202,27 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
184 | 202 | ||
185 | this.buildForm(formGroupData) | 203 | this.buildForm(formGroupData) |
186 | 204 | ||
187 | this.configService.getCustomConfig() | 205 | forkJoin([ |
188 | .subscribe( | 206 | this.configService.getCustomConfig(), |
189 | res => { | 207 | this.serverService.videoLanguagesLoaded.pipe(first()), // First so the observable completes |
190 | this.customConfig = res | 208 | this.serverService.videoCategoriesLoaded.pipe(first()) |
209 | ]).subscribe( | ||
210 | ([ config ]) => { | ||
211 | this.customConfig = config | ||
191 | 212 | ||
192 | this.updateForm() | 213 | const languages = this.serverService.getVideoLanguages() |
193 | // Force form validation | 214 | this.languageItems = languages.map(l => ({ label: l.label, value: l.id })) |
194 | this.forceCheck() | ||
195 | }, | ||
196 | 215 | ||
197 | err => this.notifier.error(err.message) | 216 | const categories = this.serverService.getVideoCategories() |
198 | ) | 217 | this.categoryItems = categories.map(l => ({ label: l.label, value: l.id })) |
218 | |||
219 | this.updateForm() | ||
220 | // Force form validation | ||
221 | this.forceCheck() | ||
222 | }, | ||
223 | |||
224 | err => this.notifier.error(err.message) | ||
225 | ) | ||
199 | } | 226 | } |
200 | 227 | ||
201 | isTranscodingEnabled () { | 228 | isTranscodingEnabled () { |
@@ -224,8 +251,23 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit { | |||
224 | ) | 251 | ) |
225 | } | 252 | } |
226 | 253 | ||
254 | getSelectedLanguageLabel () { | ||
255 | return this.i18n('{{\'{0} languages selected') | ||
256 | } | ||
257 | |||
258 | getDefaultLanguageLabel () { | ||
259 | return this.i18n('No language') | ||
260 | } | ||
261 | |||
262 | getSelectedCategoryLabel () { | ||
263 | return this.i18n('{{\'{0} categories selected') | ||
264 | } | ||
265 | |||
266 | getDefaultCategoryLabel () { | ||
267 | return this.i18n('No category') | ||
268 | } | ||
269 | |||
227 | private updateForm () { | 270 | private updateForm () { |
228 | this.form.patchValue(this.customConfig) | 271 | this.form.patchValue(this.customConfig) |
229 | } | 272 | } |
230 | |||
231 | } | 273 | } |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html index 2796dd2db..caa032149 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | <div> | 24 | <div> |
25 | <p-multiSelect | 25 | <p-multiSelect |
26 | [options]="languageItems" formControlName="videoLanguages" showToggleAll="true" | 26 | inputId="videoLanguages" [options]="languageItems" formControlName="videoLanguages" showToggleAll="true" |
27 | [defaultLabel]="getDefaultVideoLanguageLabel()" [selectedItemsLabel]="getSelectedVideoLanguageLabel()" | 27 | [defaultLabel]="getDefaultVideoLanguageLabel()" [selectedItemsLabel]="getSelectedVideoLanguageLabel()" |
28 | emptyFilterMessage="No results found" i18n-emptyFilterMessage | 28 | emptyFilterMessage="No results found" i18n-emptyFilterMessage |
29 | ></p-multiSelect> | 29 | ></p-multiSelect> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts index 77febf179..4fb828082 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts | |||
@@ -5,9 +5,9 @@ import { AuthService } from '../../../core' | |||
5 | import { FormReactive, User, UserService } from '../../../shared' | 5 | import { FormReactive, User, UserService } from '../../../shared' |
6 | import { I18n } from '@ngx-translate/i18n-polyfill' | 6 | import { I18n } from '@ngx-translate/i18n-polyfill' |
7 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' | 7 | import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' |
8 | import { Subject } from 'rxjs' | 8 | import { forkJoin, Subject } from 'rxjs' |
9 | import { SelectItem } from 'primeng/api' | 9 | import { SelectItem } from 'primeng/api' |
10 | import { switchMap } from 'rxjs/operators' | 10 | import { first } from 'rxjs/operators' |
11 | 11 | ||
12 | @Component({ | 12 | @Component({ |
13 | selector: 'my-account-video-settings', | 13 | selector: 'my-account-video-settings', |
@@ -39,30 +39,31 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI | |||
39 | videoLanguages: null | 39 | videoLanguages: null |
40 | }) | 40 | }) |
41 | 41 | ||
42 | this.serverService.videoLanguagesLoaded | 42 | forkJoin([ |
43 | .pipe(switchMap(() => this.userInformationLoaded)) | 43 | this.serverService.videoLanguagesLoaded.pipe(first()), |
44 | .subscribe(() => { | 44 | this.userInformationLoaded.pipe(first()) |
45 | const languages = this.serverService.getVideoLanguages() | 45 | ]).subscribe(() => { |
46 | 46 | const languages = this.serverService.getVideoLanguages() | |
47 | this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ] | 47 | |
48 | this.languageItems = this.languageItems | 48 | this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ] |
49 | .concat(languages.map(l => ({ label: l.label, value: l.id }))) | 49 | this.languageItems = this.languageItems |
50 | 50 | .concat(languages.map(l => ({ label: l.label, value: l.id }))) | |
51 | const videoLanguages = this.user.videoLanguages | 51 | |
52 | ? this.user.videoLanguages | 52 | const videoLanguages = this.user.videoLanguages |
53 | : this.languageItems.map(l => l.value) | 53 | ? this.user.videoLanguages |
54 | 54 | : this.languageItems.map(l => l.value) | |
55 | this.form.patchValue({ | 55 | |
56 | nsfwPolicy: this.user.nsfwPolicy, | 56 | this.form.patchValue({ |
57 | webTorrentEnabled: this.user.webTorrentEnabled, | 57 | nsfwPolicy: this.user.nsfwPolicy, |
58 | autoPlayVideo: this.user.autoPlayVideo === true, | 58 | webTorrentEnabled: this.user.webTorrentEnabled, |
59 | videoLanguages | 59 | autoPlayVideo: this.user.autoPlayVideo === true, |
60 | }) | 60 | videoLanguages |
61 | }) | 61 | }) |
62 | }) | ||
62 | } | 63 | } |
63 | 64 | ||
64 | updateDetails () { | 65 | updateDetails () { |
65 | const nsfwPolicy = this.form.value['nsfwPolicy'] | 66 | const nsfwPolicy = this.form.value[ 'nsfwPolicy' ] |
66 | const webTorrentEnabled = this.form.value['webTorrentEnabled'] | 67 | const webTorrentEnabled = this.form.value['webTorrentEnabled'] |
67 | const autoPlayVideo = this.form.value['autoPlayVideo'] | 68 | const autoPlayVideo = this.form.value['autoPlayVideo'] |
68 | 69 | ||
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts index 571f46de9..6cf1499d3 100644 --- a/client/src/app/+my-account/my-account.module.ts +++ b/client/src/app/+my-account/my-account.module.ts | |||
@@ -37,7 +37,6 @@ import { | |||
37 | } from '@app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component' | 37 | } from '@app/+my-account/my-account-video-playlists/my-account-video-playlist-elements.component' |
38 | import { DragDropModule } from '@angular/cdk/drag-drop' | 38 | import { DragDropModule } from '@angular/cdk/drag-drop' |
39 | import { MyAccountChangeEmailComponent } from '@app/+my-account/my-account-settings/my-account-change-email' | 39 | import { MyAccountChangeEmailComponent } from '@app/+my-account/my-account-settings/my-account-change-email' |
40 | import { MultiSelectModule } from 'primeng/multiselect' | ||
41 | import { MyAccountInterfaceSettingsComponent } from '@app/+my-account/my-account-settings/my-account-interface' | 40 | import { MyAccountInterfaceSettingsComponent } from '@app/+my-account/my-account-settings/my-account-interface' |
42 | 41 | ||
43 | @NgModule({ | 42 | @NgModule({ |
@@ -48,8 +47,7 @@ import { MyAccountInterfaceSettingsComponent } from '@app/+my-account/my-account | |||
48 | SharedModule, | 47 | SharedModule, |
49 | TableModule, | 48 | TableModule, |
50 | InputSwitchModule, | 49 | InputSwitchModule, |
51 | DragDropModule, | 50 | DragDropModule |
52 | MultiSelectModule | ||
53 | ], | 51 | ], |
54 | 52 | ||
55 | declarations: [ | 53 | declarations: [ |
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index eb57a2fff..d71f6357b 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -6,10 +6,8 @@ import { RouterModule } from '@angular/router' | |||
6 | import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' | 6 | import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component' |
7 | import { HelpComponent } from '@app/shared/misc/help.component' | 7 | import { HelpComponent } from '@app/shared/misc/help.component' |
8 | import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' | 8 | import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' |
9 | |||
10 | import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' | 9 | import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes' |
11 | import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' | 10 | import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared' |
12 | |||
13 | import { AUTH_INTERCEPTOR_PROVIDER } from './auth' | 11 | import { AUTH_INTERCEPTOR_PROVIDER } from './auth' |
14 | import { ButtonComponent } from './buttons/button.component' | 12 | import { ButtonComponent } from './buttons/button.component' |
15 | import { DeleteButtonComponent } from './buttons/delete-button.component' | 13 | import { DeleteButtonComponent } from './buttons/delete-button.component' |
@@ -93,6 +91,7 @@ import { VideoDownloadComponent } from '@app/shared/video/modals/video-download. | |||
93 | import { VideoReportComponent } from '@app/shared/video/modals/video-report.component' | 91 | import { VideoReportComponent } from '@app/shared/video/modals/video-report.component' |
94 | import { ClipboardModule } from 'ngx-clipboard' | 92 | import { ClipboardModule } from 'ngx-clipboard' |
95 | import { FollowService } from '@app/shared/instance/follow.service' | 93 | import { FollowService } from '@app/shared/instance/follow.service' |
94 | import { MultiSelectModule } from 'primeng/multiselect' | ||
96 | 95 | ||
97 | @NgModule({ | 96 | @NgModule({ |
98 | imports: [ | 97 | imports: [ |
@@ -113,7 +112,8 @@ import { FollowService } from '@app/shared/instance/follow.service' | |||
113 | 112 | ||
114 | PrimeSharedModule, | 113 | PrimeSharedModule, |
115 | InputMaskModule, | 114 | InputMaskModule, |
116 | NgPipesModule | 115 | NgPipesModule, |
116 | MultiSelectModule | ||
117 | ], | 117 | ], |
118 | 118 | ||
119 | declarations: [ | 119 | declarations: [ |
@@ -186,6 +186,7 @@ import { FollowService } from '@app/shared/instance/follow.service' | |||
186 | InputMaskModule, | 186 | InputMaskModule, |
187 | BytesPipe, | 187 | BytesPipe, |
188 | KeysPipe, | 188 | KeysPipe, |
189 | MultiSelectModule, | ||
189 | 190 | ||
190 | LoaderComponent, | 191 | LoaderComponent, |
191 | SmallLoaderComponent, | 192 | SmallLoaderComponent, |
diff --git a/config/default.yaml b/config/default.yaml index 5a935fede..f84ecfcf9 100644 --- a/config/default.yaml +++ b/config/default.yaml | |||
@@ -238,7 +238,53 @@ instance: | |||
238 | short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.' | 238 | short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.' |
239 | description: 'Welcome to this PeerTube instance!' # Support markdown | 239 | description: 'Welcome to this PeerTube instance!' # Support markdown |
240 | terms: 'No terms for now.' # Support markdown | 240 | terms: 'No terms for now.' # Support markdown |
241 | code_of_conduct: '' # Supports markdown | ||
242 | |||
243 | # Who moderates the instance? What is the policy regarding NSFW videos? Political videos? etc | ||
244 | moderation_information: '' # Supports markdown | ||
245 | |||
246 | # Who is behind the instance? A single person? A non profit? | ||
247 | administrator: '' | ||
248 | |||
249 | # How long do you plan to maintain this instance? | ||
250 | maintenance_lifetime: '' | ||
251 | |||
252 | # How will you pay the PeerTube instance server? With you own funds? With users donations? Advertising? | ||
253 | business_model: '' | ||
254 | |||
255 | # What are the main languages of your instance? To interact with your users for example | ||
256 | # Uncomment or add the languages you want | ||
257 | # List of supported languages: https://peertube.cpy.re/api/v1/videos/languages | ||
258 | languages: | ||
259 | # - en | ||
260 | # - es | ||
261 | # - fr | ||
262 | |||
263 | # You can specify the main categories of your instance (dedicated to music, gaming or politics etc) | ||
264 | # Uncomment or add the category ids you want | ||
265 | # List of supported categories: https://peertube.cpy.re/api/v1/videos/categories | ||
266 | categories: | ||
267 | # - 1 # Music | ||
268 | # - 2 # Films | ||
269 | # - 3 # Vehicles | ||
270 | # - 4 # Art | ||
271 | # - 5 # Sports | ||
272 | # - 6 # Travels | ||
273 | # - 7 # Gaming | ||
274 | # - 8 # People | ||
275 | # - 9 # Comedy | ||
276 | # - 10 # Entertainment | ||
277 | # - 11 # News & Politics | ||
278 | # - 12 # How To | ||
279 | # - 13 # Education | ||
280 | # - 14 # Activism | ||
281 | # - 15 # Science & Technology | ||
282 | # - 16 # Animals | ||
283 | # - 17 # Kids | ||
284 | # - 18 # Food | ||
285 | |||
241 | default_client_route: '/videos/trending' | 286 | default_client_route: '/videos/trending' |
287 | |||
242 | # Whether or not the instance is dedicated to NSFW content | 288 | # Whether or not the instance is dedicated to NSFW content |
243 | # Enabling it will allow other administrators to know that you are mainly federating sensitive content | 289 | # Enabling it will allow other administrators to know that you are mainly federating sensitive content |
244 | # Moreover, the NSFW checkbox on video upload will be automatically checked by default | 290 | # Moreover, the NSFW checkbox on video upload will be automatically checked by default |
@@ -246,6 +292,7 @@ instance: | |||
246 | # By default, "do_not_list" or "blur" or "display" NSFW videos | 292 | # By default, "do_not_list" or "blur" or "display" NSFW videos |
247 | # Could be overridden per user with a setting | 293 | # Could be overridden per user with a setting |
248 | default_nsfw_policy: 'do_not_list' | 294 | default_nsfw_policy: 'do_not_list' |
295 | |||
249 | customizations: | 296 | customizations: |
250 | javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime | 297 | javascript: '' # Directly your JavaScript code (without <script> tags). Will be eval at runtime |
251 | css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime | 298 | css: '' # Directly your CSS code (without <style> tags). Will be injected at runtime |
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 0c52bfa7a..b5244756d 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -158,7 +158,16 @@ function getAbout (req: express.Request, res: express.Response) { | |||
158 | name: CONFIG.INSTANCE.NAME, | 158 | name: CONFIG.INSTANCE.NAME, |
159 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, | 159 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, |
160 | description: CONFIG.INSTANCE.DESCRIPTION, | 160 | description: CONFIG.INSTANCE.DESCRIPTION, |
161 | terms: CONFIG.INSTANCE.TERMS | 161 | terms: CONFIG.INSTANCE.TERMS, |
162 | codeOfConduct: CONFIG.INSTANCE.CODE_OF_CONDUCT, | ||
163 | |||
164 | moderationInformation: CONFIG.INSTANCE.MODERATION_INFORMATION, | ||
165 | administrator: CONFIG.INSTANCE.ADMINISTRATOR, | ||
166 | maintenanceLifetime: CONFIG.INSTANCE.MAINTENANCE_LIFETIME, | ||
167 | businessModel: CONFIG.INSTANCE.BUSINESS_MODEL, | ||
168 | |||
169 | languages: CONFIG.INSTANCE.LANGUAGES, | ||
170 | categories: CONFIG.INSTANCE.CATEGORIES | ||
162 | } | 171 | } |
163 | } | 172 | } |
164 | 173 | ||
@@ -221,6 +230,16 @@ function customConfig (): CustomConfig { | |||
221 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, | 230 | shortDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, |
222 | description: CONFIG.INSTANCE.DESCRIPTION, | 231 | description: CONFIG.INSTANCE.DESCRIPTION, |
223 | terms: CONFIG.INSTANCE.TERMS, | 232 | terms: CONFIG.INSTANCE.TERMS, |
233 | codeOfConduct: CONFIG.INSTANCE.CODE_OF_CONDUCT, | ||
234 | |||
235 | moderationInformation: CONFIG.INSTANCE.MODERATION_INFORMATION, | ||
236 | administrator: CONFIG.INSTANCE.ADMINISTRATOR, | ||
237 | maintenanceLifetime: CONFIG.INSTANCE.MAINTENANCE_LIFETIME, | ||
238 | businessModel: CONFIG.INSTANCE.BUSINESS_MODEL, | ||
239 | |||
240 | languages: CONFIG.INSTANCE.LANGUAGES, | ||
241 | categories: CONFIG.INSTANCE.CATEGORIES, | ||
242 | |||
224 | isNSFW: CONFIG.INSTANCE.IS_NSFW, | 243 | isNSFW: CONFIG.INSTANCE.IS_NSFW, |
225 | defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE, | 244 | defaultClientRoute: CONFIG.INSTANCE.DEFAULT_CLIENT_ROUTE, |
226 | defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, | 245 | defaultNSFWPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, |
diff --git a/server/initializers/config.ts b/server/initializers/config.ts index 599f3f5ac..4e2b07e64 100644 --- a/server/initializers/config.ts +++ b/server/initializers/config.ts | |||
@@ -209,6 +209,16 @@ const CONFIG = { | |||
209 | get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') }, | 209 | get SHORT_DESCRIPTION () { return config.get<string>('instance.short_description') }, |
210 | get DESCRIPTION () { return config.get<string>('instance.description') }, | 210 | get DESCRIPTION () { return config.get<string>('instance.description') }, |
211 | get TERMS () { return config.get<string>('instance.terms') }, | 211 | get TERMS () { return config.get<string>('instance.terms') }, |
212 | get CODE_OF_CONDUCT () { return config.get<string>('instance.code_of_conduct') }, | ||
213 | |||
214 | get MODERATION_INFORMATION () { return config.get<string>('instance.moderation_information') }, | ||
215 | get ADMINISTRATOR () { return config.get<string>('instance.administrator') }, | ||
216 | get MAINTENANCE_LIFETIME () { return config.get<string>('instance.maintenance_lifetime') }, | ||
217 | get BUSINESS_MODEL () { return config.get<string>('instance.business_model') }, | ||
218 | |||
219 | get LANGUAGES () { return config.get<string[]>('instance.languages') || [] }, | ||
220 | get CATEGORIES () { return config.get<number[]>('instance.categories') || [] }, | ||
221 | |||
212 | get IS_NSFW () { return config.get<boolean>('instance.is_nsfw') }, | 222 | get IS_NSFW () { return config.get<boolean>('instance.is_nsfw') }, |
213 | get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') }, | 223 | get DEFAULT_CLIENT_ROUTE () { return config.get<string>('instance.default_client_route') }, |
214 | get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') }, | 224 | get DEFAULT_NSFW_POLICY () { return config.get<NSFWPolicyType>('instance.default_nsfw_policy') }, |
diff --git a/server/tests/api/check-params/config.ts b/server/tests/api/check-params/config.ts index 1221735c5..f716dc673 100644 --- a/server/tests/api/check-params/config.ts +++ b/server/tests/api/check-params/config.ts | |||
@@ -27,6 +27,16 @@ describe('Test config API validators', function () { | |||
27 | shortDescription: 'my short description', | 27 | shortDescription: 'my short description', |
28 | description: 'my super description', | 28 | description: 'my super description', |
29 | terms: 'my super terms', | 29 | terms: 'my super terms', |
30 | codeOfConduct: 'my super coc', | ||
31 | |||
32 | moderationInformation: 'my super moderation information', | ||
33 | administrator: 'Kuja', | ||
34 | maintenanceLifetime: 'forever', | ||
35 | businessModel: 'my super business model', | ||
36 | |||
37 | languages: [ 'en', 'es' ], | ||
38 | categories: [ 1, 2 ], | ||
39 | |||
30 | isNSFW: true, | 40 | isNSFW: true, |
31 | defaultClientRoute: '/videos/recently-added', | 41 | defaultClientRoute: '/videos/recently-added', |
32 | defaultNSFWPolicy: 'blur', | 42 | defaultNSFWPolicy: 'blur', |
diff --git a/server/tests/api/server/config.ts b/server/tests/api/server/config.ts index b2f1933d1..da75495a5 100644 --- a/server/tests/api/server/config.ts +++ b/server/tests/api/server/config.ts | |||
@@ -28,7 +28,17 @@ function checkInitialConfig (server: ServerInfo, data: CustomConfig) { | |||
28 | 'with WebTorrent and Angular.' | 28 | 'with WebTorrent and Angular.' |
29 | ) | 29 | ) |
30 | expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') | 30 | expect(data.instance.description).to.equal('Welcome to this PeerTube instance!') |
31 | |||
31 | expect(data.instance.terms).to.equal('No terms for now.') | 32 | expect(data.instance.terms).to.equal('No terms for now.') |
33 | expect(data.instance.codeOfConduct).to.be.empty | ||
34 | expect(data.instance.moderationInformation).to.be.empty | ||
35 | expect(data.instance.administrator).to.be.empty | ||
36 | expect(data.instance.maintenanceLifetime).to.be.empty | ||
37 | expect(data.instance.businessModel).to.be.empty | ||
38 | |||
39 | expect(data.instance.languages).to.have.lengthOf(0) | ||
40 | expect(data.instance.categories).to.have.lengthOf(0) | ||
41 | |||
32 | expect(data.instance.defaultClientRoute).to.equal('/videos/trending') | 42 | expect(data.instance.defaultClientRoute).to.equal('/videos/trending') |
33 | expect(data.instance.isNSFW).to.be.false | 43 | expect(data.instance.isNSFW).to.be.false |
34 | expect(data.instance.defaultNSFWPolicy).to.equal('display') | 44 | expect(data.instance.defaultNSFWPolicy).to.equal('display') |
@@ -78,7 +88,17 @@ function checkUpdatedConfig (data: CustomConfig) { | |||
78 | expect(data.instance.name).to.equal('PeerTube updated') | 88 | expect(data.instance.name).to.equal('PeerTube updated') |
79 | expect(data.instance.shortDescription).to.equal('my short description') | 89 | expect(data.instance.shortDescription).to.equal('my short description') |
80 | expect(data.instance.description).to.equal('my super description') | 90 | expect(data.instance.description).to.equal('my super description') |
91 | |||
81 | expect(data.instance.terms).to.equal('my super terms') | 92 | expect(data.instance.terms).to.equal('my super terms') |
93 | expect(data.instance.codeOfConduct).to.equal('my super coc') | ||
94 | expect(data.instance.moderationInformation).to.equal('my super moderation information') | ||
95 | expect(data.instance.administrator).to.equal('Kuja') | ||
96 | expect(data.instance.maintenanceLifetime).to.equal('forever') | ||
97 | expect(data.instance.businessModel).to.equal('my super business model') | ||
98 | |||
99 | expect(data.instance.languages).to.deep.equal([ 'en', 'es' ]) | ||
100 | expect(data.instance.categories).to.deep.equal([ 1, 2 ]) | ||
101 | |||
82 | expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added') | 102 | expect(data.instance.defaultClientRoute).to.equal('/videos/recently-added') |
83 | expect(data.instance.isNSFW).to.be.true | 103 | expect(data.instance.isNSFW).to.be.true |
84 | expect(data.instance.defaultNSFWPolicy).to.equal('blur') | 104 | expect(data.instance.defaultNSFWPolicy).to.equal('blur') |
@@ -190,6 +210,16 @@ describe('Test config', function () { | |||
190 | shortDescription: 'my short description', | 210 | shortDescription: 'my short description', |
191 | description: 'my super description', | 211 | description: 'my super description', |
192 | terms: 'my super terms', | 212 | terms: 'my super terms', |
213 | codeOfConduct: 'my super coc', | ||
214 | |||
215 | moderationInformation: 'my super moderation information', | ||
216 | administrator: 'Kuja', | ||
217 | maintenanceLifetime: 'forever', | ||
218 | businessModel: 'my super business model', | ||
219 | |||
220 | languages: [ 'en', 'es' ], | ||
221 | categories: [ 1, 2 ], | ||
222 | |||
193 | defaultClientRoute: '/videos/recently-added', | 223 | defaultClientRoute: '/videos/recently-added', |
194 | isNSFW: true, | 224 | isNSFW: true, |
195 | defaultNSFWPolicy: 'blur' as 'blur', | 225 | defaultNSFWPolicy: 'blur' as 'blur', |
diff --git a/shared/extra-utils/server/config.ts b/shared/extra-utils/server/config.ts index d784af9a9..785421c98 100644 --- a/shared/extra-utils/server/config.ts +++ b/shared/extra-utils/server/config.ts | |||
@@ -53,6 +53,16 @@ function updateCustomSubConfig (url: string, token: string, newConfig: DeepParti | |||
53 | shortDescription: 'my short description', | 53 | shortDescription: 'my short description', |
54 | description: 'my super description', | 54 | description: 'my super description', |
55 | terms: 'my super terms', | 55 | terms: 'my super terms', |
56 | codeOfConduct: 'my super coc', | ||
57 | |||
58 | moderationInformation: 'my super moderation information', | ||
59 | administrator: 'Kuja', | ||
60 | maintenanceLifetime: 'forever', | ||
61 | businessModel: 'my super business model', | ||
62 | |||
63 | languages: [ 'en', 'es' ], | ||
64 | categories: [ 1, 2 ], | ||
65 | |||
56 | defaultClientRoute: '/videos/recently-added', | 66 | defaultClientRoute: '/videos/recently-added', |
57 | isNSFW: true, | 67 | isNSFW: true, |
58 | defaultNSFWPolicy: 'blur', | 68 | defaultNSFWPolicy: 'blur', |
diff --git a/shared/models/server/about.model.ts b/shared/models/server/about.model.ts index 10dff8b8f..e32ed26ee 100644 --- a/shared/models/server/about.model.ts +++ b/shared/models/server/about.model.ts | |||
@@ -4,5 +4,15 @@ export interface About { | |||
4 | shortDescription: string | 4 | shortDescription: string |
5 | description: string | 5 | description: string |
6 | terms: string | 6 | terms: string |
7 | |||
8 | codeOfConduct: string | ||
9 | |||
10 | moderationInformation: string | ||
11 | administrator: string | ||
12 | maintenanceLifetime: string | ||
13 | businessModel: string | ||
14 | |||
15 | languages: string[] | ||
16 | categories: number[] | ||
7 | } | 17 | } |
8 | } | 18 | } |
diff --git a/shared/models/server/custom-config.model.ts b/shared/models/server/custom-config.model.ts index 1073ba32c..0c331a820 100644 --- a/shared/models/server/custom-config.model.ts +++ b/shared/models/server/custom-config.model.ts | |||
@@ -6,6 +6,16 @@ export interface CustomConfig { | |||
6 | shortDescription: string | 6 | shortDescription: string |
7 | description: string | 7 | description: string |
8 | terms: string | 8 | terms: string |
9 | codeOfConduct: string | ||
10 | |||
11 | moderationInformation: string | ||
12 | administrator: string | ||
13 | maintenanceLifetime: string | ||
14 | businessModel: string | ||
15 | |||
16 | languages: string[] | ||
17 | categories: number[] | ||
18 | |||
9 | isNSFW: boolean | 19 | isNSFW: boolean |
10 | defaultClientRoute: string | 20 | defaultClientRoute: string |
11 | defaultNSFWPolicy: NSFWPolicyType | 21 | defaultNSFWPolicy: NSFWPolicyType |