import { useEffect, useRef } from "react"; import { toast } from "react-hot-toast"; import Empty from "@/components/Empty"; import Memo from "@/components/Memo"; import MemoFilter from "@/components/MemoFilter"; import MobileHeader from "@/components/MobileHeader"; import { DEFAULT_MEMO_LIMIT } from "@/helpers/consts"; import { TAG_REG } from "@/labs/marked/parser"; import { useFilterStore, useMemoStore } from "@/store/module"; import { useTranslate } from "@/utils/i18n"; const Explore = () => { const t = useTranslate(); const filterStore = useFilterStore(); const memoStore = useMemoStore(); const filter = filterStore.state; const { loadingStatus, memos } = memoStore.state; const { tag: tagQuery, text: textQuery } = filter; const showMemoFilter = Boolean(tagQuery || textQuery); const fetchMoreRef = useRef(null); const fetchedMemos = showMemoFilter ? memos.filter((memo) => { let shouldShow = true; if (tagQuery) { const tagsSet = new Set(); for (const t of Array.from(memo.content.match(new RegExp(TAG_REG, "g")) ?? [])) { const tag = t.replace(TAG_REG, "$1").trim(); const items = tag.split("/"); let temp = ""; for (const i of items) { temp += i; tagsSet.add(temp); temp += "/"; } } if (!tagsSet.has(tagQuery)) { shouldShow = false; } } if (textQuery && !memo.content.toLowerCase().includes(textQuery.toLowerCase())) { shouldShow = false; } return shouldShow; }) : memos; const sortedMemos = fetchedMemos .filter((m) => m.rowStatus === "NORMAL" && m.visibility !== "PRIVATE") .sort((mi, mj) => mj.displayTs - mi.displayTs); useEffect(() => { memoStore.setLoadingStatus("incomplete"); }, []); useEffect(() => { if (!fetchMoreRef.current) return; const observer = new IntersectionObserver(([entry]) => { if (!entry.isIntersecting) return; observer.disconnect(); handleFetchMoreClick(); }); observer.observe(fetchMoreRef.current); return () => observer.disconnect(); }, [loadingStatus]); const handleFetchMoreClick = async () => { try { await memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, memos.length); } catch (error: any) { toast.error(error.response.data.message); } }; return (
{sortedMemos.map((memo) => ( ))} {loadingStatus === "fetching" ? (

{t("memo.fetching-data")}

) : (
{loadingStatus === "complete" ? ( sortedMemos.length === 0 && (

{t("message.no-data")}

) ) : ( {t("memo.fetch-more")} )}
)}
); }; export default Explore;