mirror of https://github.com/usememos/memos.git
chore: update memo relation list
This commit is contained in:
parent
e2fd79200e
commit
ef7e2151dc
|
|
@ -1,4 +1,6 @@
|
|||
import copy from "copy-to-clipboard";
|
||||
import { useContext, useEffect } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { Link } from "react-router-dom";
|
||||
import Icon from "@/components/Icon";
|
||||
import MemoResourceListView from "@/components/MemoResourceListView";
|
||||
|
|
@ -30,45 +32,56 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
|
|||
if (!memo) {
|
||||
return <Error message={`Memo not found: ${uid}`} />;
|
||||
}
|
||||
if (memo.name === context.memoName || context.embeddedMemos.has(resourceName)) {
|
||||
|
||||
const params = new URLSearchParams(paramsStr);
|
||||
const useSnippet = params.has("snippet");
|
||||
const inlineMode = params.has("inline");
|
||||
if (!useSnippet && (memo.name === context.memoName || context.embeddedMemos.has(resourceName))) {
|
||||
return <Error message={`Nested Rendering Error: ![[${resourceName}]]`} />;
|
||||
}
|
||||
|
||||
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
|
||||
context.embeddedMemos.add(resourceName);
|
||||
const params = new URLSearchParams(paramsStr);
|
||||
const inlineMode = params.has("inline");
|
||||
const contentNode = useSnippet ? (
|
||||
<div className={inlineMode ? "" : "line-clamp-3"}>{memo.snippet}</div>
|
||||
) : (
|
||||
<MemoContent
|
||||
contentClassName={inlineMode ? "" : "line-clamp-3"}
|
||||
memoName={memo.name}
|
||||
nodes={memo.nodes}
|
||||
embeddedMemos={context.embeddedMemos}
|
||||
/>
|
||||
);
|
||||
if (inlineMode) {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<MemoContent
|
||||
key={`${memo.name}-${memo.updateTime}`}
|
||||
memoName={memo.name}
|
||||
nodes={memo.nodes}
|
||||
embeddedMemos={context.embeddedMemos}
|
||||
/>
|
||||
{contentNode}
|
||||
<MemoResourceListView resources={memo.resources} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const copyMemoUid = (uid: string) => {
|
||||
copy(uid);
|
||||
toast.success("Copied memo UID to clipboard");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col justify-start items-start w-full px-3 py-2 bg-white dark:bg-zinc-800 rounded-lg border border-gray-200 dark:border-zinc-700 hover:shadow">
|
||||
<div className="w-full mb-1 flex flex-row justify-between items-center">
|
||||
<div className="text-sm leading-6 text-gray-400 select-none">
|
||||
<relative-time datetime={memo.displayTime?.toISOString()} format="datetime" tense="past"></relative-time>
|
||||
</div>
|
||||
<Link className="hover:opacity-80" to={`/m/${memo.uid}`} unstable_viewTransition>
|
||||
<Icon.ArrowUpRight className="w-5 h-auto opacity-80 text-gray-400" />
|
||||
</Link>
|
||||
<div className="flex justify-end items-center gap-1">
|
||||
<span className="text-xs opacity-40 leading-4 cursor-pointer hover:opacity-60" onClick={() => copyMemoUid(memo.uid)}>
|
||||
{memo.uid.slice(0, 8)}
|
||||
</span>
|
||||
<Link className="hover:opacity-80" to={`/m/${memo.uid}`} unstable_viewTransition>
|
||||
<Icon.ArrowUpRight className="w-5 h-auto opacity-80 text-gray-400" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<MemoContent
|
||||
contentClassName="line-clamp-3"
|
||||
key={`${memo.name}-${memo.updateTime}`}
|
||||
memoName={memo.name}
|
||||
nodes={memo.nodes}
|
||||
embeddedMemos={context.embeddedMemos}
|
||||
/>
|
||||
{contentNode}
|
||||
<MemoResourceListView resources={memo.resources} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const ReferencedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
|
|||
}
|
||||
|
||||
const paramsText = params.has("text") ? params.get("text") : undefined;
|
||||
const displayContent = paramsText || (memo.content.length > 12 ? `${memo.content.slice(0, 12)}...` : memo.content);
|
||||
const displayContent = paramsText || (memo.snippet.length > 12 ? `${memo.snippet.slice(0, 12)}...` : memo.snippet);
|
||||
|
||||
const handleGotoMemoDetailPage = () => {
|
||||
navigateTo(`/m/${memo.uid}`);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ const RelationListView = (props: Props) => {
|
|||
onClick={() => handleDeleteRelation(memo)}
|
||||
>
|
||||
<Icon.Link className="w-4 h-auto shrink-0 opacity-80" />
|
||||
<span className="mx-1 max-w-full text-ellipsis whitespace-nowrap overflow-hidden">{memo.content}</span>
|
||||
<span className="mx-1 max-w-full text-ellipsis whitespace-nowrap overflow-hidden">{memo.snippet}</span>
|
||||
<Icon.X className="w-4 h-auto cursor-pointer shrink-0 opacity-60 hover:opacity-100" />
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import { Tooltip } from "@mui/joy";
|
||||
import { memo, useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { MemoRelation } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import Icon from "./Icon";
|
||||
import EmbeddedContent from "./MemoContent/EmbeddedContent";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
|
|
@ -15,7 +13,6 @@ const MemoRelationListView = (props: Props) => {
|
|||
const { memo, relations: relationList } = props;
|
||||
const memoStore = useMemoStore();
|
||||
const [referencingMemoList, setReferencingMemoList] = useState<Memo[]>([]);
|
||||
const [referencedMemoList, setReferencedMemoList] = useState<Memo[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
|
|
@ -25,58 +22,17 @@ const MemoRelationListView = (props: Props) => {
|
|||
.map((relation) => memoStore.getOrFetchMemoByName(relation.relatedMemo, { skipStore: true })),
|
||||
);
|
||||
setReferencingMemoList(referencingMemoList);
|
||||
const referencedMemoList = await Promise.all(
|
||||
relationList
|
||||
.filter((relation) => relation.memo !== memo.name && relation.relatedMemo === memo.name)
|
||||
.map((relation) => memoStore.getOrFetchMemoByName(relation.memo, { skipStore: true })),
|
||||
);
|
||||
setReferencedMemoList(referencedMemoList);
|
||||
})();
|
||||
}, [memo, relationList]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{referencingMemoList.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-start items-center flex-wrap gap-2">
|
||||
{referencingMemoList.map((memo) => {
|
||||
return (
|
||||
<div key={memo.name} className="block w-auto max-w-[50%]">
|
||||
<Link
|
||||
className="px-2 border rounded-md w-auto text-sm leading-6 flex flex-row justify-start items-center flex-nowrap text-gray-600 dark:text-gray-400 dark:border-zinc-700 dark:bg-zinc-900 hover:shadow hover:opacity-80"
|
||||
to={`/m/${memo.uid}`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Tooltip title="Reference" placement="top">
|
||||
<Icon.Link className="w-4 h-auto shrink-0 opacity-70" />
|
||||
</Tooltip>
|
||||
<span className="truncate ml-1">{memo.content}</span>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
{referencedMemoList.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-start items-center flex-wrap gap-2">
|
||||
{referencedMemoList.map((memo) => {
|
||||
return (
|
||||
<div key={memo.name} className="block w-auto max-w-[50%]">
|
||||
<Link
|
||||
className="px-2 border rounded-md w-auto text-sm leading-6 flex flex-row justify-start items-center flex-nowrap text-gray-600 dark:text-gray-400 dark:border-zinc-700 dark:bg-zinc-900 hover:shadow hover:opacity-80"
|
||||
to={`/m/${memo.uid}`}
|
||||
unstable_viewTransition
|
||||
>
|
||||
<Tooltip title="Backlink" placement="top">
|
||||
<Icon.Milestone className="w-4 h-auto shrink-0 opacity-70" />
|
||||
</Tooltip>
|
||||
<span className="truncate ml-1">{memo.content}</span>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
referencingMemoList.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-start items-center flex-wrap gap-2">
|
||||
{referencingMemoList.map((memo) => {
|
||||
return <EmbeddedContent key={memo.uid} resourceName={`memos/${memo.uid}`} params={"snippet"} />;
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue