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 Renderer from "./Renderer";
import { BaseProps } from "./types"; 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 Renderer from "./Renderer";
interface Props { interface Props {

View file

@ -12,7 +12,7 @@ interface Props extends BaseProps {
} }
const CodeBlock: React.FC<Props> = ({ language, content }: Props) => { const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
const formatedLanguage = language.toLowerCase() || "plaintext"; const formatedLanguage = (language || "").toLowerCase() || "plaintext";
let highlightedCode = hljs.highlightAuto(content).value; let highlightedCode = hljs.highlightAuto(content).value;
// Users can set Markdown code blocks as `__html` to render HTML directly. // 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) { if (inlineMode) {
return ( return (
<div className="w-full"> <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} /> <MemoResourceListView resources={memo.resources} />
</div> </div>
); );
@ -56,7 +56,7 @@ const EmbeddedMemo = ({ resourceId, params: paramsStr }: Props) => {
<Icon.ArrowUpRight className="w-5 h-auto opacity-80 text-gray-400" /> <Icon.ArrowUpRight className="w-5 h-auto opacity-80 text-gray-400" />
</Link> </Link>
</div> </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} /> <MemoResourceListView resources={memo.resources} />
</div> </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 Renderer from "./Renderer";
import { BaseProps } from "./types"; import { BaseProps } from "./types";

View file

@ -1,5 +1,5 @@
import { repeat } from "lodash-es"; import { repeat } from "lodash-es";
import { Node } from "@/types/proto/api/v2/node"; import { Node } from "@/types/node";
import Renderer from "./Renderer"; import Renderer from "./Renderer";
import { BaseProps } from "./types"; 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 Renderer from "./Renderer";
import { BaseProps } from "./types"; import { BaseProps } from "./types";

View file

@ -27,7 +27,7 @@ import {
TaskListNode, TaskListNode,
TextNode, TextNode,
UnorderedListNode, UnorderedListNode,
} from "@/types/proto/api/v2/node"; } from "@/types/node";
import Blockquote from "./Blockquote"; import Blockquote from "./Blockquote";
import Bold from "./Bold"; import Bold from "./Bold";
import BoldItalic from "./BoldItalic"; 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 { interface Props {
header: string[]; header: string[];

View file

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

View file

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

View file

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

View file

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

View file

@ -257,7 +257,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
)} )}
</div> </div>
</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} /> <MemoResourceListView resources={memo.resources} />
<MemoRelationListView memo={memo} relationList={referenceRelations} /> <MemoRelationListView memo={memo} relationList={referenceRelations} />
</div> </div>

View file

@ -1,7 +1,4 @@
import { IconButton } from "@mui/joy"; 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 { generateDialog } from "./Dialog";
import Icon from "./Icon"; import Icon from "./Icon";
import MemoContent from "./MemoContent"; import MemoContent from "./MemoContent";
@ -11,17 +8,6 @@ interface Props extends DialogProps {
} }
const PreviewMarkdownDialog: React.FC<Props> = ({ content, destroy }: Props) => { 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 = () => { const handleCloseBtnClick = () => {
destroy(); destroy();
}; };
@ -37,7 +23,7 @@ const PreviewMarkdownDialog: React.FC<Props> = ({ content, destroy }: Props) =>
</IconButton> </IconButton>
</div> </div>
<div className="flex flex-col justify-start items-start max-w-full w-[32rem]"> <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> </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> <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"> <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} /> <MemoResourceListView resources={memo.resources} />
</div> </div>
<div className="flex flex-row justify-between items-center w-full bg-gray-100 dark:bg-zinc-900 py-4 px-6"> <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> </Tooltip>
</div> </div>
</div> </div>
<MemoContent memoId={memo.id} nodes={memo.nodes} readonly={true} /> <MemoContent memoId={memo.id} content={memo.content} readonly={true} />
</div> </div>
)) ))
)} )}

View file

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