aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+my-account
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-06-29 14:34:04 +0200
committerChocobozzz <me@florianbigard.com>2018-06-29 14:34:04 +0200
commit52d9f792b3fee5acce80f948295b59e3ad2073eb (patch)
tree661f577e9c7196d199b4b49e475ecd2d88e6d7b7 /client/src/app/+my-account
parent4bbfc6c606c8d3794bae25c64c516120af41f4eb (diff)
downloadPeerTube-52d9f792b3fee5acce80f948295b59e3ad2073eb.tar.gz
PeerTube-52d9f792b3fee5acce80f948295b59e3ad2073eb.tar.zst
PeerTube-52d9f792b3fee5acce80f948295b59e3ad2073eb.zip
Client: Add ability to update video channel avatar
Diffstat (limited to 'client/src/app/+my-account')
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.html18
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.scss49
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-settings.component.ts21
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html6
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss5
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts30
-rw-r--r--client/src/app/+my-account/my-account.module.ts4
-rw-r--r--client/src/app/+my-account/shared/actor-avatar-info.component.html19
-rw-r--r--client/src/app/+my-account/shared/actor-avatar-info.component.scss51
-rw-r--r--client/src/app/+my-account/shared/actor-avatar-info.component.ts48
10 files changed, 160 insertions, 91 deletions
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
index f5d593f19..ff08cb777 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.html
@@ -1,20 +1,4 @@
1<div class="user"> 1<my-actor-avatar-info [actor]="user.account" (avatarChange)="onAvatarChange($event)"></my-actor-avatar-info>
2 <img [src]="user.accountAvatarUrl" alt="Avatar" />
3
4 <div class="user-info">
5 <div class="user-info-names">
6 <div class="user-info-display-name">{{ user.account?.displayName }}</div>
7 <div class="user-info-username">{{ user.username }}</div>
8 </div>
9 <div i18n class="user-info-followers">{{ user.account?.followersCount }} subscribers</div>
10 </div>
11</div>
12
13<div class="button-file">
14 <span i18n>Change your avatar</span>
15 <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="changeAvatar()" />
16</div>
17<div i18n class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div>
18 2
19<div class="user-quota"> 3<div class="user-quota">
20 <span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }} 4 <span i18n class="user-quota-label">Video quota:</span> {{ userVideoQuotaUsed | bytes: 0 }} / {{ userVideoQuota }}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss b/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss
index ec0d40b93..16f26dfed 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.scss
@@ -1,55 +1,6 @@
1@import '_variables'; 1@import '_variables';
2@import '_mixins'; 2@import '_mixins';
3 3
4.user {
5 display: flex;
6
7 img {
8 @include avatar(50px);
9
10 margin-right: 15px;
11 }
12
13 .user-info {
14 .user-info-names {
15 display: flex;
16 align-items: center;
17
18 .user-info-display-name {
19 font-size: 20px;
20 font-weight: $font-bold;
21 }
22
23 .user-info-username {
24 margin-left: 7px;
25 position: relative;
26 top: 2px;
27 font-size: 14px;
28 color: #777272;
29 }
30 }
31
32 .user-info-followers {
33 font-size: 15px;
34 }
35 }
36}
37
38.button-file {
39 @include peertube-button-file(160px);
40
41 margin-top: 10px;
42 margin-bottom: 5px;
43}
44
45.file-max-size {
46 display: inline-block;
47 font-size: 13px;
48
49 position: relative;
50 top: -10px;
51}
52
53.user-quota { 4.user-quota {
54 font-size: 15px; 5 font-size: 15px;
55 margin-top: 20px; 6 margin-top: 20px;
diff --git a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
index 14293f14c..164a46a48 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-settings.component.ts
@@ -13,8 +13,6 @@ import { I18n } from '@ngx-translate/i18n-polyfill'
13 styleUrls: [ './my-account-settings.component.scss' ] 13 styleUrls: [ './my-account-settings.component.scss' ]
14}) 14})
15export class MyAccountSettingsComponent implements OnInit { 15export class MyAccountSettingsComponent implements OnInit {
16 @ViewChild('avatarfileInput') avatarfileInput
17
18 user: User = null 16 user: User = null
19 userVideoQuota = '0' 17 userVideoQuota = '0'
20 userVideoQuotaUsed = 0 18 userVideoQuotaUsed = 0
@@ -48,16 +46,7 @@ export class MyAccountSettingsComponent implements OnInit {
48 .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed) 46 .subscribe(data => this.userVideoQuotaUsed = data.videoQuotaUsed)
49 } 47 }
50 48
51 changeAvatar () { 49 onAvatarChange (formData: FormData) {
52 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
53 if (avatarfile.size > this.maxAvatarSize) {
54 this.notificationsService.error('Error', 'This image is too large.')
55 return
56 }
57
58 const formData = new FormData()
59 formData.append('avatarfile', avatarfile)
60
61 this.userService.changeAvatar(formData) 50 this.userService.changeAvatar(formData)
62 .subscribe( 51 .subscribe(
63 data => { 52 data => {
@@ -69,12 +58,4 @@ export class MyAccountSettingsComponent implements OnInit {
69 err => this.notificationsService.error(this.i18n('Error'), err.message) 58 err => this.notificationsService.error(this.i18n('Error'), err.message)
70 ) 59 )
71 } 60 }
72
73 get maxAvatarSize () {
74 return this.serverService.getConfig().avatar.file.size.max
75 }
76
77 get avatarExtensions () {
78 return this.serverService.getConfig().avatar.file.extensions.join(',')
79 }
80} 61}
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html
index 1c08cfdca..f7ca2ec43 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.html
@@ -1,5 +1,9 @@
1<my-actor-avatar-info
2 *ngIf="isCreation() === false && videoChannelToUpdate"
3 [actor]="videoChannelToUpdate" (avatarChange)="onAvatarChange($event)"
4></my-actor-avatar-info>
5
1<div i18n class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div> 6<div i18n class="form-sub-title" *ngIf="isCreation() === true">Create a video channel</div>
2<div i18n class="form-sub-title" *ngIf="isCreation() === false">Update {{ videoChannel?.displayName }}</div>
3 7
4<div *ngIf="error" class="alert alert-danger">{{ error }}</div> 8<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
5 9
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss
index 6fbb8ae8b..86c2598b7 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-edit.component.scss
@@ -5,6 +5,11 @@
5 margin-bottom: 20px; 5 margin-bottom: 20px;
6} 6}
7 7
8my-actor-avatar-info {
9 display: block;
10 margin-bottom: 20px;
11}
12
8input[type=text] { 13input[type=text] {
9 @include peertube-input-text(340px); 14 @include peertube-input-text(340px);
10 15
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index 1510c5015..6db8ea8d6 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -1,4 +1,4 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { NotificationsService } from 'angular2-notifications' 3import { NotificationsService } from 'angular2-notifications'
4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit' 4import { MyAccountVideoChannelEdit } from './my-account-video-channel-edit'
@@ -6,7 +6,7 @@ import { VideoChannelUpdate } from '../../../../../shared/models/videos'
6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service' 6import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
7import { Subscription } from 'rxjs' 7import { Subscription } from 'rxjs'
8import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 8import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
9import { AuthService } from '@app/core' 9import { AuthService, ServerService } from '@app/core'
10import { I18n } from '@ngx-translate/i18n-polyfill' 10import { I18n } from '@ngx-translate/i18n-polyfill'
11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 11import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
12import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service' 12import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
@@ -17,6 +17,8 @@ import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators
17 styleUrls: [ './my-account-video-channel-edit.component.scss' ] 17 styleUrls: [ './my-account-video-channel-edit.component.scss' ]
18}) 18})
19export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy { 19export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelEdit implements OnInit, OnDestroy {
20 @ViewChild('avatarfileInput') avatarfileInput
21
20 error: string 22 error: string
21 23
22 private videoChannelToUpdate: VideoChannel 24 private videoChannelToUpdate: VideoChannel
@@ -30,7 +32,8 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
30 private router: Router, 32 private router: Router,
31 private route: ActivatedRoute, 33 private route: ActivatedRoute,
32 private videoChannelService: VideoChannelService, 34 private videoChannelService: VideoChannelService,
33 private i18n: I18n 35 private i18n: I18n,
36 private serverService: ServerService
34 ) { 37 ) {
35 super() 38 super()
36 } 39 }
@@ -89,6 +92,27 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
89 ) 92 )
90 } 93 }
91 94
95 onAvatarChange (formData: FormData) {
96 this.videoChannelService.changeVideoChannelAvatar(this.videoChannelToUpdate.uuid, formData)
97 .subscribe(
98 data => {
99 this.notificationsService.success(this.i18n('Success'), this.i18n('Avatar changed.'))
100
101 this.videoChannelToUpdate.updateAvatar(data.avatar)
102 },
103
104 err => this.notificationsService.error(this.i18n('Error'), err.message)
105 )
106 }
107
108 get maxAvatarSize () {
109 return this.serverService.getConfig().avatar.file.size.max
110 }
111
112 get avatarExtensions () {
113 return this.serverService.getConfig().avatar.file.extensions.join(',')
114 }
115
92 isCreation () { 116 isCreation () {
93 return false 117 return false
94 } 118 }
diff --git a/client/src/app/+my-account/my-account.module.ts b/client/src/app/+my-account/my-account.module.ts
index 7e6b8c03e..2088273e6 100644
--- a/client/src/app/+my-account/my-account.module.ts
+++ b/client/src/app/+my-account/my-account.module.ts
@@ -10,6 +10,7 @@ import { MyAccountProfileComponent } from '@app/+my-account/my-account-settings/
10import { MyAccountVideoChannelsComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channels.component' 10import { MyAccountVideoChannelsComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channels.component'
11import { MyAccountVideoChannelCreateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-create.component' 11import { MyAccountVideoChannelCreateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-create.component'
12import { MyAccountVideoChannelUpdateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-update.component' 12import { MyAccountVideoChannelUpdateComponent } from '@app/+my-account/my-account-video-channels/my-account-video-channel-update.component'
13import { ActorAvatarInfoComponent } from '@app/+my-account/shared/actor-avatar-info.component'
13 14
14@NgModule({ 15@NgModule({
15 imports: [ 16 imports: [
@@ -26,7 +27,8 @@ import { MyAccountVideoChannelUpdateComponent } from '@app/+my-account/my-accoun
26 MyAccountVideosComponent, 27 MyAccountVideosComponent,
27 MyAccountVideoChannelsComponent, 28 MyAccountVideoChannelsComponent,
28 MyAccountVideoChannelCreateComponent, 29 MyAccountVideoChannelCreateComponent,
29 MyAccountVideoChannelUpdateComponent 30 MyAccountVideoChannelUpdateComponent,
31 ActorAvatarInfoComponent
30 ], 32 ],
31 33
32 exports: [ 34 exports: [
diff --git a/client/src/app/+my-account/shared/actor-avatar-info.component.html b/client/src/app/+my-account/shared/actor-avatar-info.component.html
new file mode 100644
index 000000000..8bdff2f5a
--- /dev/null
+++ b/client/src/app/+my-account/shared/actor-avatar-info.component.html
@@ -0,0 +1,19 @@
1<ng-container *ngIf="actor">
2 <div class="actor">
3 <img [src]="actor.avatarUrl" alt="Avatar" />
4
5 <div class="actor-info">
6 <div class="actor-info-names">
7 <div class="actor-info-display-name">{{ actor.displayName }}</div>
8 <div class="actor-info-username">{{ actor.name }}</div>
9 </div>
10 <div i18n class="actor-info-followers">{{ actor.followersCount }} subscribers</div>
11 </div>
12 </div>
13
14 <div class="button-file">
15 <span i18n>Change the avatar</span>
16 <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange()" />
17 </div>
18 <div i18n class="file-max-size">(extensions: {{ avatarExtensions }}, max size: {{ maxAvatarSize | bytes }})</div>
19</ng-container> \ No newline at end of file
diff --git a/client/src/app/+my-account/shared/actor-avatar-info.component.scss b/client/src/app/+my-account/shared/actor-avatar-info.component.scss
new file mode 100644
index 000000000..36a792f82
--- /dev/null
+++ b/client/src/app/+my-account/shared/actor-avatar-info.component.scss
@@ -0,0 +1,51 @@
1@import '_variables';
2@import '_mixins';
3
4.actor {
5 display: flex;
6
7 img {
8 @include avatar(50px);
9
10 margin-right: 15px;
11 }
12
13 .actor-info {
14 .actor-info-names {
15 display: flex;
16 align-items: center;
17
18 .actor-info-display-name {
19 font-size: 20px;
20 font-weight: $font-bold;
21 }
22
23 .actor-info-username {
24 margin-left: 7px;
25 position: relative;
26 top: 2px;
27 font-size: 14px;
28 color: #777272;
29 }
30 }
31
32 .actor-info-followers {
33 font-size: 15px;
34 }
35 }
36}
37
38.button-file {
39 @include peertube-button-file(160px);
40
41 margin-top: 10px;
42 margin-bottom: 5px;
43}
44
45.file-max-size {
46 display: inline-block;
47 font-size: 13px;
48
49 position: relative;
50 top: -10px;
51} \ No newline at end of file
diff --git a/client/src/app/+my-account/shared/actor-avatar-info.component.ts b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
new file mode 100644
index 000000000..e0b25ad33
--- /dev/null
+++ b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
@@ -0,0 +1,48 @@
1import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core'
2import { AuthService } from '../../core'
3import { ServerService } from '../../core/server'
4import { UserService } from '../../shared/users'
5import { NotificationsService } from 'angular2-notifications'
6import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
7import { Account } from '@app/shared/account/account.model'
8
9@Component({
10 selector: 'my-actor-avatar-info',
11 templateUrl: './actor-avatar-info.component.html',
12 styleUrls: [ './actor-avatar-info.component.scss' ]
13})
14export class ActorAvatarInfoComponent {
15 @ViewChild('avatarfileInput') avatarfileInput
16
17 @Input() actor: VideoChannel | Account
18
19 @Output() avatarChange = new EventEmitter<FormData>()
20
21 constructor (
22 private userService: UserService,
23 private authService: AuthService,
24 private serverService: ServerService,
25 private notificationsService: NotificationsService
26 ) {}
27
28 onAvatarChange () {
29 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
30 if (avatarfile.size > this.maxAvatarSize) {
31 this.notificationsService.error('Error', 'This image is too large.')
32 return
33 }
34
35 const formData = new FormData()
36 formData.append('avatarfile', avatarfile)
37
38 this.avatarChange.emit(formData)
39 }
40
41 get maxAvatarSize () {
42 return this.serverService.getConfig().avatar.file.size.max
43 }
44
45 get avatarExtensions () {
46 return this.serverService.getConfig().avatar.file.extensions.join(',')
47 }
48}