aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-08-11 16:07:53 +0200
committerChocobozzz <me@florianbigard.com>2020-08-11 16:18:42 +0200
commit52c4976fcf4ee255a3af68ff9778e4f5c4f84bd4 (patch)
tree887d2b6106548ad23cf016d82baf1977198027d9 /client/src/app/shared
parent3d25d5de33d8aa0ba00d7514522b25d22bf0e0a1 (diff)
downloadPeerTube-52c4976fcf4ee255a3af68ff9778e4f5c4f84bd4.tar.gz
PeerTube-52c4976fcf4ee255a3af68ff9778e4f5c4f84bd4.tar.zst
PeerTube-52c4976fcf4ee255a3af68ff9778e4f5c4f84bd4.zip
Use ng select for multiselect
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/shared-forms/index.ts1
-rw-r--r--client/src/app/shared/shared-forms/select-shared.component.scss20
-rw-r--r--client/src/app/shared/shared-forms/select/index.ts4
-rw-r--r--client/src/app/shared/shared-forms/select/select-channel.component.html (renamed from client/src/app/shared/shared-forms/select-channel.component.html)0
-rw-r--r--client/src/app/shared/shared-forms/select/select-channel.component.ts (renamed from client/src/app/shared/shared-forms/select-channel.component.ts)2
-rw-r--r--client/src/app/shared/shared-forms/select/select-checkbox.component.html41
-rw-r--r--client/src/app/shared/shared-forms/select/select-checkbox.component.scss18
-rw-r--r--client/src/app/shared/shared-forms/select/select-checkbox.component.ts75
-rw-r--r--client/src/app/shared/shared-forms/select/select-options.component.html (renamed from client/src/app/shared/shared-forms/select-options.component.html)5
-rw-r--r--client/src/app/shared/shared-forms/select/select-options.component.ts (renamed from client/src/app/shared/shared-forms/select-options.component.ts)12
-rw-r--r--client/src/app/shared/shared-forms/select/select-shared.component.scss32
-rw-r--r--client/src/app/shared/shared-forms/select/select-tags.component.html (renamed from client/src/app/shared/shared-forms/select-tags.component.html)0
-rw-r--r--client/src/app/shared/shared-forms/select/select-tags.component.scss (renamed from client/src/app/shared/shared-forms/select-tags.component.scss)0
-rw-r--r--client/src/app/shared/shared-forms/select/select-tags.component.ts (renamed from client/src/app/shared/shared-forms/select-tags.component.ts)2
-rw-r--r--client/src/app/shared/shared-forms/shared-form.module.ts15
-rw-r--r--client/src/app/shared/shared-user-settings/user-video-settings.component.html10
-rw-r--r--client/src/app/shared/shared-user-settings/user-video-settings.component.scss4
-rw-r--r--client/src/app/shared/shared-user-settings/user-video-settings.component.ts45
18 files changed, 228 insertions, 58 deletions
diff --git a/client/src/app/shared/shared-forms/index.ts b/client/src/app/shared/shared-forms/index.ts
index aa0ee015a..747df65cf 100644
--- a/client/src/app/shared/shared-forms/index.ts
+++ b/client/src/app/shared/shared-forms/index.ts
@@ -1,5 +1,6 @@
1export * from './form-validators' 1export * from './form-validators'
2export * from './form-reactive' 2export * from './form-reactive'
3export * from './select'
3export * from './input-readonly-copy.component' 4export * from './input-readonly-copy.component'
4export * from './markdown-textarea.component' 5export * from './markdown-textarea.component'
5export * from './peertube-checkbox.component' 6export * from './peertube-checkbox.component'
diff --git a/client/src/app/shared/shared-forms/select-shared.component.scss b/client/src/app/shared/shared-forms/select-shared.component.scss
deleted file mode 100644
index 4f231d28a..000000000
--- a/client/src/app/shared/shared-forms/select-shared.component.scss
+++ /dev/null
@@ -1,20 +0,0 @@
1$width-size: auto;
2
3ng-select {
4 width: $width-size;
5 @media screen and (max-width: $width-size) {
6 width: 100%;
7 }
8}
9
10// make sure the image is vertically adjusted
11ng-select ::ng-deep .ng-value-label img {
12 position: relative;
13 top: -1px;
14}
15
16ng-select ::ng-deep img {
17 border-radius: 50%;
18 height: 20px;
19 width: 20px;
20}
diff --git a/client/src/app/shared/shared-forms/select/index.ts b/client/src/app/shared/shared-forms/select/index.ts
new file mode 100644
index 000000000..33459b23b
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/index.ts
@@ -0,0 +1,4 @@
1export * from './select-channel.component'
2export * from './select-options.component'
3export * from './select-tags.component'
4export * from './select-checkbox.component'
diff --git a/client/src/app/shared/shared-forms/select-channel.component.html b/client/src/app/shared/shared-forms/select/select-channel.component.html
index 897d13ee7..897d13ee7 100644
--- a/client/src/app/shared/shared-forms/select-channel.component.html
+++ b/client/src/app/shared/shared-forms/select/select-channel.component.html
diff --git a/client/src/app/shared/shared-forms/select-channel.component.ts b/client/src/app/shared/shared-forms/select/select-channel.component.ts
index ef4192095..1b0db9b6f 100644
--- a/client/src/app/shared/shared-forms/select-channel.component.ts
+++ b/client/src/app/shared/shared-forms/select/select-channel.component.ts
@@ -1,6 +1,6 @@
1import { Component, forwardRef, Input } from '@angular/core' 1import { Component, forwardRef, Input } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' 2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import { Actor } from '../shared-main' 3import { Actor } from '@app/shared/shared-main/account/actor.model'
4 4
5export type SelectChannelItem = { 5export type SelectChannelItem = {
6 id: number 6 id: number
diff --git a/client/src/app/shared/shared-forms/select/select-checkbox.component.html b/client/src/app/shared/shared-forms/select/select-checkbox.component.html
new file mode 100644
index 000000000..3f81dd152
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-checkbox.component.html
@@ -0,0 +1,41 @@
1<ng-select
2 [items]="availableItems"
3 [(ngModel)]="selectedItems"
4 (ngModelChange)="onModelChange()"
5 i18n-placeholder placeholder="Add a new language"
6 [clearable]="true"
7 [multiple]="true"
8 [searchable]="true"
9 [closeOnSelect]="false"
10
11 bindValue="id"
12 bindLabel="label"
13
14 notFoundText="No items found" i18n-notFoundText
15
16 [selectableGroup]="selectableGroup"
17 [selectableGroupAsModel]="selectableGroupAsModel"
18
19 groupBy="group"
20 [compareWith]="compareFn"
21
22 [maxSelectedItems]="maxSelectedItems"
23>
24
25 <ng-template ng-optgroup-tmp let-item="item" let-item$="item$" let-index="index">
26 <div class="form-group-checkbox">
27 <input id="item-{{index}}" type="checkbox" [ngModel]="item$.selected"/>
28 <span role="checkbox" [attr.aria-checked]="item$.selected"></span>
29 <span>{{ item.group }}</span>
30 </div>
31 </ng-template>
32
33 <ng-template ng-option-tmp let-item="item" let-item$="item$" let-index="index">
34 <div class="form-group-checkbox">
35 <input id="item-{{index}}" type="checkbox" [ngModel]="item$.selected"/>
36 <span role="checkbox" [attr.aria-checked]="item$.selected"></span>
37 <span>{{ item.label }}</span>
38 </div>
39 </ng-template>
40
41</ng-select>
diff --git a/client/src/app/shared/shared-forms/select/select-checkbox.component.scss b/client/src/app/shared/shared-forms/select/select-checkbox.component.scss
new file mode 100644
index 000000000..145f6b26c
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-checkbox.component.scss
@@ -0,0 +1,18 @@
1@import '_variables';
2@import '_mixins';
3
4ng-select ::ng-deep {
5 .ng-option {
6 display: flex;
7 align-items: center;
8 }
9
10 .form-group-checkbox {
11 display: flex;
12 align-items: center;
13
14 input {
15 @include peertube-checkbox(1px);
16 }
17 }
18}
diff --git a/client/src/app/shared/shared-forms/select/select-checkbox.component.ts b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts
new file mode 100644
index 000000000..93653fef1
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-checkbox.component.ts
@@ -0,0 +1,75 @@
1import { Component, Input, forwardRef } from '@angular/core'
2import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'
3import { SelectOptionsItem } from './select-options.component'
4
5export type ItemSelectCheckboxValue = { id?: string | number, group?: string } | string
6
7@Component({
8 selector: 'my-select-checkbox',
9 styleUrls: [ './select-shared.component.scss', 'select-checkbox.component.scss' ],
10 templateUrl: './select-checkbox.component.html',
11 providers: [
12 {
13 provide: NG_VALUE_ACCESSOR,
14 useExisting: forwardRef(() => SelectCheckboxComponent),
15 multi: true
16 }
17 ]
18})
19export class SelectCheckboxComponent implements ControlValueAccessor {
20 @Input() availableItems: SelectOptionsItem[] = []
21 @Input() selectedItems: ItemSelectCheckboxValue[] = []
22 @Input() selectableGroup: boolean
23 @Input() selectableGroupAsModel: boolean
24 @Input() maxSelectedItems: number
25
26 propagateChange = (_: any) => { /* empty */ }
27
28 writeValue (items: ItemSelectCheckboxValue[]) {
29 if (Array.isArray(items)) {
30 this.selectedItems = items.map(i => {
31 if (typeof i === 'string' || typeof i === 'number') {
32 return i + ''
33 }
34
35 if (i.group) {
36 return { group: i.group }
37 }
38
39 return { id: i.id + '' }
40 })
41 } else {
42 this.selectedItems = items
43 }
44
45 this.propagateChange(this.selectedItems)
46 }
47
48 registerOnChange (fn: (_: any) => void) {
49 this.propagateChange = fn
50 }
51
52 registerOnTouched () {
53 // Unused
54 }
55
56 onModelChange () {
57 this.propagateChange(this.selectedItems)
58 }
59
60 compareFn (item: SelectOptionsItem, selected: ItemSelectCheckboxValue) {
61 if (typeof selected === 'string') {
62 return item.id === selected
63 }
64
65 if (this.selectableGroup && item.group && selected.group) {
66 return item.group === selected.group
67 }
68
69 if (selected.id && item.id) {
70 return item.id === selected.id
71 }
72
73 return false
74 }
75}
diff --git a/client/src/app/shared/shared-forms/select-options.component.html b/client/src/app/shared/shared-forms/select/select-options.component.html
index fda0c2c56..48eca1cf5 100644
--- a/client/src/app/shared/shared-forms/select-options.component.html
+++ b/client/src/app/shared/shared-forms/select/select-options.component.html
@@ -3,10 +3,11 @@
3 [groupBy]="groupBy" 3 [groupBy]="groupBy"
4 [(ngModel)]="selectedId" 4 [(ngModel)]="selectedId"
5 (ngModelChange)="onModelChange()" 5 (ngModelChange)="onModelChange()"
6 [bindLabel]="bindLabel"
7 [bindValue]="bindValue"
8 [clearable]="clearable" 6 [clearable]="clearable"
9 [searchable]="searchable" 7 [searchable]="searchable"
8
9 bindLabel="label"
10 bindValue="id"
10> 11>
11 <ng-template ng-option-tmp let-item="item" let-index="index"> 12 <ng-template ng-option-tmp let-item="item" let-index="index">
12 {{ item.label }} 13 {{ item.label }}
diff --git a/client/src/app/shared/shared-forms/select-options.component.ts b/client/src/app/shared/shared-forms/select/select-options.component.ts
index 09f7df53b..3ba24c732 100644
--- a/client/src/app/shared/shared-forms/select-options.component.ts
+++ b/client/src/app/shared/shared-forms/select/select-options.component.ts
@@ -1,7 +1,13 @@
1import { Component, Input, forwardRef } from '@angular/core' 1import { Component, Input, forwardRef } from '@angular/core'
2import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' 2import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'
3 3
4export type SelectOptionsItem = { id: number | string, label: string, description?: string } 4export type SelectOptionsItem = {
5 id: string | number
6 label: string
7 description?: string
8 group?: string
9 groupLabel?: string
10}
5 11
6@Component({ 12@Component({
7 selector: 'my-select-options', 13 selector: 'my-select-options',
@@ -19,14 +25,10 @@ export class SelectOptionsComponent implements ControlValueAccessor {
19 @Input() items: SelectOptionsItem[] = [] 25 @Input() items: SelectOptionsItem[] = []
20 @Input() clearable = false 26 @Input() clearable = false
21 @Input() searchable = false 27 @Input() searchable = false
22 @Input() bindValue = 'id'
23 @Input() groupBy: string 28 @Input() groupBy: string
24 29
25 selectedId: number | string 30 selectedId: number | string
26 31
27 // ng-select options
28 bindLabel = 'label'
29
30 propagateChange = (_: any) => { /* empty */ } 32 propagateChange = (_: any) => { /* empty */ }
31 33
32 writeValue (id: number | string) { 34 writeValue (id: number | string) {
diff --git a/client/src/app/shared/shared-forms/select/select-shared.component.scss b/client/src/app/shared/shared-forms/select/select-shared.component.scss
new file mode 100644
index 000000000..0b4c6b784
--- /dev/null
+++ b/client/src/app/shared/shared-forms/select/select-shared.component.scss
@@ -0,0 +1,32 @@
1@import '_variables';
2@import '_mixins';
3
4$form-base-input-width: auto;
5
6ng-select {
7 width: $form-base-input-width;
8
9 @media screen and (max-width: $form-base-input-width) {
10 width: 100%;
11 }
12}
13
14ng-select ::ng-deep {
15 .ng-value-container {
16 max-height: 100px;
17 overflow-y: auto;
18 overflow-x: hidden;
19 }
20
21 // make sure the image is vertically adjusted
22 .ng-value-label img {
23 position: relative;
24 top: -1px;
25 }
26
27 img {
28 border-radius: 50%;
29 height: 20px;
30 width: 20px;
31 }
32}
diff --git a/client/src/app/shared/shared-forms/select-tags.component.html b/client/src/app/shared/shared-forms/select/select-tags.component.html
index e1cd50882..e1cd50882 100644
--- a/client/src/app/shared/shared-forms/select-tags.component.html
+++ b/client/src/app/shared/shared-forms/select/select-tags.component.html
diff --git a/client/src/app/shared/shared-forms/select-tags.component.scss b/client/src/app/shared/shared-forms/select/select-tags.component.scss
index ad76bc7ee..ad76bc7ee 100644
--- a/client/src/app/shared/shared-forms/select-tags.component.scss
+++ b/client/src/app/shared/shared-forms/select/select-tags.component.scss
diff --git a/client/src/app/shared/shared-forms/select-tags.component.ts b/client/src/app/shared/shared-forms/select/select-tags.component.ts
index a8a19d788..93d199037 100644
--- a/client/src/app/shared/shared-forms/select-tags.component.ts
+++ b/client/src/app/shared/shared-forms/select/select-tags.component.ts
@@ -33,8 +33,6 @@ export class SelectTagsComponent implements ControlValueAccessor {
33 } 33 }
34 34
35 onModelChange () { 35 onModelChange () {
36 console.log(this.selectedItems)
37
38 this.propagateChange(this.selectedItems) 36 this.propagateChange(this.selectedItems)
39 } 37 }
40} 38}
diff --git a/client/src/app/shared/shared-forms/shared-form.module.ts b/client/src/app/shared/shared-forms/shared-form.module.ts
index ea6270083..0e0ed5bab 100644
--- a/client/src/app/shared/shared-forms/shared-form.module.ts
+++ b/client/src/app/shared/shared-forms/shared-form.module.ts
@@ -3,7 +3,6 @@ import { NgModule } from '@angular/core'
3import { FormsModule, ReactiveFormsModule } from '@angular/forms' 3import { FormsModule, ReactiveFormsModule } from '@angular/forms'
4import { InputMaskModule } from 'primeng/inputmask' 4import { InputMaskModule } from 'primeng/inputmask'
5import { InputSwitchModule } from 'primeng/inputswitch' 5import { InputSwitchModule } from 'primeng/inputswitch'
6import { MultiSelectModule } from 'primeng/multiselect'
7import { NgSelectModule } from '@ng-select/ng-select' 6import { NgSelectModule } from '@ng-select/ng-select'
8import { BatchDomainsValidatorsService } from '@app/shared/shared-forms/form-validators/batch-domains-validators.service' 7import { BatchDomainsValidatorsService } from '@app/shared/shared-forms/form-validators/batch-domains-validators.service'
9import { SharedGlobalIconModule } from '../shared-icons' 8import { SharedGlobalIconModule } from '../shared-icons'
@@ -32,9 +31,7 @@ import { PreviewUploadComponent } from './preview-upload.component'
32import { ReactiveFileComponent } from './reactive-file.component' 31import { ReactiveFileComponent } from './reactive-file.component'
33import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' 32import { TextareaAutoResizeDirective } from './textarea-autoresize.directive'
34import { TimestampInputComponent } from './timestamp-input.component' 33import { TimestampInputComponent } from './timestamp-input.component'
35import { SelectChannelComponent } from './select-channel.component' 34import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select'
36import { SelectOptionsComponent } from './select-options.component'
37import { SelectTagsComponent } from './select-tags.component'
38 35
39@NgModule({ 36@NgModule({
40 imports: [ 37 imports: [
@@ -43,7 +40,6 @@ import { SelectTagsComponent } from './select-tags.component'
43 40
44 InputMaskModule, 41 InputMaskModule,
45 InputSwitchModule, 42 InputSwitchModule,
46 MultiSelectModule,
47 NgSelectModule, 43 NgSelectModule,
48 44
49 SharedMainModule, 45 SharedMainModule,
@@ -58,9 +54,11 @@ import { SelectTagsComponent } from './select-tags.component'
58 ReactiveFileComponent, 54 ReactiveFileComponent,
59 TextareaAutoResizeDirective, 55 TextareaAutoResizeDirective,
60 TimestampInputComponent, 56 TimestampInputComponent,
57
61 SelectChannelComponent, 58 SelectChannelComponent,
62 SelectOptionsComponent, 59 SelectOptionsComponent,
63 SelectTagsComponent 60 SelectTagsComponent,
61 SelectCheckboxComponent
64 ], 62 ],
65 63
66 exports: [ 64 exports: [
@@ -69,7 +67,6 @@ import { SelectTagsComponent } from './select-tags.component'
69 67
70 InputMaskModule, 68 InputMaskModule,
71 InputSwitchModule, 69 InputSwitchModule,
72 MultiSelectModule,
73 NgSelectModule, 70 NgSelectModule,
74 71
75 InputReadonlyCopyComponent, 72 InputReadonlyCopyComponent,
@@ -79,9 +76,11 @@ import { SelectTagsComponent } from './select-tags.component'
79 ReactiveFileComponent, 76 ReactiveFileComponent,
80 TextareaAutoResizeDirective, 77 TextareaAutoResizeDirective,
81 TimestampInputComponent, 78 TimestampInputComponent,
79
82 SelectChannelComponent, 80 SelectChannelComponent,
83 SelectOptionsComponent, 81 SelectOptionsComponent,
84 SelectTagsComponent 82 SelectTagsComponent,
83 SelectCheckboxComponent
85 ], 84 ],
86 85
87 providers: [ 86 providers: [
diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.html b/client/src/app/shared/shared-user-settings/user-video-settings.component.html
index bb9f59070..655b49e18 100644
--- a/client/src/app/shared/shared-user-settings/user-video-settings.component.html
+++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.html
@@ -30,11 +30,11 @@
30 </my-help> 30 </my-help>
31 31
32 <div> 32 <div>
33 <p-multiSelect 33 <my-select-checkbox
34 inputId="videoLanguages" [options]="languageItems" formControlName="videoLanguages" [showToggleAll]="true" 34 formControlName="videoLanguages" [availableItems]="languageItems"
35 [defaultLabel]="getDefaultVideoLanguageLabel()" [selectedItemsLabel]="getSelectedVideoLanguageLabel()" 35 [selectableGroup]="true" [selectableGroupAsModel]="true"
36 emptyFilterMessage="No results found" i18n-emptyFilterMessage 36 >
37 ></p-multiSelect> 37 </my-select-checkbox >
38 </div> 38 </div>
39 </div> 39 </div>
40 40
diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.scss b/client/src/app/shared/shared-user-settings/user-video-settings.component.scss
index 430250b87..d6a17703a 100644
--- a/client/src/app/shared/shared-user-settings/user-video-settings.component.scss
+++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.scss
@@ -19,6 +19,10 @@ input[type=submit] {
19 margin-bottom: 30px; 19 margin-bottom: 30px;
20} 20}
21 21
22my-select-checkbox {
23 @include ng-select(340px);
24}
25
22.form-group-select { 26.form-group-select {
23 margin-bottom: 30px; 27 margin-bottom: 30px;
24} 28}
diff --git a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts
index 4e4539936..eb340e24d 100644
--- a/client/src/app/shared/shared-user-settings/user-video-settings.component.ts
+++ b/client/src/app/shared/shared-user-settings/user-video-settings.component.ts
@@ -1,10 +1,9 @@
1import { pick } from 'lodash-es' 1import { pick } from 'lodash-es'
2import { SelectItem } from 'primeng/api'
3import { forkJoin, Subject, Subscription } from 'rxjs' 2import { forkJoin, Subject, Subscription } from 'rxjs'
4import { first } from 'rxjs/operators' 3import { first } from 'rxjs/operators'
5import { Component, Input, OnDestroy, OnInit } from '@angular/core' 4import { Component, Input, OnDestroy, OnInit } from '@angular/core'
6import { AuthService, Notifier, ServerService, User, UserService } from '@app/core' 5import { AuthService, Notifier, ServerService, User, UserService } from '@app/core'
7import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' 6import { FormReactive, FormValidatorService, ItemSelectCheckboxValue, SelectOptionsItem } from '@app/shared/shared-forms'
8import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
9import { UserUpdateMe } from '@shared/models' 8import { UserUpdateMe } from '@shared/models'
10import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' 9import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type'
@@ -20,10 +19,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
20 @Input() notifyOnUpdate = true 19 @Input() notifyOnUpdate = true
21 @Input() userInformationLoaded: Subject<any> 20 @Input() userInformationLoaded: Subject<any>
22 21
23 languageItems: SelectItem[] = [] 22 languageItems: SelectOptionsItem[] = []
24 defaultNSFWPolicy: NSFWPolicyType 23 defaultNSFWPolicy: NSFWPolicyType
25 formValuesWatcher: Subscription 24 formValuesWatcher: Subscription
26 25
26 private allLanguagesGroup: string
27
27 constructor ( 28 constructor (
28 protected formValidatorService: FormValidatorService, 29 protected formValidatorService: FormValidatorService,
29 private authService: AuthService, 30 private authService: AuthService,
@@ -36,6 +37,8 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
36 } 37 }
37 38
38 ngOnInit () { 39 ngOnInit () {
40 this.allLanguagesGroup = this.i18n('All languages')
41
39 let oldForm: any 42 let oldForm: any
40 43
41 this.buildForm({ 44 this.buildForm({
@@ -51,13 +54,15 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
51 this.serverService.getConfig(), 54 this.serverService.getConfig(),
52 this.userInformationLoaded.pipe(first()) 55 this.userInformationLoaded.pipe(first())
53 ]).subscribe(([ languages, config ]) => { 56 ]).subscribe(([ languages, config ]) => {
54 this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ] 57 const group = this.allLanguagesGroup
58
59 this.languageItems = [ { label: this.i18n('Unknown language'), id: '_unknown', group } ]
55 this.languageItems = this.languageItems 60 this.languageItems = this.languageItems
56 .concat(languages.map(l => ({ label: l.label, value: l.id }))) 61 .concat(languages.map(l => ({ label: l.label, id: l.id, group })))
57 62
58 const videoLanguages = this.user.videoLanguages 63 const videoLanguages: ItemSelectCheckboxValue[] = this.user.videoLanguages
59 ? this.user.videoLanguages 64 ? this.user.videoLanguages.map(l => ({ id: l }))
60 : this.languageItems.map(l => l.value) 65 : [ { group } ]
61 66
62 this.defaultNSFWPolicy = config.instance.defaultNSFWPolicy 67 this.defaultNSFWPolicy = config.instance.defaultNSFWPolicy
63 68
@@ -71,10 +76,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
71 76
72 if (this.reactiveUpdate) { 77 if (this.reactiveUpdate) {
73 oldForm = { ...this.form.value } 78 oldForm = { ...this.form.value }
79
74 this.formValuesWatcher = this.form.valueChanges.subscribe((formValue: any) => { 80 this.formValuesWatcher = this.form.valueChanges.subscribe((formValue: any) => {
75 const updatedKey = Object.keys(formValue).find(k => formValue[k] !== oldForm[k]) 81 const updatedKey = Object.keys(formValue).find(k => formValue[k] !== oldForm[k])
76 oldForm = { ...this.form.value } 82 oldForm = { ...this.form.value }
77 this.updateDetails([updatedKey]) 83
84 this.updateDetails([ updatedKey ])
78 }) 85 })
79 } 86 }
80 }) 87 })
@@ -91,16 +98,24 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit,
91 const autoPlayNextVideo = this.form.value['autoPlayNextVideo'] 98 const autoPlayNextVideo = this.form.value['autoPlayNextVideo']
92 99
93 let videoLanguages: string[] = this.form.value['videoLanguages'] 100 let videoLanguages: string[] = this.form.value['videoLanguages']
101
94 if (Array.isArray(videoLanguages)) { 102 if (Array.isArray(videoLanguages)) {
95 if (videoLanguages.length === this.languageItems.length) { 103 if (videoLanguages.length > 20) {
96 videoLanguages = null // null means "All" 104 this.notifier.error(this.i18n('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.'))
97 } else if (videoLanguages.length > 20) {
98 this.notifier.error('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.')
99 return 105 return
100 } else if (videoLanguages.length === 0) { 106 }
101 this.notifier.error('You need to enabled at least 1 video language.') 107
108 if (videoLanguages.length === 0) {
109 this.notifier.error(this.i18n('You need to enable at least 1 video language.'))
102 return 110 return
103 } 111 }
112
113 if (
114 videoLanguages.length === this.languageItems.length ||
115 (videoLanguages.length === 1 && videoLanguages[0] === this.allLanguagesGroup)
116 ) {
117 videoLanguages = null // null means "All"
118 }
104 } 119 }
105 120
106 let details: UserUpdateMe = { 121 let details: UserUpdateMe = {