diff options
Diffstat (limited to 'client/src/app/shared')
8 files changed, 97 insertions, 4 deletions
diff --git a/client/src/app/shared/forms/peertube-checkbox.component.html b/client/src/app/shared/forms/peertube-checkbox.component.html new file mode 100644 index 000000000..820e7a621 --- /dev/null +++ b/client/src/app/shared/forms/peertube-checkbox.component.html | |||
@@ -0,0 +1,9 @@ | |||
1 | <div class="form-group"> | ||
2 | <label class="form-group-checkbox"> | ||
3 | <input type="checkbox" [(ngModel)]="checked" (ngModelChange)="onModelChange()" [id]="inputName" [disabled]="isDisabled" /> | ||
4 | <span role="checkbox" [attr.aria-checked]="checked"></span> | ||
5 | <span *ngIf="labelText">{{ labelText }}</span> | ||
6 | </label> | ||
7 | |||
8 | <my-help *ngIf="helpHtml" tooltipPlacement="top" helpType="custom" i18n-customHtml [customHtml]="helpHtml"></my-help> | ||
9 | </div> \ No newline at end of file | ||
diff --git a/client/src/app/shared/forms/peertube-checkbox.component.scss b/client/src/app/shared/forms/peertube-checkbox.component.scss new file mode 100644 index 000000000..cbc50dc96 --- /dev/null +++ b/client/src/app/shared/forms/peertube-checkbox.component.scss | |||
@@ -0,0 +1,23 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .form-group { | ||
5 | display: flex; | ||
6 | align-items: center; | ||
7 | |||
8 | .form-group-checkbox { | ||
9 | display: flex; | ||
10 | |||
11 | span { | ||
12 | font-weight: $font-regular; | ||
13 | margin: 0; | ||
14 | } | ||
15 | |||
16 | input { | ||
17 | @include peertube-checkbox(1px); | ||
18 | |||
19 | width: 10px; | ||
20 | margin-right: 10px; | ||
21 | } | ||
22 | } | ||
23 | } \ No newline at end of file | ||
diff --git a/client/src/app/shared/forms/peertube-checkbox.component.ts b/client/src/app/shared/forms/peertube-checkbox.component.ts new file mode 100644 index 000000000..c626c4c5d --- /dev/null +++ b/client/src/app/shared/forms/peertube-checkbox.component.ts | |||
@@ -0,0 +1,45 @@ | |||
1 | import { Component, forwardRef, Input } from '@angular/core' | ||
2 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' | ||
3 | |||
4 | @Component({ | ||
5 | selector: 'my-peertube-checkbox', | ||
6 | styleUrls: [ './peertube-checkbox.component.scss' ], | ||
7 | templateUrl: './peertube-checkbox.component.html', | ||
8 | providers: [ | ||
9 | { | ||
10 | provide: NG_VALUE_ACCESSOR, | ||
11 | useExisting: forwardRef(() => PeertubeCheckboxComponent), | ||
12 | multi: true | ||
13 | } | ||
14 | ] | ||
15 | }) | ||
16 | export class PeertubeCheckboxComponent implements ControlValueAccessor { | ||
17 | @Input() checked = false | ||
18 | @Input() inputName: string | ||
19 | @Input() labelText: string | ||
20 | @Input() helpHtml: string | ||
21 | |||
22 | isDisabled = false | ||
23 | |||
24 | propagateChange = (_: any) => { /* empty */ } | ||
25 | |||
26 | writeValue (checked: boolean) { | ||
27 | this.checked = checked | ||
28 | } | ||
29 | |||
30 | registerOnChange (fn: (_: any) => void) { | ||
31 | this.propagateChange = fn | ||
32 | } | ||
33 | |||
34 | registerOnTouched () { | ||
35 | // Unused | ||
36 | } | ||
37 | |||
38 | onModelChange () { | ||
39 | this.propagateChange(this.checked) | ||
40 | } | ||
41 | |||
42 | setDisabledState (isDisabled: boolean) { | ||
43 | this.isDisabled = isDisabled | ||
44 | } | ||
45 | } | ||
diff --git a/client/src/app/shared/misc/help.component.html b/client/src/app/shared/misc/help.component.html index f2b6eca33..1c3863e52 100644 --- a/client/src/app/shared/misc/help.component.html +++ b/client/src/app/shared/misc/help.component.html | |||
@@ -13,10 +13,14 @@ | |||
13 | </ng-template> | 13 | </ng-template> |
14 | 14 | ||
15 | <span | 15 | <span |
16 | role="button" | ||
16 | class="help-tooltip-button" | 17 | class="help-tooltip-button" |
17 | title="Get help" | 18 | title="Get help" |
18 | i18n-title | 19 | i18n-title |
20 | [attr.aria-pressed]="isPopoverOpened" | ||
19 | [popover]="tooltipTemplate" | 21 | [popover]="tooltipTemplate" |
20 | [placement]="tooltipPlacement" | 22 | [placement]="tooltipPlacement" |
21 | [outsideClick]="true" | 23 | [outsideClick]="true" |
24 | (onHidden)="onPopoverHidden()" | ||
25 | (onShown)="onPopoverShown()" | ||
22 | ></span> | 26 | ></span> |
diff --git a/client/src/app/shared/misc/help.component.ts b/client/src/app/shared/misc/help.component.ts index e7af61b4a..ba0452e77 100644 --- a/client/src/app/shared/misc/help.component.ts +++ b/client/src/app/shared/misc/help.component.ts | |||
@@ -15,6 +15,7 @@ export class HelpComponent implements OnInit, OnChanges { | |||
15 | @Input() helpType: 'custom' | 'markdownText' | 'markdownEnhanced' = 'custom' | 15 | @Input() helpType: 'custom' | 'markdownText' | 'markdownEnhanced' = 'custom' |
16 | @Input() tooltipPlacement = 'right' | 16 | @Input() tooltipPlacement = 'right' |
17 | 17 | ||
18 | isPopoverOpened = false | ||
18 | mainHtml = '' | 19 | mainHtml = '' |
19 | 20 | ||
20 | constructor (private i18n: I18n) { } | 21 | constructor (private i18n: I18n) { } |
@@ -27,6 +28,14 @@ export class HelpComponent implements OnInit, OnChanges { | |||
27 | this.init() | 28 | this.init() |
28 | } | 29 | } |
29 | 30 | ||
31 | onPopoverHidden () { | ||
32 | this.isPopoverOpened = false | ||
33 | } | ||
34 | |||
35 | onPopoverShown () { | ||
36 | this.isPopoverOpened = true | ||
37 | } | ||
38 | |||
30 | private init () { | 39 | private init () { |
31 | if (this.helpType === 'custom') { | 40 | if (this.helpType === 'custom') { |
32 | this.mainHtml = this.customHtml | 41 | this.mainHtml = this.customHtml |
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index c3f4bf88b..fdfb90600 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts | |||
@@ -45,6 +45,7 @@ import { I18nPrimengCalendarService } from '@app/shared/i18n/i18n-primeng-calend | |||
45 | import { ScreenService } from '@app/shared/misc/screen.service' | 45 | import { ScreenService } from '@app/shared/misc/screen.service' |
46 | import { VideoCaptionsValidatorsService } from '@app/shared/forms/form-validators/video-captions-validators.service' | 46 | import { VideoCaptionsValidatorsService } from '@app/shared/forms/form-validators/video-captions-validators.service' |
47 | import { VideoCaptionService } from '@app/shared/video-caption' | 47 | import { VideoCaptionService } from '@app/shared/video-caption' |
48 | import { PeertubeCheckboxComponent } from '@app/shared/forms/peertube-checkbox.component' | ||
48 | 49 | ||
49 | @NgModule({ | 50 | @NgModule({ |
50 | imports: [ | 51 | imports: [ |
@@ -77,7 +78,8 @@ import { VideoCaptionService } from '@app/shared/video-caption' | |||
77 | MarkdownTextareaComponent, | 78 | MarkdownTextareaComponent, |
78 | InfiniteScrollerDirective, | 79 | InfiniteScrollerDirective, |
79 | HelpComponent, | 80 | HelpComponent, |
80 | ReactiveFileComponent | 81 | ReactiveFileComponent, |
82 | PeertubeCheckboxComponent | ||
81 | ], | 83 | ], |
82 | 84 | ||
83 | exports: [ | 85 | exports: [ |
@@ -106,6 +108,7 @@ import { VideoCaptionService } from '@app/shared/video-caption' | |||
106 | InfiniteScrollerDirective, | 108 | InfiniteScrollerDirective, |
107 | HelpComponent, | 109 | HelpComponent, |
108 | ReactiveFileComponent, | 110 | ReactiveFileComponent, |
111 | PeertubeCheckboxComponent, | ||
109 | 112 | ||
110 | NumberFormatterPipe, | 113 | NumberFormatterPipe, |
111 | ObjectLengthPipe, | 114 | ObjectLengthPipe, |
diff --git a/client/src/app/shared/video-caption/video-caption.service.ts b/client/src/app/shared/video-caption/video-caption.service.ts index d1444902d..e835981dd 100644 --- a/client/src/app/shared/video-caption/video-caption.service.ts +++ b/client/src/app/shared/video-caption/video-caption.service.ts | |||
@@ -42,8 +42,6 @@ export class VideoCaptionService { | |||
42 | } | 42 | } |
43 | 43 | ||
44 | updateCaptions (videoId: number | string, videoCaptions: VideoCaptionEdit[]) { | 44 | updateCaptions (videoId: number | string, videoCaptions: VideoCaptionEdit[]) { |
45 | if (videoCaptions.length === 0) return of(true) | ||
46 | |||
47 | const observables: Observable<any>[] = [] | 45 | const observables: Observable<any>[] = [] |
48 | 46 | ||
49 | for (const videoCaption of videoCaptions) { | 47 | for (const videoCaption of videoCaptions) { |
@@ -58,6 +56,8 @@ export class VideoCaptionService { | |||
58 | } | 56 | } |
59 | } | 57 | } |
60 | 58 | ||
59 | if (observables.length === 0) return of(true) | ||
60 | |||
61 | return forkJoin(observables) | 61 | return forkJoin(observables) |
62 | } | 62 | } |
63 | } | 63 | } |
diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html index 3010e5ccc..20020e2a8 100644 --- a/client/src/app/shared/video/video-miniature.component.html +++ b/client/src/app/shared/video/video-miniature.component.html | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | <div class="video-miniature-information"> | 4 | <div class="video-miniature-information"> |
5 | <a | 5 | <a |
6 | class="video-miniature-name" | 6 | class="video-miniature-name" alt="" |
7 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }" | 7 | [routerLink]="[ '/videos/watch', video.uuid ]" [attr.title]="video.name" [ngClass]="{ 'blur-filter': isVideoBlur() }" |
8 | > | 8 | > |
9 | {{ video.name }} | 9 | {{ video.name }} |