SHA256
Аватары: общий компонент, кэш txId и avatar.ar в графе связей
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import { state } from '../state.js';
|
||||
import { validateArweaveTxId } from '../services/arweave-file-service.js';
|
||||
import { getCachedAvatarObjectUrl } from '../services/arweave-avatar-cache-service.js';
|
||||
|
||||
function normalizeLogin(value) {
|
||||
return String(value || '').trim();
|
||||
}
|
||||
|
||||
function pickSizeClass(size) {
|
||||
const raw = String(size || '').trim().toLowerCase();
|
||||
if (raw === 'large') return 'large';
|
||||
if (raw === 'node') return 'node-dot';
|
||||
if (raw === 'small') return '';
|
||||
return raw || '';
|
||||
}
|
||||
|
||||
export function buildAvatarInitials({ login, firstName = '', lastName = '' } = {}) {
|
||||
const first = String(firstName || '').trim();
|
||||
const last = String(lastName || '').trim();
|
||||
if (first || last) {
|
||||
const initials = `${(first[0] || '').toUpperCase()}${(last[0] || '').toUpperCase()}`.trim();
|
||||
if (initials) return initials;
|
||||
}
|
||||
const cleanLogin = normalizeLogin(login);
|
||||
return (cleanLogin[0] || '?').toUpperCase();
|
||||
}
|
||||
|
||||
export function renderUserAvatar({
|
||||
login,
|
||||
firstName = '',
|
||||
lastName = '',
|
||||
avatar = null,
|
||||
size = 'large',
|
||||
className = '',
|
||||
title = '',
|
||||
} = {}) {
|
||||
const wrap = document.createElement('div');
|
||||
const classes = ['avatar', 'avatar-image'];
|
||||
const sizeClass = pickSizeClass(size);
|
||||
if (sizeClass) classes.push(sizeClass);
|
||||
const extraClass = String(className || '').trim();
|
||||
if (extraClass) classes.push(...extraClass.split(/\s+/g));
|
||||
wrap.className = classes.join(' ');
|
||||
if (title) wrap.title = String(title);
|
||||
|
||||
const fallback = document.createElement('span');
|
||||
fallback.className = 'avatar-fallback';
|
||||
fallback.textContent = buildAvatarInitials({ login, firstName, lastName });
|
||||
wrap.append(fallback);
|
||||
|
||||
const txId = String(avatar?.ar || '').trim();
|
||||
if (!validateArweaveTxId(txId)) {
|
||||
return wrap;
|
||||
}
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.alt = 'Аватар';
|
||||
img.loading = 'lazy';
|
||||
img.decoding = 'async';
|
||||
img.hidden = true;
|
||||
wrap.append(img);
|
||||
|
||||
const gateway = state?.entrySettings?.arweaveServer;
|
||||
void getCachedAvatarObjectUrl({ gateway, txId })
|
||||
.then((objectUrl) => {
|
||||
img.onload = () => {
|
||||
fallback.hidden = true;
|
||||
img.hidden = false;
|
||||
if (objectUrl.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
}
|
||||
};
|
||||
img.onerror = () => {
|
||||
img.hidden = true;
|
||||
fallback.hidden = false;
|
||||
if (objectUrl.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
}
|
||||
};
|
||||
img.src = objectUrl;
|
||||
})
|
||||
.catch(() => {
|
||||
img.hidden = true;
|
||||
fallback.hidden = false;
|
||||
});
|
||||
|
||||
return wrap;
|
||||
}
|
||||
Reference in New Issue
Block a user