import { Select, Tooltip, Option, IconButton } from "@mui/joy"; import copy from "copy-to-clipboard"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { Link, useParams } from "react-router-dom"; import Icon from "@/components/Icon"; import Memo from "@/components/Memo"; import MemoContentV1 from "@/components/MemoContentV1"; import MemoEditor from "@/components/MemoEditor"; import showMemoEditorDialog from "@/components/MemoEditor/MemoEditorDialog"; import MemoRelationListView from "@/components/MemoRelationListView"; import MemoResourceListView from "@/components/MemoResourceListView"; import MobileHeader from "@/components/MobileHeader"; import showShareMemoDialog from "@/components/ShareMemoDialog"; import UserAvatar from "@/components/UserAvatar"; import VisibilityIcon from "@/components/VisibilityIcon"; import { UNKNOWN_ID, VISIBILITY_SELECTOR_ITEMS } from "@/helpers/consts"; import { getDateTimeString } from "@/helpers/datetime"; import useCurrentUser from "@/hooks/useCurrentUser"; import useNavigateTo from "@/hooks/useNavigateTo"; import { useGlobalStore, useMemoStore } from "@/store/module"; import { useUserV1Store, extractUsernameFromName } from "@/store/v1"; import { User, User_Role } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; const MemoDetail = () => { const t = useTranslate(); const params = useParams(); const navigateTo = useNavigateTo(); const currentUser = useCurrentUser(); const globalStore = useGlobalStore(); const memoStore = useMemoStore(); const userV1Store = useUserV1Store(); const [creator, setCreator] = useState(); const { systemStatus } = globalStore.state; const memoId = Number(params.memoId); const memo = memoStore.state.memos.find((memo) => memo.id === memoId); const allowEdit = memo?.creatorUsername === extractUsernameFromName(currentUser?.name); const referenceRelations = memo?.relationList.filter((relation) => relation.type === "REFERENCE") || []; const commentRelations = memo?.relationList.filter((relation) => relation.relatedMemoId === memo.id && relation.type === "COMMENT") || []; const comments = commentRelations .map((relation) => memoStore.state.memos.find((memo) => memo.id === relation.memoId)) .filter((memo) => memo) as Memo[]; // Prepare memo. useEffect(() => { if (memoId && !isNaN(memoId)) { memoStore .fetchMemoById(memoId) .then(async (memo) => { const user = await userV1Store.getOrFetchUserByUsername(memo.creatorUsername); setCreator(user); }) .catch((error) => { console.error(error); toast.error(error.response.data.message); }); } else { navigateTo("/404"); } }, [memoId]); // Prepare memo comments. useEffect(() => { if (!memo) { return; } (async () => { const commentRelations = memo.relationList.filter((relation) => relation.relatedMemoId === memo.id && relation.type === "COMMENT"); const requests = commentRelations.map((relation) => memoStore.fetchMemoById(relation.memoId)); await Promise.all(requests); })(); }, [memo?.relationList]); if (!memo) { return null; } const handleMemoVisibilityOptionChanged = async (value: string) => { const visibilityValue = value as Visibility; await memoStore.patchMemo({ id: memo.id, visibility: visibilityValue, }); }; const handleEditMemoClick = () => { showMemoEditorDialog({ memoId: memo.id, }); }; const handleCopyLinkBtnClick = () => { copy(`${window.location.origin}/m/${memo.id}`); toast.success(t("message.succeed-copy-link")); }; const handleCommentCreated = async () => { await memoStore.fetchMemoById(memoId); }; const disableOption = (v: string) => { const isAdminOrHost = currentUser?.role === User_Role.ADMIN || currentUser?.role === User_Role.HOST; if (v === "PUBLIC" && !isAdminOrHost) { return systemStatus.disablePublicMemos; } return false; }; return (
{memo.parent && (
#{memo.parent.id} {memo.parent.content}
)}
{getDateTimeString(memo.displayTs)}
#{memo.id} {creator?.nickname} {allowEdit && ( <> )}
{allowEdit && ( )} showShareMemoDialog(memo)}>
{comments.length === 0 ? (

{t("memo.comment.no-comment")}

) : ( <>
{t("memo.comment.self")} ({comments.length})
{comments.map((comment) => ( ))} )} {/* Only show comment editor when user login */} {currentUser && ( )}
); }; export default MemoDetail;