diff options
author | Chocobozzz <me@florianbigard.com> | 2018-03-28 17:05:46 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-03-28 17:05:46 +0200 |
commit | 5afdd0a52f2f1fa79ed9bf241b5a525366658fa1 (patch) | |
tree | 58bc17102b26893530ca64e757c2389361a36473 /client/src/app | |
parent | e33e7fc89e4f0e2fbd1d7e87a4e2a2d5aae94f29 (diff) | |
download | PeerTube-5afdd0a52f2f1fa79ed9bf241b5a525366658fa1.tar.gz PeerTube-5afdd0a52f2f1fa79ed9bf241b5a525366658fa1.tar.zst PeerTube-5afdd0a52f2f1fa79ed9bf241b5a525366658fa1.zip |
Add initial video quota info in registration form
Diffstat (limited to 'client/src/app')
-rw-r--r-- | client/src/app/shared/misc/help.component.ts | 30 | ||||
-rw-r--r-- | client/src/app/shared/misc/utils.ts | 5 | ||||
-rw-r--r-- | client/src/app/signup/signup.component.html | 14 | ||||
-rw-r--r-- | client/src/app/signup/signup.component.scss | 14 | ||||
-rw-r--r-- | client/src/app/signup/signup.component.ts | 57 |
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 @@ | |||
1 | import { Component, ElementRef, HostListener, Input, OnInit, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, HostListener, Input, OnInit, ViewChild, OnChanges } from '@angular/core' |
2 | import { MarkdownService } from '@app/videos/shared' | 2 | import { MarkdownService } from '@app/videos/shared' |
3 | import { TooltipDirective } from 'ngx-bootstrap/tooltip' | 3 | import { 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 | ||
11 | export class HelpComponent implements OnInit { | 11 | export 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 | ||
20 | function viewportHeight () { | ||
21 | return Math.max(document.documentElement.clientHeight, window.innerHeight || 0) | ||
22 | } | ||
23 | |||
24 | function populateAsyncUserVideoChannels (authService: AuthService, channel: any[]) { | 20 | function 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 | ||
101 | export { | 97 | export { |
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 | |||
4 | input:not([type=submit]) { | 18 | input: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 @@ | |||
1 | import { Component, OnInit } from '@angular/core' | 1 | import { Component, OnInit } from '@angular/core' |
2 | import { FormBuilder, FormGroup, Validators } from '@angular/forms' | 2 | import { FormBuilder, FormGroup } from '@angular/forms' |
3 | import { Router } from '@angular/router' | 3 | import { Router } from '@angular/router' |
4 | import { ServerService } from '@app/core/server' | ||
4 | 5 | ||
5 | import { NotificationsService } from 'angular2-notifications' | 6 | import { NotificationsService } from 'angular2-notifications' |
6 | |||
7 | import { AuthService } from '../core' | ||
8 | import { | ||
9 | FormReactive, | ||
10 | UserService, | ||
11 | USER_USERNAME, | ||
12 | USER_EMAIL, | ||
13 | USER_PASSWORD | ||
14 | } from '../shared' | ||
15 | import { UserCreate } from '../../../../shared' | 7 | import { UserCreate } from '../../../../shared' |
8 | import { 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 | }) |
22 | export class SignupComponent extends FormReactive implements OnInit { | 15 | export 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 | } |