-
Notifications
You must be signed in to change notification settings - Fork 0
/
send-message.ts
111 lines (102 loc) · 3.1 KB
/
send-message.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useContext } from "react";
import { ChatContext } from "../chat-context-provider";
import {
Channel,
DirectContact,
Message,
useKeysQuery,
useNostrSendDirectMessage,
useNostrSendPublicMessage,
} from "../nostr";
import { useAddDirectContact } from "./add-direct-contact";
import { PublishNostrError } from "../nostr/errors";
import { convertEvent } from "../nostr/utils/event-converter";
import { Kind } from "nostr-tools";
import { MessagesQueryUtil } from "./utils";
interface Payload {
message: string;
forwardedFrom?: string;
// Indicates reply parent message ID
parentMessage?: Message;
}
export function useSendMessage(
currentChannel?: Channel,
currentContact?: DirectContact,
onSuccess?: () => void,
) {
const queryClient = useQueryClient();
const { activeUsername } = useContext(ChatContext);
const { privateKey, publicKey } = useKeysQuery();
const { mutateAsync: sendDirectMessage } = useNostrSendDirectMessage(
privateKey!!,
currentContact?.pubkey,
undefined,
);
const { mutateAsync: sendPublicMessage } = useNostrSendPublicMessage(
currentChannel?.id,
undefined,
);
const { mutateAsync: addDirectContact } = useAddDirectContact();
return useMutation({
mutationKey: ["chats/send-message"],
mutationFn: async ({ forwardedFrom, message, parentMessage }: Payload) => {
if (!message || message.includes("Uploading")) {
throw new Error(
"[Chat][SendMessage] – empty message or has uploading file",
);
}
// Add user to direct contacts if it's not there yet
// E.g. if user opened chat room directly from search bar
if (currentContact) {
addDirectContact(currentContact);
}
if (currentChannel) {
return [
await sendPublicMessage({
message,
forwardedFrom,
parentMessageId: parentMessage?.id,
}),
parentMessage,
] as const;
} else if (currentContact) {
return [
await sendDirectMessage({
message,
forwardedFrom,
parentMessageId: parentMessage?.id,
}),
parentMessage,
] as const;
} else {
throw new Error("[Chat][SendMessage] – no receiver");
}
},
onSuccess: ([message, parentMessage]) => {
message.sent = 0;
message.parentMessage = parentMessage;
MessagesQueryUtil.pushMessageToQueryData(
queryClient,
message,
activeUsername,
currentChannel?.id ?? currentContact?.pubkey,
);
onSuccess?.();
},
onError: async (error: PublishNostrError | Error) => {
if ("event" in error) {
const message = await convertEvent<
Kind.EncryptedDirectMessage | Kind.ChannelMessage
>(error.event, publicKey!!, privateKey!!)!!;
MessagesQueryUtil.updateMessageStatusInQuery(
queryClient,
message,
2,
activeUsername,
currentChannel?.id ?? currentContact?.pubkey,
);
}
},
});
}