Merge pull request #210 from simoleo89/fix/messenger-offline-avatar

fix(messenger): show real avatar for offline friends + fix head framing
This commit is contained in:
DuckieTM
2026-06-07 08:21:22 +02:00
committed by GitHub
3 changed files with 30 additions and 11 deletions
@@ -3,7 +3,8 @@ import { FC, KeyboardEvent, useEffect, useRef, useState } from 'react';
import { FaTimes } from 'react-icons/fa';
import { GetUserProfile, LocalizeText, ReportType, SendMessageComposer } from '../../../../api';
import { DraggableWindowPosition, LayoutAvatarImageView, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common';
import { useHelp, useMessenger, useTranslation } from '../../../../hooks';
import { useFriends, useHelp, useMessenger, useTranslation } from '../../../../hooks';
import { resolveAvatarFigure } from '../friends-list/resolveAvatarFigure';
import { FriendsMessengerThreadView } from './messenger-thread/FriendsMessengerThreadView';
export const FriendsMessengerView: FC<{}> = props =>
@@ -12,6 +13,7 @@ export const FriendsMessengerView: FC<{}> = props =>
const [ lastThreadId, setLastThreadId ] = useState(-1);
const [ messageText, setMessageText ] = useState('');
const { visibleThreads = [], activeThread = null, getMessageThread = null, sendMessage = null, setActiveThreadId = null, closeThread = null } = useMessenger();
const { getFriend = null } = useFriends();
const { report = null } = useHelp();
const { settings, translateOutgoing } = useTranslation();
const messagesBox = useRef<HTMLDivElement>(null);
@@ -133,12 +135,22 @@ export const FriendsMessengerView: FC<{}> = props =>
<div className="messenger-avatar-bar">
{ visibleThreads && (visibleThreads.length > 0) && visibleThreads.map(thread =>
{
const isStaff = (thread.participant.id <= 0);
// Read the live look from the friend list (same source the friends
// list renders) so offline friends show their real avatar instead
// of the standard/anonymous one; resolveAvatarFigure is the final
// fallback when the look is genuinely missing.
const liveFriend = isStaff ? null : getFriend(thread.participant.id);
const figure = isStaff
? (thread.participant.figure === 'ADM' ? 'ha-3409-1413-70.lg-285-89.ch-3032-1334-109.sh-3016-110.hd-185-1359.ca-3225-110-62.wa-3264-62-62.fa-1206-90.hr-3322-1403' : thread.participant.figure)
: resolveAvatarFigure(liveFriend?.figure || thread.participant.figure, liveFriend?.gender ?? thread.participant.gender);
return (
<button key={ thread.threadId } className={ 'messenger-avatar-tab' + ((activeThread === thread) ? ' active' : '') + (thread.unread ? ' unread' : '') } onClick={ event => setActiveThreadId(thread.threadId) }>
<LayoutAvatarImageView
figure={ thread.participant.id > 0 ? thread.participant.figure : thread.participant.figure === 'ADM' ? 'ha-3409-1413-70.lg-285-89.ch-3032-1334-109.sh-3016-110.hd-185-1359.ca-3225-110-62.wa-3264-62-62.fa-1206-90.hr-3322-1403' : thread.participant.figure }
figure={ figure }
headOnly={ true }
direction={ thread.participant.id > 0 ? 2 : 3 }
direction={ isStaff ? 3 : 2 }
/>
</button>
);
@@ -2,10 +2,13 @@ import { GetSessionDataManager } from '@nitrots/nitro-renderer';
import { FC, useMemo } from 'react';
import { GetGroupChatData, LocalizeText, MessengerGroupType, MessengerThread, MessengerThreadChat, MessengerThreadChatGroup } from '../../../../../api';
import { Base, Flex, LayoutAvatarImageView } from '../../../../../common';
import { useFriends } from '../../../../../hooks';
import { resolveAvatarFigure } from '../../friends-list/resolveAvatarFigure';
export const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: MessengerThreadChatGroup }> = props =>
{
const { thread = null, group = null } = props;
const { getFriend = null } = useFriends();
const groupChatData = useMemo(() => ((group.type === MessengerGroupType.GROUP_CHAT) && GetGroupChatData(group.chats[0].extraData)), [ group ]);
@@ -50,7 +53,7 @@ export const FriendsMessengerThreadGroup: FC<{ thread: MessengerThread, group: M
<Flex fullWidth gap={ 2 } justifyContent={ isOwnChat ? 'end' : 'start' } className={ 'messenger-message-row ' + (isOwnChat ? 'own' : '') }>
<Base shrink className="message-avatar">
{ ((group.type === MessengerGroupType.PRIVATE_CHAT) && !isOwnChat) &&
<LayoutAvatarImageView direction={ 2 } figure={ thread.participant.figure } headOnly={ true } /> }
<LayoutAvatarImageView direction={ 2 } figure={ resolveAvatarFigure(getFriend?.(thread.participant.id)?.figure || thread.participant.figure, getFriend?.(thread.participant.id)?.gender ?? thread.participant.gender) } headOnly={ true } /> }
{ (groupChatData && !isOwnChat) &&
<LayoutAvatarImageView direction={ 2 } figure={ groupChatData.figure } headOnly={ true } /> }
</Base>
+11 -7
View File
@@ -536,14 +536,18 @@
}
& .avatar-image {
position: absolute;
left: 50% !important;
top: -31px !important;
width: 90px !important;
height: 130px !important;
position: absolute !important;
inset: 0 !important;
width: 100% !important;
height: 100% !important;
margin: 0 !important;
background-position: center -8px !important;
transform: translateX(-50%) !important;
/* head-only image at native size (no scaling -> never grainy),
centred in the tab. Tweak the 2nd value of background-position
to raise (smaller %) or lower (larger %) the face. */
background-size: auto !important;
background-position: center 35% !important;
transform: none !important;
image-rendering: pixelated !important;
}
}