diff --git a/web/src/components/Inbox/MemoCommentMessage.tsx b/web/src/components/Inbox/MemoCommentMessage.tsx index a29c4d6a..3c521957 100644 --- a/web/src/components/Inbox/MemoCommentMessage.tsx +++ b/web/src/components/Inbox/MemoCommentMessage.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { activityServiceClient } from "@/grpcweb"; import useNavigateTo from "@/hooks/useNavigateTo"; -import { useInboxStore, extractUsernameFromName } from "@/store/v1"; +import { useInboxStore, extractUsernameFromName, useMemoStore } from "@/store/v1"; import { Activity } from "@/types/proto/api/v2/activity_service"; import { Inbox, Inbox_Status } from "@/types/proto/api/v2/inbox_service"; import { useTranslate } from "@/utils/i18n"; @@ -18,6 +18,7 @@ const MemoCommentMessage = ({ inbox }: Props) => { const t = useTranslate(); const navigateTo = useNavigateTo(); const inboxStore = useInboxStore(); + const memoStore = useMemoStore(); const [activity, setActivity] = useState(undefined); useEffect(() => { @@ -34,11 +35,19 @@ const MemoCommentMessage = ({ inbox }: Props) => { }); }, [inbox.activityId]); - const handleNavigateToMemo = () => { - if (!activity?.payload?.memoComment?.relatedMemoId) { + const handleNavigateToMemo = async () => { + const relatedMemoId = activity?.payload?.memoComment?.relatedMemoId; + if (!relatedMemoId) { return; } - navigateTo(`/m/${activity?.payload?.memoComment?.relatedMemoId}`); + + const memo = await memoStore.getOrFetchMemoById(relatedMemoId); + if (!memo) { + toast.error("Memo not found"); + return; + } + + navigateTo(`/m/${memo.name}`); if (inbox.status === Inbox_Status.UNREAD) { handleArchiveMessage(true); } diff --git a/web/src/components/MemoRelationListView.tsx b/web/src/components/MemoRelationListView.tsx index 64218afb..8642a085 100644 --- a/web/src/components/MemoRelationListView.tsx +++ b/web/src/components/MemoRelationListView.tsx @@ -43,7 +43,7 @@ const MemoRelationListView = (props: Props) => {
@@ -64,7 +64,7 @@ const MemoRelationListView = (props: Props) => {
diff --git a/web/src/components/MemoView.tsx b/web/src/components/MemoView.tsx index 08eae64f..39beb317 100644 --- a/web/src/components/MemoView.tsx +++ b/web/src/components/MemoView.tsx @@ -75,7 +75,7 @@ const MemoView: React.FC = (props: Props) => { if (event.altKey) { showChangeMemoCreatedTsDialog(memo.id); } else { - navigateTo(`/m/${memo.id}`); + navigateTo(`/m/${memo.name}`); } }; diff --git a/web/src/components/ShareMemoDialog.tsx b/web/src/components/ShareMemoDialog.tsx index 3c21d797..113305e5 100644 --- a/web/src/components/ShareMemoDialog.tsx +++ b/web/src/components/ShareMemoDialog.tsx @@ -70,7 +70,7 @@ const ShareMemoDialog: React.FC = (props: Props) => { }; const handleCopyLinkBtnClick = () => { - copy(`${window.location.origin}/m/${memo.id}`); + copy(`${window.location.origin}/m/${memo.name}`); toast.success(t("message.succeed-copy-link")); }; diff --git a/web/src/pages/MemoDetail.tsx b/web/src/pages/MemoDetail.tsx index 71690855..d50d1617 100644 --- a/web/src/pages/MemoDetail.tsx +++ b/web/src/pages/MemoDetail.tsx @@ -33,8 +33,8 @@ const MemoDetail = () => { const memoStore = useMemoStore(); const userStore = useUserStore(); const [creator, setCreator] = useState(); - const memoId = Number(params.memoId); - const memo = memoStore.getMemoById(memoId); + const memoName = params.memoName; + const memo = memoStore.getMemoByName(memoName || ""); const [parentMemo, setParentMemo] = useState(undefined); const referenceRelations = memo?.relations.filter((relation) => relation.type === MemoRelation_Type.REFERENCE) || []; const commentRelations = @@ -44,9 +44,9 @@ const MemoDetail = () => { // Prepare memo. useEffect(() => { - if (memoId && !isNaN(memoId)) { + if (memoName) { memoStore - .getOrFetchMemoById(memoId) + .getOrFetchMemoByName(memoName) .then(async (memo) => { const user = await userStore.getOrFetchUserByUsername(extractUsernameFromName(memo.creator)); setCreator(user); @@ -58,7 +58,7 @@ const MemoDetail = () => { } else { navigateTo("/404"); } - }, [memoId]); + }, [memoName]); // Prepare memo comments. useEffect(() => { @@ -100,7 +100,7 @@ const MemoDetail = () => { }; const handleCopyLinkBtnClick = () => { - copy(`${window.location.origin}/m/${memo.id}`); + copy(`${window.location.origin}/m/${memo.name}`); toast.success(t("message.succeed-copy-link")); }; @@ -129,7 +129,7 @@ const MemoDetail = () => {
diff --git a/web/src/pages/Resources.tsx b/web/src/pages/Resources.tsx index 415e1390..f7b1229d 100644 --- a/web/src/pages/Resources.tsx +++ b/web/src/pages/Resources.tsx @@ -10,6 +10,7 @@ import ResourceIcon from "@/components/ResourceIcon"; import { resourceServiceClient } from "@/grpcweb"; import useLoading from "@/hooks/useLoading"; import i18n from "@/i18n"; +import { useMemoStore } from "@/store/v1"; import { Resource } from "@/types/proto/api/v2/resource_service"; import { useTranslate } from "@/utils/i18n"; @@ -38,6 +39,7 @@ const Resources = () => { const [state, setState] = useState({ searchQuery: "", }); + const memoStore = useMemoStore(); const [resources, setResources] = useState([]); const filteredResources = resources.filter((resource) => includes(resource.filename, state.searchQuery)); const groupedResources = groupResourcesByDate(filteredResources.filter((resoure) => resoure.memoId)); @@ -47,6 +49,7 @@ const Resources = () => { resourceServiceClient.listResources({}).then(({ resources }) => { setResources(resources); loadingState.setFinish(); + Promise.all(resources.map((resource) => (resource.memoId ? memoStore.getOrFetchMemoById(resource.memoId) : null))); }); }, []); @@ -109,6 +112,7 @@ const Resources = () => {
{resources.map((resource) => { + const relatedMemo = resource.memoId ? memoStore.getMemoById(resource.memoId) : null; return (
@@ -116,13 +120,15 @@ const Resources = () => {

{resource.filename}

- - #{resource.memoId} - + {relatedMemo && ( + + #{relatedMemo.id} + + )}
); diff --git a/web/src/router/index.tsx b/web/src/router/index.tsx index 06db028a..45647e00 100644 --- a/web/src/router/index.tsx +++ b/web/src/router/index.tsx @@ -112,7 +112,7 @@ const router = createBrowserRouter([ element: , }, { - path: "m/:memoId", + path: "m/:memoName", element: , }, { diff --git a/web/src/store/v1/memo.ts b/web/src/store/v1/memo.ts index 530183df..f51e1a94 100644 --- a/web/src/store/v1/memo.ts +++ b/web/src/store/v1/memo.ts @@ -47,6 +47,28 @@ export const useMemoStore = create( getMemoById: (id: number) => { return get().memoMapById[id]; }, + getOrFetchMemoByName: async (name: string) => { + const memoMap = get().memoMapById; + const memo = Object.values(memoMap).find((memo) => memo.name === name); + if (memo) { + return memo; + } + + const res = await memoServiceClient.getMemoByName({ + name, + }); + if (!res.memo) { + throw new Error("Memo not found"); + } + + memoMap[res.memo.id] = res.memo; + set({ memoMapById: memoMap }); + return res.memo; + }, + getMemoByName: (name: string) => { + const memoMap = get().memoMapById; + return Object.values(memoMap).find((memo) => memo.name === name); + }, createMemo: async (request: CreateMemoRequest) => { const { memo } = await memoServiceClient.createMemo(request); if (!memo) {