From b3baacb3e06e197d276ff1de5b544b1c7895dd0a Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:33:28 +0700 Subject: [PATCH] working on new virtual scroller --- package.json | 1 + pnpm-lock.yaml | 17 ++++++++++++++++ src/pages/_app.tsx | 9 ++++++--- src/pages/newsfeed/circle.tsx | 37 +++++++++++++++++++++++++++++++++-- src/stores/note.tsx | 2 ++ 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 3a6c1ca7..28d98e25 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@radix-ui/react-tabs": "^1.0.3", "@rehooks/local-storage": "^2.4.4", "@supabase/supabase-js": "^2.12.0", + "@tanstack/react-virtual": "3.0.0-beta.54", "@tauri-apps/api": "^1.2.0", "@uiw/react-markdown-preview": "^4.1.10", "@uiw/react-md-editor": "^3.20.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c17141f7..6fe9af12 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,7 @@ specifiers: '@rehooks/local-storage': ^2.4.4 '@supabase/supabase-js': ^2.12.0 '@tailwindcss/typography': ^0.5.9 + '@tanstack/react-virtual': 3.0.0-beta.54 '@tauri-apps/api': ^1.2.0 '@tauri-apps/cli': ^1.2.3 '@trivago/prettier-plugin-sort-imports': ^4.1.1 @@ -63,6 +64,7 @@ dependencies: '@radix-ui/react-tabs': 1.0.3_biqbaboplfbrettd7655fr4n2y '@rehooks/local-storage': 2.4.4_react@18.2.0 '@supabase/supabase-js': 2.12.0 + '@tanstack/react-virtual': 3.0.0-beta.54_react@18.2.0 '@tauri-apps/api': 1.2.0 '@uiw/react-markdown-preview': 4.1.10_zula6vjvt3wdocc4mwcxqa6nzi '@uiw/react-md-editor': 3.20.5_zula6vjvt3wdocc4mwcxqa6nzi @@ -1298,6 +1300,21 @@ packages: tailwindcss: 3.2.7_postcss@8.4.21 dev: true + /@tanstack/react-virtual/3.0.0-beta.54_react@18.2.0: + resolution: + { integrity: sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ== } + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@tanstack/virtual-core': 3.0.0-beta.54 + react: 18.2.0 + dev: false + + /@tanstack/virtual-core/3.0.0-beta.54: + resolution: + { integrity: sha512-jtkwqdP2rY2iCCDVAFuaNBH3fiEi29aTn2RhtIoky8DTTiCdc48plpHHreLwmv1PICJ4AJUUESaq3xa8fZH8+g== } + dev: false + /@tauri-apps/api/1.2.0: resolution: { integrity: sha512-lsI54KI6HGf7VImuf/T9pnoejfgkNoXveP14pVV7XarrQ46rOejIVJLFqHI9sRReJMGdh2YuCoI3cc/yCWCsrw== } diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 9f4da805..7d6adfd6 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -2,6 +2,7 @@ import DatabaseProvider from '@components/contexts/database'; import RelayProvider from '@components/contexts/relay'; import { useLocalStorage } from '@rehooks/local-storage'; +import { Provider } from 'jotai'; import type { NextPage } from 'next'; import type { AppProps } from 'next/app'; import { ReactElement, ReactNode } from 'react'; @@ -24,8 +25,10 @@ export default function MyApp({ Component, pageProps }: AppPropsWithLayout) { const [relays] = useLocalStorage('relays'); return ( - - {getLayout()} - + + + {getLayout()} + + ); } diff --git a/src/pages/newsfeed/circle.tsx b/src/pages/newsfeed/circle.tsx index f37272fc..1f7d6c53 100644 --- a/src/pages/newsfeed/circle.tsx +++ b/src/pages/newsfeed/circle.tsx @@ -1,10 +1,43 @@ import BaseLayout from '@layouts/base'; import WithSidebarLayout from '@layouts/withSidebar'; -import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react'; +import { Note } from '@components/note'; + +import { notesAtom } from '@stores/note'; + +import { useVirtualizer } from '@tanstack/react-virtual'; +import { useAtom } from 'jotai'; +import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useRef } from 'react'; export default function Page() { - return <>; + const [data]: any = useAtom(notesAtom); + + const parentRef = useRef(null); + + const virtualizer = useVirtualizer({ + count: data.length, + overscan: 5, + estimateSize: () => 600, + getScrollElement: () => parentRef.current, + getItemKey: (index) => data[index].id, + }); + const items = virtualizer.getVirtualItems(); + + return ( +
+ {items.length > 0 && ( +
+
+ {items.map((virtualRow) => ( +
+ +
+ ))} +
+
+ )} +
+ ); } Page.getLayout = function getLayout( diff --git a/src/stores/note.tsx b/src/stores/note.tsx index 21682af0..05e8bf90 100644 --- a/src/stores/note.tsx +++ b/src/stores/note.tsx @@ -2,3 +2,5 @@ import { atom } from 'jotai'; // usecase: notify user that connector has receive newer note export const hasNewerNoteAtom = atom(false); +// usecase: query notes from database +export const notesAtom = atom([]);