]>
Commit | Line | Data |
---|---|---|
e2d8587b | 1 | import { Component, Input, OnChanges, OnInit } from '@angular/core' |
746018f6 C |
2 | import { VideoChannel } from '../shared-main' |
3 | import { Account } from '../shared-main/account/account.model' | |
4 | ||
5 | type ActorInput = { | |
6 | name: string | |
d0800f76 | 7 | avatars: { width: number, url?: string, path: string }[] |
746018f6 C |
8 | url: string |
9 | } | |
10 | ||
d0800f76 | 11 | export type ActorAvatarSize = '18' | '25' | '28' | '32' | '34' | '35' | '36' | '40' | '48' | '75' | '80' | '100' | '120' |
06ec4bdd | 12 | |
746018f6 C |
13 | @Component({ |
14 | selector: 'my-actor-avatar', | |
15 | styleUrls: [ './actor-avatar.component.scss' ], | |
16 | templateUrl: './actor-avatar.component.html' | |
17 | }) | |
e2d8587b | 18 | export class ActorAvatarComponent implements OnInit, OnChanges { |
9df52d66 C |
19 | private _title: string |
20 | ||
87fdea2f C |
21 | @Input() actor: ActorInput |
22 | @Input() actorType: 'channel' | 'account' | 'unlogged' | |
746018f6 | 23 | |
0ea2f79d | 24 | @Input() previewImage: string |
746018f6 | 25 | |
4428ad54 | 26 | @Input() size: ActorAvatarSize |
746018f6 C |
27 | |
28 | // Use an external link | |
29 | @Input() href: string | |
30 | // Use routerLink | |
31 | @Input() internalHref: string | any[] | |
32 | ||
33 | @Input() set title (value) { | |
34 | this._title = value | |
35 | } | |
36 | ||
746018f6 C |
37 | get title () { |
38 | if (this._title) return this._title | |
87fdea2f C |
39 | if (this.isAccount()) return $localize`${this.actor.name} (account page)` |
40 | if (this.isChannel()) return $localize`${this.actor.name} (channel page)` | |
746018f6 C |
41 | |
42 | return '' | |
43 | } | |
44 | ||
5b0ec7cd | 45 | classes: string[] = [] |
e2d8587b C |
46 | alt: string |
47 | defaultAvatarUrl: string | |
48 | avatarUrl: string | |
5b0ec7cd | 49 | |
e2d8587b C |
50 | ngOnInit () { |
51 | this.buildDefaultAvatarUrl() | |
746018f6 | 52 | |
e2d8587b C |
53 | this.buildAlt() |
54 | this.buildAvatarUrl() | |
9e401fde | 55 | this.buildClasses() |
746018f6 C |
56 | } |
57 | ||
e2d8587b | 58 | ngOnChanges () { |
e2d8587b C |
59 | this.buildAlt() |
60 | this.buildAvatarUrl() | |
9e401fde | 61 | this.buildClasses() |
746018f6 C |
62 | } |
63 | ||
e2d8587b | 64 | private buildClasses () { |
5b0ec7cd | 65 | this.classes = [ 'avatar' ] |
9df52d66 | 66 | |
87fdea2f C |
67 | if (this.size) { |
68 | this.classes.push(`avatar-${this.size}`) | |
69 | } | |
9df52d66 | 70 | |
87fdea2f C |
71 | if (this.isChannel()) { |
72 | this.classes.push('channel') | |
73 | } else { | |
74 | this.classes.push('account') | |
75 | } | |
9df52d66 | 76 | |
87fdea2f C |
77 | // No avatar, use actor name initial |
78 | if (this.displayActorInitial()) { | |
5b0ec7cd C |
79 | this.classes.push('initial') |
80 | this.classes.push(this.getColorTheme()) | |
9df52d66 | 81 | } |
9df52d66 C |
82 | } |
83 | ||
e2d8587b C |
84 | private buildAlt () { |
85 | if (this.isAccount()) this.alt = $localize`Account avatar` | |
86 | else if (this.isChannel()) this.alt = $localize`Channel avatar` | |
87 | else this.alt = '' | |
88 | } | |
89 | ||
90 | private buildDefaultAvatarUrl () { | |
91 | this.defaultAvatarUrl = this.isChannel() | |
92 | ? VideoChannel.GET_DEFAULT_AVATAR_URL(this.getSizeNumber()) | |
93 | : Account.GET_DEFAULT_AVATAR_URL(this.getSizeNumber()) | |
94 | } | |
95 | ||
96 | private buildAvatarUrl () { | |
97 | if (!this.actor) { | |
98 | this.avatarUrl = '' | |
99 | return | |
100 | } | |
101 | ||
102 | if (this.isAccount()) { | |
103 | this.avatarUrl = Account.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber()) | |
104 | return | |
105 | } | |
106 | ||
107 | if (this.isChannel()) { | |
108 | this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber()) | |
109 | return | |
110 | } | |
111 | ||
112 | this.avatarUrl = '' | |
113 | } | |
114 | ||
87fdea2f C |
115 | displayImage () { |
116 | if (this.actorType === 'unlogged') return true | |
9e401fde | 117 | if (this.previewImage) return true |
87fdea2f C |
118 | |
119 | return !!(this.actor && this.avatarUrl) | |
120 | } | |
121 | ||
122 | displayActorInitial () { | |
9e401fde | 123 | return !this.displayImage() && this.actor && !this.avatarUrl |
87fdea2f C |
124 | } |
125 | ||
126 | displayPlaceholder () { | |
127 | return this.actorType !== 'unlogged' && !this.actor | |
128 | } | |
129 | ||
130 | getActorInitial () { | |
131 | const name = this.actor?.name | |
132 | if (!name) return '' | |
133 | ||
134 | return name.slice(0, 1) | |
135 | } | |
136 | ||
137 | private isAccount () { | |
138 | return this.actorType === 'account' | |
139 | } | |
140 | ||
141 | private isChannel () { | |
142 | return this.actorType === 'channel' | |
746018f6 C |
143 | } |
144 | ||
4428ad54 C |
145 | private getSizeNumber () { |
146 | if (this.size) return +this.size | |
147 | ||
148 | return undefined | |
149 | } | |
150 | ||
746018f6 | 151 | private getColorTheme () { |
87fdea2f | 152 | const initialLowercase = this.getActorInitial().toLowerCase() |
f41efa52 | 153 | |
746018f6 C |
154 | // Keep consistency with CSS |
155 | const themes = { | |
f41efa52 | 156 | '0123456789abc': 'blue', |
746018f6 C |
157 | def: 'green', |
158 | ghi: 'purple', | |
159 | jkl: 'gray', | |
160 | mno: 'yellow', | |
161 | pqr: 'orange', | |
1fd61899 | 162 | stvu: 'red', |
746018f6 C |
163 | wxyz: 'dark-blue' |
164 | } | |
165 | ||
166 | const theme = Object.keys(themes) | |
f41efa52 | 167 | .find(chars => chars.includes(initialLowercase)) |
746018f6 | 168 | |
dbf49527 | 169 | return themes[theme] || 'blue' |
746018f6 C |
170 | } |
171 | } |