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