diff options
26 files changed, 177 insertions, 100 deletions
diff --git a/client/src/app/+admin/users/user-edit/user-edit.component.html b/client/src/app/+admin/users/user-edit/user-edit.component.html index 0cb625b4a..819ced834 100644 --- a/client/src/app/+admin/users/user-edit/user-edit.component.html +++ b/client/src/app/+admin/users/user-edit/user-edit.component.html | |||
@@ -122,10 +122,9 @@ | |||
122 | </ng-container> | 122 | </ng-container> |
123 | </ng-template> | 123 | </ng-template> |
124 | </my-help> | 124 | </my-help> |
125 | <input | 125 | <my-input-toggle-hidden formControlName="password" id="password" |
126 | type="password" id="password" autocomplete="new-password" class="form-control" | 126 | [ngClass]="{ 'input-error': formErrors['password'] }" |
127 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 127 | autocomplete="new-password"></my-input-toggle-hidden> |
128 | > | ||
129 | <div *ngIf="formErrors.password" class="form-error"> | 128 | <div *ngIf="formErrors.password" class="form-error"> |
130 | {{ formErrors.password }} | 129 | {{ formErrors.password }} |
131 | </div> | 130 | </div> |
diff --git a/client/src/app/+login/login.component.html b/client/src/app/+login/login.component.html index 7ceae9311..390d77dd7 100644 --- a/client/src/app/+login/login.component.html +++ b/client/src/app/+login/login.component.html | |||
@@ -50,10 +50,10 @@ | |||
50 | <div class="form-group"> | 50 | <div class="form-group"> |
51 | <label i18n for="password">Password</label> | 51 | <label i18n for="password">Password</label> |
52 | <div> | 52 | <div> |
53 | <input | 53 | <my-input-toggle-hidden formControlName="password" id="password" |
54 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" autocomplete="current-password" | 54 | i18n-placeholder placeholder="Password" |
55 | formControlName="password" class="form-control" [ngClass]="{ 'input-error': formErrors['password'] }" | 55 | [ngClass]="{ 'input-error': formErrors['password'] }" |
56 | > | 56 | autocomplete="current-password"></my-input-toggle-hidden> |
57 | <a i18n-title class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a> | 57 | <a i18n-title class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a> |
58 | </div> | 58 | </div> |
59 | <div *ngIf="formErrors.password" class="form-error"> | 59 | <div *ngIf="formErrors.password" class="form-error"> |
diff --git a/client/src/app/+my-account/my-account-applications/my-account-applications.component.html b/client/src/app/+my-account/my-account-applications/my-account-applications.component.html index 3fbb79c71..68d094a4f 100644 --- a/client/src/app/+my-account/my-account-applications/my-account-applications.component.html +++ b/client/src/app/+my-account/my-account-applications/my-account-applications.component.html | |||
@@ -8,7 +8,7 @@ | |||
8 | <h2 i18n class="applications-title">SUBSCRIPTION FEED</h2> | 8 | <h2 i18n class="applications-title">SUBSCRIPTION FEED</h2> |
9 | <div i18n class="applications-description"> | 9 | <div i18n class="applications-description"> |
10 | Use third-party feed aggregators to retrieve the list of videos from | 10 | Use third-party feed aggregators to retrieve the list of videos from |
11 | channels you subscribed to. Make sure to keep your token private. | 11 | channels you subscribed to. |
12 | </div> | 12 | </div> |
13 | </div> | 13 | </div> |
14 | 14 | ||
@@ -16,12 +16,14 @@ | |||
16 | 16 | ||
17 | <div class="form-group"> | 17 | <div class="form-group"> |
18 | <label i18n for="feed-url">Feed URL</label> | 18 | <label i18n for="feed-url">Feed URL</label> |
19 | <my-input-readonly-copy [value]="feedUrl"></my-input-readonly-copy> | 19 | <my-input-toggle-hidden [value]="feedUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
20 | </div> | 20 | </div> |
21 | 21 | ||
22 | <div class="form-group"> | 22 | <div class="form-group"> |
23 | <label i18n for="feed-token">Feed Token</label> | 23 | <label i18n for="feed-token">Feed Token</label> |
24 | <my-input-readonly-copy [value]="feedToken"></my-input-readonly-copy> | 24 | <my-input-toggle-hidden [value]="feedToken" [withCopy]="true" [readonly]="true"></my-input-toggle-hidden> |
25 | |||
26 | <div class="form-group-description" i18n>⚠️ Never share your feed token with anyone.</div> | ||
25 | </div> | 27 | </div> |
26 | 28 | ||
27 | </div> | 29 | </div> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html index ce176d682..29823bdec 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html | |||
@@ -12,9 +12,8 @@ | |||
12 | <form role="form" class="change-email" (ngSubmit)="changeEmail()" [formGroup]="form" *ngIf="user.pluginAuth === null"> | 12 | <form role="form" class="change-email" (ngSubmit)="changeEmail()" [formGroup]="form" *ngIf="user.pluginAuth === null"> |
13 | 13 | ||
14 | <div class="form-group"> | 14 | <div class="form-group"> |
15 | <label i18n for="new-email">New email</label> | ||
16 | <input | 15 | <input |
17 | type="email" id="new-email" i18n-placeholder placeholder="Your new email" class="form-control" | 16 | type="email" id="new-email" i18n-placeholder placeholder="New email" class="form-control" |
18 | formControlName="new-email" [ngClass]="{ 'input-error': formErrors['new-email'] }" | 17 | formControlName="new-email" [ngClass]="{ 'input-error': formErrors['new-email'] }" |
19 | > | 18 | > |
20 | <div *ngIf="formErrors['new-email']" class="form-error"> | 19 | <div *ngIf="formErrors['new-email']" class="form-error"> |
@@ -23,11 +22,11 @@ | |||
23 | </div> | 22 | </div> |
24 | 23 | ||
25 | <div class="form-group"> | 24 | <div class="form-group"> |
26 | <label i18n for="new-email">Your current password</label> | 25 | <my-input-toggle-hidden formControlName="password" |
27 | <input | 26 | id="password" |
28 | type="password" id="password" i18n-placeholder placeholder="Your password" autocomplete="off" | 27 | i18n-placeholder placeholder="Current password" |
29 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" class="form-control" | 28 | [ngClass]="{ 'input-error': formErrors['password'] }" |
30 | > | 29 | autocomplete="current-password"></my-input-toggle-hidden> |
31 | <div *ngIf="formErrors['password']" class="form-error"> | 30 | <div *ngIf="formErrors['password']" class="form-error"> |
32 | {{ formErrors['password'] }} | 31 | {{ formErrors['password'] }} |
33 | </div> | 32 | </div> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.scss b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.scss index aec709ea0..a8b9be0d1 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.scss +++ b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.scss | |||
@@ -6,7 +6,11 @@ label { | |||
6 | font-size: 100%; | 6 | font-size: 100%; |
7 | } | 7 | } |
8 | 8 | ||
9 | input[type=password], | 9 | my-input-toggle-hidden { |
10 | width: 340px; | ||
11 | display: block; | ||
12 | } | ||
13 | |||
10 | input[type=email] { | 14 | input[type=email] { |
11 | @include peertube-input-text(340px); | 15 | @include peertube-input-text(340px); |
12 | 16 | ||
@@ -20,10 +24,13 @@ input[type=submit] { | |||
20 | 24 | ||
21 | .current-email, | 25 | .current-email, |
22 | .pending-email { | 26 | .pending-email { |
23 | font-size: 16px; | ||
24 | margin-bottom: 15px; | 27 | margin-bottom: 15px; |
25 | 28 | ||
26 | .email { | 29 | .email { |
27 | font-weight: $font-semibold; | 30 | font-weight: $font-semibold; |
28 | } | 31 | } |
29 | } | 32 | } |
33 | |||
34 | .form-group { | ||
35 | width: max-content; | ||
36 | } | ||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html index 4756cfecd..f1127b6a1 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html | |||
@@ -3,26 +3,29 @@ | |||
3 | <form role="form" (ngSubmit)="changePassword()" [formGroup]="form"> | 3 | <form role="form" (ngSubmit)="changePassword()" [formGroup]="form"> |
4 | 4 | ||
5 | <label i18n for="current-password">Change password</label> | 5 | <label i18n for="current-password">Change password</label> |
6 | <input | 6 | <my-input-toggle-hidden formControlName="current-password" |
7 | type="password" id="current-password" i18n-placeholder placeholder="Current password" autocomplete="current-password" | 7 | id="current-password" |
8 | formControlName="current-password" [ngClass]="{ 'input-error': formErrors['current-password'] }" class="form-control" | 8 | i18n-placeholder placeholder="Current password" |
9 | > | 9 | [ngClass]="{ 'input-error': formErrors['current-password'] }" |
10 | autocomplete="current-password"></my-input-toggle-hidden> | ||
10 | <div *ngIf="formErrors['current-password']" class="form-error"> | 11 | <div *ngIf="formErrors['current-password']" class="form-error"> |
11 | {{ formErrors['current-password'] }} | 12 | {{ formErrors['current-password'] }} |
12 | </div> | 13 | </div> |
13 | 14 | ||
14 | <input | 15 | <my-input-toggle-hidden formControlName="new-password" |
15 | type="password" id="new-password" i18n-placeholder placeholder="New password" autocomplete="new-password" | 16 | id="new-password" |
16 | formControlName="new-password" [ngClass]="{ 'input-error': formErrors['new-password'] }" class="form-control" | 17 | i18n-placeholder placeholder="New password" |
17 | > | 18 | [ngClass]="{ 'input-error': formErrors['new-password'] }" |
19 | autocomplete="new-password"></my-input-toggle-hidden> | ||
18 | <div *ngIf="formErrors['new-password']" class="form-error"> | 20 | <div *ngIf="formErrors['new-password']" class="form-error"> |
19 | {{ formErrors['new-password'] }} | 21 | {{ formErrors['new-password'] }} |
20 | </div> | 22 | </div> |
21 | 23 | ||
22 | <input | 24 | <my-input-toggle-hidden formControlName="new-confirmed-password" |
23 | type="password" id="new-confirmed-password" i18n-placeholder placeholder="Confirm new password" autocomplete="new-password" | 25 | id="new-confirmed-password" |
24 | formControlName="new-confirmed-password" class="form-control" | 26 | i18n-placeholder placeholder="Confirm new password" |
25 | > | 27 | [ngClass]="{ 'input-error': formErrors['new-confirmed-password'] }" |
28 | autocomplete="new-password"></my-input-toggle-hidden> | ||
26 | <div *ngIf="formErrors['new-confirmed-password']" class="form-error"> | 29 | <div *ngIf="formErrors['new-confirmed-password']" class="form-error"> |
27 | {{ formErrors['new-confirmed-password'] }} | 30 | {{ formErrors['new-confirmed-password'] }} |
28 | </div> | 31 | </div> |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss index 381afae07..0d1f3094a 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss | |||
@@ -6,14 +6,14 @@ label { | |||
6 | font-size: 100%; | 6 | font-size: 100%; |
7 | } | 7 | } |
8 | 8 | ||
9 | input[type=password] { | 9 | my-input-toggle-hidden { |
10 | @include peertube-input-text(340px); | 10 | width: 340px; |
11 | display: block; | 11 | display: block; |
12 | } | ||
12 | 13 | ||
13 | &#new-password, | 14 | #new-password, |
14 | &#new-confirmed-password { | 15 | #new-confirmed-password { |
15 | margin-top: 15px; | 16 | margin-top: 15px; |
16 | } | ||
17 | } | 17 | } |
18 | 18 | ||
19 | input[type=submit] { | 19 | input[type=submit] { |
@@ -22,4 +22,3 @@ input[type=submit] { | |||
22 | 22 | ||
23 | margin-top: 15px; | 23 | margin-top: 15px; |
24 | } | 24 | } |
25 | |||
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts index ba68bab32..e034aedef 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts +++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { filter } from 'rxjs/operators' | 1 | import { filter } from 'rxjs/operators' |
2 | import { Component, OnInit } from '@angular/core' | 2 | import { Component, OnInit } from '@angular/core' |
3 | import { AuthService, Notifier, UserService } from '@app/core' | 3 | import { AuthService, Notifier, UserService } from '@app/core' |
4 | import { USER_CONFIRM_PASSWORD_VALIDATOR, USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators' | 4 | import { USER_CONFIRM_PASSWORD_VALIDATOR, USER_PASSWORD_VALIDATOR, USER_EXISTING_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators' |
5 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 5 | import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
6 | import { User } from '@shared/models' | 6 | import { User } from '@shared/models' |
7 | 7 | ||
@@ -25,7 +25,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On | |||
25 | 25 | ||
26 | ngOnInit () { | 26 | ngOnInit () { |
27 | this.buildForm({ | 27 | this.buildForm({ |
28 | 'current-password': USER_PASSWORD_VALIDATOR, | 28 | 'current-password': USER_EXISTING_PASSWORD_VALIDATOR, |
29 | 'new-password': USER_PASSWORD_VALIDATOR, | 29 | 'new-password': USER_PASSWORD_VALIDATOR, |
30 | 'new-confirmed-password': USER_CONFIRM_PASSWORD_VALIDATOR | 30 | 'new-confirmed-password': USER_CONFIRM_PASSWORD_VALIDATOR |
31 | }) | 31 | }) |
diff --git a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.scss b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.scss index fe78a57a4..d79ff690b 100644 --- a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.scss +++ b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.scss | |||
@@ -2,8 +2,6 @@ | |||
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | .delete-me { | 4 | .delete-me { |
5 | font-size: 15px; | ||
6 | |||
7 | button { | 5 | button { |
8 | @include peertube-button; | 6 | @include peertube-button; |
9 | @include danger-button; | 7 | @include danger-button; |
diff --git a/client/src/app/+reset-password/reset-password.component.html b/client/src/app/+reset-password/reset-password.component.html index af30af4a0..db9c74f89 100644 --- a/client/src/app/+reset-password/reset-password.component.html +++ b/client/src/app/+reset-password/reset-password.component.html | |||
@@ -6,10 +6,10 @@ | |||
6 | <form role="form" (ngSubmit)="resetPassword()" [formGroup]="form"> | 6 | <form role="form" (ngSubmit)="resetPassword()" [formGroup]="form"> |
7 | <div class="form-group"> | 7 | <div class="form-group"> |
8 | <label i18n for="password">Password</label> | 8 | <label i18n for="password">Password</label> |
9 | <input | 9 | <my-input-toggle-hidden formControlName="password" id="password" |
10 | type="password" name="password" id="password" i18n-placeholder placeholder="Password" required autocomplete="new-password" | 10 | i18n-placeholder placeholder="Password" |
11 | formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" | 11 | [ngClass]="{ 'input-error': formErrors['password'] }" |
12 | > | 12 | autocomplete="new-password"></my-input-toggle-hidden> |
13 | <div *ngIf="formErrors.password" class="form-error"> | 13 | <div *ngIf="formErrors.password" class="form-error"> |
14 | {{ formErrors.password }} | 14 | {{ formErrors.password }} |
15 | </div> | 15 | </div> |
@@ -17,10 +17,10 @@ | |||
17 | 17 | ||
18 | <div class="form-group"> | 18 | <div class="form-group"> |
19 | <label i18n for="password-confirm">Confirm password</label> | 19 | <label i18n for="password-confirm">Confirm password</label> |
20 | <input | 20 | <my-input-toggle-hidden formControlName="password-confirm" id="password-confirm" |
21 | type="password" name="password-confirm" id="password-confirm" i18n-placeholder placeholder="Confirmed password" required autocomplete="new-password" | 21 | i18n-placeholder placeholder="Confirmed password" |
22 | formControlName="password-confirm" [ngClass]="{ 'input-error': formErrors['password-confirm'] }" | 22 | [ngClass]="{ 'input-error': formErrors['password-confirm'] }" |
23 | > | 23 | autocomplete="new-password"></my-input-toggle-hidden> |
24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> | 24 | <div *ngIf="formErrors['password-confirm']" class="form-error"> |
25 | {{ formErrors['password-confirm'] }} | 25 | {{ formErrors['password-confirm'] }} |
26 | </div> | 26 | </div> |
diff --git a/client/src/app/+signup/+register/register-step-user.component.html b/client/src/app/+signup/+register/register-step-user.component.html index 55fc097d0..6eab4df0c 100644 --- a/client/src/app/+signup/+register/register-step-user.component.html +++ b/client/src/app/+signup/+register/register-step-user.component.html | |||
@@ -54,10 +54,10 @@ | |||
54 | 54 | ||
55 | <div class="form-group"> | 55 | <div class="form-group"> |
56 | <label for="password" i18n>Password</label> | 56 | <label for="password" i18n>Password</label> |
57 | <input | 57 | <my-input-toggle-hidden formControlName="password" id="password" |
58 | type="password" id="password" i18n-placeholder placeholder="Password" autocomplete="new-password" | 58 | i18n-placeholder placeholder="Password" |
59 | formControlName="password" class="form-control" [ngClass]="{ 'input-error': formErrors['password'] }" | 59 | [ngClass]="{ 'input-error': formErrors['password'] }" |
60 | > | 60 | autocomplete="new-password"></my-input-toggle-hidden> |
61 | <div *ngIf="formErrors.password" class="form-error"> | 61 | <div *ngIf="formErrors.password" class="form-error"> |
62 | {{ formErrors.password }} | 62 | {{ formErrors.password }} |
63 | </div> | 63 | </div> |
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 f62464d35..4747cec27 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 | |||
@@ -213,12 +213,12 @@ | |||
213 | 213 | ||
214 | <div class="form-group"> | 214 | <div class="form-group"> |
215 | <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> | 215 | <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> |
216 | <my-input-readonly-copy id="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl"></my-input-readonly-copy> | 216 | <my-input-toggle-hidden id="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
217 | </div> | 217 | </div> |
218 | 218 | ||
219 | <div class="form-group"> | 219 | <div class="form-group"> |
220 | <label for="liveVideoStreamKey" i18n>Live stream key</label> | 220 | <label for="liveVideoStreamKey" i18n>Live stream key</label> |
221 | <my-input-readonly-copy id="liveVideoStreamKey" [value]="liveVideo.streamKey"></my-input-readonly-copy> | 221 | <my-input-toggle-hidden id="liveVideoStreamKey" [value]="liveVideo.streamKey" [withCopy]="true" [readonly]="true"></my-input-toggle-hidden> |
222 | 222 | ||
223 | <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div> | 223 | <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div> |
224 | </div> | 224 | </div> |
diff --git a/client/src/app/shared/form-validators/user-validators.ts b/client/src/app/shared/form-validators/user-validators.ts index 9efc5180d..115930146 100644 --- a/client/src/app/shared/form-validators/user-validators.ts +++ b/client/src/app/shared/form-validators/user-validators.ts | |||
@@ -39,6 +39,15 @@ export const USER_EMAIL_VALIDATOR: BuildFormValidator = { | |||
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | export const USER_EXISTING_PASSWORD_VALIDATOR: BuildFormValidator = { | ||
43 | VALIDATORS: [ | ||
44 | Validators.required | ||
45 | ], | ||
46 | MESSAGES: { | ||
47 | 'required': $localize`Password is required.` | ||
48 | } | ||
49 | } | ||
50 | |||
42 | export const USER_PASSWORD_VALIDATOR: BuildFormValidator = { | 51 | export const USER_PASSWORD_VALIDATOR: BuildFormValidator = { |
43 | VALIDATORS: [ | 52 | VALIDATORS: [ |
44 | Validators.required, | 53 | Validators.required, |
diff --git a/client/src/app/shared/shared-forms/dynamic-form-field.component.html b/client/src/app/shared/shared-forms/dynamic-form-field.component.html index 6a3c31637..658d8ce5b 100644 --- a/client/src/app/shared/shared-forms/dynamic-form-field.component.html +++ b/client/src/app/shared/shared-forms/dynamic-form-field.component.html | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | <input *ngIf="setting.type === 'input'" type="text" [id]="setting.name" [formControlName]="setting.name" /> | 6 | <input *ngIf="setting.type === 'input'" type="text" [id]="setting.name" [formControlName]="setting.name" /> |
7 | 7 | ||
8 | <input *ngIf="setting.type === 'input-password'" type="password" [id]="setting.name" [formControlName]="setting.name" /> | 8 | <my-input-toggle-hidden *ngIf="setting.type === 'input-password'" [formControlName]="setting.name" [id]="setting.name"></my-input-toggle-hidden> |
9 | 9 | ||
10 | <textarea *ngIf="setting.type === 'input-textarea'" type="text" [id]="setting.name" [formControlName]="setting.name"></textarea> | 10 | <textarea *ngIf="setting.type === 'input-textarea'" type="text" [id]="setting.name" [formControlName]="setting.name"></textarea> |
11 | 11 | ||
diff --git a/client/src/app/shared/shared-forms/index.ts b/client/src/app/shared/shared-forms/index.ts index 66b426191..1d859b991 100644 --- a/client/src/app/shared/shared-forms/index.ts +++ b/client/src/app/shared/shared-forms/index.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | export * from './form-validator.service' | 1 | export * from './form-validator.service' |
2 | export * from './form-reactive' | 2 | export * from './form-reactive' |
3 | export * from './select' | 3 | export * from './select' |
4 | export * from './input-readonly-copy.component' | 4 | export * from './input-toggle-hidden.component' |
5 | export * from './input-switch.component' | 5 | export * from './input-switch.component' |
6 | export * from './markdown-textarea.component' | 6 | export * from './markdown-textarea.component' |
7 | export * from './peertube-checkbox.component' | 7 | export * from './peertube-checkbox.component' |
diff --git a/client/src/app/shared/shared-forms/input-readonly-copy.component.html b/client/src/app/shared/shared-forms/input-readonly-copy.component.html deleted file mode 100644 index 7a75bd70b..000000000 --- a/client/src/app/shared/shared-forms/input-readonly-copy.component.html +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | <div class="input-group input-group-sm"> | ||
2 | <input [id]="id" #urlInput (click)="urlInput.select()" type="text" class="form-control readonly" readonly [value]="value" /> | ||
3 | |||
4 | <div class="input-group-append"> | ||
5 | <button [cdkCopyToClipboard]="urlInput.value" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary"> | ||
6 | <span class="glyphicon glyphicon-copy"></span> | ||
7 | </button> | ||
8 | </div> | ||
9 | </div> | ||
diff --git a/client/src/app/shared/shared-forms/input-readonly-copy.component.scss b/client/src/app/shared/shared-forms/input-readonly-copy.component.scss deleted file mode 100644 index 8dc4f113c..000000000 --- a/client/src/app/shared/shared-forms/input-readonly-copy.component.scss +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | input.readonly { | ||
2 | font-size: 15px; | ||
3 | } | ||
diff --git a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts b/client/src/app/shared/shared-forms/input-readonly-copy.component.ts deleted file mode 100644 index b04d69d05..000000000 --- a/client/src/app/shared/shared-forms/input-readonly-copy.component.ts +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { Notifier } from '@app/core' | ||
3 | |||
4 | @Component({ | ||
5 | selector: 'my-input-readonly-copy', | ||
6 | templateUrl: './input-readonly-copy.component.html', | ||
7 | styleUrls: [ './input-readonly-copy.component.scss' ] | ||
8 | }) | ||
9 | export class InputReadonlyCopyComponent { | ||
10 | @Input() id: string | ||
11 | @Input() value = '' | ||
12 | |||
13 | constructor (private notifier: Notifier) { } | ||
14 | |||
15 | activateCopiedMessage () { | ||
16 | this.notifier.success($localize`Copied`) | ||
17 | } | ||
18 | } | ||
diff --git a/client/src/app/shared/shared-forms/input-toggle-hidden.component.html b/client/src/app/shared/shared-forms/input-toggle-hidden.component.html new file mode 100644 index 000000000..f59dc6215 --- /dev/null +++ b/client/src/app/shared/shared-forms/input-toggle-hidden.component.html | |||
@@ -0,0 +1,13 @@ | |||
1 | <div class="input-group input-group-sm"> | ||
2 | <input [id]="id" [autocomplete]="autocomplete" [value]="value" [placeholder]="placeholder" [(ngModel)]="value" (ngModelChange)="update()" [ngClass]="{ 'readonly': readonly }" [readonly]="readonly" | ||
3 | #input (click)="input.select()" (input)="update()" (change)="update()" [type]="inputType" class="form-control" /> | ||
4 | |||
5 | <div *ngIf="withToggle || withCopy" class="input-group-append"> | ||
6 | <button *ngIf="withToggle" (click)="toggle()" type="button" class="btn btn-outline-secondary" [title]="toggleTitle"> | ||
7 | <span class="glyphicon glyphicon-eye-{{ show ? 'open' : 'close' }}"></span> | ||
8 | </button> | ||
9 | <button *ngIf="withCopy" [cdkCopyToClipboard]="input.value" (click)="activateCopiedMessage()" type="button" class="btn btn-outline-secondary" i18n-title title="Copy"> | ||
10 | <span class="glyphicon glyphicon-copy"></span> | ||
11 | </button> | ||
12 | </div> | ||
13 | </div> | ||
diff --git a/client/src/app/shared/shared-forms/input-toggle-hidden.component.scss b/client/src/app/shared/shared-forms/input-toggle-hidden.component.scss new file mode 100644 index 000000000..e20f69b86 --- /dev/null +++ b/client/src/app/shared/shared-forms/input-toggle-hidden.component.scss | |||
@@ -0,0 +1,11 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | input { | ||
5 | @include peertube-input-text(auto); | ||
6 | |||
7 | // set again properties of peertube-input-text that are overriden by .input-group | ||
8 | font-size: 15px !important; | ||
9 | padding-left: 15px !important; | ||
10 | padding-right: 15px !important; | ||
11 | } | ||
diff --git a/client/src/app/shared/shared-forms/input-toggle-hidden.component.ts b/client/src/app/shared/shared-forms/input-toggle-hidden.component.ts new file mode 100644 index 000000000..0e974426b --- /dev/null +++ b/client/src/app/shared/shared-forms/input-toggle-hidden.component.ts | |||
@@ -0,0 +1,66 @@ | |||
1 | import { Component, forwardRef, Input } from '@angular/core' | ||
2 | import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms' | ||
3 | import { Notifier } from '@app/core' | ||
4 | |||
5 | @Component({ | ||
6 | selector: 'my-input-toggle-hidden', | ||
7 | templateUrl: './input-toggle-hidden.component.html', | ||
8 | styleUrls: [ './input-toggle-hidden.component.scss' ], | ||
9 | providers: [ | ||
10 | { | ||
11 | provide: NG_VALUE_ACCESSOR, | ||
12 | useExisting: forwardRef(() => InputToggleHiddenComponent), | ||
13 | multi: true | ||
14 | } | ||
15 | ] | ||
16 | }) | ||
17 | export class InputToggleHiddenComponent implements ControlValueAccessor { | ||
18 | @Input() id = Math.random().toString(11).slice(2, 8) // id cannot be left empty or undefined | ||
19 | @Input() value = '' | ||
20 | @Input() autocomplete = 'off' | ||
21 | @Input() placeholder = '' | ||
22 | @Input() withToggle = true | ||
23 | @Input() withCopy = false | ||
24 | @Input() readonly = false | ||
25 | @Input() show = false | ||
26 | |||
27 | constructor (private notifier: Notifier) { } | ||
28 | |||
29 | get inputType () { | ||
30 | return this.show | ||
31 | ? 'text' | ||
32 | : 'password' | ||
33 | } | ||
34 | |||
35 | get toggleTitle () { | ||
36 | return this.show | ||
37 | ? $localize`Hide` | ||
38 | : $localize`Show` | ||
39 | } | ||
40 | |||
41 | toggle () { | ||
42 | this.show = !this.show | ||
43 | } | ||
44 | |||
45 | activateCopiedMessage () { | ||
46 | this.notifier.success($localize`Copied`) | ||
47 | } | ||
48 | |||
49 | propagateChange = (_: any) => { /* empty */ } | ||
50 | |||
51 | writeValue (value: string) { | ||
52 | this.value = value | ||
53 | } | ||
54 | |||
55 | registerOnChange (fn: (_: any) => void) { | ||
56 | this.propagateChange = fn | ||
57 | } | ||
58 | |||
59 | registerOnTouched () { | ||
60 | // Unused | ||
61 | } | ||
62 | |||
63 | update () { | ||
64 | this.propagateChange(this.value) | ||
65 | } | ||
66 | } | ||
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 060abc995..22e8dd05a 100644 --- a/client/src/app/shared/shared-forms/shared-form.module.ts +++ b/client/src/app/shared/shared-forms/shared-form.module.ts | |||
@@ -7,7 +7,7 @@ import { SharedGlobalIconModule } from '../shared-icons' | |||
7 | import { SharedMainModule } from '../shared-main/shared-main.module' | 7 | import { SharedMainModule } from '../shared-main/shared-main.module' |
8 | import { DynamicFormFieldComponent } from './dynamic-form-field.component' | 8 | import { DynamicFormFieldComponent } from './dynamic-form-field.component' |
9 | import { FormValidatorService } from './form-validator.service' | 9 | import { FormValidatorService } from './form-validator.service' |
10 | import { InputReadonlyCopyComponent } from './input-readonly-copy.component' | 10 | import { InputToggleHiddenComponent } from './input-toggle-hidden.component' |
11 | import { InputSwitchComponent } from './input-switch.component' | 11 | import { InputSwitchComponent } from './input-switch.component' |
12 | import { MarkdownTextareaComponent } from './markdown-textarea.component' | 12 | import { MarkdownTextareaComponent } from './markdown-textarea.component' |
13 | import { PeertubeCheckboxComponent } from './peertube-checkbox.component' | 13 | import { PeertubeCheckboxComponent } from './peertube-checkbox.component' |
@@ -30,7 +30,7 @@ import { TimestampInputComponent } from './timestamp-input.component' | |||
30 | ], | 30 | ], |
31 | 31 | ||
32 | declarations: [ | 32 | declarations: [ |
33 | InputReadonlyCopyComponent, | 33 | InputToggleHiddenComponent, |
34 | MarkdownTextareaComponent, | 34 | MarkdownTextareaComponent, |
35 | PeertubeCheckboxComponent, | 35 | PeertubeCheckboxComponent, |
36 | PreviewUploadComponent, | 36 | PreviewUploadComponent, |
@@ -55,7 +55,7 @@ import { TimestampInputComponent } from './timestamp-input.component' | |||
55 | InputMaskModule, | 55 | InputMaskModule, |
56 | NgSelectModule, | 56 | NgSelectModule, |
57 | 57 | ||
58 | InputReadonlyCopyComponent, | 58 | InputToggleHiddenComponent, |
59 | MarkdownTextareaComponent, | 59 | MarkdownTextareaComponent, |
60 | PeertubeCheckboxComponent, | 60 | PeertubeCheckboxComponent, |
61 | PreviewUploadComponent, | 61 | PreviewUploadComponent, |
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.html b/client/src/app/shared/shared-share-modal/video-share.component.html index 80b4e446a..bcb1db4c4 100644 --- a/client/src/app/shared/shared-share-modal/video-share.component.html +++ b/client/src/app/shared/shared-share-modal/video-share.component.html | |||
@@ -18,7 +18,7 @@ | |||
18 | <ng-template ngbNavContent> | 18 | <ng-template ngbNavContent> |
19 | <div class="nav-content"> | 19 | <div class="nav-content"> |
20 | 20 | ||
21 | <my-input-readonly-copy [value]="getPlaylistUrl()"></my-input-readonly-copy> | 21 | <my-input-toggle-hidden [value]="getPlaylistUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
22 | </div> | 22 | </div> |
23 | </ng-template> | 23 | </ng-template> |
24 | </ng-container> | 24 | </ng-container> |
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | <ng-template ngbNavContent> | 39 | <ng-template ngbNavContent> |
40 | <div class="nav-content"> | 40 | <div class="nav-content"> |
41 | <my-input-readonly-copy [value]="getPlaylistIframeCode()"></my-input-readonly-copy> | 41 | <my-input-toggle-hidden [value]="getPlaylistIframeCode()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
42 | 42 | ||
43 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> | 43 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> |
44 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). | 44 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). |
@@ -72,7 +72,7 @@ | |||
72 | 72 | ||
73 | <ng-template ngbNavContent> | 73 | <ng-template ngbNavContent> |
74 | <div class="nav-content"> | 74 | <div class="nav-content"> |
75 | <my-input-readonly-copy [value]="getVideoUrl()"></my-input-readonly-copy> | 75 | <my-input-toggle-hidden [value]="getVideoUrl()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
76 | </div> | 76 | </div> |
77 | </ng-template> | 77 | </ng-template> |
78 | </ng-container> | 78 | </ng-container> |
@@ -92,7 +92,7 @@ | |||
92 | 92 | ||
93 | <ng-template ngbNavContent> | 93 | <ng-template ngbNavContent> |
94 | <div class="nav-content"> | 94 | <div class="nav-content"> |
95 | <my-input-readonly-copy [value]="getVideoIframeCode()"></my-input-readonly-copy> | 95 | <my-input-toggle-hidden [value]="getVideoIframeCode()" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
96 | 96 | ||
97 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> | 97 | <div i18n *ngIf="notSecure()" class="alert alert-warning"> |
98 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). | 98 | The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites). |
diff --git a/client/src/app/shared/shared-share-modal/video-share.component.scss b/client/src/app/shared/shared-share-modal/video-share.component.scss index 091d4dc3b..e4d3aacff 100644 --- a/client/src/app/shared/shared-share-modal/video-share.component.scss +++ b/client/src/app/shared/shared-share-modal/video-share.component.scss | |||
@@ -1,7 +1,7 @@ | |||
1 | @import '_mixins'; | 1 | @import '_mixins'; |
2 | @import '_variables'; | 2 | @import '_variables'; |
3 | 3 | ||
4 | my-input-readonly-copy { | 4 | my-input-toggle-hidden { |
5 | width: 100%; | 5 | width: 100%; |
6 | } | 6 | } |
7 | 7 | ||
diff --git a/client/src/app/shared/shared-video-live/live-stream-information.component.html b/client/src/app/shared/shared-video-live/live-stream-information.component.html index 6693c1af2..8d9467fe5 100644 --- a/client/src/app/shared/shared-video-live/live-stream-information.component.html +++ b/client/src/app/shared/shared-video-live/live-stream-information.component.html | |||
@@ -13,12 +13,12 @@ | |||
13 | 13 | ||
14 | <div class="form-group"> | 14 | <div class="form-group"> |
15 | <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> | 15 | <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> |
16 | <my-input-readonly-copy id="liveVideoRTMPUrl" [value]="live.rtmpUrl"></my-input-readonly-copy> | 16 | <my-input-toggle-hidden id="liveVideoRTMPUrl" [value]="live.rtmpUrl" [withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"></my-input-toggle-hidden> |
17 | </div> | 17 | </div> |
18 | 18 | ||
19 | <div class="form-group"> | 19 | <div class="form-group"> |
20 | <label for="liveVideoStreamKey" i18n>Live stream key</label> | 20 | <label for="liveVideoStreamKey" i18n>Live stream key</label> |
21 | <my-input-readonly-copy id="liveVideoStreamKey" [value]="live.streamKey"></my-input-readonly-copy> | 21 | <my-input-toggle-hidden id="liveVideoStreamKey" [value]="live.streamKey" [withCopy]="true" [readonly]="true"></my-input-toggle-hidden> |
22 | 22 | ||
23 | <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div> | 23 | <div class="form-group-description" i18n>⚠️ Never share your stream key with anyone.</div> |
24 | </div> | 24 | </div> |
diff --git a/client/src/sass/application.scss b/client/src/sass/application.scss index ece8411af..3f6e6c8a7 100644 --- a/client/src/sass/application.scss +++ b/client/src/sass/application.scss | |||
@@ -120,7 +120,8 @@ code { | |||
120 | margin-top: 5px; | 120 | margin-top: 5px; |
121 | } | 121 | } |
122 | 122 | ||
123 | .input-error { | 123 | .input-error |
124 | my-input-toggle-hidden ::ng-deep input { | ||
124 | border-color: $red !important; | 125 | border-color: $red !important; |
125 | } | 126 | } |
126 | 127 | ||