import dayjs from "dayjs"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; import { useGlobalStore, useLocationStore, useMemoStore, useUserStore } from "../store/module"; import { DEFAULT_MEMO_LIMIT } from "../helpers/consts"; import useLoading from "../hooks/useLoading"; import toastHelper from "../components/Toast"; import MemoContent from "../components/MemoContent"; import MemoResources from "../components/MemoResources"; import MemoFilter from "../components/MemoFilter"; import Icon from "../components/Icon"; import { TAG_REG } from "../labs/marked/parser"; import "../less/explore.less"; interface State { memos: Memo[]; } const Explore = () => { const { t, i18n } = useTranslation(); const navigate = useNavigate(); const globalStore = useGlobalStore(); const locationStore = useLocationStore(); const userStore = useUserStore(); const memoStore = useMemoStore(); const query = locationStore.state.query; const [state, setState] = useState({ memos: [], }); const [isComplete, setIsComplete] = useState(false); const loadingState = useLoading(); const customizedProfile = globalStore.state.systemStatus.customizedProfile; const user = userStore.state.user; const location = locationStore.state; useEffect(() => { memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, 0).then((memos) => { if (memos.length < DEFAULT_MEMO_LIMIT) { setIsComplete(true); } setState({ memos, }); loadingState.setFinish(); }); }, [location]); const { tag: tagQuery, text: textQuery } = query ?? {}; const showMemoFilter = Boolean(tagQuery || textQuery); const shownMemos = showMemoFilter ? state.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; } } return shouldShow; }) : state.memos; const sortedMemos = shownMemos .filter((m) => m.rowStatus === "NORMAL") .sort((mi: Memo, mj: Memo) => { return mj.createdTs - mi.createdTs; }); const handleFetchMoreClick = async () => { try { const fetchedMemos = await memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, state.memos.length); if (fetchedMemos.length < DEFAULT_MEMO_LIMIT) { setIsComplete(true); } else { setIsComplete(false); } setState({ memos: state.memos.concat(fetchedMemos), }); } catch (error: any) { console.error(error); toastHelper.error(error.response.data.message); } }; const handleMemoContentClick = async (e: React.MouseEvent) => { const targetEl = e.target as HTMLElement; if (targetEl.className === "tag-span") { const tagName = targetEl.innerText.slice(1); const currTagQuery = locationStore.getState().query?.tag; if (currTagQuery === tagName) { locationStore.setTagQuery(undefined); } else { locationStore.setTagQuery(tagName); } } }; const handleTitleClick = () => { if (user) { navigate("/"); } else { navigate("/auth"); } }; return (
{customizedProfile.name}
{!loadingState.isLoading && (
{sortedMemos.map((memo) => { const createdAtStr = dayjs(memo.createdTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss"); return ( ); })} {isComplete ? ( state.memos.length === 0 ? (

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

) : null ) : (

{t("memo-list.fetch-more")}

)}
)}
); }; export default Explore;