From cdeddff142fd20f8cb8bb346625909d61c596603 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 7 Apr 2021 17:01:29 +0200 Subject: Add ability to update the banner --- .../account/actor-avatar-info.component.html | 42 ---------- .../account/actor-avatar-info.component.scss | 92 ---------------------- .../account/actor-avatar-info.component.ts | 77 ------------------ .../app/shared/shared-main/account/actor.model.ts | 9 ++- client/src/app/shared/shared-main/account/index.ts | 2 - .../account/video-avatar-channel.component.html | 27 ------- .../account/video-avatar-channel.component.scss | 44 ----------- .../account/video-avatar-channel.component.ts | 27 ------- .../app/shared/shared-main/shared-main.module.ts | 14 +--- .../video-channel/video-channel.model.ts | 40 +++++++++- .../video-channel/video-channel.service.ts | 10 +-- 11 files changed, 52 insertions(+), 332 deletions(-) delete mode 100644 client/src/app/shared/shared-main/account/actor-avatar-info.component.html delete mode 100644 client/src/app/shared/shared-main/account/actor-avatar-info.component.scss delete mode 100644 client/src/app/shared/shared-main/account/actor-avatar-info.component.ts delete mode 100644 client/src/app/shared/shared-main/account/video-avatar-channel.component.html delete mode 100644 client/src/app/shared/shared-main/account/video-avatar-channel.component.scss delete mode 100644 client/src/app/shared/shared-main/account/video-avatar-channel.component.ts (limited to 'client/src/app/shared/shared-main') 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 @@ - -
-
- Avatar - -
- -
- - - -
- -
- - -
- -
-
- -
-
-
{{ actor.displayName }}
-
{{ actor.name }}
-
-
{{ actor.followersCount }} subscribers
-
-
-
- - - - - 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 @@ -@import '_variables'; -@import '_mixins'; - -.actor { - display: flex; - - img { - margin-right: 15px; - - &:not(.channel) { - @include avatar(100px); - } - - &.channel { - @include channel-avatar(100px); - } - } - - .actor-img-edit-container { - position: relative; - width: 0; - - .actor-img-edit-button { - @include peertube-button-file(21px); - @include button-with-icon(19px); - @include orange-button; - - margin-top: 10px; - margin-bottom: 5px; - border-radius: 50%; - top: 55px; - right: 45px; - cursor: pointer; - - input { - width: 30px; - height: 30px; - } - - my-global-icon { - right: 7px; - } - } - } - - .actor-info { - justify-content: center; - display: inline-flex; - flex-direction: column; - - .actor-info-names { - display: flex; - align-items: center; - - .actor-info-display-name { - font-size: 20px; - font-weight: $font-bold; - - @media screen and (max-width: $small-view) { - font-size: 16px; - } - } - - .actor-info-username { - margin-left: 7px; - position: relative; - top: 2px; - font-size: 14px; - color: $grey-actor-name; - } - } - - .actor-info-followers { - font-size: 15px; - padding-bottom: .5rem; - } - } -} - -.actor-img-edit-container ::ng-deep .popover-avatar-info .popover-body { - padding: 0; - - .dropdown-item { - padding: 6px 10px; - border-radius: 4px; - - &:first-child { - @include peertube-file; - display: block; - } - } -} 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 @@ -import { Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core' -import { Notifier, ServerService } from '@app/core' -import { NgbPopover } from '@ng-bootstrap/ng-bootstrap' -import { getBytes } from '@root-helpers/bytes' -import { Account } from '../account/account.model' -import { VideoChannel } from '../video-channel/video-channel.model' -import { Actor } from './actor.model' - -@Component({ - selector: 'my-actor-avatar-info', - templateUrl: './actor-avatar-info.component.html', - styleUrls: [ './actor-avatar-info.component.scss' ] -}) -export class ActorAvatarInfoComponent implements OnInit, OnChanges { - @ViewChild('avatarfileInput') avatarfileInput: ElementRef - @ViewChild('avatarPopover') avatarPopover: NgbPopover - - @Input() actor: VideoChannel | Account - - @Output() avatarChange = new EventEmitter() - @Output() avatarDelete = new EventEmitter() - - avatarFormat = '' - maxAvatarSize = 0 - avatarExtensions = '' - - private avatarUrl: string - - constructor ( - private serverService: ServerService, - private notifier: Notifier - ) { } - - ngOnInit (): void { - this.serverService.getConfig() - .subscribe(config => { - this.maxAvatarSize = config.avatar.file.size.max - this.avatarExtensions = config.avatar.file.extensions.join(', ') - - this.avatarFormat = `${$localize`max size`}: 192*192px, ` + - `${getBytes(this.maxAvatarSize)} ${$localize`extensions`}: ${this.avatarExtensions}` - }) - } - - ngOnChanges (changes: SimpleChanges) { - if (changes['actor']) { - this.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.actor) - } - } - - onAvatarChange (input: HTMLInputElement) { - this.avatarfileInput = new ElementRef(input) - - const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ] - if (avatarfile.size > this.maxAvatarSize) { - this.notifier.error('Error', $localize`This image is too large.`) - return - } - - const formData = new FormData() - formData.append('avatarfile', avatarfile) - this.avatarPopover?.close() - this.avatarChange.emit(formData) - } - - deleteAvatar () { - this.avatarDelete.emit() - } - - hasAvatar () { - return !!this.avatarUrl - } - - isChannel () { - return !!(this.actor as VideoChannel).ownerAccount - } -} 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' export abstract class Actor implements ActorServer { id: number - url: string name: string + host: string + url: string + followingCount: number followersCount: number + createdAt: Date | string updatedAt: Date | string - avatar: ActorImage + avatar: ActorImage avatarUrl: string isLocal: boolean @@ -24,6 +27,8 @@ export abstract class Actor implements ActorServer { return absoluteAPIUrl + actor.avatar.path } + + return '' } 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 @@ export * from './account.model' export * from './account.service' -export * from './actor-avatar-info.component' export * from './actor.model' -export * 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 @@ -
- - - Channel avatar - - - - Account avatar - - - - - - Account avatar - - - - Channel avatar - - - - - - Account avatar - - -
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 @@ -@import '_mixins'; - -.wrapper { - $avatar-size: 35px; - - width: $avatar-size; - height: $avatar-size; - position: relative; - margin-right: 5px; - margin-bottom: 5px; - - &.avatar-sm { - width: 28px; - height: 28px; - margin-bottom: 3px; - } - - a { - @include disable-outline; - } - - a img { - height: 100%; - object-fit: cover; - position: absolute; - top:50%; - left:50%; - transform: translate(-50%,-50%); - border-radius: 5px; - - &:not(.channel-avatar) { - border-radius: 50%; - } - } - - a:nth-of-type(2) img { - height: 60%; - width: 60%; - border: 2px solid pvar(--mainBackgroundColor); - transform: translateX(15%); - position: relative; - background-color: pvar(--mainBackgroundColor); - } -} 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 @@ -import { Component, Input, OnInit } from '@angular/core' -import { Video } from '../video/video.model' - -@Component({ - selector: 'my-video-avatar-channel', - templateUrl: './video-avatar-channel.component.html', - styleUrls: [ './video-avatar-channel.component.scss' ] -}) -export class VideoAvatarChannelComponent implements OnInit { - @Input() video: Video - @Input() byAccount: string - - @Input() size: 'md' | 'sm' = 'md' - @Input() genericChannel: boolean - - channelLinkTitle = '' - accountLinkTitle = '' - - ngOnInit () { - this.channelLinkTitle = $localize`${this.video.account.name} (channel page)` - this.accountLinkTitle = $localize`${this.video.byAccount} (account page)` - } - - isChannelAvatarNull () { - return this.video.channel.avatar === null - } -} 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' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { RouterModule } from '@angular/router' import { + NgbButtonsModule, NgbCollapseModule, NgbDropdownModule, NgbModalModule, NgbNavModule, NgbPopoverModule, - NgbTooltipModule, - NgbButtonsModule + NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' import { LoadingBarModule } from '@ngx-loading-bar/core' import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' import { SharedGlobalIconModule } from '../shared-icons' -import { AccountService, ActorAvatarInfoComponent, VideoAvatarChannelComponent } from './account' +import { AccountService } from './account' import { AutofocusDirective, BytesPipe, @@ -32,7 +32,7 @@ import { ActionDropdownComponent, ButtonComponent, DeleteButtonComponent, EditBu import { DateToggleComponent } from './date' import { FeedComponent } from './feeds' import { LoaderComponent, SmallLoaderComponent } from './loaders' -import { HelpComponent, ListOverflowComponent, TopMenuDropdownComponent, SimpleSearchInputComponent } from './misc' +import { HelpComponent, ListOverflowComponent, SimpleSearchInputComponent, TopMenuDropdownComponent } from './misc' import { UserHistoryService, UserNotificationsComponent, UserNotificationService, UserQuotaComponent } from './users' import { RedundancyService, VideoImportService, VideoOwnershipService, VideoService } from './video' import { VideoCaptionService } from './video-caption' @@ -65,9 +65,6 @@ import { VideoChannelService } from './video-channel' ], declarations: [ - VideoAvatarChannelComponent, - ActorAvatarInfoComponent, - FromNowPipe, NumberFormatterPipe, BytesPipe, @@ -120,9 +117,6 @@ import { VideoChannelService } from './video-channel' PrimeSharedModule, - VideoAvatarChannelComponent, - ActorAvatarInfoComponent, - FromNowPipe, BytesPipe, 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 @@ +import { getAbsoluteAPIUrl } from '@app/helpers' import { Account as ServerAccount, ActorImage, VideoChannel as ServerVideoChannel, ViewsPerDate } from '@shared/models' import { Account } from '../account/account.model' import { Actor } from '../account/actor.model' @@ -6,10 +7,15 @@ export class VideoChannel extends Actor implements ServerVideoChannel { displayName: string description: string support: string + isLocal: boolean + nameWithHost: string nameWithHostForced: string + banner: ActorImage + bannerUrl: string + ownerAccount?: ServerAccount ownerBy?: string ownerAvatarUrl?: string @@ -22,6 +28,18 @@ export class VideoChannel extends Actor implements ServerVideoChannel { return Actor.GET_ACTOR_AVATAR_URL(actor) || this.GET_DEFAULT_AVATAR_URL() } + static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) { + if (channel?.banner?.url) return channel.banner.url + + if (channel && channel.banner) { + const absoluteAPIUrl = getAbsoluteAPIUrl() + + return absoluteAPIUrl + channel.banner.path + } + + return '' + } + static GET_DEFAULT_AVATAR_URL () { return `${window.location.origin}/client/assets/images/default-avatar-videochannel.png` } @@ -29,12 +47,14 @@ export class VideoChannel extends Actor implements ServerVideoChannel { constructor (hash: ServerVideoChannel) { super(hash) - this.updateComputedAttributes() - this.displayName = hash.displayName this.description = hash.description this.support = hash.support + + this.banner = hash.banner + this.isLocal = hash.isLocal + this.nameWithHost = Actor.CREATE_BY_STRING(this.name, this.host) this.nameWithHostForced = Actor.CREATE_BY_STRING(this.name, this.host, true) @@ -49,6 +69,8 @@ export class VideoChannel extends Actor implements ServerVideoChannel { this.ownerBy = Actor.CREATE_BY_STRING(hash.ownerAccount.name, hash.ownerAccount.host) this.ownerAvatarUrl = Account.GET_ACTOR_AVATAR_URL(this.ownerAccount) } + + this.updateComputedAttributes() } updateAvatar (newAvatar: ActorImage) { @@ -58,11 +80,21 @@ export class VideoChannel extends Actor implements ServerVideoChannel { } resetAvatar () { - this.avatar = null - this.avatarUrl = VideoChannel.GET_DEFAULT_AVATAR_URL() + this.updateAvatar(null) + } + + updateBanner (newBanner: ActorImage) { + this.banner = newBanner + + this.updateComputedAttributes() + } + + resetBanner () { + this.updateBanner(null) } private updateComputedAttributes () { this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this) + this.bannerUrl = VideoChannel.GET_ACTOR_BANNER_URL(this) } } 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 { ) } - changeVideoChannelAvatar (videoChannelName: string, avatarForm: FormData) { - const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/avatar/pick' + changeVideoChannelImage (videoChannelName: string, avatarForm: FormData, type: 'avatar' | 'banner') { + const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type + '/pick' - return this.authHttp.post<{ avatar: ActorImage }>(url, avatarForm) + return this.authHttp.post<{ avatar?: ActorImage, banner?: ActorImage }>(url, avatarForm) .pipe(catchError(err => this.restExtractor.handleError(err))) } - deleteVideoChannelAvatar (videoChannelName: string) { - const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/avatar' + deleteVideoChannelImage (videoChannelName: string, type: 'avatar' | 'banner') { + const url = VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannelName + '/' + type return this.authHttp.delete(url) .pipe( -- cgit v1.2.3