-import { Component, Input } from '@angular/core'
+import { Component, Input, OnChanges, OnInit } from '@angular/core'
import { VideoChannel } from '../shared-main'
import { Account } from '../shared-main/account/account.model'
styleUrls: [ './actor-avatar.component.scss' ],
templateUrl: './actor-avatar.component.html'
})
-export class ActorAvatarComponent {
+export class ActorAvatarComponent implements OnInit, OnChanges {
private _title: string
- @Input() account: ActorInput
- @Input() channel: ActorInput
+ @Input() actor: ActorInput
+ @Input() actorType: 'channel' | 'account' | 'unlogged'
@Input() previewImage: string
- @Input() size: ActorAvatarSize = '32'
+ @Input() size: ActorAvatarSize
// Use an external link
@Input() href: string
get title () {
if (this._title) return this._title
- if (this.account) return $localize`${this.account.name} (account page)`
- if (this.channel) return $localize`${this.channel.name} (channel page)`
+ if (this.isAccount()) return $localize`${this.actor.name} (account page)`
+ if (this.isChannel()) return $localize`${this.actor.name} (channel page)`
return ''
}
- get alt () {
- if (this.account) return $localize`Account avatar`
- if (this.channel) return $localize`Channel avatar`
+ classes: string[] = []
+ defaultAvatarUrl: string
+ avatarUrl: string
- return ''
+ ngOnInit () {
+ this.buildDefaultAvatarUrl()
+
+ this.buildAvatarUrl()
+ this.buildClasses()
}
- get defaultAvatarUrl () {
- if (this.account) return Account.GET_DEFAULT_AVATAR_URL(+this.size)
- if (this.channel) return VideoChannel.GET_DEFAULT_AVATAR_URL(+this.size)
+ ngOnChanges () {
+ this.buildAvatarUrl()
+ this.buildClasses()
}
- get avatarUrl () {
- if (this.account) return Account.GET_ACTOR_AVATAR_URL(this.account, +this.size)
- if (this.channel) return VideoChannel.GET_ACTOR_AVATAR_URL(this.channel, +this.size)
+ private buildClasses () {
+ this.classes = [ 'avatar' ]
- return ''
- }
+ if (this.size) {
+ this.classes.push(`avatar-${this.size}`)
+ }
- get initial () {
- const name = this.account?.name
- if (!name) return ''
+ if (this.isChannel()) {
+ this.classes.push('channel')
+ } else {
+ this.classes.push('account')
+ }
- return name.slice(0, 1)
+ // No avatar, use actor name initial
+ if (this.displayActorInitial()) {
+ this.classes.push('initial')
+ this.classes.push(this.getColorTheme())
+ }
}
- getClass (type: 'avatar' | 'initial') {
- const base = [ 'avatar' ]
+ private buildDefaultAvatarUrl () {
+ this.defaultAvatarUrl = this.isChannel()
+ ? VideoChannel.GET_DEFAULT_AVATAR_URL(this.getSizeNumber())
+ : Account.GET_DEFAULT_AVATAR_URL(this.getSizeNumber())
+ }
- if (this.size) base.push(`avatar-${this.size}`)
+ private buildAvatarUrl () {
+ if (!this.actor) {
+ this.avatarUrl = ''
+ return
+ }
- if (this.channel) base.push('channel')
- else base.push('account')
+ if (this.isAccount()) {
+ this.avatarUrl = Account.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber())
+ return
+ }
- if (type === 'initial' && this.initial) {
- base.push('initial')
- base.push(this.getColorTheme())
+ if (this.isChannel()) {
+ this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber())
+ return
}
- return base
+ this.avatarUrl = ''
+ }
+
+ displayImage () {
+ if (this.actorType === 'unlogged') return true
+ if (this.previewImage) return true
+
+ return !!(this.actor && this.avatarUrl)
}
- hasActor () {
- return !!this.account || !!this.channel
+ displayActorInitial () {
+ return !this.displayImage() && this.actor && !this.avatarUrl
+ }
+
+ displayPlaceholder () {
+ return this.actorType !== 'unlogged' && !this.actor
+ }
+
+ getActorInitial () {
+ const name = this.actor?.name
+ if (!name) return ''
+
+ return name.slice(0, 1)
+ }
+
+ private isAccount () {
+ return this.actorType === 'account'
+ }
+
+ private isChannel () {
+ return this.actorType === 'channel'
+ }
+
+ private getSizeNumber () {
+ if (this.size) return +this.size
+
+ return undefined
}
private getColorTheme () {
+ const initialLowercase = this.getActorInitial().toLowerCase()
+
// Keep consistency with CSS
const themes = {
- abc: 'blue',
- def: 'green',
- ghi: 'purple',
- jkl: 'gray',
- mno: 'yellow',
- pqr: 'orange',
- stvu: 'red',
- wxyz: 'dark-blue'
+ '0123456789abc': 'blue',
+ 'def': 'green',
+ 'ghi': 'purple',
+ 'jkl': 'gray',
+ 'mno': 'yellow',
+ 'pqr': 'orange',
+ 'stvu': 'red',
+ 'wxyz': 'dark-blue'
}
const theme = Object.keys(themes)
- .find(chars => chars.includes(this.initial))
+ .find(chars => chars.includes(initialLowercase))
- return themes[theme]
+ return themes[theme] || 'blue'
}
}