aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/shared-main/account
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-04-07 17:01:29 +0200
committerChocobozzz <chocobozzz@cpy.re>2021-04-08 10:07:53 +0200
commitcdeddff142fd20f8cb8bb346625909d61c596603 (patch)
treee7b0ae302a002fb2eadc605300294a1f135c3744 /client/src/app/shared/shared-main/account
parent282695e699a35b65441b548061ef0db5de9b3971 (diff)
downloadPeerTube-cdeddff142fd20f8cb8bb346625909d61c596603.tar.gz
PeerTube-cdeddff142fd20f8cb8bb346625909d61c596603.tar.zst
PeerTube-cdeddff142fd20f8cb8bb346625909d61c596603.zip
Add ability to update the banner
Diffstat (limited to 'client/src/app/shared/shared-main/account')
-rw-r--r--client/src/app/shared/shared-main/account/actor-avatar-info.component.html42
-rw-r--r--client/src/app/shared/shared-main/account/actor-avatar-info.component.scss92
-rw-r--r--client/src/app/shared/shared-main/account/actor-avatar-info.component.ts77
-rw-r--r--client/src/app/shared/shared-main/account/actor.model.ts9
-rw-r--r--client/src/app/shared/shared-main/account/index.ts2
-rw-r--r--client/src/app/shared/shared-main/account/video-avatar-channel.component.html27
-rw-r--r--client/src/app/shared/shared-main/account/video-avatar-channel.component.scss44
-rw-r--r--client/src/app/shared/shared-main/account/video-avatar-channel.component.ts27
8 files changed, 7 insertions, 313 deletions
diff --git a/client/src/app/shared/shared-main/account/actor-avatar-info.component.html b/client/src/app/shared/shared-main/account/actor-avatar-info.component.html
deleted file mode 100644
index f3db55310..000000000
--- a/client/src/app/shared/shared-main/account/actor-avatar-info.component.html
+++ /dev/null
@@ -1,42 +0,0 @@
1<ng-container *ngIf="actor">
2 <div class="actor">
3 <div class="d-flex">
4 <img [ngClass]="{ channel: isChannel() }" [src]="actor.avatarUrl" alt="Avatar" />
5
6 <div class="actor-img-edit-container">
7
8 <div *ngIf="!hasAvatar()" class="actor-img-edit-button" [ngbTooltip]="avatarFormat" placement="right" container="body">
9 <my-global-icon iconName="upload"></my-global-icon>
10 <label class="sr-only" for="avatarfile" i18n>Upload a new avatar</label>
11 <input #avatarfileInput type="file" title=" " name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange(avatarfileInput)"/>
12 </div>
13
14 <div *ngIf="hasAvatar()" class="actor-img-edit-button" #avatarPopover="ngbPopover" [ngbPopover]="avatarEditContent" popoverClass="popover-avatar-info" autoClose="outside" placement="right">
15 <my-global-icon iconName="edit"></my-global-icon>
16 <label class="sr-only" for="avatarMenu" i18n>Change your avatar</label>
17 </div>
18
19 </div>
20 </div>
21
22 <div class="actor-info">
23 <div class="actor-info-names">
24 <div class="actor-info-display-name">{{ actor.displayName }}</div>
25 <div class="actor-info-username">{{ actor.name }}</div>
26 </div>
27 <div i18n class="actor-info-followers">{{ actor.followersCount }} subscribers</div>
28 </div>
29 </div>
30</ng-container>
31
32<ng-template #avatarEditContent>
33 <div class="dropdown-item c-hand" [ngbTooltip]="avatarFormat" placement="right" container="body">
34 <my-global-icon iconName="upload"></my-global-icon>
35 <span for="avatarfile" i18n>Upload a new avatar</span>
36 <input #avatarfileInput type="file" title=" " name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange(avatarfileInput)"/>
37 </div>
38 <div class="dropdown-item c-hand" (click)="deleteAvatar()" (key.enter)="deleteAvatar()">
39 <my-global-icon iconName="delete"></my-global-icon>
40 <span i18n>Remove avatar</span>
41 </div>
42</ng-template>
diff --git a/client/src/app/shared/shared-main/account/actor-avatar-info.component.scss b/client/src/app/shared/shared-main/account/actor-avatar-info.component.scss
deleted file mode 100644
index 40ba4269b..000000000
--- a/client/src/app/shared/shared-main/account/actor-avatar-info.component.scss
+++ /dev/null
@@ -1,92 +0,0 @@
1@import '_variables';
2@import '_mixins';
3
4.actor {
5 display: flex;
6
7 img {
8 margin-right: 15px;
9
10 &:not(.channel) {
11 @include avatar(100px);
12 }
13
14 &.channel {
15 @include channel-avatar(100px);
16 }
17 }
18
19 .actor-img-edit-container {
20 position: relative;
21 width: 0;
22
23 .actor-img-edit-button {
24 @include peertube-button-file(21px);
25 @include button-with-icon(19px);
26 @include orange-button;
27
28 margin-top: 10px;
29 margin-bottom: 5px;
30 border-radius: 50%;
31 top: 55px;
32 right: 45px;
33 cursor: pointer;
34
35 input {
36 width: 30px;
37 height: 30px;
38 }
39
40 my-global-icon {
41 right: 7px;
42 }
43 }
44 }
45
46 .actor-info {
47 justify-content: center;
48 display: inline-flex;
49 flex-direction: column;
50
51 .actor-info-names {
52 display: flex;
53 align-items: center;
54
55 .actor-info-display-name {
56 font-size: 20px;
57 font-weight: $font-bold;
58
59 @media screen and (max-width: $small-view) {
60 font-size: 16px;
61 }
62 }
63
64 .actor-info-username {
65 margin-left: 7px;
66 position: relative;
67 top: 2px;
68 font-size: 14px;
69 color: $grey-actor-name;
70 }
71 }
72
73 .actor-info-followers {
74 font-size: 15px;
75 padding-bottom: .5rem;
76 }
77 }
78}
79
80.actor-img-edit-container ::ng-deep .popover-avatar-info .popover-body {
81 padding: 0;
82
83 .dropdown-item {
84 padding: 6px 10px;
85 border-radius: 4px;
86
87 &:first-child {
88 @include peertube-file;
89 display: block;
90 }
91 }
92}
diff --git a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts b/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts
deleted file mode 100644
index 87e9e917c..000000000
--- a/client/src/app/shared/shared-main/account/actor-avatar-info.component.ts
+++ /dev/null
@@ -1,77 +0,0 @@
1import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core'
2import { Notifier, ServerService } from '@app/core'
3import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
4import { getBytes } from '@root-helpers/bytes'
5import { Account } from '../account/account.model'
6import { VideoChannel } from '../video-channel/video-channel.model'
7import { Actor } from './actor.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 implements OnInit, OnChanges {
15 @ViewChild('avatarfileInput') avatarfileInput: ElementRef<HTMLInputElement>
16 @ViewChild('avatarPopover') avatarPopover: NgbPopover
17
18 @Input() actor: VideoChannel | Account
19
20 @Output() avatarChange = new EventEmitter<FormData>()
21 @Output() avatarDelete = new EventEmitter<void>()
22
23 avatarFormat = ''
24 maxAvatarSize = 0
25 avatarExtensions = ''
26
27 private avatarUrl: string
28
29 constructor (
30 private serverService: ServerService,
31 private notifier: Notifier
32 ) { }
33
34 ngOnInit (): void {
35 this.serverService.getConfig()
36 .subscribe(config => {
37 this.maxAvatarSize = config.avatar.file.size.max
38 this.avatarExtensions = config.avatar.file.extensions.join(', ')
39
40 this.avatarFormat = `${$localize`max size`}: 192*192px, ` +
41 `${getBytes(this.maxAvatarSize)} ${$localize`extensions`}: ${this.avatarExtensions}`
42 })
43 }
44
45 ngOnChanges (changes: SimpleChanges) {
46 if (changes['actor']) {
47 this.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.actor)
48 }
49 }
50
51 onAvatarChange (input: HTMLInputElement) {
52 this.avatarfileInput = new ElementRef(input)
53
54 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
55 if (avatarfile.size > this.maxAvatarSize) {
56 this.notifier.error('Error', $localize`This image is too large.`)
57 return
58 }
59
60 const formData = new FormData()
61 formData.append('avatarfile', avatarfile)
62 this.avatarPopover?.close()
63 this.avatarChange.emit(formData)
64 }
65
66 deleteAvatar () {
67 this.avatarDelete.emit()
68 }
69
70 hasAvatar () {
71 return !!this.avatarUrl
72 }
73
74 isChannel () {
75 return !!(this.actor as VideoChannel).ownerAccount
76 }
77}
diff --git a/client/src/app/shared/shared-main/account/actor.model.ts b/client/src/app/shared/shared-main/account/actor.model.ts
index c105a88ac..670823060 100644
--- a/client/src/app/shared/shared-main/account/actor.model.ts
+++ b/client/src/app/shared/shared-main/account/actor.model.ts
@@ -3,15 +3,18 @@ import { getAbsoluteAPIUrl } from '@app/helpers'
3 3
4export abstract class Actor implements ActorServer { 4export abstract class Actor implements ActorServer {
5 id: number 5 id: number
6 url: string
7 name: string 6 name: string
7
8 host: string 8 host: string
9 url: string
10
9 followingCount: number 11 followingCount: number
10 followersCount: number 12 followersCount: number
13
11 createdAt: Date | string 14 createdAt: Date | string
12 updatedAt: Date | string 15 updatedAt: Date | string
13 avatar: ActorImage
14 16
17 avatar: ActorImage
15 avatarUrl: string 18 avatarUrl: string
16 19
17 isLocal: boolean 20 isLocal: boolean
@@ -24,6 +27,8 @@ export abstract class Actor implements ActorServer {
24 27
25 return absoluteAPIUrl + actor.avatar.path 28 return absoluteAPIUrl + actor.avatar.path
26 } 29 }
30
31 return ''
27 } 32 }
28 33
29 static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) { 34 static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) {
diff --git a/client/src/app/shared/shared-main/account/index.ts b/client/src/app/shared/shared-main/account/index.ts
index 61c800e56..b80ddb9f5 100644
--- a/client/src/app/shared/shared-main/account/index.ts
+++ b/client/src/app/shared/shared-main/account/index.ts
@@ -1,5 +1,3 @@
1export * from './account.model' 1export * from './account.model'
2export * from './account.service' 2export * from './account.service'
3export * from './actor-avatar-info.component'
4export * from './actor.model' 3export * from './actor.model'
5export * from './video-avatar-channel.component'
diff --git a/client/src/app/shared/shared-main/account/video-avatar-channel.component.html b/client/src/app/shared/shared-main/account/video-avatar-channel.component.html
deleted file mode 100644
index 5058f05dd..000000000
--- a/client/src/app/shared/shared-main/account/video-avatar-channel.component.html
+++ /dev/null
@@ -1,27 +0,0 @@
1<div class="wrapper" [ngClass]="'avatar-' + size">
2 <ng-container *ngIf="!isChannelAvatarNull() && !genericChannel">
3 <a [routerLink]="[ '/video-channels', video.byVideoChannel ]" [title]="channelLinkTitle">
4 <img [src]="video.videoChannelAvatarUrl" i18n-alt alt="Channel avatar" class="channel-avatar" />
5 </a>
6
7 <a [routerLink]="[ '/accounts', video.byAccount ]" [title]="accountLinkTitle">
8 <img [src]="video.accountAvatarUrl" i18n-alt alt="Account avatar" />
9 </a>
10 </ng-container>
11
12 <ng-container *ngIf="!isChannelAvatarNull() && genericChannel">
13 <a [routerLink]="[ '/accounts', video.byAccount ]" [title]="accountLinkTitle">
14 <img [src]="video.accountAvatarUrl" i18n-alt alt="Account avatar" />
15 </a>
16
17 <a [routerLink]="[ '/video-channels', video.byVideoChannel ]" [title]="channelLinkTitle">
18 <img [src]="video.videoChannelAvatarUrl" i18n-alt alt="Channel avatar" class="channel-avatar" />
19 </a>
20 </ng-container>
21
22 <ng-container *ngIf="isChannelAvatarNull()">
23 <a [routerLink]="[ '/accounts', video.byAccount ]" [title]="accountLinkTitle">
24 <img [src]="video.accountAvatarUrl" i18n-alt alt="Account avatar" />
25 </a>
26 </ng-container>
27</div>
diff --git a/client/src/app/shared/shared-main/account/video-avatar-channel.component.scss b/client/src/app/shared/shared-main/account/video-avatar-channel.component.scss
deleted file mode 100644
index 4998e85fa..000000000
--- a/client/src/app/shared/shared-main/account/video-avatar-channel.component.scss
+++ /dev/null
@@ -1,44 +0,0 @@
1@import '_mixins';
2
3.wrapper {
4 $avatar-size: 35px;
5
6 width: $avatar-size;
7 height: $avatar-size;
8 position: relative;
9 margin-right: 5px;
10 margin-bottom: 5px;
11
12 &.avatar-sm {
13 width: 28px;
14 height: 28px;
15 margin-bottom: 3px;
16 }
17
18 a {
19 @include disable-outline;
20 }
21
22 a img {
23 height: 100%;
24 object-fit: cover;
25 position: absolute;
26 top:50%;
27 left:50%;
28 transform: translate(-50%,-50%);
29 border-radius: 5px;
30
31 &:not(.channel-avatar) {
32 border-radius: 50%;
33 }
34 }
35
36 a:nth-of-type(2) img {
37 height: 60%;
38 width: 60%;
39 border: 2px solid pvar(--mainBackgroundColor);
40 transform: translateX(15%);
41 position: relative;
42 background-color: pvar(--mainBackgroundColor);
43 }
44}
diff --git a/client/src/app/shared/shared-main/account/video-avatar-channel.component.ts b/client/src/app/shared/shared-main/account/video-avatar-channel.component.ts
deleted file mode 100644
index 440e2b522..000000000
--- a/client/src/app/shared/shared-main/account/video-avatar-channel.component.ts
+++ /dev/null
@@ -1,27 +0,0 @@
1import { Component, Input, OnInit } from '@angular/core'
2import { Video } from '../video/video.model'
3
4@Component({
5 selector: 'my-video-avatar-channel',
6 templateUrl: './video-avatar-channel.component.html',
7 styleUrls: [ './video-avatar-channel.component.scss' ]
8})
9export class VideoAvatarChannelComponent implements OnInit {
10 @Input() video: Video
11 @Input() byAccount: string
12
13 @Input() size: 'md' | 'sm' = 'md'
14 @Input() genericChannel: boolean
15
16 channelLinkTitle = ''
17 accountLinkTitle = ''
18
19 ngOnInit () {
20 this.channelLinkTitle = $localize`${this.video.account.name} (channel page)`
21 this.accountLinkTitle = $localize`${this.video.byAccount} (account page)`
22 }
23
24 isChannelAvatarNull () {
25 return this.video.channel.avatar === null
26 }
27}