Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion projects/stream-chat-angular/src/lib/channel.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ describe('ChannelService', () => {
service.usersTypingInChannel$.subscribe(typingUsersSpy);
const typingUsersInThreadSpy = jasmine.createSpy();
service.usersTypingInThread$.subscribe(typingUsersInThreadSpy);
service.isMessageLoadingInProgress = true;
messagesSpy.calls.reset();
activeChannelSpy.calls.reset();
messageToQuoteSpy.calls.reset();
Expand Down Expand Up @@ -386,6 +387,7 @@ describe('ChannelService', () => {
(activeChannel as MockChannel).handleEvent('message.new', mockMessage());

expect(messagesSpy).not.toHaveBeenCalled();
expect(service.isMessageLoadingInProgress).toBeFalse();
});

it('should tell if user #hasMoreChannels$', async () => {
Expand Down Expand Up @@ -2177,7 +2179,11 @@ describe('ChannelService', () => {
service.activeChannelMessages$.subscribe(messagesSpy);
messagesSpy.calls.reset();
const messageId = '1232121123';
await service.jumpToMessage(messageId);
const response = service.jumpToMessage(messageId);

expect(service.isMessageLoadingInProgress).toBeTrue();

await response;

expect(jumpToMessageIdSpy).toHaveBeenCalledWith({
id: messageId,
Expand All @@ -2187,6 +2193,7 @@ describe('ChannelService', () => {
expect(messagesSpy).toHaveBeenCalledWith(
jasmine.arrayContaining([jasmine.objectContaining({ id: messageId })])
);
expect(service.isMessageLoadingInProgress).toBeFalse();
});

it(`should display error notification if message couldn't be loaded`, async () => {
Expand All @@ -2211,6 +2218,7 @@ describe('ChannelService', () => {
expect(notificationService.addTemporaryNotification).toHaveBeenCalledWith(
'streamChat.Message not found'
);
expect(service.isMessageLoadingInProgress).toBeFalse();
});

it('should pin message', async () => {
Expand Down
9 changes: 9 additions & 0 deletions projects/stream-chat-angular/src/lib/channel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ export class ChannelService<
* @internal
*/
static readonly MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
/**
* @internal
*/
isMessageLoadingInProgress = false;
messagePageSize = 25;
private channelsSubject = new BehaviorSubject<Channel<T>[] | undefined>(
undefined
Expand Down Expand Up @@ -568,6 +572,7 @@ export class ChannelService<
this.stopWatchForActiveChannelEvents(prevActiveChannel);
this.flushMarkReadQueue();
this.areReadEventsPaused = false;
this.isMessageLoadingInProgress = false;
const readState =
channel.state.read[this.chatClientService.chatClient.user?.id || ''];
this.activeChannelLastReadMessageId = readState?.last_read_message_id;
Expand Down Expand Up @@ -613,6 +618,7 @@ export class ChannelService<
this.activeChannelLastReadMessageId = undefined;
this.activeChannelUnreadCount = undefined;
this.areReadEventsPaused = false;
this.isMessageLoadingInProgress = false;
}

/**
Expand Down Expand Up @@ -1268,6 +1274,7 @@ export class ChannelService<
* @param parentMessageId The ID of the parent message if we want to load a thread message
*/
async jumpToMessage(messageId: string, parentMessageId?: string) {
this.isMessageLoadingInProgress = true;
const activeChannel = this.activeChannelSubject.getValue();
try {
await activeChannel?.state.loadMessageIntoState(
Expand All @@ -1289,6 +1296,8 @@ export class ChannelService<
'streamChat.Message not found'
);
throw error;
} finally {
this.isMessageLoadingInProgress = false;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ describe('MessageListComponent', () => {
expect(component['resetScrollState']).not.toHaveBeenCalled();
});

it('should jump to first unread message if openMessageListAt specifies', () => {
it('should jump to first unread message if openMessageListAt specifies', fakeAsync(() => {
component.openMessageListAt = 'last-read-message';

const channel = generateMockChannels()[0];
Expand All @@ -1097,6 +1097,7 @@ describe('MessageListComponent', () => {
messages[messages.length - 2].id;
channelServiceMock.activeChannel$.next(channel);
channelServiceMock.activeChannelMessages$.next(messages);
tick();

expect(component.lastReadMessageId).toBe(messages[messages.length - 2].id);

Expand All @@ -1105,7 +1106,7 @@ describe('MessageListComponent', () => {
);

expect(component.isJumpingToLatestUnreadMessage).toBeTrue();
});
}));

it('should display new message indicator - new mesage is the first on the given day', () => {
component.openMessageListAt = 'last-read-message';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ export class MessageListComponent
);
this.subscriptions.push(
this.channelService.activeChannel$.subscribe((channel) => {
let isNewChannel = false;
let wasChannelSwitch = false;
if (this.channelId !== channel?.id) {
isNewChannel = true;
wasChannelSwitch = true;
if (this.checkIfUnreadNotificationIsVisibleTimeout) {
clearTimeout(this.checkIfUnreadNotificationIsVisibleTimeout);
}
Expand Down Expand Up @@ -227,9 +227,18 @@ export class MessageListComponent
) {
this.lastReadMessageId = lastReadMessageId;
this.unreadCount = unreadCount || 0;
if (isNewChannel && this.lastReadMessageId) {
if (wasChannelSwitch && this.lastReadMessageId) {
// Delay jumping to last read message in case we need to give precedence to channelService.jumpToMessage
if (this.openMessageListAt === 'last-read-message') {
this.jumpToFirstUnreadMessage();
setTimeout(() => {
// Don't jump if a jump to a message was already started (using channelService.jumpToMessage)
if (
!this.isJumpingToMessage &&
!this.channelService.isMessageLoadingInProgress
) {
this.jumpToFirstUnreadMessage();
}
}, 0);
} else {
// Wait till messages and the unread banner is rendered
// If unread banner isn't visible on the screen, we display the unread notificaion
Expand Down Expand Up @@ -702,8 +711,9 @@ export class MessageListComponent
const lastReadIndex = messages.findIndex(
(m) => m.id === this.lastReadMessageId
);
this.firstUnreadMessageId =
messages[lastReadIndex + 1]?.id || this.lastReadMessageId;
if (lastReadIndex !== -1) {
this.firstUnreadMessageId = messages[lastReadIndex + 1]?.id;
}
}
}),
tap(
Expand Down
4 changes: 3 additions & 1 deletion projects/stream-chat-angular/src/lib/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@ export const mockChannelService = (): MockChannelService => {
channel;
};

const jumpToMessage = () => {};
const jumpToMessage = () => {
activeChannelMessages$.next(activeChannelMessages$.getValue());
};

const clearMessageJump = () => {};

Expand Down
Loading