Skip to content

Commit

Permalink
Display user quota progress bars above upload form (#2981)
Browse files Browse the repository at this point in the history
* Move user-quota to my-user-quota shared component

* Add user-quota to upload form

* Increase progress bar height and make it focusable

* Correct syntax parenthesis

* Add explicit title to user-quota bars + tooltip with quota values

* Hide user-quota in second upload step

* Customize focus styles on user-quota

Co-authored-by: kimsible <[email protected]>
  • Loading branch information
kimsible and kimsible authored Jul 24, 2020
1 parent b40a219 commit 2e7f262
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,7 @@ <h2 i18n class="account-title">PROFILE SETTINGS</h2>

<div class="form-group form-group-right col-12 col-lg-8 col-xl-9">

<div class="user-quota mb-3">
<div>
<div class="progress" i18n-title title="Total video quota">
<div class="progress-bar" role="progressbar" [style]="{ width: userVideoQuotaPercentage + '%' }" [attr.aria-valuenow]="userVideoQuotaUsed" aria-valuemin="0" [attr.aria-valuemax]="user.videoQuota">{{ userVideoQuotaUsed | bytes: 0 }}</div>
<span class="ml-auto mr-2">{{ userVideoQuota }}</span>
</div>
</div>

<div *ngIf="hasDailyQuota()" class="mt-3">
<div class="progress" i18n-title title="Daily video quota">
<div class="progress-bar secondary" role="progressbar" [style]="{ width: userVideoQuotaDailyPercentage + '%' }" [attr.aria-valuenow]="userVideoQuotaUsedDaily" aria-valuemin="0" [attr.aria-valuemax]="user.videoQuotaDaily">{{ userVideoQuotaUsedDaily | bytes: 0 }}</div>
<span class="ml-auto mr-2">{{ userVideoQuotaDaily }}</span>
</div>
</div>
</div>
<my-user-quota [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-quota>

<my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
@import '_variables';
@import '_mixins';

.user-quota {
font-size: 15px;
margin-top: 20px;

label {
margin-right: 5px;
}
}

.account-title {
@include settings-big-title;

Expand All @@ -18,14 +9,6 @@
}
}

.progress {
@include progressbar;
width: 500px;
max-width: 100%;
}

@media screen and (max-width: $small-view) {
.progress {
width: 100%;
}
.form-group {
max-width: 500px;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BytesPipe } from 'ngx-pipes'
import { ViewportScroller } from '@angular/common'
import { AfterViewChecked, Component, OnInit } from '@angular/core'
import { AuthService, Notifier, User, UserService } from '@app/core'
Expand All @@ -12,14 +11,6 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
export class MyAccountSettingsComponent implements OnInit, AfterViewChecked {
user: User = null

userVideoQuota = '0'
userVideoQuotaUsed = 0
userVideoQuotaPercentage = 15

userVideoQuotaDaily = '0'
userVideoQuotaUsedDaily = 0
userVideoQuotaDailyPercentage = 15

private lastScrollHash: string

constructor (
Expand All @@ -36,31 +27,6 @@ export class MyAccountSettingsComponent implements OnInit, AfterViewChecked {

ngOnInit () {
this.user = this.authService.getUser()

this.authService.userInformationLoaded.subscribe(
() => {
if (this.user.videoQuota !== -1) {
this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString()
} else {
this.userVideoQuota = this.i18n('Unlimited')
}

if (this.user.videoQuotaDaily !== -1) {
this.userVideoQuotaDaily = new BytesPipe().transform(this.user.videoQuotaDaily, 0).toString()
} else {
this.userVideoQuotaDaily = this.i18n('Unlimited')
}
}
)

this.userService.getMyVideoQuotaUsed()
.subscribe(data => {
this.userVideoQuotaUsed = data.videoQuotaUsed
this.userVideoQuotaPercentage = this.userVideoQuotaUsed * 100 / this.user.videoQuota

this.userVideoQuotaUsedDaily = data.videoQuotaUsedDaily
this.userVideoQuotaDailyPercentage = this.userVideoQuotaUsedDaily * 100 / this.user.videoQuotaDaily
})
}

ngAfterViewChecked () {
Expand All @@ -83,8 +49,4 @@ export class MyAccountSettingsComponent implements OnInit, AfterViewChecked {
err => this.notifier.error(err.message)
)
}

hasDailyQuota () {
return this.user.videoQuotaDaily !== -1
}
}
2 changes: 2 additions & 0 deletions client/src/app/+videos/+video-edit/video-add.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
Instead, <a routerLink="/admin/users">create a dedicated account</a> to upload your videos.
</div>

<my-user-quota *ngIf="!isInSecondStep()" [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-quota>

<div class="title-page title-page-single" *ngIf="isInSecondStep()">
<ng-container *ngIf="secondStepType === 'import-url' || secondStepType === 'import-torrent'" i18n>Import {{ videoName }}</ng-container>
<ng-container *ngIf="secondStepType === 'upload'" i18n>Upload {{ videoName }}</ng-container>
Expand Down
6 changes: 3 additions & 3 deletions client/src/app/+videos/+video-edit/video-add.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ $border-color: #EAEAEA;
$nav-link-height: 40px;

.margin-content {
padding-top: 50px;
padding-top: 20px;
}

.alert {
Expand All @@ -16,7 +16,7 @@ $nav-link-height: 40px;

::ng-deep .video-add-nav {
border-bottom: $border-width $border-type $border-color;
margin: 50px 0 0 0 !important;
margin: 20px 0 0 0 !important;

&.hide-nav {
display: none !important;
Expand Down Expand Up @@ -64,7 +64,7 @@ $nav-link-height: 40px;
padding-bottom: 20px;
display: flex;
justify-content: center;
align-items: center;
padding-top: 20px;

&.dragover {
border: 3px dashed pvar(--mainColor);
Expand Down
10 changes: 9 additions & 1 deletion client/src/app/+videos/+video-edit/video-add.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, HostListener, OnInit, ViewChild } from '@angular/core'
import { AuthService, CanComponentDeactivate, ServerService } from '@app/core'
import { AuthService, CanComponentDeactivate, ServerService, User } from '@app/core'
import { ServerConfig } from '@shared/models'
import { VideoImportTorrentComponent } from './video-add-components/video-import-torrent.component'
import { VideoImportUrlComponent } from './video-add-components/video-import-url.component'
Expand All @@ -15,6 +15,8 @@ export class VideoAddComponent implements OnInit, CanComponentDeactivate {
@ViewChild('videoImportUrl') videoImportUrl: VideoImportUrlComponent
@ViewChild('videoImportTorrent') videoImportTorrent: VideoImportTorrentComponent

user: User = null

secondStepType: 'upload' | 'import-url' | 'import-torrent'
videoName: string
serverConfig: ServerConfig
Expand All @@ -24,7 +26,13 @@ export class VideoAddComponent implements OnInit, CanComponentDeactivate {
private serverService: ServerService
) {}

get userInformationLoaded () {
return this.auth.userInformationLoaded
}

ngOnInit () {
this.user = this.auth.getUser()

this.serverConfig = this.serverService.getTmpConfig()

this.serverService.getConfig()
Expand Down
4 changes: 3 additions & 1 deletion client/src/app/shared/shared-main/shared-main.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { DateToggleComponent } from './date'
import { FeedComponent } from './feeds'
import { LoaderComponent, SmallLoaderComponent } from './loaders'
import { HelpComponent, ListOverflowComponent, TopMenuDropdownComponent } from './misc'
import { UserHistoryService, UserNotificationsComponent, UserNotificationService } from './users'
import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users'
import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video'
import { VideoCaptionService } from './video-caption'
import { VideoChannelService } from './video-channel'
Expand Down Expand Up @@ -83,6 +83,7 @@ import { AUTH_INTERCEPTOR_PROVIDER } from './auth'
ListOverflowComponent,
TopMenuDropdownComponent,

UserQuotaComponent,
UserNotificationsComponent
],

Expand Down Expand Up @@ -132,6 +133,7 @@ import { AUTH_INTERCEPTOR_PROVIDER } from './auth'
ListOverflowComponent,
TopMenuDropdownComponent,

UserQuotaComponent,
UserNotificationsComponent
],

Expand Down
1 change: 1 addition & 0 deletions client/src/app/shared/shared-main/users/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './user-history.service'
export * from './user-notification.model'
export * from './user-notification.service'
export * from './user-notifications.component'
export * from './user-quota.component'
21 changes: 21 additions & 0 deletions client/src/app/shared/shared-main/users/user-quota.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="user-quota mb-3">
<div>
<strong class="user-quota-title" tabindex="0" i18n>Total video quota</strong>
<div class="progress" tabindex="0" [ngbTooltip]="titleVideoQuota()">
<div class="progress-bar" tabindex="0" role="progressbar" [style]="{ width: userVideoQuotaPercentage + '%' }"
[attr.aria-valuenow]="userVideoQuotaUsed" aria-valuemin="0" [attr.aria-valuemax]="user.videoQuota">
{{ userVideoQuotaUsed | bytes: 0 }}</div>
<span class="ml-auto mr-2">{{ userVideoQuota }}</span>
</div>
</div>

<div *ngIf="hasDailyQuota()" class="mt-3">
<strong class="user-quota-title" tabindex="0" i18n>Daily video quota</strong>
<div class="progress" tabindex="0" [ngbTooltip]="titleVideoQuotaDaily()">
<div class="progress-bar secondary" role="progressbar" [style]="{ width: userVideoQuotaDailyPercentage + '%' }"
[attr.aria-valuenow]="userVideoQuotaUsedDaily" aria-valuemin="0" [attr.aria-valuemax]="user.videoQuotaDaily">
{{ userVideoQuotaUsedDaily | bytes: 0 }}</div>
<span class="ml-auto mr-2">{{ userVideoQuotaDaily }}</span>
</div>
</div>
</div>
31 changes: 31 additions & 0 deletions client/src/app/shared/shared-main/users/user-quota.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@import '_variables';
@import '_mixins';

.user-quota {
font-size: 15px;
margin-top: 20px;

label {
margin-right: 5px;
}

&, .progress {
width: 100% !important;
}

.user-quota-title, .progress {
@include disable-outline;
@include button-focus(pvar(--mainColorLightest));
}

.progress {
@include progressbar;

height: 2rem;

span {
align-self: center;
}
}
}

68 changes: 68 additions & 0 deletions client/src/app/shared/shared-main/users/user-quota.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Subject } from 'rxjs'
import { BytesPipe } from 'ngx-pipes'
import { Component, Input, OnInit } from '@angular/core'
import { User, UserService } from '@app/core'
import { I18n } from '@ngx-translate/i18n-polyfill'

@Component({
selector: 'my-user-quota',
templateUrl: './user-quota.component.html',
styleUrls: ['./user-quota.component.scss']
})

export class UserQuotaComponent implements OnInit {
@Input() user: User = null
@Input() userInformationLoaded: Subject<any>

userVideoQuota = '0'
userVideoQuotaUsed = 0
userVideoQuotaPercentage = 15

userVideoQuotaDaily = '0'
userVideoQuotaUsedDaily = 0
userVideoQuotaDailyPercentage = 15

constructor (
private userService: UserService,
private i18n: I18n
) { }

ngOnInit () {
this.userInformationLoaded.subscribe(
() => {
if (this.user.videoQuota !== -1) {
this.userVideoQuota = new BytesPipe().transform(this.user.videoQuota, 0).toString()
} else {
this.userVideoQuota = this.i18n('Unlimited')
}

if (this.user.videoQuotaDaily !== -1) {
this.userVideoQuotaDaily = new BytesPipe().transform(this.user.videoQuotaDaily, 0).toString()
} else {
this.userVideoQuotaDaily = this.i18n('Unlimited')
}
}
)

this.userService.getMyVideoQuotaUsed()
.subscribe(data => {
this.userVideoQuotaUsed = data.videoQuotaUsed
this.userVideoQuotaPercentage = this.userVideoQuotaUsed * 100 / this.user.videoQuota

this.userVideoQuotaUsedDaily = data.videoQuotaUsedDaily
this.userVideoQuotaDailyPercentage = this.userVideoQuotaUsedDaily * 100 / this.user.videoQuotaDaily
})
}

hasDailyQuota () {
return this.user.videoQuotaDaily !== -1
}

titleVideoQuota () {
return `${new BytesPipe().transform(this.userVideoQuotaUsed, 0).toString()} / ${this.userVideoQuota}`
}

titleVideoQuotaDaily () {
return `${new BytesPipe().transform(this.userVideoQuotaUsedDaily, 0).toString()} / ${this.userVideoQuotaDaily}`
}
}

0 comments on commit 2e7f262

Please sign in to comment.