From 79e948ac05efb6a13e6c0dd9a658f9a12b880152 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 27 May 2023 12:14:30 +0700 Subject: [PATCH] wip: refactor chats to use zustand --- .../20230418080146_create_chats.sql | 1 + src/app/chat/components/item.tsx | 12 +- src/app/chat/components/list.tsx | 6 +- src/app/chat/components/messageList.tsx | 23 ++-- src/app/chat/components/messages/form.tsx | 119 ++++++++---------- src/app/chat/components/messages/item.tsx | 19 ++- src/app/chat/components/messages/user.tsx | 10 +- src/app/chat/components/self.tsx | 52 -------- src/app/chat/components/sidebar.tsx | 30 +++++ src/app/chat/hooks/useDecryptMessage.tsx | 41 +++--- src/app/chat/layout.tsx | 1 - src/app/chat/pages/index.page.tsx | 81 +++++++----- src/app/prefetch/pages/index.page.tsx | 37 ++++-- src/app/space/components/following.tsx | 4 +- src/renderer/_default.page.server.tsx | 2 +- src/shared/appHeader.tsx | 14 +-- src/shared/eventCollector.tsx | 30 ++--- src/shared/form/imagePicker.tsx | 4 - src/shared/navigation.tsx | 2 +- src/stores/chat.tsx | 14 --- src/utils/storage.tsx | 5 +- 21 files changed, 229 insertions(+), 278 deletions(-) delete mode 100644 src/app/chat/components/self.tsx create mode 100644 src/app/chat/components/sidebar.tsx delete mode 100644 src/stores/chat.tsx diff --git a/src-tauri/migrations/20230418080146_create_chats.sql b/src-tauri/migrations/20230418080146_create_chats.sql index 551a1d4c..1dcd8cd0 100644 --- a/src-tauri/migrations/20230418080146_create_chats.sql +++ b/src-tauri/migrations/20230418080146_create_chats.sql @@ -7,5 +7,6 @@ CREATE TABLE receiver_pubkey INTEGER NOT NULL, sender_pubkey TEXT NOT NULL, content TEXT NOT NULL, + tags JSON, created_at INTEGER NOT NULL ); \ No newline at end of file diff --git a/src/app/chat/components/item.tsx b/src/app/chat/components/item.tsx index c5583706..cabf8c52 100644 --- a/src/app/chat/components/item.tsx +++ b/src/app/chat/components/item.tsx @@ -1,19 +1,18 @@ import { Image } from "@shared/image"; - +import { useActiveAccount } from "@stores/accounts"; import { DEFAULT_AVATAR } from "@stores/constants"; - import { usePageContext } from "@utils/hooks/usePageContext"; import { useProfile } from "@utils/hooks/useProfile"; import { shortenKey } from "@utils/shortenKey"; - import { twMerge } from "tailwind-merge"; -export default function ChatsListItem({ pubkey }: { pubkey: string }) { +export function ChatsListItem({ pubkey }: { pubkey: string }) { const pageContext = usePageContext(); const searchParams: any = pageContext.urlParsed.search; const pagePubkey = searchParams.pubkey; + const account = useActiveAccount((state: any) => state.account); const { user, isError, isLoading } = useProfile(pubkey); return ( @@ -43,10 +42,13 @@ export default function ChatsListItem({ pubkey }: { pubkey: string }) { className="h-5 w-5 rounded bg-white object-cover" /> -
+
{user?.nip05 || user.name || shortenKey(pubkey)}
+ {account?.pubkey === pubkey && ( + (you) + )}
)} diff --git a/src/app/chat/components/list.tsx b/src/app/chat/components/list.tsx index 2903353a..f1998fd3 100644 --- a/src/app/chat/components/list.tsx +++ b/src/app/chat/components/list.tsx @@ -1,5 +1,4 @@ -import ChatsListItem from "@app/chat/components/item"; -import ChatsListSelfItem from "@app/chat/components/self"; +import { ChatsListItem } from "@app/chat/components/item"; import { useActiveAccount } from "@stores/accounts"; import { useChats } from "@stores/chats"; import { useEffect } from "react"; @@ -16,7 +15,6 @@ export default function ChatsList() { return (
- {!chats ? ( <>
@@ -29,7 +27,7 @@ export default function ChatsList() {
) : ( - chats.map((item) => ( + chats.map((item: { sender_pubkey: string }) => ( )) )} diff --git a/src/app/chat/components/messageList.tsx b/src/app/chat/components/messageList.tsx index 210eee8d..c5757c25 100644 --- a/src/app/chat/components/messageList.tsx +++ b/src/app/chat/components/messageList.tsx @@ -1,44 +1,39 @@ import { ChatMessageItem } from "@app/chat/components/messages/item"; import { useActiveAccount } from "@stores/accounts"; -import { sortedChatMessagesAtom } from "@stores/chat"; -import { useAtomValue } from "jotai"; +import { useChatMessages } from "@stores/chats"; import { useCallback, useRef } from "react"; import { Virtuoso } from "react-virtuoso"; -export default function ChatMessageList() { +export function ChatMessageList() { const account = useActiveAccount((state: any) => state.account); + const messages = useChatMessages((state: any) => state.messages); const virtuosoRef = useRef(null); - const data = useAtomValue(sortedChatMessagesAtom); const itemContent: any = useCallback( (index: string | number) => { return ( - + ); }, - [account.privkey, account.pubkey, data], + [account.privkey, account.pubkey, messages], ); const computeItemKey = useCallback( (index: string | number) => { - return data[index].id; + return messages[index].id; }, - [data], + [messages], ); return (
state.account); + const addMessage = useChatMessages((state: any) => state.add); + const [value, setValue] = useState(""); - const [value, setValue] = useAtom(chatContentAtom); - const resetValue = useResetAtom(chatContentAtom); + const encryptMessage = useCallback(async () => { + return await nip04.encrypt(userPrivkey, receiverPubkey, value); + }, [receiverPubkey, value]); - const encryptMessage = useCallback( - async (privkey: string) => { - return await nip04.encrypt(privkey, receiverPubkey, value); - }, - [receiverPubkey, value], - ); + const submit = async () => { + const message = await encryptMessage(); - const submitEvent = () => { - encryptMessage(account.privkey) - .then((encryptedContent) => { - const event: any = { - content: encryptedContent, - created_at: dateToUnix(), - kind: 4, - pubkey: account.pubkey, - tags: [["p", receiverPubkey]], - }; - event.id = getEventHash(event); - event.sig = getSignature(event, account.privkey); - // publish note - pool.publish(event, WRITEONLY_RELAYS); - // reset state - resetValue(); - }) - .catch(console.error); + const event: any = { + content: message, + created_at: dateToUnix(), + kind: 4, + pubkey: userPubkey, + tags: [["p", receiverPubkey]], + }; + + event.id = getEventHash(event); + event.sig = getSignature(event, userPrivkey); + + // publish message + pool.publish(event, WRITEONLY_RELAYS); + + // add message to store + addMessage({ + receiver_pubkey: receiverPubkey, + sender_pubkey: event.pubkey, + content: event.content, + tags: event.tags, + created_at: event.created_at, + }); + + // reset state + setValue(""); }; - const handleEnterPress = (e) => { + const handleEnterPress = (e: { + key: string; + shiftKey: any; + preventDefault: () => void; + }) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); - submitEvent(); + submit(); } }; return ( -
-
-