aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--client/src/app/shared/misc/help.component.ts30
-rw-r--r--client/src/app/shared/misc/utils.ts5
-rw-r--r--client/src/app/signup/signup.component.html14
-rw-r--r--client/src/app/signup/signup.component.scss14
-rw-r--r--client/src/app/signup/signup.component.ts57
5 files changed, 93 insertions, 27 deletions
diff --git a/client/src/app/shared/misc/help.component.ts b/client/src/app/shared/misc/help.component.ts
index 19ac38b58..89dd1dae5 100644
--- a/client/src/app/shared/misc/help.component.ts
+++ b/client/src/app/shared/misc/help.component.ts
@@ -1,4 +1,4 @@
1import { Component, ElementRef, HostListener, Input, OnInit, ViewChild } from '@angular/core' 1import { Component, ElementRef, HostListener, Input, OnInit, ViewChild, OnChanges } from '@angular/core'
2import { MarkdownService } from '@app/videos/shared' 2import { MarkdownService } from '@app/videos/shared'
3import { TooltipDirective } from 'ngx-bootstrap/tooltip' 3import { TooltipDirective } from 'ngx-bootstrap/tooltip'
4 4
@@ -8,7 +8,7 @@ import { TooltipDirective } from 'ngx-bootstrap/tooltip'
8 templateUrl: './help.component.html' 8 templateUrl: './help.component.html'
9}) 9})
10 10
11export class HelpComponent implements OnInit { 11export class HelpComponent implements OnInit, OnChanges {
12 @ViewChild('tooltipDirective') tooltipDirective: TooltipDirective 12 @ViewChild('tooltipDirective') tooltipDirective: TooltipDirective
13 @Input() preHtml = '' 13 @Input() preHtml = ''
14 @Input() postHtml = '' 14 @Input() postHtml = ''
@@ -20,6 +20,23 @@ export class HelpComponent implements OnInit {
20 constructor (private elementRef: ElementRef) { } 20 constructor (private elementRef: ElementRef) { }
21 21
22 ngOnInit () { 22 ngOnInit () {
23 this.init()
24 }
25
26 ngOnChanges () {
27 this.init()
28 }
29
30 @HostListener('document:click', ['$event.target'])
31 public onClick (targetElement) {
32 const clickedInside = this.elementRef.nativeElement.contains(targetElement)
33
34 if (this.tooltipDirective.isOpen && !clickedInside) {
35 this.tooltipDirective.hide()
36 }
37 }
38
39 private init () {
23 if (this.helpType === 'custom') { 40 if (this.helpType === 'custom') {
24 this.mainHtml = this.customHtml 41 this.mainHtml = this.customHtml
25 return 42 return
@@ -36,15 +53,6 @@ export class HelpComponent implements OnInit {
36 } 53 }
37 } 54 }
38 55
39 @HostListener('document:click', ['$event.target'])
40 public onClick (targetElement) {
41 const clickedInside = this.elementRef.nativeElement.contains(targetElement)
42
43 if (this.tooltipDirective.isOpen && !clickedInside) {
44 this.tooltipDirective.hide()
45 }
46 }
47
48 private formatMarkdownSupport (rules: string[]) { 56 private formatMarkdownSupport (rules: string[]) {
49 return '<a href="https://en.wikipedia.org/wiki/Markdown#Example" target="_blank" rel="noopener noreferrer">Markdown</a> ' + 57 return '<a href="https://en.wikipedia.org/wiki/Markdown#Example" target="_blank" rel="noopener noreferrer">Markdown</a> ' +
50 'compatible that supports:' + 58 'compatible that supports:' +
diff --git a/client/src/app/shared/misc/utils.ts b/client/src/app/shared/misc/utils.ts
index d520b1a7b..99f6b3cf0 100644
--- a/client/src/app/shared/misc/utils.ts
+++ b/client/src/app/shared/misc/utils.ts
@@ -17,10 +17,6 @@ function getParameterByName (name: string, url: string) {
17 return decodeURIComponent(results[2].replace(/\+/g, ' ')) 17 return decodeURIComponent(results[2].replace(/\+/g, ' '))
18} 18}
19 19
20function viewportHeight () {
21 return Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
22}
23
24function populateAsyncUserVideoChannels (authService: AuthService, channel: any[]) { 20function populateAsyncUserVideoChannels (authService: AuthService, channel: any[]) {
25 return new Promise(res => { 21 return new Promise(res => {
26 authService.userInformationLoaded 22 authService.userInformationLoaded
@@ -99,7 +95,6 @@ function isInMobileView () {
99} 95}
100 96
101export { 97export {
102 viewportHeight,
103 getParameterByName, 98 getParameterByName,
104 populateAsyncUserVideoChannels, 99 populateAsyncUserVideoChannels,
105 getAbsoluteAPIUrl, 100 getAbsoluteAPIUrl,
diff --git a/client/src/app/signup/signup.component.html b/client/src/app/signup/signup.component.html
index f95897ea4..5f48786e5 100644
--- a/client/src/app/signup/signup.component.html
+++ b/client/src/app/signup/signup.component.html
@@ -4,6 +4,20 @@
4 Create an account 4 Create an account
5 </div> 5 </div>
6 6
7 <div class="initial-user-quota">
8 <span class="initial-user-quota-label">Initial video quota:</span>
9
10 <span *ngIf="initialUserVideoQuota !== -1">
11 {{ initialUserVideoQuota | bytes: 0 }}
12
13 <my-help helpType="custom" [customHtml]="quotaHelpIndication"></my-help>
14 </span>
15
16 <ng-template [ngIf]="initialUserVideoQuota === -1">
17 Unlimited
18 </ng-template>
19 </div>
20
7 <div *ngIf="error" class="alert alert-danger">{{ error }}</div> 21 <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
8 22
9 <form role="form" (ngSubmit)="signup()" [formGroup]="form"> 23 <form role="form" (ngSubmit)="signup()" [formGroup]="form">
diff --git a/client/src/app/signup/signup.component.scss b/client/src/app/signup/signup.component.scss
index efec6b706..6efb95ea6 100644
--- a/client/src/app/signup/signup.component.scss
+++ b/client/src/app/signup/signup.component.scss
@@ -1,6 +1,20 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.initial-user-quota {
5 font-size: 15px;
6 margin-bottom: 20px;
7
8 .initial-user-quota-label {
9 font-weight: $font-semibold;
10 }
11
12 my-help {
13 margin-left: 5px;
14 }
15}
16
17
4input:not([type=submit]) { 18input:not([type=submit]) {
5 @include peertube-input-text(340px); 19 @include peertube-input-text(340px);
6 display: block; 20 display: block;
diff --git a/client/src/app/signup/signup.component.ts b/client/src/app/signup/signup.component.ts
index 13390a32a..93d73a11e 100644
--- a/client/src/app/signup/signup.component.ts
+++ b/client/src/app/signup/signup.component.ts
@@ -1,18 +1,11 @@
1import { Component, OnInit } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { FormBuilder, FormGroup, Validators } from '@angular/forms' 2import { FormBuilder, FormGroup } from '@angular/forms'
3import { Router } from '@angular/router' 3import { Router } from '@angular/router'
4import { ServerService } from '@app/core/server'
4 5
5import { NotificationsService } from 'angular2-notifications' 6import { NotificationsService } from 'angular2-notifications'
6
7import { AuthService } from '../core'
8import {
9 FormReactive,
10 UserService,
11 USER_USERNAME,
12 USER_EMAIL,
13 USER_PASSWORD
14} from '../shared'
15import { UserCreate } from '../../../../shared' 7import { UserCreate } from '../../../../shared'
8import { FormReactive, USER_EMAIL, USER_PASSWORD, USER_USERNAME, UserService } from '../shared'
16 9
17@Component({ 10@Component({
18 selector: 'my-signup', 11 selector: 'my-signup',
@@ -21,6 +14,7 @@ import { UserCreate } from '../../../../shared'
21}) 14})
22export class SignupComponent extends FormReactive implements OnInit { 15export class SignupComponent extends FormReactive implements OnInit {
23 error: string = null 16 error: string = null
17 quotaHelpIndication = ''
24 18
25 form: FormGroup 19 form: FormGroup
26 formErrors = { 20 formErrors = {
@@ -34,15 +28,32 @@ export class SignupComponent extends FormReactive implements OnInit {
34 'password': USER_PASSWORD.MESSAGES 28 'password': USER_PASSWORD.MESSAGES
35 } 29 }
36 30
31 private static getApproximateTime (seconds: number) {
32 const hours = Math.floor(seconds / 3600)
33 let pluralSuffix = ''
34 if (hours > 1) pluralSuffix = 's'
35 if (hours > 0) return `~ ${hours} hour${pluralSuffix}`
36
37 const minutes = Math.floor(seconds % 3600 / 60)
38 if (minutes > 1) pluralSuffix = 's'
39
40 return `~ ${minutes} minute${pluralSuffix}`
41 }
42
37 constructor ( 43 constructor (
38 private formBuilder: FormBuilder, 44 private formBuilder: FormBuilder,
39 private router: Router, 45 private router: Router,
40 private notificationsService: NotificationsService, 46 private notificationsService: NotificationsService,
41 private userService: UserService 47 private userService: UserService,
48 private serverService: ServerService
42 ) { 49 ) {
43 super() 50 super()
44 } 51 }
45 52
53 get initialUserVideoQuota () {
54 return this.serverService.getConfig().user.videoQuota
55 }
56
46 buildForm () { 57 buildForm () {
47 this.form = this.formBuilder.group({ 58 this.form = this.formBuilder.group({
48 username: [ '', USER_USERNAME.VALIDATORS ], 59 username: [ '', USER_USERNAME.VALIDATORS ],
@@ -55,6 +66,9 @@ export class SignupComponent extends FormReactive implements OnInit {
55 66
56 ngOnInit () { 67 ngOnInit () {
57 this.buildForm() 68 this.buildForm()
69
70 this.serverService.configLoaded
71 .subscribe(() => this.buildQuotaHelpIndication())
58 } 72 }
59 73
60 signup () { 74 signup () {
@@ -71,4 +85,25 @@ export class SignupComponent extends FormReactive implements OnInit {
71 err => this.error = err.message 85 err => this.error = err.message
72 ) 86 )
73 } 87 }
88
89 private buildQuotaHelpIndication () {
90 if (this.initialUserVideoQuota === -1) return
91
92 const initialUserVideoQuotaBit = this.initialUserVideoQuota * 8
93
94 // 1080p: ~ 6Mbps
95 // 720p: ~ 4Mbps
96 // 360p: ~ 1.5Mbps
97 const fullHdSeconds = initialUserVideoQuotaBit / (6 * 1000 * 1000)
98 const hdSeconds = initialUserVideoQuotaBit / (4 * 1000 * 1000)
99 const normalSeconds = initialUserVideoQuotaBit / (1.5 * 1000 * 1000)
100
101 const lines = [
102 SignupComponent.getApproximateTime(fullHdSeconds) + ' of full HD videos',
103 SignupComponent.getApproximateTime(hdSeconds) + ' of HD videos',
104 SignupComponent.getApproximateTime(normalSeconds) + ' of normal quality videos'
105 ]
106
107 this.quotaHelpIndication = lines.join('<br />')
108 }
74} 109}