@@ -40,6 +40,7 @@ import {
4040import SBUUtils from '../../libs/SBUUtils' ;
4141import ChatFlatList from '../ChatFlatList' ;
4242import { ReactionAddons } from '../ReactionAddons' ;
43+ import { UnreadMessagesFloatingProps } from '../UnreadMessagesFloating' ;
4344
4445type PressActions = { onPress ?: ( ) => void ; onLongPress ?: ( ) => void ; bottomSheetItem ?: BottomSheetItem } ;
4546type HandleableMessage = SendbirdUserMessage | SendbirdFileMessage ;
@@ -50,6 +51,7 @@ export type ChannelMessageListProps<T extends SendbirdGroupChannel | SendbirdOpe
5051 channel : T ;
5152 messages : SendbirdMessage [ ] ;
5253 newMessages : SendbirdMessage [ ] ;
54+ unreadFirstMessage ?: SendbirdMessage ;
5355 searchItem ?: { startingPoint : number } ;
5456
5557 scrolledAwayFromBottom : boolean ;
@@ -68,6 +70,7 @@ export type ChannelMessageListProps<T extends SendbirdGroupChannel | SendbirdOpe
6870 onResendFailedMessage : ( failedMessage : HandleableMessage ) => Promise < HandleableMessage | void > ;
6971 onPressParentMessage ?: ( parentMessage : SendbirdMessage , childMessage : HandleableMessage ) => void ;
7072 onPressMediaMessage ?: ( message : SendbirdFileMessage , deleteMessage : ( ) => Promise < void > , uri : string ) => void ;
73+ onPressMarkAsUnreadMessage ?: ( message : HandleableMessage ) => void ;
7174
7275 renderMessage : ( props : {
7376 focused : boolean ;
@@ -84,14 +87,18 @@ export type ChannelMessageListProps<T extends SendbirdGroupChannel | SendbirdOpe
8487 enableMessageGrouping : ChannelMessageListProps < T > [ 'enableMessageGrouping' ] ;
8588 bottomSheetItem ?: BottomSheetItem ;
8689 isFirstItem : boolean ;
90+ isFirstUnreadMessage ?: boolean ;
8791 hideParentMessage ?: boolean ;
8892 } ) => React . ReactElement | null ;
8993 renderNewMessagesButton :
9094 | null
9195 | ( ( props : { visible : boolean ; onPress : ( ) => void ; newMessages : SendbirdMessage [ ] } ) => React . ReactElement | null ) ;
9296 renderScrollToBottomButton : null | ( ( props : { visible : boolean ; onPress : ( ) => void } ) => React . ReactElement | null ) ;
97+ renderUnreadMessagesFloating ?: null | ( ( props : UnreadMessagesFloatingProps ) => React . ReactElement | null ) ;
98+ unreadMessagesFloatingProps ?: UnreadMessagesFloatingProps ;
9399 flatListComponent ?: React . ComponentType < FlatListProps < SendbirdMessage > > ;
94100 flatListProps ?: Omit < FlatListProps < SendbirdMessage > , 'data' | 'renderItem' > ;
101+ onViewableItemsChanged ?: FlatListProps < SendbirdMessage > [ 'onViewableItemsChanged' ] ;
95102} & {
96103 ref ?: Ref < FlatList < SendbirdMessage > > | undefined ;
97104} ;
@@ -108,21 +115,26 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
108115 onResendFailedMessage,
109116 onPressMediaMessage,
110117 onPressParentMessage,
118+ onPressMarkAsUnreadMessage,
111119 currentUserId,
120+ renderUnreadMessagesFloating,
112121 renderNewMessagesButton,
113122 renderScrollToBottomButton,
114123 renderMessage,
115124 messages,
116125 newMessages,
126+ unreadFirstMessage,
117127 enableMessageGrouping,
118128 onScrolledAwayFromBottom,
119129 scrolledAwayFromBottom,
120130 onBottomReached,
121131 onTopReached,
122132 flatListComponent,
123133 flatListProps,
134+ onViewableItemsChanged,
124135 onPressNewMessagesButton,
125136 onPressScrollToBottomButton,
137+ unreadMessagesFloatingProps,
126138 } : ChannelMessageListProps < T > ,
127139 ref : React . ForwardedRef < FlatList < SendbirdMessage > > ,
128140) => {
@@ -139,6 +151,7 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
139151 onDeleteMessage,
140152 onResendFailedMessage,
141153 onPressMediaMessage,
154+ onPressMarkAsUnreadMessage,
142155 } ) ;
143156
144157 const renderItem : ListRenderItem < SendbirdMessage > = useFreshCallback ( ( { item, index } ) => {
@@ -147,6 +160,7 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
147160 message : item ,
148161 prevMessage : messages [ index + 1 ] ,
149162 nextMessage : messages [ index - 1 ] ,
163+ isFirstUnreadMessage : unreadFirstMessage ?. messageId === item . messageId ,
150164 onPress,
151165 onLongPress,
152166 onPressParentMessage,
@@ -166,9 +180,21 @@ const ChannelMessageList = <T extends SendbirdGroupChannel | SendbirdOpenChannel
166180 { channel . isFrozen && (
167181 < ChannelFrozenBanner style = { styles . frozenBanner } text = { STRINGS . LABELS . CHANNEL_MESSAGE_LIST_FROZEN } />
168182 ) }
183+ { renderUnreadMessagesFloating && (
184+ < View
185+ style = { [ channel . isFrozen ? styles . unreadMsgFloatingWhenFrozen : styles . unreadMsgFloating , safeAreaLayout ] }
186+ >
187+ { renderUnreadMessagesFloating ( {
188+ visible : unreadMessagesFloatingProps ?. visible ?? false ,
189+ onPressClose : ( ) => unreadMessagesFloatingProps ?. onPressClose ( ) ,
190+ unreadMessageCount : unreadMessagesFloatingProps ?. unreadMessageCount ?? 0 ,
191+ } ) }
192+ </ View >
193+ ) }
169194 < ChatFlatList
170195 flatListComponent = { flatListComponent }
171196 { ...flatListProps }
197+ onViewableItemsChanged = { onViewableItemsChanged }
172198 onTopReached = { onTopReached }
173199 onBottomReached = { onBottomReached }
174200 onScrolledAwayFromBottom = { onScrolledAwayFromBottom }
@@ -212,6 +238,7 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
212238 onReplyInThreadMessage,
213239 onDeleteMessage,
214240 onPressMediaMessage,
241+ onPressMarkAsUnreadMessage,
215242} : Pick <
216243 ChannelMessageListProps < T > ,
217244 | 'channel'
@@ -222,6 +249,7 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
222249 | 'onDeleteMessage'
223250 | 'onResendFailedMessage'
224251 | 'onPressMediaMessage'
252+ | 'onPressMarkAsUnreadMessage'
225253> ) : CreateMessagePressActions => {
226254 const handlers = useSBUHandlers ( ) ;
227255 const { colors } = useUIKitTheme ( ) ;
@@ -281,6 +309,10 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
281309 }
282310 } ;
283311
312+ const onMarkAsUnread = ( message : HandleableMessage ) => {
313+ onPressMarkAsUnreadMessage ?.( message ) ;
314+ } ;
315+
284316 const openSheetForFailedMessage = ( message : HandleableMessage ) => {
285317 openSheet ( {
286318 sheetItems : [
@@ -323,6 +355,11 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
323355 title : STRINGS . LABELS . CHANNEL_MESSAGE_COPY ,
324356 onPress : ( ) => onCopyText ( message ) ,
325357 } ) ,
358+ markAsUnread : ( message : HandleableMessage ) => ( {
359+ icon : 'mark-as-unread' as const ,
360+ title : STRINGS . LABELS . CHANNEL_MESSAGE_MARK_AS_UNREAD ,
361+ onPress : ( ) => onMarkAsUnread ( message ) ,
362+ } ) ,
326363 edit : ( message : HandleableMessage ) => ( {
327364 icon : 'edit' as const ,
328365 title : STRINGS . LABELS . CHANNEL_MESSAGE_EDIT ,
@@ -356,6 +393,9 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
356393 if ( message . isUserMessage ( ) ) {
357394 sheetItems . push ( menu . copy ( message ) ) ;
358395 if ( ! channel . isEphemeral ) {
396+ if ( channel . isGroupChannel ( ) && sbOptions . uikit . groupChannel . channel . enableMarkAsUnread ) {
397+ sheetItems . push ( menu . markAsUnread ( message ) ) ;
398+ }
359399 if ( isMyMessage ( message , currentUserId ) && message . sendingStatus === 'succeeded' ) {
360400 sheetItems . push ( menu . edit ( message ) ) ;
361401 sheetItems . push ( menu . delete ( message ) ) ;
@@ -384,6 +424,9 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
384424 } else if ( sbOptions . uikit . groupChannel . channel . replyType === 'quote_reply' ) {
385425 sheetItems . push ( menu . reply ( message ) ) ;
386426 }
427+ if ( sbOptions . uikit . groupChannel . channel . enableMarkAsUnread ) {
428+ sheetItems . push ( menu . markAsUnread ( message ) ) ;
429+ }
387430 }
388431 }
389432 }
@@ -446,6 +489,18 @@ const styles = createStyleSheet({
446489 frozenListPadding : {
447490 paddingBottom : 32 ,
448491 } ,
492+ unreadMsgFloating : {
493+ position : 'absolute' ,
494+ zIndex : 999 ,
495+ top : 12 ,
496+ alignSelf : 'center' ,
497+ } ,
498+ unreadMsgFloatingWhenFrozen : {
499+ position : 'absolute' ,
500+ zIndex : 999 ,
501+ top : 40 ,
502+ alignSelf : 'center' ,
503+ } ,
449504 newMsgButton : {
450505 position : 'absolute' ,
451506 zIndex : 999 ,
0 commit comments