1- import { MouseEventHandler } from 'react' ;
1+ import { MouseEventHandler , useMemo } from 'react' ;
22import { useTranslation } from 'react-i18next' ;
33import { useAtomValue } from 'jotai' ;
44import {
@@ -71,30 +71,25 @@ function ThreadReplyChip({
7171 const nicknames = useAtomValue ( nicknamesAtom ) ;
7272
7373 const thread = room . getThread ( mEventId ) ;
74- let replyEvents : MatrixEvent [ ] = [ ] ;
7574
76- if ( thread ) {
77- replyEvents = thread . events . filter ( ( ev ) => {
78- const { getId : getEvId } = ev ;
79- return getEvId . call ( ev ) !== mEventId && ! reactionOrEditEvent ( ev ) ;
80- } ) ;
81- } else {
75+ const replyEvents = useMemo ( ( ) => {
8276 const linkedTimelines = getLinkedTimelines ( getLiveTimeline ( room ) ) ;
83- const allEvents = linkedTimelines . flatMap ( ( tl ) => tl . getEvents ( ) || [ ] ) ;
84- replyEvents = allEvents . filter ( ( ev ) => {
85- const { getId : getEvId , threadRootId } = ev ;
86- return threadRootId === mEventId && getEvId . call ( ev ) !== mEventId && ! reactionOrEditEvent ( ev ) ;
87- } ) ;
88- }
77+ return linkedTimelines
78+ . flatMap ( ( tl ) => tl . getEvents ( ) )
79+ . filter (
80+ ( ev ) => ev . threadRootId === mEventId && ev . getId ( ) !== mEventId && ! reactionOrEditEvent ( ev )
81+ ) ;
82+ } , [ room , mEventId ] ) ;
83+
84+ if ( ! thread ) return null ;
8985
90- const replyCount = replyEvents . length ;
86+ const replyCount = thread . length ?? 0 ;
9187 if ( replyCount === 0 ) return null ;
9288
9389 const uniqueSenders : string [ ] = [ ] ;
9490 const seen = new Set < string > ( ) ;
9591 replyEvents . forEach ( ( ev ) => {
96- const { getSender : getEvSender } = ev ;
97- const s = getEvSender . call ( ev ) ;
92+ const s = ev . getSender ( ) ;
9893 if ( s && ! seen . has ( s ) ) {
9994 seen . add ( s ) ;
10095 uniqueSenders . push ( s ) ;
@@ -104,11 +99,9 @@ function ThreadReplyChip({
10499 const latestReply = replyEvents . at ( - 1 ) ;
105100 let latestSenderId = '' ;
106101 let latestBody = '' ;
107-
108102 if ( latestReply ) {
109- const { getSender : getLatestSender , getContent : getLatestContent } = latestReply ;
110- latestSenderId = getLatestSender . call ( latestReply ) ?? '' ;
111- latestBody = ( getLatestContent . call ( latestReply ) ?. body as string | undefined ) ?? '' ;
103+ latestSenderId = latestReply . getSender ( ) ?? '' ;
104+ latestBody = ( latestReply . getContent ( ) ?. body as string | undefined ) ?? '' ;
112105 }
113106
114107 const latestSenderName =
@@ -124,32 +117,34 @@ function ThreadReplyChip({
124117 variant = { isOpen ? 'Primary' : 'SurfaceVariant' }
125118 radii = "300"
126119 before = {
127- < Box alignItems = "Center" style = { { gap : 0 } } >
128- { uniqueSenders . slice ( 0 , 3 ) . map ( ( senderId , index ) => {
129- const avatarMxc = getMemberAvatarMxc ( room , senderId ) ;
130- const avatarUrl = avatarMxc
131- ? ( mxcUrlToHttp ( mx , avatarMxc , useAuthentication , 20 , 20 , 'crop' ) ?? undefined )
132- : undefined ;
133- const displayName =
134- getMemberDisplayName ( room , senderId , nicknames ) ??
135- getMxIdLocalPart ( senderId ) ??
136- senderId ;
137- return (
138- < Avatar key = { senderId } size = "200" style = { { marginLeft : index > 0 ? '-4px' : 0 } } >
139- < UserAvatar
140- userId = { senderId }
141- src = { avatarUrl }
142- alt = { displayName }
143- renderFallback = { ( ) => (
144- < span style = { { fontSize : '10px' , fontWeight : 'bold' , lineHeight : 1 } } >
145- { displayName [ 0 ] ?. toUpperCase ( ) ?? '?' }
146- </ span >
147- ) }
148- />
149- </ Avatar >
150- ) ;
151- } ) }
152- </ Box >
120+ uniqueSenders . length > 0 ? (
121+ < Box alignItems = "Center" style = { { gap : 0 } } >
122+ { uniqueSenders . slice ( 0 , 3 ) . map ( ( senderId , index ) => {
123+ const avatarMxc = getMemberAvatarMxc ( room , senderId ) ;
124+ const avatarUrl = avatarMxc
125+ ? ( mxcUrlToHttp ( mx , avatarMxc , useAuthentication , 20 , 20 , 'crop' ) ?? undefined )
126+ : undefined ;
127+ const displayName =
128+ getMemberDisplayName ( room , senderId , nicknames ) ??
129+ getMxIdLocalPart ( senderId ) ??
130+ senderId ;
131+ return (
132+ < Avatar key = { senderId } size = "200" style = { { marginLeft : index > 0 ? '-4px' : 0 } } >
133+ < UserAvatar
134+ userId = { senderId }
135+ src = { avatarUrl }
136+ alt = { displayName }
137+ renderFallback = { ( ) => (
138+ < span style = { { fontSize : '10px' , fontWeight : 'bold' , lineHeight : 1 } } >
139+ { displayName [ 0 ] ?. toUpperCase ( ) ?? '?' }
140+ </ span >
141+ ) }
142+ />
143+ </ Avatar >
144+ ) ;
145+ } ) }
146+ </ Box >
147+ ) : undefined
153148 }
154149 onClick = { onToggle }
155150 style = { { marginTop : config . space . S200 } }
@@ -174,7 +169,6 @@ function ThreadReplyChip({
174169 </ Chip >
175170 ) ;
176171}
177-
178172export interface TimelineEventRendererOptions {
179173 room : Room ;
180174 mx : MatrixClient ;
0 commit comments