Skip to content

Commit

Permalink
Merge pull request #496 from GetStream/missing_ws_events
Browse files Browse the repository at this point in the history
Missing ws events
  • Loading branch information
szuperaz authored Nov 2, 2023
2 parents 3e6e2c1 + d13f5e0 commit bcb361c
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 31 deletions.
56 changes: 29 additions & 27 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
"ngx-popperjs": "^12.2.2",
"pretty-bytes": "^5.6.0",
"rxjs": "^7.1.0",
"stream-chat": "^8.11.0",
"stream-chat": "^8.14.0",
"ts-node": "^10.2.1",
"tslib": "^2.3.0",
"uuidv4": "^6.2.12",
Expand Down
17 changes: 17 additions & 0 deletions projects/stream-chat-angular/src/lib/channel.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2152,4 +2152,21 @@ describe('ChannelService', () => {
expect(spy).toHaveBeenCalledWith(channel);
expect(service.activeChannelLastReadMessageId).toBeUndefined();
});

it('should update user references on `user.updated` event', async () => {
await init();
const spy = jasmine.createSpy();
service.activeChannel$.subscribe(spy);
let activeChannel!: Channel<DefaultStreamChatGenerics>;
service.activeChannel$.pipe(take(1)).subscribe((c) => (activeChannel = c!));
activeChannel.state.members['jack'].user!.name = 'John';
mockChatClient.activeChannels[activeChannel.cid] = activeChannel;
spy.calls.reset();
events$.next({ eventType: 'user.updated' } as ClientEvent);

const updatedChannel = spy.calls.mostRecent()
.args[0] as Channel<DefaultStreamChatGenerics>;

expect(updatedChannel.state.members['jack'].user!.name).toBe('John');
});
});
37 changes: 37 additions & 0 deletions projects/stream-chat-angular/src/lib/channel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,43 @@ export class ChannelService<
this.handleRemovedFromChannelNotification(clientEvent);
}
});
break;
}
case 'user.updated': {
this.ngZone.run(() => {
const updatedChannels = this.channelsSubject.getValue()?.map((c) => {
if (this.chatClientService.chatClient.activeChannels[c.cid]) {
return this.chatClientService.chatClient.activeChannels[c.cid];
} else {
return c;
}
});
this.channelsSubject.next(updatedChannels);
const activeChannel = this.activeChannelSubject.getValue();
if (activeChannel) {
this.activeChannelSubject.next(
this.chatClientService.chatClient.activeChannels[
activeChannel.cid
] || activeChannel
);
this.activeChannelMessagesSubject.next(
activeChannel.state.messages.map((m) => {
m.readBy = getReadBy(m, activeChannel);
return { ...m };
})
);
const activeParentMessage =
this.activeParentMessageIdSubject.getValue();
if (activeParentMessage) {
const messages = activeChannel.state.threads[activeParentMessage];
this.activeThreadMessagesSubject.next([...messages]);
}
this.activeChannelPinnedMessagesSubject.next([
...activeChannel.state.pinnedMessages,
]);
}
});
break;
}
}
}
Expand Down
55 changes: 55 additions & 0 deletions projects/stream-chat-angular/src/lib/chat-client.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,59 @@ describe('ChatClientService', () => {

expect(invitesSpy).not.toHaveBeenCalled();
});

it('should update total unread count', () => {
const spy = jasmine.createSpy();
service.user$.subscribe(spy);

expect(spy).toHaveBeenCalledWith(
jasmine.objectContaining({ total_unread_count: 0 })
);

spy.calls.reset();

const event1 = {
id: 'mockevent',
type: 'notification.invite_accepted',
channel: { cid: 'what-i-ate-for-lunch' },
member: { user: mockChatClient.user },
} as any as Event;
mockChatClient.handleEvent(event1.type, event1);

expect(spy).not.toHaveBeenCalledWith();

const event2 = {
id: 'mockevent',
type: 'message.new',
channel: { cid: 'what-i-ate-for-lunch' },
member: { user: mockChatClient.user },
total_unread_count: 2,
} as any as Event;
mockChatClient.handleEvent(event2.type, event2);

expect(spy).toHaveBeenCalledWith(
jasmine.objectContaining({ total_unread_count: 2 })
);
});

it('should update user object on `user.updated` event', () => {
const spy = jasmine.createSpy();
service.user$.subscribe(spy);

const updatedName = mockCurrentUser().name! + ' updated';
const event = {
id: 'mockevent',
type: 'user.updated',
user: {
id: mockChatClient.user.id,
name: updatedName,
},
} as any as Event;
mockChatClient.user.name = updatedName;
mockChatClient.handleEvent(event.type, event);

expect(spy).toHaveBeenCalledWith(
jasmine.objectContaining({ name: updatedName })
);
});
});
31 changes: 28 additions & 3 deletions projects/stream-chat-angular/src/lib/chat-client.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable, NgZone } from '@angular/core';
import { BehaviorSubject, Observable, ReplaySubject } from 'rxjs';
import { BehaviorSubject, Observable, ReplaySubject, take } from 'rxjs';
import {
Channel,
ChannelFilters,
Expand Down Expand Up @@ -57,7 +57,7 @@ export class ChatClientService<
/**
* Emits the current chat user
*/
user$: Observable<UserResponse<T> | undefined>;
user$: Observable<OwnUserResponse<T> | UserResponse<T> | undefined>;
private notificationSubject = new ReplaySubject<ClientEvent<T>>(1);
private connectionStateSubject = new ReplaySubject<'offline' | 'online'>(1);
private appSettingsSubject = new BehaviorSubject<AppSettings | undefined>(
Expand All @@ -66,7 +66,9 @@ export class ChatClientService<
private pendingInvitesSubject = new BehaviorSubject<
(ChannelResponse<T> | Channel<T>)[]
>([]);
private userSubject = new ReplaySubject<UserResponse<T> | undefined>(1);
private userSubject = new ReplaySubject<
OwnUserResponse<T> | UserResponse<T> | undefined
>(1);
private subscriptions: { unsubscribe: () => void }[] = [];

constructor(
Expand Down Expand Up @@ -137,6 +139,7 @@ export class ChatClientService<
this.appSettingsSubject.next(undefined);
this.subscriptions.push(
this.chatClient.on((e) => {
this.updateUser(e);
this.updatePendingInvites(e);
this.notificationSubject.next({
eventType: e.type,
Expand Down Expand Up @@ -233,4 +236,26 @@ export class ChatClientService<
}
}
}

private updateUser(e: Event<T>) {
if (typeof e.total_unread_count !== 'undefined') {
let user: OwnUserResponse<T> | UserResponse<T> | undefined;
this.userSubject.pipe(take(1)).subscribe((u) => {
user = u;
});
if (user && user.total_unread_count !== e.total_unread_count) {
this.userSubject.next({
...user,
total_unread_count: e.total_unread_count,
});
}
}
if (
e.type === 'user.updated' &&
this.chatClient.user &&
e.user?.id === this.chatClient.user.id
) {
this.userSubject.next({ ...this.chatClient.user });
}
}
}
1 change: 1 addition & 0 deletions projects/stream-chat-angular/src/lib/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const mockCurrentUser = () =>
id: 'currentUser',
name: 'Bob',
image: 'link/to/photo',
total_unread_count: 0,
} as UserResponse<DefaultStreamChatGenerics>);

export const mockMessage = (id?: number) =>
Expand Down

0 comments on commit bcb361c

Please sign in to comment.