aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/shared-main
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
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')
-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
-rw-r--r--client/src/app/shared/shared-main/shared-main.module.ts14
-rw-r--r--client/src/app/shared/shared-main/video-channel/video-channel.model.ts40
-rw-r--r--client/src/app/shared/shared-main/video-channel/video-channel.service.ts10
11 files changed, 52 insertions, 332 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}
diff --git a/client/src/app/shared/shared-main/shared-main.module.ts b/client/src/app/shared/shared-main/shared-main.module.ts
index 3e21d491a..16d230f46 100644
--- a/client/src/app/shared/shared-main/shared-main.module.ts
+++ b/client/src/app/shared/shared-main/shared-main.module.ts
@@ -6,18 +6,18 @@ import { NgModule } from '@angular/core'
6import { FormsModule, ReactiveFormsModule } from '@angular/forms' 6import { FormsModule, ReactiveFormsModule } from '@angular/forms'
7import { RouterModule } from '@angular/router' 7import { RouterModule } from '@angular/router'
8import { 8import {
9 NgbButtonsModule,
9 NgbCollapseModule, 10 NgbCollapseModule,
10 NgbDropdownModule, 11 NgbDropdownModule,
11 NgbModalModule, 12 NgbModalModule,
12 NgbNavModule, 13 NgbNavModule,
13 NgbPopoverModule, 14 NgbPopoverModule,
14 NgbTooltipModule, 15 NgbTooltipModule
15 NgbButtonsModule
16} from '@ng-bootstrap/ng-bootstrap' 16} from '@ng-bootstrap/ng-bootstrap'
17import { LoadingBarModule } from '@ngx-loading-bar/core' 17import { LoadingBarModule } from '@ngx-loading-bar/core'
18import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' 18import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
19import { SharedGlobalIconModule } from '../shared-icons' 19import { SharedGlobalIconModule } from '../shared-icons'
20import { AccountService, ActorAvatarInfoComponent, VideoAvatarChannelComponent } from './account' 20import { AccountService } from './account'
21import { 21import {
22 AutofocusDirective, 22 AutofocusDirective,
23 BytesPipe, 23 BytesPipe,
@@ -32,7 +32,7 @@ import { ActionDropdownComponent, ButtonComponent, DeleteButtonComponent, EditBu
32import { DateToggleComponent } from './date' 32import { DateToggleComponent } from './date'
33import { FeedComponent } from './feeds' 33import { FeedComponent } from './feeds'
34import { LoaderComponent, SmallLoaderComponent } from './loaders' 34import { LoaderComponent, SmallLoaderComponent } from './loaders'
35import { HelpComponent, ListOverflowComponent, TopMenuDropdownComponent, SimpleSearchInputComponent } from './misc' 35import { HelpComponent, ListOverflowComponent, SimpleSearchInputComponent, TopMenuDropdownComponent } from './misc'
36import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users' 36import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users'
37import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' 37import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video'
38import { VideoCaptionService } from './video-caption' 38import { VideoCaptionService } from './video-caption'
@@ -65,9 +65,6 @@ import { VideoChannelService } from './video-channel'
65 ], 65 ],
66 66
67 declarations: [ 67 declarations: [
68 VideoAvatarChannelComponent,
69 ActorAvatarInfoComponent,
70
71 FromNowPipe, 68 FromNowPipe,
72 NumberFormatterPipe, 69 NumberFormatterPipe,
73 BytesPipe, 70 BytesPipe,
@@ -120,9 +117,6 @@ import { VideoChannelService } from './video-channel'
120 117
121 PrimeSharedModule, 118 PrimeSharedModule,
122 119
123 VideoAvatarChannelComponent,
124 ActorAvatarInfoComponent,
125
126 FromNowPipe, 120 FromNowPipe,
127 BytesPipe, 121 BytesPipe,
128 NumberFormatterPipe, 122 NumberFormatterPipe,
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
index b4c3365a9..d8be42eef 100644
--- a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
+++ b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts
@@ -1,3 +1,4 @@
1import { getAbsoluteAPIUrl } from '@app/helpers'
1import { Account as ServerAccount, ActorImage, VideoChannel as ServerVideoChannel, ViewsPerDate } from '@shared/models' 2import { Account as ServerAccount, ActorImage, VideoChannel as ServerVideoChannel, ViewsPerDate } from '@shared/models'
2import { Account } from '../account/account.model' 3import { Account } from '../account/account.model'
3import { Actor } from '../account/actor.model' 4import { Actor } from '../account/actor.model'
@@ -6,10 +7,15 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
6 displayName: string 7 displayName: string
7 description: string 8 description: string
8 support: string 9 support: string
10
9 isLocal: boolean 11 isLocal: boolean
12
10 nameWithHost: string 13 nameWithHost: string
11 nameWithHostForced: string 14 nameWithHostForced: string
12 15
16 banner: ActorImage
17 bannerUrl: string
18
13 ownerAccount?: ServerAccount 19 ownerAccount?: ServerAccount
14 ownerBy?: string 20 ownerBy?: string
15 ownerAvatarUrl?: string 21 ownerAvatarUrl?: string
@@ -22,6 +28,18 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
22 return Actor.GET_ACTOR_AVATAR_URL(actor) || this.GET_DEFAULT_AVATAR_URL() 28 return Actor.GET_ACTOR_AVATAR_URL(actor) || this.GET_DEFAULT_AVATAR_URL()
23 } 29 }
24 30
31 static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) {
32 if (channel?.banner?.url) return channel.banner.url
33
34 if (channel && channel.banner) {
35 const absoluteAPIUrl = getAbsoluteAPIUrl()
36
37 return absoluteAPIUrl + channel.banner.path
38 }
39
40 return ''
41 }
42
25 static GET_DEFAULT_AVATAR_URL () { 43 static GET_DEFAULT_AVATAR_URL () {
26 return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png` 44 return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png`
27 } 45 }
@@ -29,12 +47,14 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
29 constructor (hash: ServerVideoChannel) { 47 constructor (hash: ServerVideoChannel) {
30 super(hash) 48 super(hash)
31 49
32 this.updateComputedAttributes()
33
34 this.displayName = hash.displayName 50 this.displayName = hash.displayName
35 this.description = hash.description 51 this.description = hash.description
36 this.support = hash.support 52 this.support = hash.support
53
54 this.banner = hash.banner
55
37 this.isLocal = hash.isLocal 56 this.isLocal = hash.isLocal
57
38 this.nameWithHost = Actor.CREATE_BY_STRING(this.name, this.host) 58 this.nameWithHost = Actor.CREATE_BY_STRING(this.name, this.host)
39 this.nameWithHostForced = Actor.CREATE_BY_STRING(this.name, this.host, true) 59 this.nameWithHostForced = Actor.CREATE_BY_STRING(this.name, this.host, true)
40 60
@@ -49,6 +69,8 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
49 this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host) 69 this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host)
50 this.ownerAvatarUrl = Account.GET_ACTOR_AVATAR_URL(this.ownerAccount) 70 this.ownerAvatarUrl = Account.GET_ACTOR_AVATAR_URL(this.ownerAccount)
51 } 71 }
72
73 this.updateComputedAttributes()
52 } 74 }
53 75
54 updateAvatar (newAvatar: ActorImage) { 76 updateAvatar (newAvatar: ActorImage) {
@@ -58,11 +80,21 @@ export class VideoChannel extends Actor implements ServerVideoChannel {
58 } 80 }
59 81
60 resetAvatar () { 82 resetAvatar () {
61 this.avatar = null 83 this.updateAvatar(null)
62 this.avatarUrl = VideoChannel.GET_DEFAULT_AVATAR_URL() 84 }
85
86 updateBanner (newBanner: ActorImage) {
87 this.banner = newBanner
88
89 this.updateComputedAttributes()
90 }
91
92 resetBanner () {
93 this.updateBanner(null)
63 } 94 }
64 95
65 private updateComputedAttributes () { 96 private updateComputedAttributes () {
66 this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this) 97 this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this)
98 this.bannerUrl = VideoChannel.GET_ACTOR_BANNER_URL(this)
67 } 99 }
68} 100}
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.service.ts b/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
index 3f9ef74fa..e65261763 100644
--- a/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
+++ b/client/src/app/shared/shared-main/video-channel/video-channel.service.ts
@@ -82,15 +82,15 @@ export class VideoChannelService {
82 ) 82 )
83 } 83 }
84 84
85 changeVideoChannelAvatar (videoChannelName: string, avatarForm: FormData) { 85 changeVideoChannelImage (videoChannelName: string, avatarForm: FormData, type: 'avatar' | 'banner') {
86 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/avatar/pick' 86 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type + '/pick'
87 87
88 return this.authHttp.post<{ avatar: ActorImage }>(url, avatarForm) 88 return this.authHttp.post<{ avatar?: ActorImage, banner?: ActorImage }>(url, avatarForm)
89 .pipe(catchError(err => this.restExtractor.handleError(err))) 89 .pipe(catchError(err => this.restExtractor.handleError(err)))
90 } 90 }
91 91
92 deleteVideoChannelAvatar (videoChannelName: string) { 92 deleteVideoChannelImage (videoChannelName: string, type: 'avatar' | 'banner') {
93 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/avatar' 93 const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type
94 94
95 return this.authHttp.delete(url) 95 return this.authHttp.delete(url)
96 .pipe( 96 .pipe(