diff --git a/web/src/pages/Explore.tsx b/web/src/pages/Explore.tsx index 167949d9..2036bac6 100644 --- a/web/src/pages/Explore.tsx +++ b/web/src/pages/Explore.tsx @@ -8,6 +8,8 @@ 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 { TAG_REG } from "../labs/marked/parser"; import "../less/explore.less"; interface State { @@ -20,6 +22,7 @@ const Explore = () => { const locationStore = useLocationStore(); const userStore = useUserStore(); const memoStore = useMemoStore(); + const query = locationStore.state.query; const [state, setState] = useState({ memos: [], }); @@ -30,7 +33,7 @@ const Explore = () => { const location = locationStore.state; useEffect(() => { - memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, state.memos.length).then((memos) => { + memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, 0).then((memos) => { if (memos.length < DEFAULT_MEMO_LIMIT) { setIsComplete(true); } @@ -41,6 +44,39 @@ const Explore = () => { }); }, [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 memoSort = (mi: Memo, mj: Memo) => { + return mj.displayTs - mi.displayTs; + }; + shownMemos.sort(memoSort); + const sortedMemos = shownMemos.filter((m) => m.rowStatus === "NORMAL"); + const handleFetchMoreClick = async () => { try { const fetchedMemos = await memoStore.fetchAllMemos(DEFAULT_MEMO_LIMIT, state.memos.length); @@ -58,6 +94,20 @@ const Explore = () => { } }; + 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); + } + } + }; + return (
@@ -80,7 +130,8 @@ const Explore = () => {
{!loadingState.isLoading && (
- {state.memos.map((memo) => { + + {sortedMemos.map((memo) => { const createdAtStr = dayjs(memo.displayTs).locale(i18n.language).format("YYYY/MM/DD HH:mm:ss"); return (
@@ -90,7 +141,7 @@ const Explore = () => { @{memo.creator.nickname || memo.creator.username}
- undefined} /> + );