diff --git a/src/app/chats/chat.tsx b/src/app/chats/chat.tsx
index 243cbae9..4767cc6f 100644
--- a/src/app/chats/chat.tsx
+++ b/src/app/chats/chat.tsx
@@ -1,5 +1,5 @@
import { NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk';
-import { useQuery } from '@tanstack/react-query';
+import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useCallback, useEffect, useRef } from 'react';
import { useParams } from 'react-router-dom';
import { VList, VListHandle } from 'virtua';
@@ -16,8 +16,6 @@ import { User } from '@shared/user';
import { useNostr } from '@utils/hooks/useNostr';
export function ChatScreen() {
- const listRef = useRef(null);
-
const { db } = useStorage();
const { ndk } = useNDK();
const { pubkey } = useParams();
@@ -30,10 +28,39 @@ export function ChatScreen() {
refetchOnWindowFocus: false,
});
+ const queryClient = useQueryClient();
+ const listRef = useRef(null);
+
+ const newMessage = useMutation({
+ mutationFn: async (event: NDKEvent) => {
+ // Cancel any outgoing refetches
+ await queryClient.cancelQueries({ queryKey: ['nip04-dm', pubkey] });
+
+ // Snapshot the previous value
+ const prevMessages = queryClient.getQueryData(['nip04-dm', pubkey]);
+
+ // Optimistically update to the new value
+ queryClient.setQueryData(['nip04-dm', pubkey], (prev: NDKEvent[]) => [
+ ...prev,
+ event,
+ ]);
+
+ // Return a context object with the snapshotted value
+ return { prevMessages };
+ },
+ onSettled: () => {
+ queryClient.invalidateQueries({ queryKey: ['nip04-dm', pubkey] });
+ },
+ });
+
const renderItem = useCallback(
(message: NDKEvent) => {
return (
-
+
);
},
[data]
@@ -57,7 +84,7 @@ export function ChatScreen() {
);
sub.addListener('event', (event) => {
- console.log(event);
+ newMessage.mutate(event);
});
return () => {
@@ -96,11 +123,7 @@ export function ChatScreen() {
)}
-
+
diff --git a/src/app/chats/components/chatForm.tsx b/src/app/chats/components/chatForm.tsx
index ace68a08..3cf6c4d0 100644
--- a/src/app/chats/components/chatForm.tsx
+++ b/src/app/chats/components/chatForm.tsx
@@ -1,6 +1,6 @@
-import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
-import { nip04 } from 'nostr-tools';
-import { useCallback, useState } from 'react';
+import { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
+import { useState } from 'react';
+import { toast } from 'sonner';
import { MediaUploader } from '@app/chats/components/mediaUploader';
@@ -8,34 +8,26 @@ import { useNDK } from '@libs/ndk/provider';
import { EnterIcon } from '@shared/icons';
-export function ChatForm({
- receiverPubkey,
- userPrivkey,
-}: {
- receiverPubkey: string;
- userPubkey: string;
- userPrivkey: string;
-}) {
+export function ChatForm({ receiverPubkey }: { receiverPubkey: string }) {
const { ndk } = useNDK();
const [value, setValue] = useState('');
- const encryptMessage = useCallback(async () => {
- return await nip04.encrypt(userPrivkey, receiverPubkey, value);
- }, [receiverPubkey, value]);
-
const submit = async () => {
- const message = await encryptMessage();
- const tags = [['p', receiverPubkey]];
+ try {
+ const recipient = new NDKUser({ pubkey: receiverPubkey });
+ const message = await ndk.signer.encrypt(recipient, value);
- const event = new NDKEvent(ndk);
- event.content = message;
- event.kind = NDKKind.EncryptedDirectMessage;
- event.tags = tags;
+ const event = new NDKEvent(ndk);
+ event.content = message;
+ event.kind = NDKKind.EncryptedDirectMessage;
+ event.tag(recipient);
- await event.publish();
+ const publish = await event.publish();
- // reset state
- setValue('');
+ if (publish) setValue('');
+ } catch (e) {
+ toast.error(e);
+ }
};
const handleEnterPress = (e: {
@@ -61,7 +53,7 @@ export function ChatForm({
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
- placeholder="Message"
+ placeholder="Message..."
className="h-10 flex-1 resize-none bg-transparent px-3 text-neutral-900 placeholder:text-neutral-600 focus:outline-none dark:text-neutral-100 dark:placeholder:text-neutral-300"
/>
) : (
-
+ {decryptedContent}
)}
);
diff --git a/src/app/chats/index.tsx b/src/app/chats/index.tsx
index 67698c9a..40364e94 100644
--- a/src/app/chats/index.tsx
+++ b/src/app/chats/index.tsx
@@ -1,15 +1,20 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
-import { useCallback } from 'react';
-import { Outlet } from 'react-router-dom';
+import { useCallback, useEffect } from 'react';
+import { Outlet, useNavigate } from 'react-router-dom';
import { ChatListItem } from '@app/chats/components/chatListItem';
+import { useNDK } from '@libs/ndk/provider';
+
import { LoaderIcon } from '@shared/icons';
import { useNostr } from '@utils/hooks/useNostr';
export function ChatsScreen() {
+ const navigate = useNavigate();
+
+ const { ndk } = useNDK();
const { getAllNIP04Chats } = useNostr();
const { status, data } = useQuery({
queryKey: ['nip04-chats'],
@@ -29,6 +34,10 @@ export function ChatsScreen() {
[data]
);
+ useEffect(() => {
+ if (!ndk.signer) navigate('/new/privkey');
+ }, []);
+
return (