@@ -12,6 +12,7 @@ import {
1212 useTranslationContext ,
1313} from '../../context' ;
1414import type { ReactionSort } from 'stream-chat' ;
15+ import { defaultReactionOptions } from './reactionOptions' ;
1516
1617export type MessageReactionsDetailProps = Partial <
1718 Pick < MessageContextValue , 'handleFetchReactions' | 'reactionDetailsSort' >
@@ -27,6 +28,21 @@ export type MessageReactionsDetailProps = Partial<
2728
2829const defaultReactionDetailsSort = { created_at : - 1 } as const ;
2930
31+ export const MessageReactionsDetailLoadingIndicator = ( ) => {
32+ const elements = useMemo (
33+ ( ) =>
34+ Array . from ( { length : 3 } , ( _ , index ) => (
35+ < div className = 'str-chat__message-reactions-detail__skeleton-item' key = { index } >
36+ < div className = 'str-chat__message-reactions-detail__skeleton-avatar' />
37+ < div className = 'str-chat__message-reactions-detail__skeleton-line' />
38+ </ div >
39+ ) ) ,
40+ [ ] ,
41+ ) ;
42+
43+ return < > { elements } </ > ;
44+ } ;
45+
3046export function MessageReactionsDetail ( {
3147 handleFetchReactions,
3248 onSelectedReactionTypeChange,
@@ -37,7 +53,11 @@ export function MessageReactionsDetail({
3753 totalReactionCount,
3854} : MessageReactionsDetailProps ) {
3955 const { client } = useChatContext ( ) ;
40- const { Avatar = DefaultAvatar } = useComponentContext ( MessageReactionsDetail . name ) ;
56+ const {
57+ Avatar = DefaultAvatar ,
58+ LoadingIndicator = MessageReactionsDetailLoadingIndicator ,
59+ reactionOptions = defaultReactionOptions ,
60+ } = useComponentContext ( MessageReactionsDetail . name ) ;
4161 const { t } = useTranslationContext ( ) ;
4262
4363 const {
@@ -73,7 +93,7 @@ export function MessageReactionsDetail({
7393 return (
7494 < div
7595 className = 'str-chat__message-reactions-detail'
76- data-testid = 'reactions-list-modal '
96+ data-testid = 'message- reactions-detail '
7797 >
7898 { typeof totalReactionCount === 'number' && (
7999 < div className = 'str-chat__message-reactions-detail__total-count' >
@@ -92,7 +112,11 @@ export function MessageReactionsDetail({
92112 < button
93113 aria-pressed = { reactionType === selectedReactionType }
94114 className = 'str-chat__message-reactions-detail__reaction-type-list-item-button'
95- onClick = { ( ) => onSelectedReactionTypeChange ?.( reactionType ) }
115+ onClick = { ( ) =>
116+ onSelectedReactionTypeChange ?.(
117+ selectedReactionType === reactionType ? null : reactionType ,
118+ )
119+ }
96120 >
97121 < span className = 'str-chat__message-reactions-detail__reaction-type-list-item-icon' >
98122 < EmojiComponent />
@@ -115,30 +139,20 @@ export function MessageReactionsDetail({
115139 className = 'str-chat__message-reactions-detail__user-list'
116140 data-testid = 'all-reacting-users'
117141 >
118- { areReactionsLoading && (
119- < >
120- < div className = 'str-chat__message-reactions-detail__skeleton-item' >
121- < div className = 'str-chat__message-reactions-detail__skeleton-avatar' />
122- < div className = 'str-chat__message-reactions-detail__skeleton-line' />
123- </ div >
124- < div className = 'str-chat__message-reactions-detail__skeleton-item' >
125- < div className = 'str-chat__message-reactions-detail__skeleton-avatar' />
126- < div className = 'str-chat__message-reactions-detail__skeleton-line' />
127- </ div >
128- < div className = 'str-chat__message-reactions-detail__skeleton-item' >
129- < div className = 'str-chat__message-reactions-detail__skeleton-avatar' />
130- < div className = 'str-chat__message-reactions-detail__skeleton-line' />
131- </ div >
132- </ >
133- ) }
142+ { areReactionsLoading && < LoadingIndicator /> }
134143 { ! areReactionsLoading && (
135144 < >
136- { reactionDetailsWithLegacyFallback . map ( ( { user } ) => {
145+ { reactionDetailsWithLegacyFallback . map ( ( { type , user } ) => {
137146 const belongsToCurrentUser = client . user ?. id === user ?. id ;
147+ const EmojiComponent = Array . isArray ( reactionOptions )
148+ ? undefined
149+ : ( reactionOptions . quick [ type ] ?. Component ??
150+ reactionOptions . extended ?. [ type ] ?. Component ) ;
151+
138152 return (
139153 < div
140154 className = 'str-chat__message-reactions-detail__user-list-item'
141- key = { user ?. id }
155+ key = { ` ${ user ?. id } - ${ type } ` }
142156 >
143157 < Avatar
144158 className = 'str-chat__avatar--with-border'
@@ -154,20 +168,22 @@ export function MessageReactionsDetail({
154168 >
155169 { belongsToCurrentUser ? t ( 'You' ) : user ?. name || user ?. id }
156170 </ span >
157- { belongsToCurrentUser && selectedReactionType && (
171+ { belongsToCurrentUser && (
158172 < button
159173 className = 'str-chat__message-reactions-detail__user-list-item-button'
160174 data-testid = 'remove-reaction-button'
161- onClick = { ( e ) => {
162- contextHandleReaction ( selectedReactionType , e ) . then ( ( ) => {
163- refetch ( ) ;
164- } ) ;
175+ onClick = { async ( e ) => {
176+ await contextHandleReaction ( type , e ) ;
177+ refetch ( ) ;
165178 } }
166179 >
167180 { t ( 'Tap to remove' ) }
168181 </ button >
169182 ) }
170183 </ div >
184+ < span className = 'str-chat__message-reactions-detail__user-list-item-icon' >
185+ { EmojiComponent && ! selectedReactionType && < EmojiComponent /> }
186+ </ span >
171187 </ div >
172188 ) ;
173189 } ) }
0 commit comments