Skip to content

Commit 6c35e82

Browse files
authored
Merge pull request #15 from jtclarkjr/fix/unsend-db-messages
fix: unsend initial loaded messages not removed from ui
2 parents d5fbaad + f842b45 commit 6c35e82

File tree

4 files changed

+62
-22
lines changed

4 files changed

+62
-22
lines changed

components/realtime-chat.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export const RealtimeChat = ({
4949
loading,
5050
queueStatus,
5151
clearFailedMessages,
52-
onMessageUpdate
52+
onMessageUpdate,
53+
markMessageAsDeleted,
54+
deletedMessageIds
5355
} = useRealtimeChat({
5456
roomId,
5557
username,
@@ -61,7 +63,8 @@ export const RealtimeChat = ({
6163
const { unsendMessage, isUnsending } = useUnsendMessage({
6264
userId,
6365
roomId,
64-
onMessageUpdate
66+
onMessageUpdate,
67+
markMessageAsDeleted
6568
})
6669

6770
const {
@@ -100,7 +103,8 @@ export const RealtimeChat = ({
100103
initialMessages,
101104
realtimeMessages,
102105
streamingMessages,
103-
userId
106+
userId,
107+
deletedMessageIds
104108
})
105109

106110
// Smart auto-scroll that only scrolls when appropriate

hooks/chat/use-realtime-chat.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,42 @@ export function useRealtimeChat({
209209
)
210210
}, [missedMessages, optimisticMessages, deletedMessageIds])
211211

212+
// Callback to update confirmed messages and track deleted messages
213+
const handleMessageUpdate = useCallback(
214+
(updater: (messages: ChatMessage[]) => ChatMessage[]) => {
215+
setConfirmedMessages((current) => {
216+
const updated = updater(current)
217+
218+
// Check if any messages were marked as deleted and add them to deletedMessageIds
219+
updated.forEach((msg) => {
220+
if (msg.isDeleted) {
221+
setDeletedMessageIds((prev) => new Set(prev).add(msg.id))
222+
}
223+
})
224+
225+
return updated
226+
})
227+
},
228+
[]
229+
)
230+
231+
// Direct method to mark a message as deleted (for unsend)
232+
const markMessageAsDeleted = useCallback((messageId: string) => {
233+
setDeletedMessageIds((prev) => new Set(prev).add(messageId))
234+
// Also update confirmed messages if the message exists there
235+
setConfirmedMessages((current) =>
236+
current.map((msg) =>
237+
msg.id === messageId
238+
? {
239+
...msg,
240+
isDeleted: true,
241+
content: 'This message was deleted'
242+
}
243+
: msg
244+
)
245+
)
246+
}, [])
247+
212248
return {
213249
messages: allMessages,
214250
sendMessage,
@@ -217,6 +253,8 @@ export function useRealtimeChat({
217253
loading: missedMessagesLoading,
218254
queueStatus,
219255
clearFailedMessages,
220-
onMessageUpdate: setConfirmedMessages
256+
onMessageUpdate: handleMessageUpdate,
257+
markMessageAsDeleted,
258+
deletedMessageIds
221259
}
222260
}

hooks/messages/use-message-merging.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ interface UseMessageMergingProps {
88
realtimeMessages: ChatMessage[]
99
streamingMessages: ChatMessage[]
1010
userId: string
11+
deletedMessageIds?: Set<string>
1112
}
1213

1314
export function useMessageMerging({
1415
initialMessages,
1516
realtimeMessages,
1617
streamingMessages,
17-
userId
18+
userId,
19+
deletedMessageIds = new Set()
1820
}: UseMessageMergingProps) {
1921
const allMessages = useMemo(() => {
2022
const mergedMessages = [...initialMessages, ...realtimeMessages]
@@ -39,6 +41,12 @@ export function useMessageMerging({
3941
const uniqueMessages = mergedMessages.filter((message, index, self) => {
4042
if (!message) return false
4143
if (!message.id) return false
44+
45+
// Filter out deleted messages (check both isDeleted flag and deletedMessageIds set)
46+
if (message.isDeleted || deletedMessageIds.has(message.id)) {
47+
return false
48+
}
49+
4250
// Filter out messages without content or invalid structure
4351
const isStreamingMessage = streamingMessages.some((sm) => sm === message)
4452
if (
@@ -90,7 +98,7 @@ export function useMessageMerging({
9098
})
9199

92100
return sortedMessages
93-
}, [initialMessages, realtimeMessages, streamingMessages, userId])
101+
}, [initialMessages, realtimeMessages, streamingMessages, userId, deletedMessageIds])
94102

95103
return allMessages
96104
}

hooks/messages/use-unsend-message.tsx

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ interface UseUnsendMessageProps {
88
userId: string
99
roomId: string
1010
onMessageUpdate: (updater: (messages: ChatMessage[]) => ChatMessage[]) => void
11+
markMessageAsDeleted: (messageId: string) => void
1112
}
1213

1314
interface UseUnsendMessageReturn {
@@ -18,7 +19,8 @@ interface UseUnsendMessageReturn {
1819
export function useUnsendMessage({
1920
userId,
2021
roomId,
21-
onMessageUpdate
22+
onMessageUpdate,
23+
markMessageAsDeleted
2224
}: UseUnsendMessageProps): UseUnsendMessageReturn {
2325
const [unsendingMessages, setUnsendingMessages] = useState<Set<string>>(
2426
new Set()
@@ -41,20 +43,8 @@ export function useUnsendMessage({
4143
})
4244

4345
if (result.success) {
44-
// Update the message in the local state to show it as deleted
45-
onMessageUpdate((current) =>
46-
current.map((msg) =>
47-
msg.id === messageId
48-
? {
49-
...msg,
50-
isDeleted: true,
51-
deletedAt: result.message.deletedAt,
52-
deletedBy: result.message.deletedBy,
53-
content: 'This message was deleted'
54-
}
55-
: msg
56-
)
57-
)
46+
// Mark message as deleted - this handles both confirmed and missed messages
47+
markMessageAsDeleted(messageId)
5848
return true
5949
} else {
6050
console.error('Failed to unsend message:', result.error)
@@ -71,7 +61,7 @@ export function useUnsendMessage({
7161
})
7262
}
7363
},
74-
[userId, roomId, onMessageUpdate, unsendingMessages, unsendMessageMutation]
64+
[userId, roomId, onMessageUpdate, markMessageAsDeleted, unsendingMessages, unsendMessageMutation]
7565
)
7666

7767
const isUnsending = useCallback(

0 commit comments

Comments
 (0)