Skip to content

Commit

Permalink
fix: make _hydrateMembers merge objects instead of overriding them (#…
Browse files Browse the repository at this point in the history
…1397)

Co-authored-by: MartinCupela <[email protected]>
  • Loading branch information
arnautov-anton and MartinCupela authored Nov 28, 2024
1 parent 3fd7d11 commit 6a51159
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
39 changes: 29 additions & 10 deletions src/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1661,8 +1661,10 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
) {
const { state: clientState, user, userID } = this.getClient();

// add the Users
// add the members and users
if (state.members) {
this._hydrateMembers({ members: state.members });

for (const member of state.members) {
if (member.user) {
clientState.updateUserReference(member.user, this.cid);
Expand Down Expand Up @@ -1728,10 +1730,6 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
}
}

if (state.members) {
this._hydrateMembers(state.members);
}

return {
messageSet,
};
Expand All @@ -1747,13 +1745,34 @@ export class Channel<StreamChatGenerics extends ExtendableGenerics = DefaultGene
}
}

_hydrateMembers(members: ChannelMemberResponse<StreamChatGenerics>[]) {
this.state.members = members.reduce((acc, member) => {
_hydrateMembers({
members,
overrideCurrentState = true,
}: {
members: ChannelMemberResponse<StreamChatGenerics>[];
/**
* If set to `true` then `ChannelState.members` will be overriden with the newly
* provided `members`, setting this property to `false` will merge current `ChannelState.members`
* object with the newly provided `members`
* (new members with the same `userId` will replace the old ones).
*/
overrideCurrentState?: boolean;
}) {
const newMembersById = members.reduce<ChannelState<StreamChatGenerics>['members']>((membersById, member) => {
if (member.user) {
acc[member.user.id] = member;
membersById[member.user.id] = member;
}
return acc;
}, {} as ChannelState<StreamChatGenerics>['members']);
return membersById;
}, {});

if (overrideCurrentState) {
this.state.members = newMembersById;
} else if (!overrideCurrentState && members.length) {
this.state.members = {
...this.state.members,
...newMembersById,
};
}
}

_disconnect() {
Expand Down
2 changes: 1 addition & 1 deletion src/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class Thread<SCG extends ExtendableGenerics = DefaultGenerics> {
const channel = client.channel(threadData.channel.type, threadData.channel.id, {
name: threadData.channel.name,
});
channel._hydrateMembers(threadData.channel.members ?? []);
channel._hydrateMembers({ members: threadData.channel.members ?? [], overrideCurrentState: false });

// For when read object is undefined and due to that unreadMessageCount for
// the current user isn't being incremented on message.new
Expand Down
8 changes: 7 additions & 1 deletion test/unit/threads.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ describe('Threads 2.0', () => {
beforeEach(() => {
client = new StreamChat('apiKey');
client._setUser({ id: TEST_USER_ID });
channelResponse = generateChannel({ channel: { id: uuidv4(), name: 'Test channel' } }).channel as ChannelResponse;
channelResponse = generateChannel({
channel: { id: uuidv4(), name: 'Test channel', members: [] },
}).channel as ChannelResponse;
channel = client.channel(channelResponse.type, channelResponse.id);
parentMessageResponse = generateMsg() as MessageResponse;
threadManager = new ThreadManager({ client });
Expand All @@ -57,12 +59,16 @@ describe('Threads 2.0', () => {
describe('Thread', () => {
it('initializes properly', () => {
const threadResponse = generateThreadResponse(channelResponse, parentMessageResponse);
// mimic pre-cached channel with existing members
channel._hydrateMembers({ members: [{ user: { id: TEST_USER_ID } }] });
const thread = new Thread({ client, threadData: threadResponse });
const state = thread.state.getLatestValue();

expect(threadResponse.channel.members).to.have.lengthOf(0);
expect(threadResponse.read).to.have.lengthOf(0);
expect(state.read).to.have.keys([TEST_USER_ID]);

expect(thread.channel.state.members).to.have.keys([TEST_USER_ID]);
expect(thread.id).to.equal(parentMessageResponse.id);
expect(thread.channel.data?.name).to.equal(channelResponse.name);
});
Expand Down

0 comments on commit 6a51159

Please sign in to comment.