diff --git a/projects/stream-chat-angular/src/assets/i18n/en.ts b/projects/stream-chat-angular/src/assets/i18n/en.ts index 68c6fb15..933ba382 100644 --- a/projects/stream-chat-angular/src/assets/i18n/en.ts +++ b/projects/stream-chat-angular/src/assets/i18n/en.ts @@ -130,5 +130,6 @@ export const en = { "You can't uplod more than {{max}} attachments", 'You currently have {{count}} attachments, the maximum is {{max}}': 'You currently have {{count}} attachments, the maximum is {{max}}', + 'and others': 'and others', }, }; diff --git a/projects/stream-chat-angular/src/lib/list-users.spec.ts b/projects/stream-chat-angular/src/lib/list-users.spec.ts index c45308d6..426f3a4a 100644 --- a/projects/stream-chat-angular/src/lib/list-users.spec.ts +++ b/projects/stream-chat-angular/src/lib/list-users.spec.ts @@ -48,4 +48,19 @@ describe('listUsers', () => { expect(listUsers(readBy)).toBe('Bob, Sophie, Jack, Rose, John +1'); }); + + it(`shouldn't display number if #displayRestCount is set to false`, () => { + const readBy = [ + { id: 'id1', name: 'Bob' }, + { id: 'id2', name: 'Sophie' }, + { id: 'id3', name: 'Jack' }, + { id: 'id4', name: 'Rose' }, + { id: 'id5', name: 'John' }, + { id: 'id6', name: 'Adam' }, + ]; + + expect(listUsers(readBy, false, 'and more')).toBe( + 'Bob, Sophie, Jack, Rose, John and more' + ); + }); }); diff --git a/projects/stream-chat-angular/src/lib/list-users.ts b/projects/stream-chat-angular/src/lib/list-users.ts index dd715fe0..3700ec80 100644 --- a/projects/stream-chat-angular/src/lib/list-users.ts +++ b/projects/stream-chat-angular/src/lib/list-users.ts @@ -1,6 +1,10 @@ import { UserResponse } from 'stream-chat'; -export const listUsers = (users: UserResponse[]) => { +export const listUsers = ( + users: UserResponse[], + displayRestCount = true, + othersText = '' +) => { let outStr = ''; const slicedArr = users.map((item) => item.name || item.id).slice(0, 5); @@ -9,7 +13,7 @@ export const listUsers = (users: UserResponse[]) => { const commaSeparatedUsers = slicedArr.join(', '); outStr = commaSeparatedUsers; if (restLength > 0) { - outStr += ` +${restLength}`; + outStr += displayRestCount ? ` +${restLength}` : ` ${othersText}`; } return outStr; diff --git a/projects/stream-chat-angular/src/lib/message/message.component.spec.ts b/projects/stream-chat-angular/src/lib/message/message.component.spec.ts index fc78ff42..03810176 100644 --- a/projects/stream-chat-angular/src/lib/message/message.component.spec.ts +++ b/projects/stream-chat-angular/src/lib/message/message.component.spec.ts @@ -59,6 +59,12 @@ describe('MessageComponent', () => { let setAsActiveParentMessageSpy: jasmine.Spy; let jumpToMessageSpy: jasmine.Spy; let bouncedMessage$: BehaviorSubject; + const mockChannel = { + cid: 'messaging:general', + data: { + member_count: 5, + }, + }; beforeEach(() => { resendMessageSpy = jasmine.createSpy('resendMessage'); @@ -91,6 +97,13 @@ describe('MessageComponent', () => { { provide: ChannelService, useValue: { + _activeChannel$: of(mockChannel), + get activeChannel$() { + return this._activeChannel$; + }, + set activeChannel$(value) { + this._activeChannel$ = value; + }, resendMessage: resendMessageSpy, setAsActiveParentMessage: setAsActiveParentMessageSpy, jumpToMessage: jumpToMessageSpy, @@ -129,6 +142,7 @@ describe('MessageComponent', () => { queryMessageOptionsButton = () => nativeElement.querySelector('[data-testid="message-options-button"]'); message = mockMessage(); + message.cid = mockChannel.cid; component.message = message; component.ngOnChanges({ message: {} as SimpleChange }); component.ngAfterViewInit(); diff --git a/projects/stream-chat-angular/src/lib/message/message.component.ts b/projects/stream-chat-angular/src/lib/message/message.component.ts index 4d02f344..38ff98f5 100644 --- a/projects/stream-chat-angular/src/lib/message/message.component.ts +++ b/projects/stream-chat-angular/src/lib/message/message.component.ts @@ -39,6 +39,7 @@ import { NgxFloatUiContentComponent, NgxFloatUiLooseDirective, } from 'ngx-float-ui'; +import { TranslateService } from '@ngx-translate/core'; type MessagePart = { content: string; @@ -125,6 +126,7 @@ export class MessageComponent private showMessageMenuTimeout?: ReturnType; private shouldPreventMessageMenuClose = false; private _visibleMessageActionsCount = 0; + private channelMemberCount?: number; constructor( private chatClientService: ChatClientService, @@ -134,7 +136,8 @@ export class MessageComponent private dateParser: DateParserService, private messageService: MessageService, public messageActionsService: MessageActionsService, - private ngZone: NgZone + private ngZone: NgZone, + private translateService: TranslateService ) { this.displayAs = this.messageService.displayAs; } @@ -180,6 +183,26 @@ export class MessageComponent } }) ); + this.subscriptions.push( + this.channelService.activeChannel$.subscribe((activeChannel) => { + const newChannelMemberCount = activeChannel?.data?.member_count; + if (newChannelMemberCount !== this.channelMemberCount) { + const shouldUpdateText = + this.channelMemberCount !== undefined && + newChannelMemberCount != undefined && + ((this.channelMemberCount <= 1000 && newChannelMemberCount > 100) || + (this.channelMemberCount > 100 && newChannelMemberCount <= 100)); + this.channelMemberCount = activeChannel?.data?.member_count; + if ( + this.message && + this.message.cid === activeChannel?.cid && + shouldUpdateText + ) { + this.updateReadByText(); + } + } + }) + ); } ngOnChanges(changes: SimpleChanges): void { @@ -194,9 +217,7 @@ export class MessageComponent : []; this.setIsSentByCurrentUser(); this.setLastReadUser(); - this.readByText = this.message?.readBy - ? listUsers(this.message.readBy) - : ''; + this.updateReadByText(); this.isOnlyReadByMe = !!( this.message && this.message.readBy && @@ -567,6 +588,16 @@ export class MessageComponent return content; } + private updateReadByText() { + const others = this.translateService.instant( + 'streamChat.and others' + ) as string; + const hasMoreThan100Members = (this.channelMemberCount ?? 0) > 100; + this.readByText = this.message?.readBy + ? listUsers(this.message.readBy, !hasMoreThan100Members, others) + : ''; + } + private setIsSentByCurrentUser() { this.isSentByCurrentUser = this.message?.user?.id === this.userId; }