diff options
author | Chocobozzz <me@florianbigard.com> | 2021-04-08 12:09:54 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-04-08 13:38:04 +0200 |
commit | 27ec473f5306621643fcb169be7cfe6b15136265 (patch) | |
tree | bc4a8d81c5baa58ae1af6434731644da7c2df109 /client/src | |
parent | 84531547bc0934a2abda586d539f7455b455d488 (diff) | |
download | PeerTube-27ec473f5306621643fcb169be7cfe6b15136265.tar.gz PeerTube-27ec473f5306621643fcb169be7cfe6b15136265.tar.zst PeerTube-27ec473f5306621643fcb169be7cfe6b15136265.zip |
Set channel banner/avatar in creation form
Diffstat (limited to 'client/src')
10 files changed, 112 insertions, 57 deletions
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts index a625493de..b3265210f 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-create.component.ts | |||
@@ -8,10 +8,12 @@ import { | |||
8 | VIDEO_CHANNEL_SUPPORT_VALIDATOR | 8 | VIDEO_CHANNEL_SUPPORT_VALIDATOR |
9 | } from '@app/shared/form-validators/video-channel-validators' | 9 | } from '@app/shared/form-validators/video-channel-validators' |
10 | import { FormValidatorService } from '@app/shared/shared-forms' | 10 | import { FormValidatorService } from '@app/shared/shared-forms' |
11 | import { VideoChannelService } from '@app/shared/shared-main' | 11 | import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' |
12 | import { VideoChannelCreate } from '@shared/models' | 12 | import { VideoChannelCreate } from '@shared/models' |
13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' | 13 | import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' |
14 | import { MyVideoChannelEdit } from './my-video-channel-edit' | 14 | import { MyVideoChannelEdit } from './my-video-channel-edit' |
15 | import { switchMap } from 'rxjs/operators' | ||
16 | import { of } from 'rxjs' | ||
15 | 17 | ||
16 | @Component({ | 18 | @Component({ |
17 | templateUrl: './my-video-channel-edit.component.html', | 19 | templateUrl: './my-video-channel-edit.component.html', |
@@ -19,6 +21,10 @@ import { MyVideoChannelEdit } from './my-video-channel-edit' | |||
19 | }) | 21 | }) |
20 | export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { | 22 | export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { |
21 | error: string | 23 | error: string |
24 | videoChannel = new VideoChannel({}) | ||
25 | |||
26 | private avatar: FormData | ||
27 | private banner: FormData | ||
22 | 28 | ||
23 | constructor ( | 29 | constructor ( |
24 | protected formValidatorService: FormValidatorService, | 30 | protected formValidatorService: FormValidatorService, |
@@ -50,23 +56,43 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
50 | support: body.support || null | 56 | support: body.support || null |
51 | } | 57 | } |
52 | 58 | ||
53 | this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( | 59 | this.videoChannelService.createVideoChannel(videoChannelCreate) |
54 | () => { | 60 | .pipe( |
55 | this.authService.refreshUserInformation() | 61 | switchMap(() => this.uploadAvatar()), |
62 | switchMap(() => this.uploadBanner()) | ||
63 | ).subscribe( | ||
64 | () => { | ||
65 | this.authService.refreshUserInformation() | ||
66 | |||
67 | this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) | ||
68 | this.router.navigate(['/my-library', 'video-channels']) | ||
69 | }, | ||
56 | 70 | ||
57 | this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) | 71 | err => { |
58 | this.router.navigate([ '/my-library', 'video-channels' ]) | 72 | if (err.status === HttpStatusCode.CONFLICT_409) { |
59 | }, | 73 | this.error = $localize`This name already exists on this instance.` |
74 | return | ||
75 | } | ||
60 | 76 | ||
61 | err => { | 77 | this.error = err.message |
62 | if (err.status === HttpStatusCode.CONFLICT_409) { | ||
63 | this.error = $localize`This name already exists on this instance.` | ||
64 | return | ||
65 | } | 78 | } |
79 | ) | ||
80 | } | ||
81 | |||
82 | onAvatarChange (formData: FormData) { | ||
83 | this.avatar = formData | ||
84 | } | ||
85 | |||
86 | onAvatarDelete () { | ||
87 | this.avatar = null | ||
88 | } | ||
89 | |||
90 | onBannerChange (formData: FormData) { | ||
91 | this.banner = formData | ||
92 | } | ||
66 | 93 | ||
67 | this.error = err.message | 94 | onBannerDelete () { |
68 | } | 95 | this.banner = null |
69 | ) | ||
70 | } | 96 | } |
71 | 97 | ||
72 | isCreation () { | 98 | isCreation () { |
@@ -76,4 +102,20 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements | |||
76 | getFormButtonTitle () { | 102 | getFormButtonTitle () { |
77 | return $localize`Create` | 103 | return $localize`Create` |
78 | } | 104 | } |
105 | |||
106 | getUsername () { | ||
107 | return this.form.value.name | ||
108 | } | ||
109 | |||
110 | private uploadAvatar () { | ||
111 | if (!this.avatar) return of(undefined) | ||
112 | |||
113 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.avatar, 'avatar') | ||
114 | } | ||
115 | |||
116 | private uploadBanner () { | ||
117 | if (!this.banner) return of(undefined) | ||
118 | |||
119 | return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.banner, 'banner') | ||
120 | } | ||
79 | } | 121 | } |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html index 7b8928907..2910dffad 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html | |||
@@ -10,7 +10,7 @@ | |||
10 | <ng-container *ngIf="!isCreation()"> | 10 | <ng-container *ngIf="!isCreation()"> |
11 | <li class="breadcrumb-item active" i18n>Edit</li> | 11 | <li class="breadcrumb-item active" i18n>Edit</li> |
12 | <li class="breadcrumb-item active" aria-current="page"> | 12 | <li class="breadcrumb-item active" aria-current="page"> |
13 | <a *ngIf="videoChannelToUpdate" [routerLink]="[ '/my-library/video-channels/update', videoChannelToUpdate?.nameWithHost ]">{{ videoChannelToUpdate?.displayName }}</a> | 13 | <a *ngIf="videoChannel" [routerLink]="[ '/my-library/video-channels/update', videoChannel?.nameWithHost ]">{{ videoChannel?.displayName }}</a> |
14 | </li> | 14 | </li> |
15 | </ng-container> | 15 | </ng-container> |
16 | </ol> | 16 | </ol> |
@@ -23,10 +23,22 @@ | |||
23 | <div class="form-row"> <!-- channel grid --> | 23 | <div class="form-row"> <!-- channel grid --> |
24 | <div class="form-group col-12 col-lg-4 col-xl-3"> | 24 | <div class="form-group col-12 col-lg-4 col-xl-3"> |
25 | <div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div> | 25 | <div *ngIf="isCreation()" class="video-channel-title" i18n>NEW CHANNEL</div> |
26 | <div *ngIf="!isCreation() && videoChannelToUpdate" class="video-channel-title" i18n>CHANNEL</div> | 26 | <div *ngIf="!isCreation() && videoChannel" class="video-channel-title" i18n>CHANNEL</div> |
27 | </div> | 27 | </div> |
28 | 28 | ||
29 | <div class="form-group col-12 col-lg-8 col-xl-9"> | 29 | <div class="form-group col-12 col-lg-8 col-xl-9"> |
30 | <h6 i18n>Banner image of your channel</h6> | ||
31 | |||
32 | <my-actor-banner-edit | ||
33 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
34 | [actor]="videoChannel" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()" | ||
35 | ></my-actor-banner-edit> | ||
36 | |||
37 | <my-actor-avatar-edit | ||
38 | *ngIf="videoChannel" [previewImage]="isCreation()" | ||
39 | [actor]="videoChannel" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()" | ||
40 | [displayUsername]="!isCreation()" [displaySubscribers]="!isCreation()" | ||
41 | ></my-actor-avatar-edit> | ||
30 | 42 | ||
31 | <div class="form-group" *ngIf="isCreation()"> | 43 | <div class="form-group" *ngIf="isCreation()"> |
32 | <label i18n for="name">Name</label> | 44 | <label i18n for="name">Name</label> |
@@ -44,18 +56,6 @@ | |||
44 | </div> | 56 | </div> |
45 | </div> | 57 | </div> |
46 | 58 | ||
47 | <h6 i18n>Banner image of your channel</h6> | ||
48 | |||
49 | <my-actor-banner-edit | ||
50 | *ngIf="!isCreation() && videoChannelToUpdate" | ||
51 | [actor]="videoChannelToUpdate" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()" | ||
52 | ></my-actor-banner-edit> | ||
53 | |||
54 | <my-actor-avatar-edit | ||
55 | *ngIf="!isCreation() && videoChannelToUpdate" | ||
56 | [actor]="videoChannelToUpdate" (avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()" | ||
57 | ></my-actor-avatar-edit> | ||
58 | |||
59 | <div class="form-group"> | 59 | <div class="form-group"> |
60 | <label i18n for="display-name">Display name</label> | 60 | <label i18n for="display-name">Display name</label> |
61 | <input | 61 | <input |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts index 0cdf2fe34..33bb90f14 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts | |||
@@ -2,8 +2,7 @@ import { FormReactive } from '@app/shared/shared-forms' | |||
2 | import { VideoChannel } from '@app/shared/shared-main' | 2 | import { VideoChannel } from '@app/shared/shared-main' |
3 | 3 | ||
4 | export abstract class MyVideoChannelEdit extends FormReactive { | 4 | export abstract class MyVideoChannelEdit extends FormReactive { |
5 | // We need it even in the create component because it's used in the edit template | 5 | videoChannel: VideoChannel |
6 | videoChannelToUpdate: VideoChannel | ||
7 | 6 | ||
8 | abstract isCreation (): boolean | 7 | abstract isCreation (): boolean |
9 | abstract getFormButtonTitle (): string | 8 | abstract getFormButtonTitle (): string |
@@ -12,12 +11,6 @@ export abstract class MyVideoChannelEdit extends FormReactive { | |||
12 | return window.location.host | 11 | return window.location.host |
13 | } | 12 | } |
14 | 13 | ||
15 | // We need this method so angular does not complain in child template that doesn't need this | ||
16 | onAvatarChange (formData: FormData) { /* empty */ } | ||
17 | onAvatarDelete () { /* empty */ } | ||
18 | onBannerChange (formData: FormData) { /* empty */ } | ||
19 | onBannerDelete () { /* empty */ } | ||
20 | |||
21 | // Should be implemented by the child | 14 | // Should be implemented by the child |
22 | isBulkUpdateVideosDisplayed () { | 15 | isBulkUpdateVideosDisplayed () { |
23 | return false | 16 | return false |
diff --git a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts index 22935a87a..a29af176c 100644 --- a/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts +++ b/client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts | |||
@@ -21,7 +21,7 @@ import { MyVideoChannelEdit } from './my-video-channel-edit' | |||
21 | }) | 21 | }) |
22 | export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { | 22 | export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements OnInit, OnDestroy { |
23 | error: string | 23 | error: string |
24 | videoChannelToUpdate: VideoChannel | 24 | videoChannel: VideoChannel |
25 | 25 | ||
26 | private paramsSub: Subscription | 26 | private paramsSub: Subscription |
27 | private oldSupportField: string | 27 | private oldSupportField: string |
@@ -56,7 +56,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
56 | 56 | ||
57 | this.videoChannelService.getVideoChannel(videoChannelId).subscribe( | 57 | this.videoChannelService.getVideoChannel(videoChannelId).subscribe( |
58 | videoChannelToUpdate => { | 58 | videoChannelToUpdate => { |
59 | this.videoChannelToUpdate = videoChannelToUpdate | 59 | this.videoChannel = videoChannelToUpdate |
60 | 60 | ||
61 | this.oldSupportField = videoChannelToUpdate.support | 61 | this.oldSupportField = videoChannelToUpdate.support |
62 | 62 | ||
@@ -87,7 +87,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
87 | bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false | 87 | bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false |
88 | } | 88 | } |
89 | 89 | ||
90 | this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.name, videoChannelUpdate).subscribe( | 90 | this.videoChannelService.updateVideoChannel(this.videoChannel.name, videoChannelUpdate).subscribe( |
91 | () => { | 91 | () => { |
92 | this.authService.refreshUserInformation() | 92 | this.authService.refreshUserInformation() |
93 | 93 | ||
@@ -101,12 +101,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
101 | } | 101 | } |
102 | 102 | ||
103 | onAvatarChange (formData: FormData) { | 103 | onAvatarChange (formData: FormData) { |
104 | this.videoChannelService.changeVideoChannelImage(this.videoChannelToUpdate.name, formData, 'avatar') | 104 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'avatar') |
105 | .subscribe( | 105 | .subscribe( |
106 | data => { | 106 | data => { |
107 | this.notifier.success($localize`Avatar changed.`) | 107 | this.notifier.success($localize`Avatar changed.`) |
108 | 108 | ||
109 | this.videoChannelToUpdate.updateAvatar(data.avatar) | 109 | this.videoChannel.updateAvatar(data.avatar) |
110 | }, | 110 | }, |
111 | 111 | ||
112 | (err: HttpErrorResponse) => uploadErrorHandler({ | 112 | (err: HttpErrorResponse) => uploadErrorHandler({ |
@@ -118,12 +118,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
118 | } | 118 | } |
119 | 119 | ||
120 | onAvatarDelete () { | 120 | onAvatarDelete () { |
121 | this.videoChannelService.deleteVideoChannelImage(this.videoChannelToUpdate.name, 'avatar') | 121 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'avatar') |
122 | .subscribe( | 122 | .subscribe( |
123 | data => { | 123 | data => { |
124 | this.notifier.success($localize`Avatar deleted.`) | 124 | this.notifier.success($localize`Avatar deleted.`) |
125 | 125 | ||
126 | this.videoChannelToUpdate.resetAvatar() | 126 | this.videoChannel.resetAvatar() |
127 | }, | 127 | }, |
128 | 128 | ||
129 | err => this.notifier.error(err.message) | 129 | err => this.notifier.error(err.message) |
@@ -131,12 +131,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
131 | } | 131 | } |
132 | 132 | ||
133 | onBannerChange (formData: FormData) { | 133 | onBannerChange (formData: FormData) { |
134 | this.videoChannelService.changeVideoChannelImage(this.videoChannelToUpdate.name, formData, 'banner') | 134 | this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'banner') |
135 | .subscribe( | 135 | .subscribe( |
136 | data => { | 136 | data => { |
137 | this.notifier.success($localize`Banner changed.`) | 137 | this.notifier.success($localize`Banner changed.`) |
138 | 138 | ||
139 | this.videoChannelToUpdate.updateBanner(data.banner) | 139 | this.videoChannel.updateBanner(data.banner) |
140 | }, | 140 | }, |
141 | 141 | ||
142 | (err: HttpErrorResponse) => uploadErrorHandler({ | 142 | (err: HttpErrorResponse) => uploadErrorHandler({ |
@@ -148,12 +148,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements | |||
148 | } | 148 | } |
149 | 149 | ||
150 | onBannerDelete () { | 150 | onBannerDelete () { |
151 | this.videoChannelService.deleteVideoChannelImage(this.videoChannelToUpdate.name, 'banner') | 151 | this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'banner') |
152 | .subscribe( | 152 | .subscribe( |
153 | data => { | 153 | data => { |
154 | this.notifier.success($localize`Banner deleted.`) | 154 | this.notifier.success($localize`Banner deleted.`) |
155 | 155 | ||
156 | this.videoChannelToUpdate.resetBanner() | 156 | this.videoChannel.resetBanner() |
157 | }, | 157 | }, |
158 | 158 | ||
159 | err => this.notifier.error(err.message) | 159 | err => this.notifier.error(err.message) |
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.html b/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.html index 10f2ef262..0829263f4 100644 --- a/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.html +++ b/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <div class="actor" *ngIf="actor"> | 1 | <div class="actor" *ngIf="actor"> |
2 | <div class="d-flex"> | 2 | <div class="d-flex"> |
3 | <img [ngClass]="{ channel: isChannel() }" [src]="actor.avatarUrl" alt="Avatar" /> | 3 | <img [ngClass]="{ channel: isChannel() }" [src]="preview || actor.avatarUrl" alt="Avatar" /> |
4 | 4 | ||
5 | <div class="actor-img-edit-container"> | 5 | <div class="actor-img-edit-container"> |
6 | 6 | ||
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.ts b/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.ts index 6f76172e9..d0d269489 100644 --- a/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.ts +++ b/client/src/app/shared/shared-actor-image/actor-avatar-edit.component.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' |
2 | import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' | ||
2 | import { Notifier, ServerService } from '@app/core' | 3 | import { Notifier, ServerService } from '@app/core' |
3 | import { Account, VideoChannel } from '@app/shared/shared-main' | 4 | import { Account, VideoChannel } from '@app/shared/shared-main' |
4 | import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' | 5 | import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' |
@@ -20,6 +21,7 @@ export class ActorAvatarEditComponent implements OnInit { | |||
20 | @Input() editable = true | 21 | @Input() editable = true |
21 | @Input() displaySubscribers = true | 22 | @Input() displaySubscribers = true |
22 | @Input() displayUsername = true | 23 | @Input() displayUsername = true |
24 | @Input() previewImage = false | ||
23 | 25 | ||
24 | @Output() avatarChange = new EventEmitter<FormData>() | 26 | @Output() avatarChange = new EventEmitter<FormData>() |
25 | @Output() avatarDelete = new EventEmitter<void>() | 27 | @Output() avatarDelete = new EventEmitter<void>() |
@@ -28,7 +30,10 @@ export class ActorAvatarEditComponent implements OnInit { | |||
28 | maxAvatarSize = 0 | 30 | maxAvatarSize = 0 |
29 | avatarExtensions = '' | 31 | avatarExtensions = '' |
30 | 32 | ||
33 | preview: SafeResourceUrl | ||
34 | |||
31 | constructor ( | 35 | constructor ( |
36 | private sanitizer: DomSanitizer, | ||
32 | private serverService: ServerService, | 37 | private serverService: ServerService, |
33 | private notifier: Notifier | 38 | private notifier: Notifier |
34 | ) { } | 39 | ) { } |
@@ -57,14 +62,19 @@ export class ActorAvatarEditComponent implements OnInit { | |||
57 | formData.append('avatarfile', avatarfile) | 62 | formData.append('avatarfile', avatarfile) |
58 | this.avatarPopover?.close() | 63 | this.avatarPopover?.close() |
59 | this.avatarChange.emit(formData) | 64 | this.avatarChange.emit(formData) |
65 | |||
66 | if (this.previewImage) { | ||
67 | this.preview = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(avatarfile)) | ||
68 | } | ||
60 | } | 69 | } |
61 | 70 | ||
62 | deleteAvatar () { | 71 | deleteAvatar () { |
72 | this.preview = undefined | ||
63 | this.avatarDelete.emit() | 73 | this.avatarDelete.emit() |
64 | } | 74 | } |
65 | 75 | ||
66 | hasAvatar () { | 76 | hasAvatar () { |
67 | return !!this.actor.avatar | 77 | return !!this.preview || !!this.actor.avatar |
68 | } | 78 | } |
69 | 79 | ||
70 | isChannel () { | 80 | isChannel () { |
diff --git a/client/src/app/shared/shared-actor-image/actor-banner-edit.component.html b/client/src/app/shared/shared-actor-image/actor-banner-edit.component.html index eb1b66422..266fc26c5 100644 --- a/client/src/app/shared/shared-actor-image/actor-banner-edit.component.html +++ b/client/src/app/shared/shared-actor-image/actor-banner-edit.component.html | |||
@@ -1,7 +1,7 @@ | |||
1 | <div class="actor" *ngIf="actor"> | 1 | <div class="actor" *ngIf="actor"> |
2 | <div class="actor-img-edit-container"> | 2 | <div class="actor-img-edit-container"> |
3 | <div class="banner-placeholder"> | 3 | <div class="banner-placeholder"> |
4 | <img *ngIf="hasBanner()" [src]="actor.bannerUrl" alt="Banner" /> | 4 | <img *ngIf="hasBanner()" [src]="preview || actor.bannerUrl" alt="Banner" /> |
5 | </div> | 5 | </div> |
6 | 6 | ||
7 | <div *ngIf="!hasBanner()" class="actor-img-edit-button" [ngbTooltip]="bannerFormat" placement="right" container="body"> | 7 | <div *ngIf="!hasBanner()" class="actor-img-edit-button" [ngbTooltip]="bannerFormat" placement="right" container="body"> |
diff --git a/client/src/app/shared/shared-actor-image/actor-banner-edit.component.ts b/client/src/app/shared/shared-actor-image/actor-banner-edit.component.ts index 48451744c..8c12d3c4c 100644 --- a/client/src/app/shared/shared-actor-image/actor-banner-edit.component.ts +++ b/client/src/app/shared/shared-actor-image/actor-banner-edit.component.ts | |||
@@ -1,4 +1,5 @@ | |||
1 | import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core' |
2 | import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' | ||
2 | import { Notifier, ServerService } from '@app/core' | 3 | import { Notifier, ServerService } from '@app/core' |
3 | import { VideoChannel } from '@app/shared/shared-main' | 4 | import { VideoChannel } from '@app/shared/shared-main' |
4 | import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' | 5 | import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' |
@@ -17,6 +18,7 @@ export class ActorBannerEditComponent implements OnInit { | |||
17 | @ViewChild('bannerPopover') bannerPopover: NgbPopover | 18 | @ViewChild('bannerPopover') bannerPopover: NgbPopover |
18 | 19 | ||
19 | @Input() actor: VideoChannel | 20 | @Input() actor: VideoChannel |
21 | @Input() previewImage = false | ||
20 | 22 | ||
21 | @Output() bannerChange = new EventEmitter<FormData>() | 23 | @Output() bannerChange = new EventEmitter<FormData>() |
22 | @Output() bannerDelete = new EventEmitter<void>() | 24 | @Output() bannerDelete = new EventEmitter<void>() |
@@ -25,7 +27,10 @@ export class ActorBannerEditComponent implements OnInit { | |||
25 | maxBannerSize = 0 | 27 | maxBannerSize = 0 |
26 | bannerExtensions = '' | 28 | bannerExtensions = '' |
27 | 29 | ||
30 | preview: SafeResourceUrl | ||
31 | |||
28 | constructor ( | 32 | constructor ( |
33 | private sanitizer: DomSanitizer, | ||
29 | private serverService: ServerService, | 34 | private serverService: ServerService, |
30 | private notifier: Notifier | 35 | private notifier: Notifier |
31 | ) { } | 36 | ) { } |
@@ -54,13 +59,18 @@ export class ActorBannerEditComponent implements OnInit { | |||
54 | formData.append('bannerfile', bannerfile) | 59 | formData.append('bannerfile', bannerfile) |
55 | this.bannerPopover?.close() | 60 | this.bannerPopover?.close() |
56 | this.bannerChange.emit(formData) | 61 | this.bannerChange.emit(formData) |
62 | |||
63 | if (this.previewImage) { | ||
64 | this.preview = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(bannerfile)) | ||
65 | } | ||
57 | } | 66 | } |
58 | 67 | ||
59 | deleteBanner () { | 68 | deleteBanner () { |
69 | this.preview = undefined | ||
60 | this.bannerDelete.emit() | 70 | this.bannerDelete.emit() |
61 | } | 71 | } |
62 | 72 | ||
63 | hasBanner () { | 73 | hasBanner () { |
64 | return !!this.actor.bannerUrl | 74 | return !!this.preview || !!this.actor.bannerUrl |
65 | } | 75 | } |
66 | } | 76 | } |
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 670823060..1ee0c297e 100644 --- a/client/src/app/shared/shared-main/account/actor.model.ts +++ b/client/src/app/shared/shared-main/account/actor.model.ts | |||
@@ -47,11 +47,11 @@ export abstract class Actor implements ActorServer { | |||
47 | return host.trim() === thisHost | 47 | return host.trim() === thisHost |
48 | } | 48 | } |
49 | 49 | ||
50 | protected constructor (hash: ActorServer) { | 50 | protected constructor (hash: Partial<ActorServer>) { |
51 | this.id = hash.id | 51 | this.id = hash.id |
52 | this.url = hash.url | 52 | this.url = hash.url ?? '' |
53 | this.name = hash.name | 53 | this.name = hash.name ?? '' |
54 | this.host = hash.host | 54 | this.host = hash.host ?? '' |
55 | this.followingCount = hash.followingCount | 55 | this.followingCount = hash.followingCount |
56 | this.followersCount = hash.followersCount | 56 | this.followersCount = hash.followersCount |
57 | 57 | ||
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 d8be42eef..1ba3fcc0e 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 | |||
@@ -44,7 +44,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
44 | return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png` | 44 | return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png` |
45 | } | 45 | } |
46 | 46 | ||
47 | constructor (hash: ServerVideoChannel) { | 47 | constructor (hash: Partial<ServerVideoChannel>) { |
48 | super(hash) | 48 | super(hash) |
49 | 49 | ||
50 | this.displayName = hash.displayName | 50 | this.displayName = hash.displayName |
@@ -93,7 +93,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
93 | this.updateBanner(null) | 93 | this.updateBanner(null) |
94 | } | 94 | } |
95 | 95 | ||
96 | private updateComputedAttributes () { | 96 | updateComputedAttributes () { |
97 | 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) | 98 | this.bannerUrl = VideoChannel.GET_ACTOR_BANNER_URL(this) |
99 | } | 99 | } |