Skip to content

Commit

Permalink
feat: optimized message list
Browse files Browse the repository at this point in the history
  • Loading branch information
szuperaz committed Jul 22, 2024
1 parent 22566f8 commit 418841d
Show file tree
Hide file tree
Showing 19 changed files with 1,719 additions and 457 deletions.
14 changes: 7 additions & 7 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 @@ -117,7 +117,7 @@
"@ctrl/ngx-emoji-mart": "^8.2.0",
"@floating-ui/dom": "^1.6.3",
"@ngx-translate/core": "^14.0.0",
"@stream-io/stream-chat-css": "4.17.3",
"@stream-io/stream-chat-css": "4.17.4",
"@stream-io/transliterate": "^1.5.2",
"angular-mentions": "1.4.0",
"dayjs": "^1.11.10",
Expand Down
20 changes: 20 additions & 0 deletions projects/stream-chat-angular/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,29 @@
"paths": ["stream-chat-angular"],
"patterns": ["dist/*", "public-api"]
}
],
"@typescript-eslint/no-unused-vars": [
"error",
{
"args": "all",
"argsIgnorePattern": "^_",
"caughtErrors": "all",
"caughtErrorsIgnorePattern": "^error",
"destructuredArrayIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"ignoreRestSiblings": true
}
]
}
},
{
"files": ["*.spec.ts"],
"rules": {
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-member-access": "off"
}
},
{
"files": ["*.service.ts"],
"parserOptions": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Input,
NgZone,
OnChanges,
OnDestroy,
OnInit,
SimpleChanges,
} from '@angular/core';
Expand All @@ -27,7 +28,7 @@ import {
styleUrls: ['./avatar.component.scss'],
})
export class AvatarComponent
implements OnChanges, OnInit, OnChanges, AfterViewInit
implements OnChanges, OnInit, OnChanges, AfterViewInit, OnDestroy
{
/**
* An optional name of the image, used for fallback image or image title (if `imageUrl` is provided)
Expand Down Expand Up @@ -109,6 +110,10 @@ export class AvatarComponent
}
}

ngOnDestroy(): void {
this.subscriptions.forEach((s) => s.unsubscribe());
}

private setFallbackChannelImage() {
if (this.type !== 'channel') {
this.fallbackChannelImage = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class ChannelListComponent implements OnDestroy {
this.isLoadingMoreChannels = false;
}

trackByChannelId(index: number, item: Channel<DefaultStreamChatGenerics>) {
trackByChannelId(_: number, item: Channel<DefaultStreamChatGenerics>) {
return item.cid;
}
}
12 changes: 12 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 @@ -671,6 +671,18 @@ describe('ChannelService', () => {
(activeChannel as MockChannel).handleEvent('message.deleted', { message });

expect(spy).toHaveBeenCalledWith(jasmine.arrayContaining([message]));

spy.calls.reset();
activeChannel.state.messages.splice(
activeChannel.state.messages.findIndex((m) => m.id === message.id)
);
(activeChannel as MockChannel).handleEvent('message.deleted', {
message,
type: 'message.deleted',
});

expect(spy).toHaveBeenCalled();
expect(spy).not.toHaveBeenCalledWith(jasmine.arrayContaining([message]));
});

it('should move channel to the top of the list', async () => {
Expand Down
37 changes: 9 additions & 28 deletions projects/stream-chat-angular/src/lib/channel.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,14 +311,11 @@ export class ChannelService<
beforeUpdateMessage?: (
message: StreamMessage<T>
) => StreamMessage<T> | Promise<StreamMessage<T>>;
/**
* @internal
*/
static readonly MAX_MESSAGE_COUNT_IN_MESSAGE_LIST = 250;
/**
* @internal
*/
static readonly MAX_MESSAGE_REACTIONS_TO_FETCH = 1200;
messagePageSize = 25;
private channelsSubject = new BehaviorSubject<Channel<T>[] | undefined>(
undefined
);
Expand Down Expand Up @@ -347,7 +344,6 @@ export class ChannelService<
private latestMessageDateByUserByChannelsSubject = new BehaviorSubject<{
[key: string]: Date;
}>({});
private messagePageSize = 25;
private readonly attachmentMaxSizeFallbackInMB = 100;
private messageToQuoteSubject = new BehaviorSubject<
StreamMessage<T> | undefined
Expand Down Expand Up @@ -518,28 +514,6 @@ export class ChannelService<
.pipe(shareReplay(1));
}

/**
* internal
*/
removeOldMessageFromMessageList() {
const channel = this.activeChannelSubject.getValue();
const channelMessages = channel?.state.latestMessages;
const targetLength = Math.ceil(
ChannelService.MAX_MESSAGE_COUNT_IN_MESSAGE_LIST / 2
);
if (
!channel ||
!channelMessages ||
channelMessages !== channel?.state.latestMessages ||
channelMessages.length <= targetLength
) {
return;
}
const messages = channelMessages;
messages.splice(0, messages.length - targetLength);
this.activeChannelMessagesSubject.next(messages);
}

/**
* If set to false, read events won't be sent as new messages are received. If set to true active channel (if any) will immediately be marked as read.
*/
Expand Down Expand Up @@ -1646,6 +1620,13 @@ export class ChannelService<
return this.activeChannelMessagesSubject.getValue() || [];
}

/**
* The current thread replies
*/
get activeChannelThreadReplies() {
return this.activeThreadMessagesSubject.getValue() || [];
}

/**
* Get the last 1200 reactions of a message in the current active channel. If you need to fetch more reactions please use the [following endpoint](https://getstream.io/chat/docs/javascript/send_reaction/?language=javascript#paginating-reactions).
* @param messageId
Expand Down Expand Up @@ -1750,7 +1731,7 @@ export class ChannelService<
const messageIndex = messages.findIndex(
(m) => m.id === event?.message?.id
);
if (messageIndex !== -1) {
if (messageIndex !== -1 || event.type === 'message.deleted') {
isThreadReply
? this.activeThreadMessagesSubject.next([...messages])
: this.activeChannelMessagesSubject.next([...messages]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class MessageActionsService<
},
isVisible: (
enabledActions: string[],
isMine: boolean,
_: boolean,
message: StreamMessage<T>
) => enabledActions.indexOf('read-events') !== -1 && !message.parent_id,
},
Expand All @@ -64,7 +64,7 @@ export class MessageActionsService<
},
isVisible: (
enabledActions: string[],
isMine: boolean,
_: boolean,
message: StreamMessage<T>
) => enabledActions.indexOf('send-reply') !== -1 && !message.parent_id,
},
Expand All @@ -91,7 +91,7 @@ export class MessageActionsService<
'streamChat.Message has been successfully flagged',
'success'
);
} catch (err) {
} catch (error) {
this.notificationService.addTemporaryNotification(
'streamChat.Error adding flag'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@
</button>
</div>
</ng-template>
<div #scrollContainer data-testid="scroll-container" class="str-chat__list">
<div
#scrollContainer
data-testid="scroll-container"
class="str-chat__list"
style="overscroll-behavior-y: none"
>
<ng-container *ngIf="mode === 'main' && isEmpty && emptyListTemplate">
<ng-container *ngTemplateOutlet="emptyListTemplate"></ng-container>
</ng-container>
Expand All @@ -83,12 +88,16 @@
<ng-container *ngIf="mode === 'thread' && isEmpty && emptyListTemplate">
<ng-container *ngTemplateOutlet="emptyListTemplate"></ng-container>
</ng-container>
<stream-loading-indicator
<stream-loading-indicator-placeholder
*ngIf="
isLoading && direction === 'bottom-to-top' && displayLoadingIndicator
((loadingState === 'loading-top' && direction === 'bottom-to-top') ||
(loadingState === 'loading-bottom' &&
direction === 'top-to-bottom')) &&
displayLoadingIndicator;
else loadingIndicatorPlaceholder
"
data-testid="top-loading-indicator"
></stream-loading-indicator>
></stream-loading-indicator-placeholder>
<ng-container *ngIf="messages$ | async as messages">
<ng-container
*ngFor="
Expand Down Expand Up @@ -159,12 +168,20 @@
</ng-container>
</ng-container>
</ng-container>
<stream-loading-indicator
<stream-loading-indicator-placeholder
*ngIf="
isLoading && direction === 'top-to-bottom' && displayLoadingIndicator
((loadingState === 'loading-bottom' &&
direction === 'bottom-to-top') ||
(loadingState === 'loading-top' &&
direction === 'top-to-bottom')) &&
displayLoadingIndicator;
else loadingIndicatorPlaceholder
"
data-testid="bottom-loading-indicator"
></stream-loading-indicator>
></stream-loading-indicator-placeholder>
<ng-template #loadingIndicatorPlaceholder>
<div class="str-chat__loading-indicator-placeholder"></div>
</ng-template>
</ul>
<ng-template #defaultTypingIndicator let-usersTyping$="usersTyping$">
<!-- eslint-disable-next-line @angular-eslint/template/no-any -->
Expand Down
Loading

0 comments on commit 418841d

Please sign in to comment.