1+ import { match } from 'ts-pattern' ;
12import { useCallback } from 'react' ;
23import { useGroupChannelMessages } from '@sendbird/uikit-tools' ;
34import { MessageMetaArray } from '@sendbird/chat/message' ;
@@ -19,9 +20,10 @@ import {
1920 VOICE_MESSAGE_FILE_NAME ,
2021 VOICE_MESSAGE_MIME_TYPE ,
2122} from '../../../../utils/consts' ;
22- import type { SendableMessageType } from '../../../../utils' ;
23+ import type { SendableMessageType , CoreMessageType } from '../../../../utils' ;
2324import type { ReplyType } from '../../../../types' ;
24- import type { GroupChannelProviderProps } from '../GroupChannelProvider' ;
25+ import type { GroupChannelProviderProps , OnBeforeHandler } from '../GroupChannelProvider' ;
26+ import useSendbirdStateContext from '../../../../hooks/useSendbirdStateContext' ;
2527
2628type MessageListDataSource = ReturnType < typeof useGroupChannelMessages > ;
2729type MessageActions = {
@@ -39,6 +41,13 @@ interface Params extends GroupChannelProviderProps, MessageListDataSource {
3941}
4042
4143const pass = < T > ( value : T ) => value ;
44+ type MessageParamsByType = {
45+ user : UserMessageCreateParams ;
46+ file : FileMessageCreateParams ;
47+ multipleFiles : MultipleFilesMessageCreateParams ;
48+ voice : FileMessageCreateParams ;
49+ update : UserMessageUpdateParams ;
50+ } ;
4251
4352/**
4453 * @description This hook controls common processes related to message sending, updating.
@@ -60,7 +69,7 @@ export function useMessageActions(params: Params): MessageActions {
6069 quoteMessage,
6170 replyType,
6271 } = params ;
63-
72+ const { eventHandlers } = useSendbirdStateContext ( ) ;
6473 const buildInternalMessageParams = useCallback (
6574 < T extends BaseMessageCreateParams > ( basicParams : T ) : T => {
6675 const messageParams = { ...basicParams } as T ;
@@ -84,33 +93,71 @@ export function useMessageActions(params: Params): MessageActions {
8493 [ ] ,
8594 ) ;
8695
96+ const processParams = useCallback ( async < T extends keyof MessageParamsByType > (
97+ handler : OnBeforeHandler < MessageParamsByType [ T ] > ,
98+ params : ReturnType < typeof buildInternalMessageParams > ,
99+ type : keyof MessageParamsByType ,
100+ ) : Promise < MessageParamsByType [ T ] > => {
101+ try {
102+ const result = await handler ( params as MessageParamsByType [ T ] ) ;
103+ return ( result === undefined ? params : result ) as MessageParamsByType [ T ] ;
104+ } catch ( error ) {
105+ if ( typeof eventHandlers ?. message === 'object' ) {
106+ match ( type )
107+ . with ( 'file' , 'voice' , ( ) => {
108+ if ( ( params as any ) . file ) {
109+ eventHandlers . message . onFileUploadFailed ?.( error ) ;
110+ }
111+ eventHandlers . message . onSendMessageFailed ?.( params as CoreMessageType , error ) ;
112+ } )
113+ . with ( 'multipleFiles' , ( ) => {
114+ if ( ( params as MultipleFilesMessageCreateParams ) . fileInfoList ) {
115+ eventHandlers . message . onFileUploadFailed ?.( error ) ;
116+ }
117+ eventHandlers . message . onSendMessageFailed ?.( params as CoreMessageType , error ) ;
118+ } )
119+ . with ( 'user' , ( ) => {
120+ eventHandlers . message . onSendMessageFailed ?.(
121+ params as CoreMessageType ,
122+ error ,
123+ ) ;
124+ } )
125+ . with ( 'update' , ( ) => {
126+ eventHandlers . message . onUpdateMessageFailed ?.(
127+ params as CoreMessageType ,
128+ error ,
129+ ) ;
130+ } )
131+ . exhaustive ( ) ;
132+ }
133+ throw error ;
134+ }
135+ } , [ eventHandlers ] ) ;
136+
87137 return {
88138 sendUserMessage : useCallback (
89139 async ( params ) => {
90140 const internalParams = buildInternalMessageParams < UserMessageCreateParams > ( params ) ;
91- const processedParams = await onBeforeSendUserMessage ( internalParams ) ;
92-
141+ const processedParams = await processParams ( onBeforeSendUserMessage , internalParams , 'user' ) as UserMessageCreateParams ;
93142 return sendUserMessage ( processedParams , asyncScrollToBottom ) ;
94143 } ,
95- [ buildInternalMessageParams , sendUserMessage , scrollToBottom ] ,
144+ [ buildInternalMessageParams , sendUserMessage , scrollToBottom , processParams ] ,
96145 ) ,
97146 sendFileMessage : useCallback (
98147 async ( params ) => {
99148 const internalParams = buildInternalMessageParams < FileMessageCreateParams > ( params ) ;
100- const processedParams = await onBeforeSendFileMessage ( internalParams ) ;
101-
149+ const processedParams = await processParams ( onBeforeSendFileMessage , internalParams , 'file' ) as FileMessageCreateParams ;
102150 return sendFileMessage ( processedParams , asyncScrollToBottom ) ;
103151 } ,
104- [ buildInternalMessageParams , sendFileMessage , scrollToBottom ] ,
152+ [ buildInternalMessageParams , sendFileMessage , scrollToBottom , processParams ] ,
105153 ) ,
106154 sendMultipleFilesMessage : useCallback (
107155 async ( params ) => {
108156 const internalParams = buildInternalMessageParams < MultipleFilesMessageCreateParams > ( params ) ;
109- const processedParams = await onBeforeSendMultipleFilesMessage ( internalParams ) ;
110-
157+ const processedParams = await processParams ( onBeforeSendMultipleFilesMessage , internalParams , 'multipleFiles' ) as MultipleFilesMessageCreateParams ;
111158 return sendMultipleFilesMessage ( processedParams , asyncScrollToBottom ) ;
112159 } ,
113- [ buildInternalMessageParams , sendMultipleFilesMessage , scrollToBottom ] ,
160+ [ buildInternalMessageParams , sendMultipleFilesMessage , scrollToBottom , processParams ] ,
114161 ) ,
115162 sendVoiceMessage : useCallback (
116163 async ( params : FileMessageCreateParams , duration : number ) => {
@@ -129,20 +176,18 @@ export function useMessageActions(params: Params): MessageActions {
129176 } ) ,
130177 ] ,
131178 } ) ;
132- const processedParams = await onBeforeSendVoiceMessage ( internalParams ) ;
133-
179+ const processedParams = await processParams ( onBeforeSendVoiceMessage , internalParams , 'voice' ) ;
134180 return sendFileMessage ( processedParams , asyncScrollToBottom ) ;
135181 } ,
136- [ buildInternalMessageParams , sendFileMessage , scrollToBottom ] ,
182+ [ buildInternalMessageParams , sendFileMessage , scrollToBottom , processParams ] ,
137183 ) ,
138184 updateUserMessage : useCallback (
139185 async ( messageId : number , params : UserMessageUpdateParams ) => {
140186 const internalParams = buildInternalMessageParams < UserMessageUpdateParams > ( params ) ;
141- const processedParams = await onBeforeUpdateUserMessage ( internalParams ) ;
142-
187+ const processedParams = await processParams ( onBeforeUpdateUserMessage , internalParams , 'update' ) ;
143188 return updateUserMessage ( messageId , processedParams ) ;
144189 } ,
145- [ buildInternalMessageParams , updateUserMessage ] ,
190+ [ buildInternalMessageParams , updateUserMessage , processParams ] ,
146191 ) ,
147192 } ;
148193}
0 commit comments