@@ -11,7 +11,7 @@ import {
11
11
} from "react-native"
12
12
import { GiftedChat , Bubble } from "react-native-gifted-chat"
13
13
import { StackScreenProps } from "@react-navigation/stack"
14
- import { User , MessageDraft , Message , Channel } from "@pubnub/chat"
14
+ import { User , MessageDraft , Message , Channel , ThreadMessage } from "@pubnub/chat"
15
15
16
16
import { EnhancedIMessage , mapPNMessageToGChatMessage } from "../../../utils"
17
17
import { ChatContext } from "../../../context"
@@ -107,11 +107,37 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
107
107
}
108
108
} , [ ] )
109
109
110
+ const handleEditMessage = useCallback (
111
+ async ( message : Message ) => {
112
+ if ( ! currentChannel ) {
113
+ return
114
+ }
115
+ const newMessageDraft = currentChannel . createMessageDraft ( {
116
+ userSuggestionSource : "global" ,
117
+ isTypingIndicatorTriggered : currentChannel . type !== "public" ,
118
+ } )
119
+ newMessageDraft . value = message . text
120
+ setText ( newMessageDraft . value )
121
+ setGiftedChatMappedMessages ( ( curr ) =>
122
+ curr . map ( ( m ) => {
123
+ return {
124
+ ...m ,
125
+ isBeingEdited : m . originalPnMessage . timetoken === message . timetoken ,
126
+ }
127
+ } )
128
+ )
129
+
130
+ setMessageDraft ( newMessageDraft )
131
+ } ,
132
+ [ currentChannel ]
133
+ )
134
+
110
135
const { ActionsMenuComponent, handlePresentModalPress } = useActionsMenu ( {
111
136
onQuote : handleQuote ,
112
137
onPinMessage : handlePin ,
113
138
onToggleEmoji : handleEmoji ,
114
139
onDeleteMessage : handleDeleteMessage ,
140
+ onEditMessage : handleEditMessage ,
115
141
} )
116
142
117
143
useEffect ( ( ) => {
@@ -245,6 +271,17 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
245
271
}
246
272
} , [ currentChannel , currentChannelMembership ] )
247
273
274
+ function resetMessageBeingEdited ( ) {
275
+ setGiftedChatMappedMessages ( ( curr ) =>
276
+ curr . map ( ( m ) => {
277
+ return {
278
+ ...m ,
279
+ isBeingEdited : false ,
280
+ }
281
+ } )
282
+ )
283
+ }
284
+
248
285
const resetInput = ( ) => {
249
286
if ( ! messageDraft ) {
250
287
return
@@ -254,6 +291,11 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
254
291
messageDraft . files = undefined
255
292
setText ( "" )
256
293
setImage ( "" )
294
+ resetMessageBeingEdited ( )
295
+ }
296
+
297
+ function getMessageBeingEdited ( ) {
298
+ return giftedChatMappedMessages . find ( ( m ) => m . isBeingEdited ) ?. originalPnMessage
257
299
}
258
300
259
301
const onSend = async ( ) => {
@@ -262,17 +304,29 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
262
304
}
263
305
264
306
try {
265
- await messageDraft . send ( )
307
+ const messageBeingEdited = getMessageBeingEdited ( )
308
+ if ( messageBeingEdited ) {
309
+ await messageBeingEdited . editText ( messageDraft . value )
310
+ } else {
311
+ await messageDraft . send ( )
312
+ }
266
313
} catch ( error ) {
314
+ let alertFn = ( _ : string ) => null
315
+ if ( Platform . OS === "web" ) {
316
+ alertFn = alert
317
+ } else {
318
+ alertFn = Alert . alert
319
+ }
320
+
321
+ if ( typeof error === "string" ) {
322
+ alertFn ( error )
323
+ resetMessageBeingEdited ( )
324
+ }
267
325
const e = error as { status : { errorData : { status : number } } }
268
326
if ( e ?. status ?. errorData ?. status !== 403 ) {
269
327
return
270
328
}
271
- if ( Platform . OS === "web" ) {
272
- alert ( `You cannot send messages to this channel: ${ currentChannel ?. id } ` )
273
- } else {
274
- Alert . alert ( "You cannot send messages to this channel:" , currentChannel ?. id )
275
- }
329
+ alertFn ( `You cannot send messages to this channel: ${ currentChannel ?. id } ` )
276
330
}
277
331
resetInput ( )
278
332
}
@@ -311,13 +365,25 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
311
365
}
312
366
313
367
const renderBubble = ( props : Bubble < EnhancedIMessage > [ "props" ] ) => {
368
+ const isBeingEditedStyles = props . currentMessage . isBeingEdited
369
+ ? {
370
+ borderWidth : 1 ,
371
+ borderColor : colors . teal700 ,
372
+ }
373
+ : { }
374
+
314
375
return (
315
376
< View >
316
377
< Bubble
317
378
{ ...props }
318
379
wrapperStyle = { {
319
380
left : { padding : 12 , backgroundColor : colors . neutral50 } ,
320
- right : { marginLeft : 0 , padding : 12 , backgroundColor : colors . teal100 } ,
381
+ right : {
382
+ marginLeft : 0 ,
383
+ padding : 12 ,
384
+ backgroundColor : colors . teal100 ,
385
+ ...isBeingEditedStyles ,
386
+ } ,
321
387
} }
322
388
/>
323
389
{ props . currentMessage ?. originalPnMessage . hasThread ? (
@@ -384,7 +450,7 @@ export function ChatScreen({}: StackScreenProps<HomeStackParamList, "Chat">) {
384
450
< SafeAreaView style = { styles . content } >
385
451
< GiftedChat
386
452
messages = { giftedChatMappedMessages }
387
- onSend = { ( messages ) => onSend ( messages ) }
453
+ onSend = { onSend }
388
454
onInputTextChanged = { handleInputChange }
389
455
renderMessageText = { renderMessageText }
390
456
renderFooter = { renderFooter }
0 commit comments