feat: real-time user profile updates and propagate avatarColor to all Avatar callsites
Broadcast user_updated events over WebSocket when profile fields change, updating members, DM participants, friends, and cached messages in real time. Widen useVoiceParticipantMeta to return the full user object and add a standalone avatarColor prop to Avatar so all ~16 callsites now resolve the user's chosen gradient color instead of falling back to hash-based colors.
This commit is contained in:
@@ -57,6 +57,7 @@ interface ChatState {
|
||||
markChannelUnread: (channelId: string) => void;
|
||||
ackChannel: (channelId: string) => void;
|
||||
onChannelAck: (channelId: string, messageId: string) => void;
|
||||
updateUserInMessages: (user: { id: string; [key: string]: any }) => void;
|
||||
}
|
||||
|
||||
/** Find which channel a message belongs to by scanning the message cache. */
|
||||
@@ -593,4 +594,23 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
||||
return { readStates: newReadStates, unreadChannels: newUnread };
|
||||
});
|
||||
},
|
||||
|
||||
updateUserInMessages: (user: { id: string; [key: string]: any }) => {
|
||||
set((state) => {
|
||||
const newMessages = new Map(state.messages);
|
||||
let changed = false;
|
||||
for (const [channelId, msgs] of newMessages) {
|
||||
let channelChanged = false;
|
||||
const updated = msgs.map(m => {
|
||||
if (m.userId === user.id) {
|
||||
channelChanged = true;
|
||||
return { ...m, user: { ...m.user, ...user } };
|
||||
}
|
||||
return m;
|
||||
});
|
||||
if (channelChanged) { newMessages.set(channelId, updated); changed = true; }
|
||||
}
|
||||
return changed ? { messages: newMessages } : {};
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -34,6 +34,7 @@ interface SocialState {
|
||||
addIncomingRequest: (request: FriendRequest, origin: string) => void;
|
||||
addFriendFromAccepted: (friend: Friend, requestId: string, origin: string) => void;
|
||||
updateFriendPresence: (userId: string, status: string) => void;
|
||||
updateFriendProfile: (user: User) => void;
|
||||
removeFriendLocally: (userId: string, origin: string) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
@@ -289,5 +290,19 @@ export const useSocialStore = create<SocialState>((set, get) => ({
|
||||
}));
|
||||
},
|
||||
|
||||
// Called from WS handler on user_updated to keep friend profile data live
|
||||
updateFriendProfile: (user: User) => {
|
||||
set((state) => ({
|
||||
friends: state.friends.map(f =>
|
||||
f.id === user.id
|
||||
? { ...f, displayName: user.displayName, avatar: user.avatar,
|
||||
banner: user.banner, accentColor: user.accentColor,
|
||||
avatarColor: user.avatarColor, bio: user.bio,
|
||||
customStatus: user.customStatus, status: user.status }
|
||||
: f
|
||||
),
|
||||
}));
|
||||
},
|
||||
|
||||
reset: () => set({ friends: [], requests: [], isLoading: false, error: null }),
|
||||
}));
|
||||
|
||||
@@ -60,6 +60,7 @@ interface SpaceState {
|
||||
addSpace: (space: Space) => void;
|
||||
removeSpace: (spaceId: string) => void;
|
||||
updateMemberPresence: (userId: string, status: string) => void;
|
||||
updateUserEverywhere: (user: User) => void;
|
||||
addMember: (member: MemberWithUser) => void;
|
||||
removeMember: (userId: string) => void;
|
||||
populateFromReady: (origin: string, spaces: SpaceWithChannelsAndMembers[], folders?: SpaceFolder[], dmChannels?: DmChannel[]) => void;
|
||||
@@ -304,6 +305,20 @@ export const useSpaceStore = create<SpaceState>((set, get) => ({
|
||||
}));
|
||||
},
|
||||
|
||||
updateUserEverywhere: (user: User) => {
|
||||
set((state) => ({
|
||||
members: state.members.map(m =>
|
||||
m.userId === user.id ? { ...m, user: { ...m.user, ...user } } : m
|
||||
),
|
||||
dmChannels: state.dmChannels.map(dm => ({
|
||||
...dm,
|
||||
members: dm.members.map(m =>
|
||||
m.id === user.id ? { ...m, ...user } : m
|
||||
),
|
||||
})),
|
||||
}));
|
||||
},
|
||||
|
||||
addMember: (member: MemberWithUser) => {
|
||||
set((state) => ({
|
||||
members: [...state.members.filter(m => m.userId !== member.userId), member],
|
||||
|
||||
Reference in New Issue
Block a user