104 lines
2.8 KiB
JavaScript
Raw Normal View History

2025-12-04 20:29:35 +01:00
/**
* @fileoverview User Avatar Component for Rantii
* @author retoor <retoor@molodetz.nl>
* @description Displays user avatar with fallback to initials
* @keywords avatar, user, profile, image, picture
*/
import { BaseComponent } from './base-component.js';
import { buildAvatarUrl } from '../utils/url.js';
class UserAvatar extends BaseComponent {
static get observedAttributes() {
return ['avatar', 'username', 'size', 'user-id'];
}
init() {
this.render();
}
render() {
const avatarData = this.getAttr('avatar');
const username = this.getAttr('username') || '';
const size = this.getAttr('size') || 'medium';
const userId = this.getAttr('user-id');
this.addClass('avatar', `avatar-${size}`);
let avatar = null;
if (avatarData) {
try {
avatar = JSON.parse(avatarData);
} catch (e) {
avatar = null;
}
}
const bgColor = avatar?.b || '#54556e';
const imageUrl = buildAvatarUrl(avatar);
if (imageUrl) {
this.setHtml(`
<div class="avatar-wrapper" style="background-color: ${bgColor}">
<img class="avatar-image" src="${imageUrl}" alt="${username}" loading="lazy">
</div>
`);
} else {
const initials = this.getInitials(username);
this.setHtml(`
<div class="avatar-wrapper avatar-initials" style="background-color: ${bgColor}">
<span>${initials}</span>
</div>
`);
}
if (userId || username) {
this.style.cursor = 'pointer';
this.setAttribute('role', 'button');
this.setAttribute('tabindex', '0');
}
}
getInitials(username) {
if (!username) return '?';
return username.substring(0, 2).toUpperCase();
}
onAttributeChanged(name, oldValue, newValue) {
this.render();
}
onConnected() {
this.on(this, 'click', this.handleClick);
this.on(this, 'keydown', this.handleKeydown);
}
handleClick(e) {
const username = this.getAttr('username');
if (username) {
this.getRouter()?.goToUser(username);
}
}
handleKeydown(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
this.handleClick(e);
}
}
setAvatar(avatar, username) {
if (avatar && typeof avatar === 'object') {
this.setAttr('avatar', JSON.stringify(avatar));
}
if (username) {
this.setAttr('username', username);
}
this.render();
}
}
customElements.define('user-avatar', UserAvatar);
export { UserAvatar };