From 340f6e48069f5ea662b6a073da96d5ab0e589784 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 22 Apr 2023 08:09:17 +0700 Subject: [PATCH] use swr for subscribe relaypool (only chats/channels page) --- package.json | 2 ++ pnpm-lock.yaml | 32 +++++++++++++++++++++ src/app/nostr/channel/page.tsx | 33 ++++++++++++++-------- src/app/nostr/chat/page.tsx | 22 +++++++++++---- src/components/channels/messages/index.tsx | 6 ++-- src/components/chats/messageList.tsx | 9 +++--- 6 files changed, 78 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index eab4db19..4a6d0c3e 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,11 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.43.9", + "react-loading-skeleton": "^3.2.1", "react-player": "^2.12.0", "react-string-replace": "^1.1.0", "react-virtuoso": "^4.2.2", + "swr": "^2.1.3", "tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql", "unique-names-generator": "^4.7.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb8c2944..711d7f46 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -46,9 +46,11 @@ specifiers: react: ^18.2.0 react-dom: ^18.2.0 react-hook-form: ^7.43.9 + react-loading-skeleton: ^3.2.1 react-player: ^2.12.0 react-string-replace: ^1.1.0 react-virtuoso: ^4.2.2 + swr: ^2.1.3 tailwindcss: ^3.3.1 tauri-plugin-sql-api: github:tauri-apps/tauri-plugin-sql typescript: ^4.9.5 @@ -77,9 +79,11 @@ dependencies: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-hook-form: 7.43.9_react@18.2.0 + react-loading-skeleton: 3.2.1_react@18.2.0 react-player: 2.12.0_react@18.2.0 react-string-replace: 1.1.0 react-virtuoso: 4.2.2_biqbaboplfbrettd7655fr4n2y + swr: 2.1.3_react@18.2.0 tauri-plugin-sql-api: github.com/tauri-apps/tauri-plugin-sql/62b21ef24303d80e9905f57b2b6d27efc8677c23 unique-names-generator: 4.7.1 @@ -4183,6 +4187,15 @@ packages: resolution: { integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== } + /react-loading-skeleton/3.2.1_react@18.2.0: + resolution: + { integrity: sha512-e1KwEOuBa1REXWoseELIJXlsqWTCHL5IQnqhVhI33WmnuTK7LK1DXl4mmcOLsWVcwqXeOATU9VFJEjz2ytZSng== } + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + /react-player/2.12.0_react@18.2.0: resolution: { integrity: sha512-rymLRz/2GJJD+Wc01S7S+i9pGMFYnNmQibR2gVE3KmHJCBNN8BhPAlOPTGZtn1uKpJ6p4RPLlzPQ1OLreXd8gw== } @@ -4677,6 +4690,16 @@ packages: engines: { node: '>= 0.4' } dev: true + /swr/2.1.3_react@18.2.0: + resolution: + { integrity: sha512-g3ApxIM4Fjbd6vvEAlW60hJlKcYxHb+wtehogTygrh6Jsw7wNagv9m4Oj5Gq6zvvZw0tcyhVGL9L0oISvl3sUw== } + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + use-sync-external-store: 1.2.0_react@18.2.0 + dev: false + /synckit/0.8.5: resolution: { integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== } @@ -4956,6 +4979,15 @@ packages: tslib: 2.5.0 dev: false + /use-sync-external-store/1.2.0_react@18.2.0: + resolution: + { integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== } + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /utf-8-validate/5.0.10: resolution: { integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== } diff --git a/src/app/nostr/channel/page.tsx b/src/app/nostr/channel/page.tsx index ce87d1af..ba83d9d8 100644 --- a/src/app/nostr/channel/page.tsx +++ b/src/app/nostr/channel/page.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ChannelMessages } from '@components/channels/messages/index'; +import { ChannelMessages } from '@components/channels/messages'; import { FormChannel } from '@components/form/channel'; import { RelayContext } from '@components/relaysProvider'; @@ -14,6 +14,7 @@ import { useSetAtom } from 'jotai'; import { useResetAtom } from 'jotai/utils'; import { useSearchParams } from 'next/navigation'; import { useContext, useEffect, useRef } from 'react'; +import useSWRSubscription from 'swr/subscription'; export default function Page() { const searchParams = useSearchParams(); @@ -30,23 +31,18 @@ export default function Page() { const muted = useRef(new Set()); const hided = useRef(new Set()); - useEffect(() => { - // reset channel reply - resetChannelReply(); - // reset channel messages - resetChannelMessages(); - // subscribe event + useSWRSubscription(id, () => { const unsubscribe = pool.subscribe( [ { authors: [activeAccount.pubkey], kinds: [43, 44], - since: dateToUnix(hoursAgo(24, now.current)), + since: dateToUnix(hoursAgo(48, now.current)), }, { '#e': [id], kinds: [42], - since: dateToUnix(hoursAgo(24, now.current)), + since: dateToUnix(hoursAgo(48, now.current)), }, ], FULL_RELAYS, @@ -61,7 +57,7 @@ export default function Page() { } else if (hided.current.has(event.id)) { console.log('hided'); } else { - setChannelMessages((messages) => [event, ...messages]); + setChannelMessages((prev) => [...prev, event]); } } } @@ -70,7 +66,22 @@ export default function Page() { return () => { unsubscribe(); }; - }, [pool, id, activeAccount.pubkey, setChannelMessages, resetChannelReply, resetChannelMessages]); + }); + + useEffect(() => { + let ignore = false; + + if (!ignore) { + // reset channel reply + resetChannelReply(); + // reset channel messages + resetChannelMessages(); + } + + return () => { + ignore = true; + }; + }, [resetChannelReply, resetChannelMessages]); return (
diff --git a/src/app/nostr/chat/page.tsx b/src/app/nostr/chat/page.tsx index c918f89c..57865643 100644 --- a/src/app/nostr/chat/page.tsx +++ b/src/app/nostr/chat/page.tsx @@ -12,6 +12,7 @@ import { useSetAtom } from 'jotai'; import { useResetAtom } from 'jotai/utils'; import { useSearchParams } from 'next/navigation'; import { useContext, useEffect } from 'react'; +import useSWRSubscription from 'swr/subscription'; export default function Page() { const searchParams = useSearchParams(); @@ -23,10 +24,7 @@ export default function Page() { const setChatMessages = useSetAtom(chatMessagesAtom); const resetChatMessages = useResetAtom(chatMessagesAtom); - useEffect(() => { - // reset stored messages - resetChatMessages(); - // fetch messages from relays + useSWRSubscription(pubkey, () => { const unsubscribe = pool.subscribe( [ { @@ -42,14 +40,26 @@ export default function Page() { ], FULL_RELAYS, (event: any) => { - setChatMessages((data) => [...data, event]); + setChatMessages((prev) => [...prev, event]); } ); return () => { unsubscribe(); }; - }, [pubkey, activeAccount.pubkey, setChatMessages, pool]); + }); + + useEffect(() => { + let ignore = false; + + if (!ignore) { + resetChatMessages(); + } + + return () => { + ignore = true; + }; + }, [resetChatMessages]); return (
diff --git a/src/components/channels/messages/index.tsx b/src/components/channels/messages/index.tsx index 2d832b23..c53f1af7 100644 --- a/src/components/channels/messages/index.tsx +++ b/src/components/channels/messages/index.tsx @@ -1,15 +1,14 @@ import ChannelMessageItem from '@components/channels/messages/item'; -import { Placeholder } from '@components/note/placeholder'; import { sortedChannelMessagesAtom } from '@stores/channel'; import { useAtomValue } from 'jotai'; import { useCallback, useRef } from 'react'; +import Skeleton from 'react-loading-skeleton'; import { Virtuoso } from 'react-virtuoso'; export const ChannelMessages = () => { const virtuosoRef = useRef(null); - const data = useAtomValue(sortedChannelMessagesAtom); const itemContent: any = useCallback( @@ -46,6 +45,5 @@ export const ChannelMessages = () => { }; const COMPONENTS = { - EmptyPlaceholder: () => , - ScrollSeekPlaceholder: () => , + EmptyPlaceholder: () => , }; diff --git a/src/components/chats/messageList.tsx b/src/components/chats/messageList.tsx index 3cebf4e2..2498be2b 100644 --- a/src/components/chats/messageList.tsx +++ b/src/components/chats/messageList.tsx @@ -1,19 +1,19 @@ import MessageListItem from '@components/chats/messageListItem'; -import { Placeholder } from '@components/note/placeholder'; import { sortedChatMessagesAtom } from '@stores/chat'; import useLocalStorage from '@rehooks/local-storage'; import { useAtomValue } from 'jotai'; import { useCallback, useRef } from 'react'; +import Skeleton from 'react-loading-skeleton'; import { Virtuoso } from 'react-virtuoso'; export const MessageList = () => { - const [activeAccount]: any = useLocalStorage('account', {}); const virtuosoRef = useRef(null); - const data = useAtomValue(sortedChatMessagesAtom); + const [activeAccount]: any = useLocalStorage('account', {}); + const itemContent: any = useCallback( (index: string | number) => { return ( @@ -50,6 +50,5 @@ export const MessageList = () => { }; const COMPONENTS = { - EmptyPlaceholder: () => , - ScrollSeekPlaceholder: () => , + EmptyPlaceholder: () => , };