feat: use gomark wasm in frontend

This commit is contained in:
Steven 2024-01-31 22:25:24 +08:00
parent 3158c4b8b5
commit 8ce6a32aac
21 changed files with 2363 additions and 37 deletions

Binary file not shown.

View file

@ -1,4 +1,4 @@
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
import { BaseProps } from "./types";

View file

@ -1,4 +1,4 @@
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
interface Props {

View file

@ -12,7 +12,7 @@ interface Props extends BaseProps {
}
const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
const formatedLanguage = language.toLowerCase() || "plaintext";
const formatedLanguage = (language || "").toLowerCase() || "plaintext";
let highlightedCode = hljs.highlightAuto(content).value;
// Users can set Markdown code blocks as `__html` to render HTML directly.

View file

@ -42,7 +42,7 @@ const EmbeddedMemo = ({ resourceId, params: paramsStr }: Props) => {
if (inlineMode) {
return (
<div className="w-full">
<MemoContent nodes={memo.nodes} memoId={memo.id} embeddedMemos={context.embeddedMemos} />
<MemoContent memoId={memo.id} content={memo.content} embeddedMemos={context.embeddedMemos} />
<MemoResourceListView resources={memo.resources} />
</div>
);
@ -56,7 +56,7 @@ const EmbeddedMemo = ({ resourceId, params: paramsStr }: Props) => {
<Icon.ArrowUpRight className="w-5 h-auto opacity-80 text-gray-400" />
</Link>
</div>
<MemoContent nodes={memo.nodes} memoId={memo.id} embeddedMemos={context.embeddedMemos} />
<MemoContent memoId={memo.id} content={memo.content} embeddedMemos={context.embeddedMemos} />
<MemoResourceListView resources={memo.resources} />
</div>
);

View file

@ -1,4 +1,4 @@
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
import { BaseProps } from "./types";

View file

@ -1,5 +1,5 @@
import { repeat } from "lodash-es";
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
import { BaseProps } from "./types";

View file

@ -1,4 +1,4 @@
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
import { BaseProps } from "./types";

View file

@ -27,7 +27,7 @@ import {
TaskListNode,
TextNode,
UnorderedListNode,
} from "@/types/proto/api/v2/node";
} from "@/types/node";
import Blockquote from "./Blockquote";
import Bold from "./Bold";
import BoldItalic from "./BoldItalic";

View file

@ -1,4 +1,4 @@
import { TableNode_Row } from "@/types/proto/api/v2/node";
import { TableNode_Row } from "@/types/node";
interface Props {
header: string[];

View file

@ -3,7 +3,7 @@ import classNames from "classnames";
import { repeat } from "lodash-es";
import { useContext } from "react";
import { useMemoStore } from "@/store/v1";
import { Node, NodeType } from "@/types/proto/api/v2/node";
import { Node, NodeType } from "@/types/node";
import Renderer from "./Renderer";
import { RendererContext } from "./types";
@ -35,12 +35,13 @@ const TaskList: React.FC<Props> = ({ index, indent, complete, children }: Props)
}
node.taskListNode!.complete = on;
const content = window.restore(context.nodes);
await memoStore.updateMemo(
{
id: context.memoId,
nodes: context.nodes,
content,
},
["nodes"],
["content"],
);
};

View file

@ -1,5 +1,5 @@
import { repeat } from "lodash-es";
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
import Renderer from "./Renderer";
interface Props {

View file

@ -1,12 +1,12 @@
import { memo, useRef } from "react";
import useCurrentUser from "@/hooks/useCurrentUser";
import { useMemoStore } from "@/store/v1";
import { Node, NodeType } from "@/types/proto/api/v2/node";
import { Node, NodeType } from "@/types/node";
import Renderer from "./Renderer";
import { RendererContext } from "./types";
interface Props {
nodes: Node[];
content: string;
memoId?: number;
readonly?: boolean;
disableFilter?: boolean;
@ -18,10 +18,11 @@ interface Props {
}
const MemoContent: React.FC<Props> = (props: Props) => {
const { className, memoId, nodes, embeddedMemos, onClick } = props;
const { className, content, memoId, embeddedMemos, onClick } = props;
const currentUser = useCurrentUser();
const memoStore = useMemoStore();
const memoContentContainerRef = useRef<HTMLDivElement>(null);
const nodes = window.parse(content);
const allowEdit = !props.readonly && memoId && currentUser?.id === memoStore.getMemoById(memoId)?.creatorId;
const handleMemoContentClick = async (e: React.MouseEvent) => {

View file

@ -1,5 +1,5 @@
import { createContext } from "react";
import { Node } from "@/types/proto/api/v2/node";
import { Node } from "@/types/node";
interface Context {
nodes: Node[];

View file

@ -257,7 +257,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
)}
</div>
</div>
<MemoContent memoId={memo.id} nodes={memo.nodes} readonly={readonly} onClick={handleMemoContentClick} />
<MemoContent memoId={memo.id} content={memo.content} readonly={readonly} onClick={handleMemoContentClick} />
<MemoResourceListView resources={memo.resources} />
<MemoRelationListView memo={memo} relationList={referenceRelations} />
</div>

View file

@ -1,7 +1,4 @@
import { IconButton } from "@mui/joy";
import { useEffect, useState } from "react";
import { memoServiceClient } from "@/grpcweb";
import { Node } from "@/types/proto/api/v2/node";
import { generateDialog } from "./Dialog";
import Icon from "./Icon";
import MemoContent from "./MemoContent";
@ -11,17 +8,6 @@ interface Props extends DialogProps {
}
const PreviewMarkdownDialog: React.FC<Props> = ({ content, destroy }: Props) => {
const [nodes, setNodes] = useState<Node[]>([]);
useEffect(() => {
(async () => {
const { nodes } = await memoServiceClient.previewMemoContent({
content,
});
setNodes(nodes);
})();
}, []);
const handleCloseBtnClick = () => {
destroy();
};
@ -37,7 +23,7 @@ const PreviewMarkdownDialog: React.FC<Props> = ({ content, destroy }: Props) =>
</IconButton>
</div>
<div className="flex flex-col justify-start items-start max-w-full w-[32rem]">
{content !== "" ? <MemoContent nodes={nodes} /> : <p className="text-gray-400 dark:text-gray-600">Nothing to preview</p>}
{content !== "" ? <MemoContent content={content} /> : <p className="text-gray-400 dark:text-gray-600">Nothing to preview</p>}
</div>
</>
);

View file

@ -113,7 +113,7 @@ const ShareMemoDialog: React.FC<Props> = (props: Props) => {
>
<span className="w-full px-6 pt-5 pb-2 text-sm text-gray-500">{getDateTimeString(memo.displayTime)}</span>
<div className="w-full px-6 text-base pb-4">
<MemoContent memoId={memo.id} nodes={memo.nodes} readonly={true} disableFilter />
<MemoContent memoId={memo.id} content={memo.content} readonly={true} disableFilter />
<MemoResourceListView resources={memo.resources} />
</div>
<div className="flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-900 py-4 px-6">

View file

@ -125,7 +125,7 @@ const Archived = () => {
</Tooltip>
</div>
</div>
<MemoContent memoId={memo.id} nodes={memo.nodes} readonly={true} />
<MemoContent memoId={memo.id} content={memo.content} readonly={true} />
</div>
))
)}

View file

@ -137,7 +137,7 @@ const MemoDetail = () => {
</Link>
</div>
)}
<MemoContent memoId={memo.id} nodes={memo.nodes} readonly={readonly} />
<MemoContent memoId={memo.id} content={memo.content} readonly={readonly} />
<MemoResourceListView resources={memo.resources} />
<MemoRelationListView memo={memo} relationList={referenceRelations} />
<div className="w-full mt-3 flex flex-row justify-between items-center gap-2">

10
web/src/types/global.d.ts vendored Normal file
View file

@ -0,0 +1,10 @@
import { Node } from "./node";
declare global {
interface Window {
parse: (content: string) => Node[];
restore: (input: Node[]) => string;
}
}
export {};

2328
web/src/types/node.ts Normal file

File diff suppressed because it is too large Load diff