fix p2p conversation avatars
This commit is contained in:
@@ -6,6 +6,7 @@ import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
import { Avatar } from '@/app/Avatar';
|
||||
import { Icon } from '@/app/Icon';
|
||||
import { CreateGroupModal } from '@/features/groups/CreateGroupModal';
|
||||
import { friendAvatarLookup } from '@/features/messages/chat-list';
|
||||
import { fetchAllPages } from '@/lib/api/client';
|
||||
import { getFriends } from '@/lib/api/friends';
|
||||
import { getGroups } from '@/lib/api/groups';
|
||||
@@ -74,7 +75,7 @@ export function ChatListColumn() {
|
||||
// to carry the REST-only `avatar_file_id` this app uploads avatars through -- shares ContactsListColumn's
|
||||
// exact `['friends']` query key, so this is a cache read whenever that page has already been visited.
|
||||
const friendsQuery = useQuery({ queryKey: ['friends'], queryFn: () => fetchAllPages((cursor) => getFriends('', cursor)) });
|
||||
const avatarByUserId = new Map(friendsQuery.data?.map((f) => [f.user_id, f.avatar_file_id]));
|
||||
const avatarByPeer = friendAvatarLookup(friendsQuery.data);
|
||||
const [query, setQuery] = useState('');
|
||||
const [creatingGroup, setCreatingGroup] = useState(false);
|
||||
const sorted = [...contacts].sort((a, b) => {
|
||||
@@ -158,7 +159,7 @@ export function ChatListColumn() {
|
||||
const memberCount = isGroup ? memberCountByTopic.get(contact.topic) : undefined;
|
||||
const muted = !!contact.private?.mute_notifications;
|
||||
const avatarFileId =
|
||||
contact.topic === 'slf' ? meQuery.data?.profile.avatar_file_id : isGroup ? avatarByGroupTopic.get(contact.topic) : avatarByUserId.get(contact.topic);
|
||||
contact.topic === 'slf' ? meQuery.data?.profile.avatar_file_id : isGroup ? avatarByGroupTopic.get(contact.topic) : avatarByPeer.get(contact.topic);
|
||||
return (
|
||||
<Link
|
||||
key={contact.topic}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export interface FriendAvatarSource {
|
||||
user_id: string;
|
||||
topic?: string;
|
||||
avatar_file_id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* P2P contacts are keyed by their `p2p...` topic after the first subscription,
|
||||
* while the friends API identifies the same person with a `usr...` user ID.
|
||||
* Keep both aliases so avatars work during both the initial and established
|
||||
* conversation states.
|
||||
*/
|
||||
export function friendAvatarLookup(friends: FriendAvatarSource[] = []) {
|
||||
const avatars = new Map<string, string | undefined>();
|
||||
for (const friend of friends) {
|
||||
if (friend.user_id) avatars.set(friend.user_id, friend.avatar_file_id);
|
||||
if (friend.topic) avatars.set(friend.topic, friend.avatar_file_id);
|
||||
}
|
||||
return avatars;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { friendAvatarLookup } from '../src/features/messages/chat-list.ts';
|
||||
|
||||
test('friend avatars resolve by both user ID and established P2P topic', () => {
|
||||
const avatars = friendAvatarLookup([
|
||||
{
|
||||
user_id: 'usr-potter',
|
||||
topic: 'p2p-potter',
|
||||
avatar_file_id: 'https://example.com/potter.png',
|
||||
},
|
||||
]);
|
||||
|
||||
assert.equal(avatars.get('usr-potter'), 'https://example.com/potter.png');
|
||||
assert.equal(avatars.get('p2p-potter'), 'https://example.com/potter.png');
|
||||
});
|
||||
|
||||
test('friend avatar lookup tolerates a new conversation without a topic alias', () => {
|
||||
const avatars = friendAvatarLookup([{ user_id: 'usr-new', avatar_file_id: 'avatar-file-id' }]);
|
||||
|
||||
assert.equal(avatars.get('usr-new'), 'avatar-file-id');
|
||||
assert.equal(avatars.has(''), false);
|
||||
});
|
||||
Reference in New Issue
Block a user