1+ import type { ComponentProps , PropsWithChildren } from 'react' ;
12import React , {
23 useCallback ,
34 useEffect ,
@@ -11,7 +12,7 @@ import clsx from 'clsx';
1112import debounce from 'lodash.debounce' ;
1213import defaultsDeep from 'lodash.defaultsdeep' ;
1314import throttle from 'lodash.throttle' ;
14- import type { ComponentProps , PropsWithChildren } from 'react ' ;
15+ import { localMessageToNewMessagePayload } from 'stream-chat ' ;
1516import type {
1617 APIErrorResponse ,
1718 ChannelAPIResponse ,
@@ -21,15 +22,14 @@ import type {
2122 ErrorFromResponse ,
2223 Event ,
2324 EventAPIResponse ,
25+ LocalMessage ,
2426 Message ,
2527 MessageResponse ,
2628 SendMessageAPIResponse ,
2729 SendMessageOptions ,
2830 Channel as StreamChannel ,
2931 StreamChat ,
3032 Thread ,
31- UpdatedMessage ,
32- UserResponse ,
3333} from 'stream-chat' ;
3434
3535import { initialState , makeChannelReducer } from './channelState' ;
@@ -50,8 +50,6 @@ import type {
5050 ChannelNotifications ,
5151 ComponentContextValue ,
5252 MarkReadWrapperOptions ,
53- MessageToSend ,
54- StreamMessage ,
5553} from '../../context' ;
5654import {
5755 ChannelActionProvider ,
@@ -77,12 +75,7 @@ import {
7775 useChannelContainerClasses ,
7876 useImageFlagEmojisOnWindowsClass ,
7977} from './hooks/useChannelContainerClasses' ;
80- import {
81- findInMsgSetByDate ,
82- findInMsgSetById ,
83- generateMessageId ,
84- makeAddNotifications ,
85- } from './utils' ;
78+ import { findInMsgSetByDate , findInMsgSetById , makeAddNotifications } from './utils' ;
8679import { useThreadContext } from '../Threads' ;
8780import { getChannel } from '../../utils' ;
8881
@@ -166,10 +159,6 @@ type ChannelPropsForwardedToComponentContext = Pick<
166159 | 'StreamedMessageText'
167160> ;
168161
169- const isUserResponseArray = (
170- output : string [ ] | UserResponse [ ] ,
171- ) : output is UserResponse [ ] => ( output as UserResponse [ ] ) [ 0 ] ?. id != null ;
172-
173162export type ChannelProps = ChannelPropsForwardedToComponentContext & {
174163 // todo: move to MessageComposer configuration
175164 /** List of accepted file types */
@@ -186,7 +175,7 @@ export type ChannelProps = ChannelPropsForwardedToComponentContext & {
186175 */
187176 channelQueryOptions ?: ChannelQueryOptions ;
188177 /** Custom action handler to override the default `client.deleteMessage(message.id)` function */
189- doDeleteMessageRequest ?: ( message : StreamMessage ) => Promise < MessageResponse > ;
178+ doDeleteMessageRequest ?: ( message : LocalMessage ) => Promise < MessageResponse > ;
190179 /** Custom action handler to override the default `channel.markRead` request function (advanced usage only) */
191180 doMarkReadRequest ?: (
192181 channel : StreamChannel ,
@@ -201,7 +190,7 @@ export type ChannelProps = ChannelPropsForwardedToComponentContext & {
201190 /** Custom action handler to override the default `client.updateMessage` request function (advanced usage only) */
202191 doUpdateMessageRequest ?: (
203192 cid : string ,
204- updatedMessage : UpdatedMessage ,
193+ updatedMessage : LocalMessage | MessageResponse ,
205194 options ?: UpdateMessageOptions ,
206195 ) => ReturnType < StreamChat [ 'updateMessage' ] > ;
207196 /** If true, chat users will be able to drag and drop file uploads to the entire channel window */
@@ -943,7 +932,7 @@ const ChannelInner = (
943932 ) ;
944933
945934 const deleteMessage = useCallback (
946- async ( message : StreamMessage ) : Promise < MessageResponse > => {
935+ async ( message : LocalMessage ) : Promise < MessageResponse > => {
947936 if ( ! message ?. id ) {
948937 throw new Error ( 'Cannot delete a message - missing message ID.' ) ;
949938 }
@@ -960,9 +949,9 @@ const ChannelInner = (
960949 [ client , doDeleteMessageRequest ] ,
961950 ) ;
962951
963- const updateMessage = ( updatedMessage : MessageToSend | StreamMessage ) => {
952+ const updateMessage = ( updatedMessage : MessageResponse | LocalMessage ) => {
964953 // add the message to the local channel state
965- channel . state . addMessageSorted ( updatedMessage as MessageResponse , true ) ;
954+ channel . state . addMessageSorted ( updatedMessage , true ) ;
966955
967956 dispatch ( {
968957 channel,
@@ -971,43 +960,28 @@ const ChannelInner = (
971960 } ) ;
972961 } ;
973962
974- const doSendMessage = async (
975- message : MessageToSend | StreamMessage ,
976- customMessageData ?: Partial < Message > ,
977- options ?: SendMessageOptions ,
978- ) => {
979- const { attachments, id, mentioned_users = [ ] , parent_id, text } = message ;
980-
981- // channel.sendMessage expects an array of user id strings
982- const mentions = isUserResponseArray ( mentioned_users )
983- ? mentioned_users . map ( ( { id } ) => id )
984- : mentioned_users ;
985-
986- const messageData = {
987- attachments,
988- id,
989- mentioned_users : mentions ,
990- parent_id,
991- // todo: move to message composer
992- // quoted_message_id:
993- // parent_id === quotedMessage?.parent_id ? quotedMessage?.id : undefined,
994- text,
995- ...customMessageData ,
996- } as Message ;
997-
963+ const doSendMessage = async ( {
964+ localMessage,
965+ message,
966+ options,
967+ } : {
968+ localMessage : LocalMessage ;
969+ message : Message ;
970+ options ?: SendMessageOptions ;
971+ } ) => {
998972 try {
999973 let messageResponse : void | SendMessageAPIResponse ;
1000974
1001975 if ( doSendMessageRequest ) {
1002- messageResponse = await doSendMessageRequest ( channel , messageData , options ) ;
976+ messageResponse = await doSendMessageRequest ( channel , message , options ) ;
1003977 } else {
1004- messageResponse = await channel . sendMessage ( messageData , options ) ;
978+ messageResponse = await channel . sendMessage ( message , options ) ;
1005979 }
1006980
1007- let existingMessage ;
981+ let existingMessage : LocalMessage | undefined = undefined ;
1008982 for ( let i = channel . state . messages . length - 1 ; i >= 0 ; i -- ) {
1009983 const msg = channel . state . messages [ i ] ;
1010- if ( msg . id && msg . id === messageData . id ) {
984+ if ( msg . id && msg . id === message . id ) {
1011985 existingMessage = msg ;
1012986 break ;
1013987 }
@@ -1051,79 +1025,61 @@ const ChannelInner = (
10511025 error . message . includes ( 'already exists' )
10521026 ) {
10531027 updateMessage ( {
1054- ...message ,
1028+ ...localMessage ,
10551029 status : 'received' ,
10561030 } ) ;
10571031 } else {
10581032 updateMessage ( {
1059- ...message ,
1033+ ...localMessage ,
10601034 error : parsedError ,
1061- errorStatusCode : parsedError . status || undefined ,
10621035 status : 'failed' ,
10631036 } ) ;
10641037
10651038 thread ?. upsertReplyLocally ( {
10661039 message : {
1067- ...message ,
1068- // @ts -expect-error error is local
1040+ ...localMessage ,
10691041 error : parsedError ,
1070- errorStatusCode : parsedError . status || undefined ,
10711042 status : 'failed' ,
10721043 } ,
10731044 } ) ;
10741045 }
10751046 }
10761047 } ;
10771048
1078- const sendMessage = async (
1079- { attachments = [ ] , mentioned_users = [ ] , parent, text = '' } : MessageToSend ,
1080- customMessageData ?: Partial < Message > ,
1081- options ?: SendMessageOptions ,
1082- ) => {
1049+ const sendMessage = async ( {
1050+ localMessage,
1051+ message,
1052+ options,
1053+ } : {
1054+ localMessage : LocalMessage ;
1055+ message : Message ;
1056+ options ?: SendMessageOptions ;
1057+ } ) => {
10831058 channel . state . filterErrorMessages ( ) ;
10841059
1085- const messagePreview = {
1086- attachments,
1087- created_at : new Date ( ) ,
1088- html : text ,
1089- id : customMessageData ?. id ?? generateMessageId ( { client } ) ,
1090- mentioned_users,
1091- parent_id : parent ?. id ,
1092- reactions : [ ] ,
1093- status : 'sending' ,
1094- text,
1095- type : 'regular' ,
1096- user : client . user ,
1097- } ;
1098-
10991060 thread ?. upsertReplyLocally ( {
1100- // @ts -expect-error message type mismatch
1101- message : messagePreview ,
1061+ message : localMessage ,
11021062 } ) ;
11031063
1104- updateMessage ( messagePreview ) ;
1064+ updateMessage ( localMessage ) ;
11051065
1106- await doSendMessage ( messagePreview , customMessageData , options ) ;
1066+ await doSendMessage ( { localMessage , message , options } ) ;
11071067 } ;
11081068
1109- const retrySendMessage = async ( message : StreamMessage ) => {
1069+ const retrySendMessage = async ( localMessage : LocalMessage ) => {
11101070 updateMessage ( {
1111- ...message ,
1112- errorStatusCode : undefined ,
1071+ ...localMessage ,
1072+ error : null ,
11131073 status : 'sending' ,
11141074 } ) ;
11151075
1116- if ( message . attachments ) {
1117- // remove scraped attachments added during the message composition in MessageInput to prevent sync issues
1118- message . attachments = message . attachments . filter (
1119- ( attachment ) => ! attachment . og_scrape_url ,
1120- ) ;
1121- }
1122-
1123- await doSendMessage ( message ) ;
1076+ await doSendMessage ( {
1077+ localMessage,
1078+ message : localMessageToNewMessagePayload ( localMessage ) ,
1079+ } ) ;
11241080 } ;
11251081
1126- const removeMessage = ( message : StreamMessage ) => {
1082+ const removeMessage = ( message : LocalMessage ) => {
11271083 channel . state . removeMessage ( message ) ;
11281084
11291085 dispatch ( {
@@ -1135,7 +1091,7 @@ const ChannelInner = (
11351091
11361092 /** THREAD */
11371093
1138- const openThread = ( message : StreamMessage , event ?: React . BaseSyntheticEvent ) => {
1094+ const openThread = ( message : LocalMessage , event ?: React . BaseSyntheticEvent ) => {
11391095 event ?. preventDefault ( ) ;
11401096 // todo: revisit how to open a thread
11411097
@@ -1162,7 +1118,7 @@ const ChannelInner = (
11621118 threadInstance : t ,
11631119 type : 'openThread' ,
11641120 } ) ;
1165- client . threads . addThread ( t ) ;
1121+ // client.threads.addThread(t);
11661122 } ) ;
11671123 } ;
11681124
0 commit comments