From 27ec473f5306621643fcb169be7cfe6b15136265 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 8 Apr 2021 12:09:54 +0200 Subject: [PATCH] Set channel banner/avatar in creation form --- .../my-video-channel-create.component.ts | 70 +++++++++++++++---- .../my-video-channel-edit.component.html | 28 ++++---- .../my-video-channel-edit.ts | 9 +-- .../my-video-channel-update.component.ts | 22 +++--- .../actor-avatar-edit.component.html | 2 +- .../actor-avatar-edit.component.ts | 12 +++- .../actor-banner-edit.component.html | 2 +- .../actor-banner-edit.component.ts | 12 +++- .../shared/shared-main/account/actor.model.ts | 8 +-- .../video-channel/video-channel.model.ts | 4 +- 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 { VIDEO_CHANNEL_SUPPORT_VALIDATOR } from '@app/shared/form-validators/video-channel-validators' import { FormValidatorService } from '@app/shared/shared-forms' -import { VideoChannelService } from '@app/shared/shared-main' +import { VideoChannel, VideoChannelService } from '@app/shared/shared-main' import { VideoChannelCreate } from '@shared/models' import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes' import { MyVideoChannelEdit } from './my-video-channel-edit' +import { switchMap } from 'rxjs/operators' +import { of } from 'rxjs' @Component({ templateUrl: './my-video-channel-edit.component.html', @@ -19,6 +21,10 @@ import { MyVideoChannelEdit } from './my-video-channel-edit' }) export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements OnInit { error: string + videoChannel = new VideoChannel({}) + + private avatar: FormData + private banner: FormData constructor ( protected formValidatorService: FormValidatorService, @@ -50,23 +56,43 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements support: body.support || null } - this.videoChannelService.createVideoChannel(videoChannelCreate).subscribe( - () => { - this.authService.refreshUserInformation() + this.videoChannelService.createVideoChannel(videoChannelCreate) + .pipe( + switchMap(() => this.uploadAvatar()), + switchMap(() => this.uploadBanner()) + ).subscribe( + () => { + this.authService.refreshUserInformation() + + this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) + this.router.navigate(['/my-library', 'video-channels']) + }, - this.notifier.success($localize`Video channel ${videoChannelCreate.displayName} created.`) - this.router.navigate([ '/my-library', 'video-channels' ]) - }, + err => { + if (err.status === HttpStatusCode.CONFLICT_409) { + this.error = $localize`This name already exists on this instance.` + return + } - err => { - if (err.status === HttpStatusCode.CONFLICT_409) { - this.error = $localize`This name already exists on this instance.` - return + this.error = err.message } + ) + } + + onAvatarChange (formData: FormData) { + this.avatar = formData + } + + onAvatarDelete () { + this.avatar = null + } + + onBannerChange (formData: FormData) { + this.banner = formData + } - this.error = err.message - } - ) + onBannerDelete () { + this.banner = null } isCreation () { @@ -76,4 +102,20 @@ export class MyVideoChannelCreateComponent extends MyVideoChannelEdit implements getFormButtonTitle () { return $localize`Create` } + + getUsername () { + return this.form.value.name + } + + private uploadAvatar () { + if (!this.avatar) return of(undefined) + + return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.avatar, 'avatar') + } + + private uploadBanner () { + if (!this.banner) return of(undefined) + + return this.videoChannelService.changeVideoChannelImage(this.getUsername(), this.banner, 'banner') + } } 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 @@ @@ -23,10 +23,22 @@
NEW CHANNEL
-
CHANNEL
+
CHANNEL
+
Banner image of your channel
+ + + +
@@ -44,18 +56,6 @@
-
Banner image of your channel
- - - - -
{ - this.videoChannelToUpdate = videoChannelToUpdate + this.videoChannel = videoChannelToUpdate this.oldSupportField = videoChannelToUpdate.support @@ -87,7 +87,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements bulkVideosSupportUpdate: body.bulkVideosSupportUpdate || false } - this.videoChannelService.updateVideoChannel(this.videoChannelToUpdate.name, videoChannelUpdate).subscribe( + this.videoChannelService.updateVideoChannel(this.videoChannel.name, videoChannelUpdate).subscribe( () => { this.authService.refreshUserInformation() @@ -101,12 +101,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements } onAvatarChange (formData: FormData) { - this.videoChannelService.changeVideoChannelImage(this.videoChannelToUpdate.name, formData, 'avatar') + this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'avatar') .subscribe( data => { this.notifier.success($localize`Avatar changed.`) - this.videoChannelToUpdate.updateAvatar(data.avatar) + this.videoChannel.updateAvatar(data.avatar) }, (err: HttpErrorResponse) => uploadErrorHandler({ @@ -118,12 +118,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements } onAvatarDelete () { - this.videoChannelService.deleteVideoChannelImage(this.videoChannelToUpdate.name, 'avatar') + this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'avatar') .subscribe( data => { this.notifier.success($localize`Avatar deleted.`) - this.videoChannelToUpdate.resetAvatar() + this.videoChannel.resetAvatar() }, err => this.notifier.error(err.message) @@ -131,12 +131,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements } onBannerChange (formData: FormData) { - this.videoChannelService.changeVideoChannelImage(this.videoChannelToUpdate.name, formData, 'banner') + this.videoChannelService.changeVideoChannelImage(this.videoChannel.name, formData, 'banner') .subscribe( data => { this.notifier.success($localize`Banner changed.`) - this.videoChannelToUpdate.updateBanner(data.banner) + this.videoChannel.updateBanner(data.banner) }, (err: HttpErrorResponse) => uploadErrorHandler({ @@ -148,12 +148,12 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements } onBannerDelete () { - this.videoChannelService.deleteVideoChannelImage(this.videoChannelToUpdate.name, 'banner') + this.videoChannelService.deleteVideoChannelImage(this.videoChannel.name, 'banner') .subscribe( data => { this.notifier.success($localize`Banner deleted.`) - this.videoChannelToUpdate.resetBanner() + this.videoChannel.resetBanner() }, 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 @@
- Avatar + Avatar
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 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' import { Notifier, ServerService } from '@app/core' import { Account, VideoChannel } from '@app/shared/shared-main' import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' @@ -20,6 +21,7 @@ export class ActorAvatarEditComponent implements OnInit { @Input() editable = true @Input() displaySubscribers = true @Input() displayUsername = true + @Input() previewImage = false @Output() avatarChange = new EventEmitter() @Output() avatarDelete = new EventEmitter() @@ -28,7 +30,10 @@ export class ActorAvatarEditComponent implements OnInit { maxAvatarSize = 0 avatarExtensions = '' + preview: SafeResourceUrl + constructor ( + private sanitizer: DomSanitizer, private serverService: ServerService, private notifier: Notifier ) { } @@ -57,14 +62,19 @@ export class ActorAvatarEditComponent implements OnInit { formData.append('avatarfile', avatarfile) this.avatarPopover?.close() this.avatarChange.emit(formData) + + if (this.previewImage) { + this.preview = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(avatarfile)) + } } deleteAvatar () { + this.preview = undefined this.avatarDelete.emit() } hasAvatar () { - return !!this.actor.avatar + return !!this.preview || !!this.actor.avatar } 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 @@
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 @@ import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core' +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' import { Notifier, ServerService } from '@app/core' import { VideoChannel } from '@app/shared/shared-main' import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' @@ -17,6 +18,7 @@ export class ActorBannerEditComponent implements OnInit { @ViewChild('bannerPopover') bannerPopover: NgbPopover @Input() actor: VideoChannel + @Input() previewImage = false @Output() bannerChange = new EventEmitter() @Output() bannerDelete = new EventEmitter() @@ -25,7 +27,10 @@ export class ActorBannerEditComponent implements OnInit { maxBannerSize = 0 bannerExtensions = '' + preview: SafeResourceUrl + constructor ( + private sanitizer: DomSanitizer, private serverService: ServerService, private notifier: Notifier ) { } @@ -54,13 +59,18 @@ export class ActorBannerEditComponent implements OnInit { formData.append('bannerfile', bannerfile) this.bannerPopover?.close() this.bannerChange.emit(formData) + + if (this.previewImage) { + this.preview = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(bannerfile)) + } } deleteBanner () { + this.preview = undefined this.bannerDelete.emit() } hasBanner () { - return !!this.actor.bannerUrl + return !!this.preview || !!this.actor.bannerUrl } } 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 { return host.trim() === thisHost } - protected constructor (hash: ActorServer) { + protected constructor (hash: Partial) { this.id = hash.id - this.url = hash.url - this.name = hash.name - this.host = hash.host + this.url = hash.url ?? '' + this.name = hash.name ?? '' + this.host = hash.host ?? '' this.followingCount = hash.followingCount this.followersCount = hash.followersCount 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 { return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png` } - constructor (hash: ServerVideoChannel) { + constructor (hash: Partial) { super(hash) this.displayName = hash.displayName @@ -93,7 +93,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { this.updateBanner(null) } - private updateComputedAttributes () { + updateComputedAttributes () { this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this) this.bannerUrl = VideoChannel.GET_ACTOR_BANNER_URL(this) } -- 2.41.0