import BaseLayout from '@layouts/base'; import WithSidebarLayout from '@layouts/withSidebar'; import { DatabaseContext } from '@components/contexts/database'; import { Note } from '@components/note'; import FormBasic from '@components/note/form/basic'; import { Placeholder } from '@components/note/placeholder'; import { atomHasNewerNote } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; import { useAtom } from 'jotai'; import { Key, useCallback, useState } from 'react'; import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useEffect, useRef } from 'react'; import { Virtuoso } from 'react-virtuoso'; export default function Page() { const { db }: any = useContext(DatabaseContext); const [data, setData] = useState([]); const [reload, setReload] = useState(false); const [hasNewerNote, setHasNewerNote] = useAtom(atomHasNewerNote); const now = useRef(new Date()); const limit = useRef(30); const offset = useRef(0); const loadMore = useCallback(async () => { offset.current += limit.current; // next query const result = await db.select( `SELECT * FROM cache_notes WHERE created_at <= ${dateToUnix(now.current)} ORDER BY created_at DESC LIMIT ${limit.current} OFFSET ${offset.current}` ); setData((data) => [...data, ...result]); }, [db]); const loadNewest = useCallback(async () => { const result = await db.select( `SELECT * FROM cache_notes WHERE created_at > ${dateToUnix(now.current)} ORDER BY created_at DESC LIMIT ${limit.current}` ); // update data setData((data) => [...result, ...data]); // update hasNewerNote to false to disable button setHasNewerNote(false); // update current time, fixed duplicate note now.current = new Date(); }, [db, setHasNewerNote]); const ItemContent = useCallback( (index: Key) => { const event = data[index]; return ; }, [data] ); const computeItemKey = useCallback( (index: Key) => { return data[index].id; }, [data] ); useEffect(() => { const getData = async () => { const result = await db.select(`SELECT * FROM cache_notes ORDER BY created_at DESC LIMIT ${limit.current}`); if (result.length > 0) { setData(result); } else { setReload(true); } }; if (reload === false) { getData().catch(console.error); } else { // auto reload after 8s const timer = setTimeout(() => { getData().catch(console.error); }, 8000); return () => clearTimeout(timer); } }, [db, reload]); return (
{hasNewerNote && (
)} , EmptyPlaceholder: () => , ScrollSeekPlaceholder: () => , }} computeItemKey={computeItemKey} scrollSeekConfiguration={{ enter: (velocity) => Math.abs(velocity) > 800, exit: (velocity) => Math.abs(velocity) < 500, }} endReached={loadMore} overscan={800} increaseViewportBy={1000} className="scrollbar-hide relative h-full w-full" style={{ contain: 'strict', }} />
); } Page.getLayout = function getLayout( page: | string | number | boolean | ReactElement> | ReactFragment | ReactPortal ) { return ( {page} ); };