diff options
author | Chocobozzz <me@florianbigard.com> | 2018-07-17 14:44:19 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-07-17 14:56:15 +0200 |
commit | 0f7fedc39857ebc0eb29182c1588a92b9adfb75a (patch) | |
tree | f1516e93a93d1042bbc4d14d10575b88cae6bba1 | |
parent | 4bdd9473fdecfa7e309e3c59b05b29d0a20ac397 (diff) | |
download | PeerTube-0f7fedc39857ebc0eb29182c1588a92b9adfb75a.tar.gz PeerTube-0f7fedc39857ebc0eb29182c1588a92b9adfb75a.tar.zst PeerTube-0f7fedc39857ebc0eb29182c1588a92b9adfb75a.zip |
Improve frontend accessibility
In particular checkboxes, likes/dislikes, share button, video thumbnails
and help buttons
22 files changed, 162 insertions, 119 deletions
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 97900e523..6e3f83ccf 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 | |||
@@ -85,12 +85,10 @@ | |||
85 | 85 | ||
86 | <div i18n class="inner-form-title">Signup</div> | 86 | <div i18n class="inner-form-title">Signup</div> |
87 | 87 | ||
88 | <div class="form-group"> | 88 | <my-peertube-checkbox |
89 | <input type="checkbox" id="signupEnabled" formControlName="signupEnabled"> | 89 | inputName="signupEnabled" formControlName="signupEnabled" |
90 | 90 | i18n-labelText labelText="Signup enabled" | |
91 | <label for="signupEnabled"></label> | 91 | ></my-peertube-checkbox> |
92 | <label i18n for="signupEnabled">Signup enabled</label> | ||
93 | </div> | ||
94 | 92 | ||
95 | <div *ngIf="isSignupEnabled()" class="form-group"> | 93 | <div *ngIf="isSignupEnabled()" class="form-group"> |
96 | <label i18n for="signupLimit">Signup limit</label> | 94 | <label i18n for="signupLimit">Signup limit</label> |
@@ -152,33 +150,24 @@ | |||
152 | </div> | 150 | </div> |
153 | </div> | 151 | </div> |
154 | 152 | ||
155 | <div class="form-group"> | 153 | <my-peertube-checkbox |
156 | <input type="checkbox" id="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted"> | 154 | inputName="servicesTwitterWhitelisted" formControlName="servicesTwitterWhitelisted" |
157 | 155 | i18n-labelText labelText="Instance whitelisted by Twitter" | |
158 | <label for="servicesTwitterWhitelisted"></label> | 156 | i18n-helpHtml helpHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> |
159 | <label i18n for="servicesTwitterWhitelisted">Instance whitelisted by Twitter</label> | ||
160 | <my-help | ||
161 | helpType="custom" i18n-customHtml | ||
162 | customHtml="If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> | ||
163 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> | 157 | If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> |
164 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted." | 158 | Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> to see if you instance is whitelisted." |
165 | ></my-help> | 159 | ></my-peertube-checkbox> |
166 | |||
167 | </div> | ||
168 | </tab> | 160 | </tab> |
169 | 161 | ||
170 | <tab i18n-heading heading="Advanced configuration"> | 162 | <tab i18n-heading heading="Advanced configuration"> |
171 | 163 | ||
172 | <div i18n class="inner-form-title">Transcoding</div> | 164 | <div i18n class="inner-form-title">Transcoding</div> |
173 | 165 | ||
174 | <div class="form-group"> | 166 | <my-peertube-checkbox |
175 | <input type="checkbox" id="transcodingEnabled" formControlName="transcodingEnabled"> | 167 | inputName="transcodingEnabled" formControlName="transcodingEnabled" |
176 | 168 | i18n-labelText labelText="Transcoding enabled" | |
177 | <label for="transcodingEnabled"></label> | 169 | i18n-helpHtml helpHtml="If you disable transcoding, many videos from your users will not work!" |
178 | <label i18n for="transcodingEnabled">Transcoding enabled</label> | 170 | ></my-peertube-checkbox> |
179 | |||
180 | <my-help helpType="custom" i18n-customHtml customHtml="If you disable transcoding, many videos from your users will not work!"></my-help> | ||
181 | </div> | ||
182 | 171 | ||
183 | <ng-template [ngIf]="isTranscodingEnabled()"> | 172 | <ng-template [ngIf]="isTranscodingEnabled()"> |
184 | 173 | ||
@@ -197,12 +186,11 @@ Check this checkbox, save the configuration and test with a video URL of your in | |||
197 | </div> | 186 | </div> |
198 | 187 | ||
199 | <div class="form-group" *ngFor="let resolution of resolutions"> | 188 | <div class="form-group" *ngFor="let resolution of resolutions"> |
200 | <input | 189 | <my-peertube-checkbox |
201 | type="checkbox" [id]="getResolutionKey(resolution)" | 190 | [inputName]="getResolutionKey(resolution)" [formControlName]="getResolutionKey(resolution)" |
202 | [formControlName]="getResolutionKey(resolution)" | 191 | i18n-labelText labelText="Resolution {{resolution}} enabled" |
203 | > | 192 | ></my-peertube-checkbox> |
204 | <label [for]="getResolutionKey(resolution)"></label> | 193 | |
205 | <label i18n [for]="getResolutionKey(resolution)">Resolution {{ resolution }} enabled</label> | ||
206 | </div> | 194 | </div> |
207 | </ng-template> | 195 | </ng-template> |
208 | 196 | ||
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 98587eb18..96629940f 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 | |||
@@ -15,14 +15,10 @@ | |||
15 | </div> | 15 | </div> |
16 | </div> | 16 | </div> |
17 | 17 | ||
18 | <div class="form-group"> | 18 | <my-peertube-checkbox |
19 | <input | 19 | inputName="autoPlayVideo" formControlName="autoPlayVideo" |
20 | type="checkbox" id="autoPlayVideo" | 20 | i18n-labelText labelText="Automatically plays video" |
21 | formControlName="autoPlayVideo" | 21 | ></my-peertube-checkbox> |
22 | > | ||
23 | <label for="autoPlayVideo"></label> | ||
24 | <label i18n for="autoPlayVideo">Automatically plays video</label> | ||
25 | </div> | ||
26 | 22 | ||
27 | <input type="submit" i18n-value value="Save" [disabled]="!form.valid"> | 23 | <input type="submit" i18n-value value="Save" [disabled]="!form.valid"> |
28 | </form> | 24 | </form> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss index ed59e4689..1881be762 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss +++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.scss | |||
@@ -1,10 +1,6 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | input[type=checkbox] { | ||
5 | @include peertube-checkbox(1px); | ||
6 | } | ||
7 | |||
8 | input[type=submit] { | 4 | input[type=submit] { |
9 | @include peertube-button; | 5 | @include peertube-button; |
10 | @include orange-button; | 6 | @include orange-button; |
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html index 7ac6371db..4823e2db9 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.html +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.html | |||
@@ -9,8 +9,7 @@ | |||
9 | <div *ngFor="let videos of videoPages; let i = index" class="videos-page"> | 9 | <div *ngFor="let videos of videoPages; let i = index" class="videos-page"> |
10 | <div class="video" *ngFor="let video of videos; let j = index"> | 10 | <div class="video" *ngFor="let video of videos; let j = index"> |
11 | <div class="checkbox-container"> | 11 | <div class="checkbox-container"> |
12 | <input [id]="'video-check-' + video.id" type="checkbox" [(ngModel)]="checkedVideos[video.id]" /> | 12 | <my-peertube-checkbox [inputName]="'video-check-' + video.id" [(ngModel)]="checkedVideos[video.id]"></my-peertube-checkbox> |
13 | <label [for]="'video-check-' + video.id"></label> | ||
14 | </div> | 13 | </div> |
15 | 14 | ||
16 | <my-video-thumbnail [video]="video"></my-video-thumbnail> | 15 | <my-video-thumbnail [video]="video"></my-video-thumbnail> |
diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss index 65c0c8bb2..9cd985273 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss | |||
@@ -52,17 +52,6 @@ | |||
52 | margin-top: 47px; | 52 | margin-top: 47px; |
53 | } | 53 | } |
54 | 54 | ||
55 | .checkbox-container { | ||
56 | display: flex; | ||
57 | align-items: center; | ||
58 | margin-right: 20px; | ||
59 | margin-left: 12px; | ||
60 | |||
61 | input[type=checkbox] { | ||
62 | @include peertube-checkbox(2px); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | my-video-thumbnail { | 55 | my-video-thumbnail { |
67 | margin-right: 10px; | 56 | margin-right: 10px; |
68 | } | 57 | } |
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 }} |
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.html b/client/src/app/videos/+video-edit/shared/video-edit.component.html index 4675cb827..16dbf5cfc 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.html +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.html | |||
@@ -110,31 +110,22 @@ | |||
110 | </div> | 110 | </div> |
111 | </div> | 111 | </div> |
112 | 112 | ||
113 | <div class="form-group form-group-checkbox"> | 113 | <my-peertube-checkbox |
114 | <input type="checkbox" id="nsfw" formControlName="nsfw" /> | 114 | inputName="nsfw" formControlName="nsfw" |
115 | <label for="nsfw"></label> | 115 | i18n-labelText labelText="This video contains mature or explicit content" |
116 | <label i18n for="nsfw">This video contains mature or explicit content</label> | 116 | i18n-helpHtml helpHtml="Some instances do not list videos containing mature or explicit content by default." |
117 | <my-help | 117 | ></my-peertube-checkbox> |
118 | tooltipPlacement="top" helpType="custom" i18n-customHtml | 118 | |
119 | customHtml="Some instances do not list videos containing mature or explicit content by default." | 119 | <my-peertube-checkbox |
120 | ></my-help> | 120 | inputName="commentsEnabled" formControlName="commentsEnabled" |
121 | </div> | 121 | i18n-labelText labelText="Enable video comments" |
122 | 122 | ></my-peertube-checkbox> | |
123 | <div class="form-group form-group-checkbox"> | 123 | |
124 | <input type="checkbox" id="commentsEnabled" formControlName="commentsEnabled" /> | 124 | <my-peertube-checkbox |
125 | <label for="commentsEnabled"></label> | 125 | inputName="waitTranscoding" formControlName="waitTranscoding" |
126 | <label i18n for="commentsEnabled">Enable video comments</label> | 126 | i18n-labelText labelText="Wait transcoding before publishing the video" |
127 | </div> | 127 | i18n-helpHtml helpHtml="If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends." |
128 | 128 | ></my-peertube-checkbox> | |
129 | <div class="form-group form-group-checkbox"> | ||
130 | <input type="checkbox" id="waitTranscoding" formControlName="waitTranscoding" /> | ||
131 | <label for="waitTranscoding"></label> | ||
132 | <label i18n for="waitTranscoding">Wait transcoding before publishing the video</label> | ||
133 | <my-help | ||
134 | tooltipPlacement="top" helpType="custom" i18n-customHtml | ||
135 | customHtml="If you decide not to wait for transcoding before publishing the video, it could be unplayable until transcoding ends." | ||
136 | ></my-help> | ||
137 | </div> | ||
138 | 129 | ||
139 | </div> | 130 | </div> |
140 | </tab> | 131 | </tab> |
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.scss b/client/src/app/videos/+video-edit/shared/video-edit.component.scss index 03b8359de..058ccba36 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.scss +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.scss | |||
@@ -16,31 +16,12 @@ | |||
16 | input { | 16 | input { |
17 | @include peertube-input-text(100%); | 17 | @include peertube-input-text(100%); |
18 | display: block; | 18 | display: block; |
19 | |||
20 | &[type=checkbox] { | ||
21 | @include peertube-checkbox(1px); | ||
22 | } | ||
23 | } | 19 | } |
24 | 20 | ||
25 | input, select { | 21 | input, select { |
26 | font-size: 15px | 22 | font-size: 15px |
27 | } | 23 | } |
28 | 24 | ||
29 | .form-group-checkbox { | ||
30 | display: flex; | ||
31 | align-items: center; | ||
32 | |||
33 | label { | ||
34 | font-weight: $font-regular; | ||
35 | margin: 0; | ||
36 | } | ||
37 | |||
38 | input { | ||
39 | width: 10px; | ||
40 | margin-right: 10px; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | .label-tags + span { | 25 | .label-tags + span { |
45 | font-size: 15px; | 26 | font-size: 15px; |
46 | } | 27 | } |
diff --git a/client/src/app/videos/+video-edit/shared/video-edit.component.ts b/client/src/app/videos/+video-edit/shared/video-edit.component.ts index 743c015cb..00c7bc41d 100644 --- a/client/src/app/videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/videos/+video-edit/shared/video-edit.component.ts | |||
@@ -49,6 +49,7 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
49 | calendarDateFormat: string | 49 | calendarDateFormat: string |
50 | 50 | ||
51 | private schedulerInterval | 51 | private schedulerInterval |
52 | private firstPatchDone = false | ||
52 | 53 | ||
53 | constructor ( | 54 | constructor ( |
54 | private formValidatorService: FormValidatorService, | 55 | private formValidatorService: FormValidatorService, |
@@ -167,6 +168,7 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
167 | .pipe(map(res => parseInt(res.toString(), 10))) | 168 | .pipe(map(res => parseInt(res.toString(), 10))) |
168 | .subscribe( | 169 | .subscribe( |
169 | newPrivacyId => { | 170 | newPrivacyId => { |
171 | |||
170 | this.schedulePublicationEnabled = newPrivacyId === this.SPECIAL_SCHEDULED_PRIVACY | 172 | this.schedulePublicationEnabled = newPrivacyId === this.SPECIAL_SCHEDULED_PRIVACY |
171 | 173 | ||
172 | // Value changed | 174 | // Value changed |
@@ -182,11 +184,18 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
182 | scheduleControl.clearValidators() | 184 | scheduleControl.clearValidators() |
183 | 185 | ||
184 | waitTranscodingControl.enable() | 186 | waitTranscodingControl.enable() |
185 | waitTranscodingControl.setValue(true) | 187 | |
188 | // Do not update the control value on first patch (values come from the server) | ||
189 | if (this.firstPatchDone === true) { | ||
190 | waitTranscodingControl.setValue(true) | ||
191 | } | ||
186 | } | 192 | } |
187 | 193 | ||
188 | scheduleControl.updateValueAndValidity() | 194 | scheduleControl.updateValueAndValidity() |
189 | waitTranscodingControl.updateValueAndValidity() | 195 | waitTranscodingControl.updateValueAndValidity() |
196 | |||
197 | this.firstPatchDone = true | ||
198 | |||
190 | } | 199 | } |
191 | ) | 200 | ) |
192 | } | 201 | } |
diff --git a/client/src/app/videos/+video-edit/video-update.component.ts b/client/src/app/videos/+video-edit/video-update.component.ts index 774772e14..952fe0293 100644 --- a/client/src/app/videos/+video-edit/video-update.component.ts +++ b/client/src/app/videos/+video-edit/video-update.component.ts | |||
@@ -107,6 +107,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
107 | }, | 107 | }, |
108 | 108 | ||
109 | err => { | 109 | err => { |
110 | this.loadingBar.complete() | ||
110 | this.isUpdatingVideo = false | 111 | this.isUpdatingVideo = false |
111 | this.notificationsService.error(this.i18n('Error'), err.message) | 112 | this.notificationsService.error(this.i18n('Error'), err.message) |
112 | console.error(err) | 113 | console.error(err) |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index 21f8f5534..e7e9f367c 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -48,15 +48,15 @@ | |||
48 | <div class="video-actions-rates"> | 48 | <div class="video-actions-rates"> |
49 | <div class="video-actions"> | 49 | <div class="video-actions"> |
50 | <div | 50 | <div |
51 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" | 51 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" |
52 | class="action-button action-button-like" | 52 | class="action-button action-button-like" role="button" [attr.aria-pressed]="userRating === 'like'" |
53 | > | 53 | > |
54 | <span class="icon icon-like" i18n-title title="Like this video" ></span> | 54 | <span class="icon icon-like" i18n-title title="Like this video" ></span> |
55 | </div> | 55 | </div> |
56 | 56 | ||
57 | <div | 57 | <div |
58 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" | 58 | *ngIf="isUserLoggedIn()" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" |
59 | class="action-button action-button-dislike" | 59 | class="action-button action-button-dislike" role="button" [attr.aria-pressed]="userRating === 'dislike'" |
60 | > | 60 | > |
61 | <span class="icon icon-dislike" i18n-title title="Dislike this video"></span> | 61 | <span class="icon icon-dislike" i18n-title title="Dislike this video"></span> |
62 | </div> | 62 | </div> |
@@ -66,12 +66,12 @@ | |||
66 | <span class="icon-text" i18n>Support</span> | 66 | <span class="icon-text" i18n>Support</span> |
67 | </div> | 67 | </div> |
68 | 68 | ||
69 | <div (click)="showShareModal()" class="action-button action-button-share"> | 69 | <div (click)="showShareModal()" class="action-button action-button-share" role="button"> |
70 | <span class="icon icon-share"></span> | 70 | <span class="icon icon-share"></span> |
71 | <span class="icon-text" i18n>Share</span> | 71 | <span class="icon-text" i18n>Share</span> |
72 | </div> | 72 | </div> |
73 | 73 | ||
74 | <div class="action-more" dropdown dropup="true" placement="right"> | 74 | <div class="action-more" dropdown dropup="true" placement="right" role="button"> |
75 | <div class="action-button" dropdownToggle> | 75 | <div class="action-button" dropdownToggle> |
76 | <span class="icon icon-more"></span> | 76 | <span class="icon icon-more"></span> |
77 | </div> | 77 | </div> |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 43afbae1a..4f8549e8f 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -314,7 +314,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
314 | if (!errorMessage) return | 314 | if (!errorMessage) return |
315 | 315 | ||
316 | // Display a message in the video player instead of a notification | 316 | // Display a message in the video player instead of a notification |
317 | if (errorMessage.indexOf('http error') !== -1) { | 317 | if (errorMessage.indexOf('from xs param') !== -1) { |
318 | this.flushPlayer() | 318 | this.flushPlayer() |
319 | this.remoteServerDown = true | 319 | this.remoteServerDown = true |
320 | return | 320 | return |
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index 6d96e1c0b..b02f4373a 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts | |||
@@ -269,7 +269,7 @@ class PeerTubePlugin extends Plugin { | |||
269 | } | 269 | } |
270 | 270 | ||
271 | // Remote instance is down | 271 | // Remote instance is down |
272 | if (err.message.indexOf('http error from xs param') !== -1) { | 272 | if (err.message.indexOf('from xs param') !== -1) { |
273 | this.handleError(err) | 273 | this.handleError(err) |
274 | } | 274 | } |
275 | 275 | ||
diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index 9f8346950..3d518394a 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss | |||
@@ -240,7 +240,7 @@ | |||
240 | @mixin peertube-checkbox ($border-width) { | 240 | @mixin peertube-checkbox ($border-width) { |
241 | display: none; | 241 | display: none; |
242 | 242 | ||
243 | & + label { | 243 | & + span { |
244 | position: relative; | 244 | position: relative; |
245 | width: 18px; | 245 | width: 18px; |
246 | height: 18px; | 246 | height: 18px; |
@@ -263,7 +263,7 @@ | |||
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
266 | &:checked + label { | 266 | &:checked + span { |
267 | border-color: transparent; | 267 | border-color: transparent; |
268 | background: $orange-color; | 268 | background: $orange-color; |
269 | animation: jelly 0.6s ease; | 269 | animation: jelly 0.6s ease; |
@@ -274,7 +274,7 @@ | |||
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | & + label + label { | 277 | & + span + span { |
278 | font-size: 15px; | 278 | font-size: 15px; |
279 | font-weight: $font-regular; | 279 | font-weight: $font-regular; |
280 | margin-left: 5px; | 280 | margin-left: 5px; |
@@ -282,8 +282,8 @@ | |||
282 | display: inline; | 282 | display: inline; |
283 | } | 283 | } |
284 | 284 | ||
285 | &[disabled] + label, | 285 | &[disabled] + span, |
286 | &[disabled] + label + label{ | 286 | &[disabled] + span + span{ |
287 | opacity: 0.5; | 287 | opacity: 0.5; |
288 | cursor: default; | 288 | cursor: default; |
289 | } | 289 | } |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index cb05ec2b5..98ce73257 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -321,7 +321,7 @@ class PeerTubeEmbed { | |||
321 | } | 321 | } |
322 | 322 | ||
323 | private handleError (err: Error) { | 323 | private handleError (err: Error) { |
324 | if (err.message.indexOf('http error') !== -1) { | 324 | if (err.message.indexOf('from xs param') !== -1) { |
325 | this.player.dispose() | 325 | this.player.dispose() |
326 | this.videoElement = null | 326 | this.videoElement = null |
327 | this.displayError('This video is not available because the remote instance is not responding.') | 327 | this.displayError('This video is not available because the remote instance is not responding.') |