From 52c4976fcf4ee255a3af68ff9778e4f5c4f84bd4 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 11 Aug 2020 16:07:53 +0200 Subject: Use ng select for multiselect --- client/src/app/shared/shared-forms/index.ts | 1 + .../shared-forms/select-channel.component.html | 16 ----- .../shared-forms/select-channel.component.ts | 58 ----------------- .../shared-forms/select-options.component.html | 18 ------ .../shared-forms/select-options.component.ts | 47 -------------- .../shared-forms/select-shared.component.scss | 20 ------ .../shared/shared-forms/select-tags.component.html | 13 ---- .../shared/shared-forms/select-tags.component.scss | 3 - .../shared/shared-forms/select-tags.component.ts | 40 ------------ client/src/app/shared/shared-forms/select/index.ts | 4 ++ .../select/select-channel.component.html | 16 +++++ .../select/select-channel.component.ts | 58 +++++++++++++++++ .../select/select-checkbox.component.html | 41 ++++++++++++ .../select/select-checkbox.component.scss | 18 ++++++ .../select/select-checkbox.component.ts | 75 ++++++++++++++++++++++ .../select/select-options.component.html | 19 ++++++ .../select/select-options.component.ts | 49 ++++++++++++++ .../select/select-shared.component.scss | 32 +++++++++ .../shared-forms/select/select-tags.component.html | 13 ++++ .../shared-forms/select/select-tags.component.scss | 3 + .../shared-forms/select/select-tags.component.ts | 38 +++++++++++ .../app/shared/shared-forms/shared-form.module.ts | 15 ++--- .../user-video-settings.component.html | 10 +-- .../user-video-settings.component.scss | 4 ++ .../user-video-settings.component.ts | 45 ++++++++----- 25 files changed, 413 insertions(+), 243 deletions(-) delete mode 100644 client/src/app/shared/shared-forms/select-channel.component.html delete mode 100644 client/src/app/shared/shared-forms/select-channel.component.ts delete mode 100644 client/src/app/shared/shared-forms/select-options.component.html delete mode 100644 client/src/app/shared/shared-forms/select-options.component.ts delete mode 100644 client/src/app/shared/shared-forms/select-shared.component.scss delete mode 100644 client/src/app/shared/shared-forms/select-tags.component.html delete mode 100644 client/src/app/shared/shared-forms/select-tags.component.scss delete mode 100644 client/src/app/shared/shared-forms/select-tags.component.ts create mode 100644 client/src/app/shared/shared-forms/select/index.ts create mode 100644 client/src/app/shared/shared-forms/select/select-channel.component.html create mode 100644 client/src/app/shared/shared-forms/select/select-channel.component.ts create mode 100644 client/src/app/shared/shared-forms/select/select-checkbox.component.html create mode 100644 client/src/app/shared/shared-forms/select/select-checkbox.component.scss create mode 100644 client/src/app/shared/shared-forms/select/select-checkbox.component.ts create mode 100644 client/src/app/shared/shared-forms/select/select-options.component.html create mode 100644 client/src/app/shared/shared-forms/select/select-options.component.ts create mode 100644 client/src/app/shared/shared-forms/select/select-shared.component.scss create mode 100644 client/src/app/shared/shared-forms/select/select-tags.component.html create mode 100644 client/src/app/shared/shared-forms/select/select-tags.component.scss create mode 100644 client/src/app/shared/shared-forms/select/select-tags.component.ts (limited to 'client/src/app/shared') 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 @@ export * from './form-validators' export * from './form-reactive' +export * from './select' export * from './input-readonly-copy.component' export * from './markdown-textarea.component' export * from './peertube-checkbox.component' diff --git a/client/src/app/shared/shared-forms/select-channel.component.html b/client/src/app/shared/shared-forms/select-channel.component.html deleted file mode 100644 index 897d13ee7..000000000 --- a/client/src/app/shared/shared-forms/select-channel.component.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - {{ channel.label }} - - diff --git a/client/src/app/shared/shared-forms/select-channel.component.ts b/client/src/app/shared/shared-forms/select-channel.component.ts deleted file mode 100644 index ef4192095..000000000 --- a/client/src/app/shared/shared-forms/select-channel.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Component, forwardRef, Input } from '@angular/core' -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' -import { Actor } from '../shared-main' - -export type SelectChannelItem = { - id: number - label: string - support: string - avatarPath?: string -} - -@Component({ - selector: 'my-select-channel', - styleUrls: [ './select-shared.component.scss' ], - templateUrl: './select-channel.component.html', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => SelectChannelComponent), - multi: true - } - ] -}) -export class SelectChannelComponent implements ControlValueAccessor { - @Input() items: SelectChannelItem[] = [] - - selectedId: number - - // ng-select options - bindLabel = 'label' - bindValue = 'id' - clearable = false - searchable = false - - get channels () { - return this.items.map(c => Object.assign(c, { - avatarPath: c.avatarPath ? c.avatarPath : Actor.GET_DEFAULT_AVATAR_URL() - })) - } - - propagateChange = (_: any) => { /* empty */ } - - writeValue (id: number) { - this.selectedId = id - } - - registerOnChange (fn: (_: any) => void) { - this.propagateChange = fn - } - - registerOnTouched () { - // Unused - } - - onModelChange () { - this.propagateChange(this.selectedId) - } -} diff --git a/client/src/app/shared/shared-forms/select-options.component.html b/client/src/app/shared/shared-forms/select-options.component.html deleted file mode 100644 index fda0c2c56..000000000 --- a/client/src/app/shared/shared-forms/select-options.component.html +++ /dev/null @@ -1,18 +0,0 @@ - - - {{ item.label }} - -
- {{ item.description }} -
-
-
diff --git a/client/src/app/shared/shared-forms/select-options.component.ts b/client/src/app/shared/shared-forms/select-options.component.ts deleted file mode 100644 index 09f7df53b..000000000 --- a/client/src/app/shared/shared-forms/select-options.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Component, Input, forwardRef } from '@angular/core' -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' - -export type SelectOptionsItem = { id: number | string, label: string, description?: string } - -@Component({ - selector: 'my-select-options', - styleUrls: [ './select-shared.component.scss' ], - templateUrl: './select-options.component.html', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => SelectOptionsComponent), - multi: true - } - ] -}) -export class SelectOptionsComponent implements ControlValueAccessor { - @Input() items: SelectOptionsItem[] = [] - @Input() clearable = false - @Input() searchable = false - @Input() bindValue = 'id' - @Input() groupBy: string - - selectedId: number | string - - // ng-select options - bindLabel = 'label' - - propagateChange = (_: any) => { /* empty */ } - - writeValue (id: number | string) { - this.selectedId = id - } - - registerOnChange (fn: (_: any) => void) { - this.propagateChange = fn - } - - registerOnTouched () { - // Unused - } - - onModelChange () { - this.propagateChange(this.selectedId) - } -} 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 @@ -$width-size: auto; - -ng-select { - width: $width-size; - @media screen and (max-width: $width-size) { - width: 100%; - } -} - -// make sure the image is vertically adjusted -ng-select ::ng-deep .ng-value-label img { - position: relative; - top: -1px; -} - -ng-select ::ng-deep img { - border-radius: 50%; - height: 20px; - width: 20px; -} diff --git a/client/src/app/shared/shared-forms/select-tags.component.html b/client/src/app/shared/shared-forms/select-tags.component.html deleted file mode 100644 index e1cd50882..000000000 --- a/client/src/app/shared/shared-forms/select-tags.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - diff --git a/client/src/app/shared/shared-forms/select-tags.component.scss b/client/src/app/shared/shared-forms/select-tags.component.scss deleted file mode 100644 index ad76bc7ee..000000000 --- a/client/src/app/shared/shared-forms/select-tags.component.scss +++ /dev/null @@ -1,3 +0,0 @@ -ng-select ::ng-deep .ng-arrow-wrapper { - display: none; -} diff --git a/client/src/app/shared/shared-forms/select-tags.component.ts b/client/src/app/shared/shared-forms/select-tags.component.ts deleted file mode 100644 index a8a19d788..000000000 --- a/client/src/app/shared/shared-forms/select-tags.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Component, Input, forwardRef } from '@angular/core' -import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' - -@Component({ - selector: 'my-select-tags', - styleUrls: [ './select-shared.component.scss', './select-tags.component.scss' ], - templateUrl: './select-tags.component.html', - providers: [ - { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => SelectTagsComponent), - multi: true - } - ] -}) -export class SelectTagsComponent implements ControlValueAccessor { - @Input() availableItems: string[] = [] - @Input() selectedItems: string[] = [] - - propagateChange = (_: any) => { /* empty */ } - - writeValue (items: string[]) { - this.selectedItems = items - this.propagateChange(this.selectedItems) - } - - registerOnChange (fn: (_: any) => void) { - this.propagateChange = fn - } - - registerOnTouched () { - // Unused - } - - onModelChange () { - console.log(this.selectedItems) - - this.propagateChange(this.selectedItems) - } -} 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 @@ +export * from './select-channel.component' +export * from './select-options.component' +export * from './select-tags.component' +export * from './select-checkbox.component' diff --git a/client/src/app/shared/shared-forms/select/select-channel.component.html b/client/src/app/shared/shared-forms/select/select-channel.component.html new file mode 100644 index 000000000..897d13ee7 --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-channel.component.html @@ -0,0 +1,16 @@ + + + + {{ channel.label }} + + diff --git a/client/src/app/shared/shared-forms/select/select-channel.component.ts b/client/src/app/shared/shared-forms/select/select-channel.component.ts new file mode 100644 index 000000000..1b0db9b6f --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-channel.component.ts @@ -0,0 +1,58 @@ +import { Component, forwardRef, Input } from '@angular/core' +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' +import { Actor } from '@app/shared/shared-main/account/actor.model' + +export type SelectChannelItem = { + id: number + label: string + support: string + avatarPath?: string +} + +@Component({ + selector: 'my-select-channel', + styleUrls: [ './select-shared.component.scss' ], + templateUrl: './select-channel.component.html', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectChannelComponent), + multi: true + } + ] +}) +export class SelectChannelComponent implements ControlValueAccessor { + @Input() items: SelectChannelItem[] = [] + + selectedId: number + + // ng-select options + bindLabel = 'label' + bindValue = 'id' + clearable = false + searchable = false + + get channels () { + return this.items.map(c => Object.assign(c, { + avatarPath: c.avatarPath ? c.avatarPath : Actor.GET_DEFAULT_AVATAR_URL() + })) + } + + propagateChange = (_: any) => { /* empty */ } + + writeValue (id: number) { + this.selectedId = id + } + + registerOnChange (fn: (_: any) => void) { + this.propagateChange = fn + } + + registerOnTouched () { + // Unused + } + + onModelChange () { + this.propagateChange(this.selectedId) + } +} 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 @@ + + + +
+ + + {{ item.group }} +
+
+ + +
+ + + {{ item.label }} +
+
+ +
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 @@ +@import '_variables'; +@import '_mixins'; + +ng-select ::ng-deep { + .ng-option { + display: flex; + align-items: center; + } + + .form-group-checkbox { + display: flex; + align-items: center; + + input { + @include peertube-checkbox(1px); + } + } +} 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 @@ +import { Component, Input, forwardRef } from '@angular/core' +import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' +import { SelectOptionsItem } from './select-options.component' + +export type ItemSelectCheckboxValue = { id?: string | number, group?: string } | string + +@Component({ + selector: 'my-select-checkbox', + styleUrls: [ './select-shared.component.scss', 'select-checkbox.component.scss' ], + templateUrl: './select-checkbox.component.html', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectCheckboxComponent), + multi: true + } + ] +}) +export class SelectCheckboxComponent implements ControlValueAccessor { + @Input() availableItems: SelectOptionsItem[] = [] + @Input() selectedItems: ItemSelectCheckboxValue[] = [] + @Input() selectableGroup: boolean + @Input() selectableGroupAsModel: boolean + @Input() maxSelectedItems: number + + propagateChange = (_: any) => { /* empty */ } + + writeValue (items: ItemSelectCheckboxValue[]) { + if (Array.isArray(items)) { + this.selectedItems = items.map(i => { + if (typeof i === 'string' || typeof i === 'number') { + return i + '' + } + + if (i.group) { + return { group: i.group } + } + + return { id: i.id + '' } + }) + } else { + this.selectedItems = items + } + + this.propagateChange(this.selectedItems) + } + + registerOnChange (fn: (_: any) => void) { + this.propagateChange = fn + } + + registerOnTouched () { + // Unused + } + + onModelChange () { + this.propagateChange(this.selectedItems) + } + + compareFn (item: SelectOptionsItem, selected: ItemSelectCheckboxValue) { + if (typeof selected === 'string') { + return item.id === selected + } + + if (this.selectableGroup && item.group && selected.group) { + return item.group === selected.group + } + + if (selected.id && item.id) { + return item.id === selected.id + } + + return false + } +} diff --git a/client/src/app/shared/shared-forms/select/select-options.component.html b/client/src/app/shared/shared-forms/select/select-options.component.html new file mode 100644 index 000000000..48eca1cf5 --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-options.component.html @@ -0,0 +1,19 @@ + + + {{ item.label }} + +
+ {{ item.description }} +
+
+
diff --git a/client/src/app/shared/shared-forms/select/select-options.component.ts b/client/src/app/shared/shared-forms/select/select-options.component.ts new file mode 100644 index 000000000..3ba24c732 --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-options.component.ts @@ -0,0 +1,49 @@ +import { Component, Input, forwardRef } from '@angular/core' +import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' + +export type SelectOptionsItem = { + id: string | number + label: string + description?: string + group?: string + groupLabel?: string +} + +@Component({ + selector: 'my-select-options', + styleUrls: [ './select-shared.component.scss' ], + templateUrl: './select-options.component.html', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectOptionsComponent), + multi: true + } + ] +}) +export class SelectOptionsComponent implements ControlValueAccessor { + @Input() items: SelectOptionsItem[] = [] + @Input() clearable = false + @Input() searchable = false + @Input() groupBy: string + + selectedId: number | string + + propagateChange = (_: any) => { /* empty */ } + + writeValue (id: number | string) { + this.selectedId = id + } + + registerOnChange (fn: (_: any) => void) { + this.propagateChange = fn + } + + registerOnTouched () { + // Unused + } + + onModelChange () { + this.propagateChange(this.selectedId) + } +} 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 @@ +@import '_variables'; +@import '_mixins'; + +$form-base-input-width: auto; + +ng-select { + width: $form-base-input-width; + + @media screen and (max-width: $form-base-input-width) { + width: 100%; + } +} + +ng-select ::ng-deep { + .ng-value-container { + max-height: 100px; + overflow-y: auto; + overflow-x: hidden; + } + + // make sure the image is vertically adjusted + .ng-value-label img { + position: relative; + top: -1px; + } + + img { + border-radius: 50%; + height: 20px; + width: 20px; + } +} diff --git a/client/src/app/shared/shared-forms/select/select-tags.component.html b/client/src/app/shared/shared-forms/select/select-tags.component.html new file mode 100644 index 000000000..e1cd50882 --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-tags.component.html @@ -0,0 +1,13 @@ + + diff --git a/client/src/app/shared/shared-forms/select/select-tags.component.scss b/client/src/app/shared/shared-forms/select/select-tags.component.scss new file mode 100644 index 000000000..ad76bc7ee --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-tags.component.scss @@ -0,0 +1,3 @@ +ng-select ::ng-deep .ng-arrow-wrapper { + display: none; +} diff --git a/client/src/app/shared/shared-forms/select/select-tags.component.ts b/client/src/app/shared/shared-forms/select/select-tags.component.ts new file mode 100644 index 000000000..93d199037 --- /dev/null +++ b/client/src/app/shared/shared-forms/select/select-tags.component.ts @@ -0,0 +1,38 @@ +import { Component, Input, forwardRef } from '@angular/core' +import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms' + +@Component({ + selector: 'my-select-tags', + styleUrls: [ './select-shared.component.scss', './select-tags.component.scss' ], + templateUrl: './select-tags.component.html', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SelectTagsComponent), + multi: true + } + ] +}) +export class SelectTagsComponent implements ControlValueAccessor { + @Input() availableItems: string[] = [] + @Input() selectedItems: string[] = [] + + propagateChange = (_: any) => { /* empty */ } + + writeValue (items: string[]) { + this.selectedItems = items + this.propagateChange(this.selectedItems) + } + + registerOnChange (fn: (_: any) => void) { + this.propagateChange = fn + } + + registerOnTouched () { + // Unused + } + + onModelChange () { + this.propagateChange(this.selectedItems) + } +} 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' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { InputMaskModule } from 'primeng/inputmask' import { InputSwitchModule } from 'primeng/inputswitch' -import { MultiSelectModule } from 'primeng/multiselect' import { NgSelectModule } from '@ng-select/ng-select' import { BatchDomainsValidatorsService } from '@app/shared/shared-forms/form-validators/batch-domains-validators.service' import { SharedGlobalIconModule } from '../shared-icons' @@ -32,9 +31,7 @@ import { PreviewUploadComponent } from './preview-upload.component' import { ReactiveFileComponent } from './reactive-file.component' import { TextareaAutoResizeDirective } from './textarea-autoresize.directive' import { TimestampInputComponent } from './timestamp-input.component' -import { SelectChannelComponent } from './select-channel.component' -import { SelectOptionsComponent } from './select-options.component' -import { SelectTagsComponent } from './select-tags.component' +import { SelectChannelComponent, SelectCheckboxComponent, SelectOptionsComponent, SelectTagsComponent } from './select' @NgModule({ imports: [ @@ -43,7 +40,6 @@ import { SelectTagsComponent } from './select-tags.component' InputMaskModule, InputSwitchModule, - MultiSelectModule, NgSelectModule, SharedMainModule, @@ -58,9 +54,11 @@ import { SelectTagsComponent } from './select-tags.component' ReactiveFileComponent, TextareaAutoResizeDirective, TimestampInputComponent, + SelectChannelComponent, SelectOptionsComponent, - SelectTagsComponent + SelectTagsComponent, + SelectCheckboxComponent ], exports: [ @@ -69,7 +67,6 @@ import { SelectTagsComponent } from './select-tags.component' InputMaskModule, InputSwitchModule, - MultiSelectModule, NgSelectModule, InputReadonlyCopyComponent, @@ -79,9 +76,11 @@ import { SelectTagsComponent } from './select-tags.component' ReactiveFileComponent, TextareaAutoResizeDirective, TimestampInputComponent, + SelectChannelComponent, SelectOptionsComponent, - SelectTagsComponent + SelectTagsComponent, + SelectCheckboxComponent ], 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 @@
- + +
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] { margin-bottom: 30px; } +my-select-checkbox { + @include ng-select(340px); +} + .form-group-select { margin-bottom: 30px; } 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 @@ import { pick } from 'lodash-es' -import { SelectItem } from 'primeng/api' import { forkJoin, Subject, Subscription } from 'rxjs' import { first } from 'rxjs/operators' import { Component, Input, OnDestroy, OnInit } from '@angular/core' import { AuthService, Notifier, ServerService, User, UserService } from '@app/core' -import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' +import { FormReactive, FormValidatorService, ItemSelectCheckboxValue, SelectOptionsItem } from '@app/shared/shared-forms' import { I18n } from '@ngx-translate/i18n-polyfill' import { UserUpdateMe } from '@shared/models' import { NSFWPolicyType } from '@shared/models/videos/nsfw-policy.type' @@ -20,10 +19,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, @Input() notifyOnUpdate = true @Input() userInformationLoaded: Subject - languageItems: SelectItem[] = [] + languageItems: SelectOptionsItem[] = [] defaultNSFWPolicy: NSFWPolicyType formValuesWatcher: Subscription + private allLanguagesGroup: string + constructor ( protected formValidatorService: FormValidatorService, private authService: AuthService, @@ -36,6 +37,8 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, } ngOnInit () { + this.allLanguagesGroup = this.i18n('All languages') + let oldForm: any this.buildForm({ @@ -51,13 +54,15 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, this.serverService.getConfig(), this.userInformationLoaded.pipe(first()) ]).subscribe(([ languages, config ]) => { - this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ] + const group = this.allLanguagesGroup + + this.languageItems = [ { label: this.i18n('Unknown language'), id: '_unknown', group } ] this.languageItems = this.languageItems - .concat(languages.map(l => ({ label: l.label, value: l.id }))) + .concat(languages.map(l => ({ label: l.label, id: l.id, group }))) - const videoLanguages = this.user.videoLanguages - ? this.user.videoLanguages - : this.languageItems.map(l => l.value) + const videoLanguages: ItemSelectCheckboxValue[] = this.user.videoLanguages + ? this.user.videoLanguages.map(l => ({ id: l })) + : [ { group } ] this.defaultNSFWPolicy = config.instance.defaultNSFWPolicy @@ -71,10 +76,12 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, if (this.reactiveUpdate) { oldForm = { ...this.form.value } + this.formValuesWatcher = this.form.valueChanges.subscribe((formValue: any) => { const updatedKey = Object.keys(formValue).find(k => formValue[k] !== oldForm[k]) oldForm = { ...this.form.value } - this.updateDetails([updatedKey]) + + this.updateDetails([ updatedKey ]) }) } }) @@ -91,16 +98,24 @@ export class UserVideoSettingsComponent extends FormReactive implements OnInit, const autoPlayNextVideo = this.form.value['autoPlayNextVideo'] let videoLanguages: string[] = this.form.value['videoLanguages'] + if (Array.isArray(videoLanguages)) { - if (videoLanguages.length === this.languageItems.length) { - videoLanguages = null // null means "All" - } else if (videoLanguages.length > 20) { - this.notifier.error('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.') + if (videoLanguages.length > 20) { + this.notifier.error(this.i18n('Too many languages are enabled. Please enable them all or stay below 20 enabled languages.')) return - } else if (videoLanguages.length === 0) { - this.notifier.error('You need to enabled at least 1 video language.') + } + + if (videoLanguages.length === 0) { + this.notifier.error(this.i18n('You need to enable at least 1 video language.')) return } + + if ( + videoLanguages.length === this.languageItems.length || + (videoLanguages.length === 1 && videoLanguages[0] === this.allLanguagesGroup) + ) { + videoLanguages = null // null means "All" + } } let details: UserUpdateMe = { -- cgit v1.2.3