]>
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 | defaultAvatarUrl: string |
47 | avatarUrl: string | |
5b0ec7cd | 48 | |
e2d8587b C |
49 | ngOnInit () { |
50 | this.buildDefaultAvatarUrl() | |
746018f6 | 51 | |
e2d8587b | 52 | this.buildAvatarUrl() |
9e401fde | 53 | this.buildClasses() |
746018f6 C |
54 | } |
55 | ||
e2d8587b | 56 | ngOnChanges () { |
e2d8587b | 57 | this.buildAvatarUrl() |
9e401fde | 58 | this.buildClasses() |
746018f6 C |
59 | } |
60 | ||
e2d8587b | 61 | private buildClasses () { |
5b0ec7cd | 62 | this.classes = [ 'avatar' ] |
9df52d66 | 63 | |
87fdea2f C |
64 | if (this.size) { |
65 | this.classes.push(`avatar-${this.size}`) | |
66 | } | |
9df52d66 | 67 | |
87fdea2f C |
68 | if (this.isChannel()) { |
69 | this.classes.push('channel') | |
70 | } else { | |
71 | this.classes.push('account') | |
72 | } | |
9df52d66 | 73 | |
87fdea2f C |
74 | // No avatar, use actor name initial |
75 | if (this.displayActorInitial()) { | |
5b0ec7cd C |
76 | this.classes.push('initial') |
77 | this.classes.push(this.getColorTheme()) | |
9df52d66 | 78 | } |
9df52d66 C |
79 | } |
80 | ||
e2d8587b C |
81 | private buildDefaultAvatarUrl () { |
82 | this.defaultAvatarUrl = this.isChannel() | |
83 | ? VideoChannel.GET_DEFAULT_AVATAR_URL(this.getSizeNumber()) | |
84 | : Account.GET_DEFAULT_AVATAR_URL(this.getSizeNumber()) | |
85 | } | |
86 | ||
87 | private buildAvatarUrl () { | |
88 | if (!this.actor) { | |
89 | this.avatarUrl = '' | |
90 | return | |
91 | } | |
92 | ||
93 | if (this.isAccount()) { | |
94 | this.avatarUrl = Account.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber()) | |
95 | return | |
96 | } | |
97 | ||
98 | if (this.isChannel()) { | |
99 | this.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(this.actor, this.getSizeNumber()) | |
100 | return | |
101 | } | |
102 | ||
103 | this.avatarUrl = '' | |
104 | } | |
105 | ||
87fdea2f C |
106 | displayImage () { |
107 | if (this.actorType === 'unlogged') return true | |
9e401fde | 108 | if (this.previewImage) return true |
87fdea2f C |
109 | |
110 | return !!(this.actor && this.avatarUrl) | |
111 | } | |
112 | ||
113 | displayActorInitial () { | |
9e401fde | 114 | return !this.displayImage() && this.actor && !this.avatarUrl |
87fdea2f C |
115 | } |
116 | ||
117 | displayPlaceholder () { | |
118 | return this.actorType !== 'unlogged' && !this.actor | |
119 | } | |
120 | ||
121 | getActorInitial () { | |
122 | const name = this.actor?.name | |
123 | if (!name) return '' | |
124 | ||
125 | return name.slice(0, 1) | |
126 | } | |
127 | ||
128 | private isAccount () { | |
129 | return this.actorType === 'account' | |
130 | } | |
131 | ||
132 | private isChannel () { | |
133 | return this.actorType === 'channel' | |
746018f6 C |
134 | } |
135 | ||
4428ad54 C |
136 | private getSizeNumber () { |
137 | if (this.size) return +this.size | |
138 | ||
139 | return undefined | |
140 | } | |
141 | ||
746018f6 | 142 | private getColorTheme () { |
87fdea2f | 143 | const initialLowercase = this.getActorInitial().toLowerCase() |
f41efa52 | 144 | |
746018f6 C |
145 | // Keep consistency with CSS |
146 | const themes = { | |
f41efa52 | 147 | '0123456789abc': 'blue', |
d0fbc9fd C |
148 | 'def': 'green', |
149 | 'ghi': 'purple', | |
150 | 'jkl': 'gray', | |
151 | 'mno': 'yellow', | |
152 | 'pqr': 'orange', | |
153 | 'stvu': 'red', | |
154 | 'wxyz': 'dark-blue' | |
746018f6 C |
155 | } |
156 | ||
157 | const theme = Object.keys(themes) | |
f41efa52 | 158 | .find(chars => chars.includes(initialLowercase)) |
746018f6 | 159 | |
dbf49527 | 160 | return themes[theme] || 'blue' |
746018f6 C |
161 | } |
162 | } |