aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.component.html7
-rw-r--r--client/src/app/+login/login.component.html8
-rw-r--r--client/src/app/+my-account/my-account-applications/my-account-applications.component.html8
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.html13
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.scss11
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.html27
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.scss13
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts4
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.scss2
-rw-r--r--client/src/app/+reset-password/reset-password.component.html16
-rw-r--r--client/src/app/+signup/+register/register-step-user.component.html8
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-edit.component.html4
-rw-r--r--client/src/app/shared/form-validators/user-validators.ts9
-rw-r--r--client/src/app/shared/shared-forms/dynamic-form-field.component.html2
-rw-r--r--client/src/app/shared/shared-forms/index.ts2
-rw-r--r--client/src/app/shared/shared-forms/input-readonly-copy.component.html9
-rw-r--r--client/src/app/shared/shared-forms/input-readonly-copy.component.scss3
-rw-r--r--client/src/app/shared/shared-forms/input-readonly-copy.component.ts18
-rw-r--r--client/src/app/shared/shared-forms/input-toggle-hidden.component.html13
-rw-r--r--client/src/app/shared/shared-forms/input-toggle-hidden.component.scss11
-rw-r--r--client/src/app/shared/shared-forms/input-toggle-hidden.component.ts66
-rw-r--r--client/src/app/shared/shared-forms/shared-form.module.ts6
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.html8
-rw-r--r--client/src/app/shared/shared-share-modal/video-share.component.scss2
-rw-r--r--client/src/app/shared/shared-video-live/live-stream-information.component.html4
-rw-r--r--client/src/sass/application.scss3
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
9input[type=password], 9my-input-toggle-hidden {
10 width: 340px;
11 display: block;
12}
13
10input[type=email] { 14input[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
9input[type=password] { 9my-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
19input[type=submit] { 19input[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 @@
1import { filter } from 'rxjs/operators' 1import { filter } from 'rxjs/operators'
2import { Component, OnInit } from '@angular/core' 2import { Component, OnInit } from '@angular/core'
3import { AuthService, Notifier, UserService } from '@app/core' 3import { AuthService, Notifier, UserService } from '@app/core'
4import { USER_CONFIRM_PASSWORD_VALIDATOR, USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators' 4import { USER_CONFIRM_PASSWORD_VALIDATOR, USER_PASSWORD_VALIDATOR, USER_EXISTING_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators'
5import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' 5import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
6import { User } from '@shared/models' 6import { 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
42export const USER_EXISTING_PASSWORD_VALIDATOR: BuildFormValidator = {
43 VALIDATORS: [
44 Validators.required
45 ],
46 MESSAGES: {
47 'required': $localize`Password is required.`
48 }
49}
50
42export const USER_PASSWORD_VALIDATOR: BuildFormValidator = { 51export 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 @@
1export * from './form-validator.service' 1export * from './form-validator.service'
2export * from './form-reactive' 2export * from './form-reactive'
3export * from './select' 3export * from './select'
4export * from './input-readonly-copy.component' 4export * from './input-toggle-hidden.component'
5export * from './input-switch.component' 5export * from './input-switch.component'
6export * from './markdown-textarea.component' 6export * from './markdown-textarea.component'
7export * from './peertube-checkbox.component' 7export * 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 @@
1input.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 @@
1import { Component, Input } from '@angular/core'
2import { 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})
9export 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
4input {
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 @@
1import { Component, forwardRef, Input } from '@angular/core'
2import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
3import { 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})
17export 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'
7import { SharedMainModule } from '../shared-main/shared-main.module' 7import { SharedMainModule } from '../shared-main/shared-main.module'
8import { DynamicFormFieldComponent } from './dynamic-form-field.component' 8import { DynamicFormFieldComponent } from './dynamic-form-field.component'
9import { FormValidatorService } from './form-validator.service' 9import { FormValidatorService } from './form-validator.service'
10import { InputReadonlyCopyComponent } from './input-readonly-copy.component' 10import { InputToggleHiddenComponent } from './input-toggle-hidden.component'
11import { InputSwitchComponent } from './input-switch.component' 11import { InputSwitchComponent } from './input-switch.component'
12import { MarkdownTextareaComponent } from './markdown-textarea.component' 12import { MarkdownTextareaComponent } from './markdown-textarea.component'
13import { PeertubeCheckboxComponent } from './peertube-checkbox.component' 13import { 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
4my-input-readonly-copy { 4my-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
124my-input-toggle-hidden ::ng-deep input {
124 border-color: $red !important; 125 border-color: $red !important;
125} 126}
126 127