Skip to content

Commit

Permalink
fix all dms bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
reyamir committed Nov 17, 2023
1 parent 077712c commit 6725dca
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 42 deletions.
43 changes: 33 additions & 10 deletions src/app/chats/chat.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -16,8 +16,6 @@ import { User } from '@shared/user';
import { useNostr } from '@utils/hooks/useNostr';

export function ChatScreen() {
const listRef = useRef<VListHandle>(null);

const { db } = useStorage();
const { ndk } = useNDK();
const { pubkey } = useParams();
Expand All @@ -30,10 +28,39 @@ export function ChatScreen() {
refetchOnWindowFocus: false,
});

const queryClient = useQueryClient();
const listRef = useRef<VListHandle>(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 (
<ChatMessage message={message} self={message.pubkey === db.account.pubkey} />
<ChatMessage
key={message.id}
message={message}
isSelf={message.pubkey === db.account.pubkey}
/>
);
},
[data]
Expand All @@ -57,7 +84,7 @@ export function ChatScreen() {
);

sub.addListener('event', (event) => {
console.log(event);
newMessage.mutate(event);
});

return () => {
Expand Down Expand Up @@ -96,11 +123,7 @@ export function ChatScreen() {
)}
</div>
<div className="shrink-0 rounded-b-lg border-t border-neutral-300 bg-neutral-200 p-3 dark:border-neutral-700 dark:bg-neutral-800">
<ChatForm
receiverPubkey={pubkey}
userPubkey={db.account.pubkey}
userPrivkey={''}
/>
<ChatForm receiverPubkey={pubkey} />
</div>
</div>
</div>
Expand Down
42 changes: 17 additions & 25 deletions src/app/chats/components/chatForm.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,33 @@
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';

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: {
Expand All @@ -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"
/>
<button
Expand Down
8 changes: 3 additions & 5 deletions src/app/chats/components/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,22 @@ import { twMerge } from 'tailwind-merge';

import { useDecryptMessage } from '@app/chats/hooks/useDecryptMessage';

export function ChatMessage({ message, self }: { message: NDKEvent; self: boolean }) {
export function ChatMessage({ message, isSelf }: { message: NDKEvent; isSelf: boolean }) {
const decryptedContent = useDecryptMessage(message);

return (
<div
className={twMerge(
'my-2 w-max max-w-[400px] rounded-t-xl px-3 py-3',
self
isSelf
? 'ml-auto rounded-l-xl bg-blue-500 text-white'
: 'rounded-r-xl bg-neutral-200 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100'
)}
>
{!decryptedContent ? (
<p>Decrypting...</p>
) : (
<div>
<p className="select-text whitespace-pre-line">{decryptedContent}</p>
</div>
<p className="select-text whitespace-pre-line break-all">{decryptedContent}</p>
)}
</div>
);
Expand Down
13 changes: 11 additions & 2 deletions src/app/chats/index.tsx
Original file line number Diff line number Diff line change
@@ -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'],
Expand All @@ -29,6 +34,10 @@ export function ChatsScreen() {
[data]
);

useEffect(() => {
if (!ndk.signer) navigate('/new/privkey');
}, []);

return (
<div className="grid h-full w-full grid-cols-3">
<div className="col-span-1 h-full overflow-y-auto border-r border-neutral-200 scrollbar-none dark:border-neutral-800">
Expand Down

0 comments on commit 6725dca

Please sign in to comment.