Чат: аватары-фото сотрудников и ботов
- chatApplyAvatar(el, userId): подгружает фото из Mattermost
/users/{id}/image (работает и для сотрудников, и для ботов) и накладывает
на кружок-аватар; до загрузки/при ошибке остаются инициалы. Кэш по userId.
- Применено в сообщениях (chatBuildMessageEl) и в пикере коллег
(chatRenderDmPickerList)
- Переиспользует существующий chatApiFetchBlob (Bearer-токен)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,28 @@ function chatApiFetchBlob(path) {
|
||||
});
|
||||
}
|
||||
|
||||
var chatAvatarCache = {}; // userId -> objectURL профільного фото (юзери і боти)
|
||||
|
||||
// Підвантажує аватар користувача/бота з Mattermost (/users/{id}/image) і
|
||||
// накладає його на елемент-кружок. Поки фото не завантажилось (або якщо
|
||||
// сталася помилка) лишаються ініціали, вже намальовані на елементі.
|
||||
function chatApplyAvatar(el, userId) {
|
||||
if (!el || !userId) return;
|
||||
el.style.position = 'relative';
|
||||
el.style.overflow = 'hidden';
|
||||
var img = document.createElement('img');
|
||||
img.alt = '';
|
||||
img.style.cssText = 'position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity 150ms;';
|
||||
img.onload = function () { img.style.opacity = '1'; };
|
||||
el.appendChild(img);
|
||||
if (chatAvatarCache[userId]) { img.src = chatAvatarCache[userId]; return; }
|
||||
chatApiFetchBlob('/users/' + userId + '/image').then(function (blob) {
|
||||
var url = URL.createObjectURL(blob);
|
||||
chatAvatarCache[userId] = url;
|
||||
img.src = url;
|
||||
}).catch(function () { /* лишаємо ініціали */ });
|
||||
}
|
||||
|
||||
function chatResolveUserIds(ids) {
|
||||
var missing = ids.filter(function (id) { return id && !chatUserNames[id]; });
|
||||
missing = missing.filter(function (id, i) { return missing.indexOf(id) === i; });
|
||||
@@ -314,6 +336,7 @@ function chatBuildMessageEl(post, context) {
|
||||
avatar.style.cssText = 'width:2rem; height:2rem; border-radius:50%; background:hsl(205 80% 55% / 0.15); color:hsl(205 80% 45%); display:flex; align-items:center; justify-content:center; font-size:0.625rem; font-weight:700; flex-shrink:0;';
|
||||
var senderName = chatUserNames[post.user_id] || post.user_id;
|
||||
avatar.textContent = senderName.slice(0, 2).toUpperCase();
|
||||
chatApplyAvatar(avatar, post.user_id);
|
||||
wrap.appendChild(avatar);
|
||||
|
||||
var body = document.createElement('div');
|
||||
@@ -709,6 +732,11 @@ function chatRenderDmPickerList() {
|
||||
}
|
||||
};
|
||||
row.appendChild(checkbox);
|
||||
var av = document.createElement('div');
|
||||
av.style.cssText = 'width:1.75rem; height:1.75rem; border-radius:50%; background:hsl(205 80% 55% / 0.15); color:hsl(205 80% 45%); display:flex; align-items:center; justify-content:center; font-size:0.5625rem; font-weight:700; flex-shrink:0;';
|
||||
av.textContent = c.name.slice(0, 2).toUpperCase();
|
||||
chatApplyAvatar(av, c.mattermostId);
|
||||
row.appendChild(av);
|
||||
var name = document.createElement('span');
|
||||
name.textContent = c.name;
|
||||
row.appendChild(name);
|
||||
|
||||
Reference in New Issue
Block a user