import { mergeAttributes, Node } from "@tiptap/core"; import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react"; import { ContextItemWithId } from "../../shims/typings"; import { useDispatch, useSelector } from "react-redux"; import { vscBadgeBackground } from ".."; import { setEditingContextItemAtIndex } from "../../redux/slices/stateSlice"; import { RootState } from "../../redux/store"; import CodeSnippetPreview from "../markdown/CodeSnippetPreview"; const CodeBlockComponent = ({ node, deleteNode, selected, editor, updateAttributes, }) => { const dispatch = useDispatch(); const item: ContextItemWithId = node.attrs.item; const contextItems = useSelector( (state: RootState) => state.state.contextItems ); return ( { deleteNode(); }} onEdit={async () => { dispatch(setEditingContextItemAtIndex({ item })); if (item.id === contextItems[0]?.id) { // Find and delete the /edit command let index = 0; for (const el of editor.getJSON().content) { if (el.type === "slashcommand") { if (el.attrs.id === "/edit") { editor .chain() .deleteRange({ from: index, to: index + 2 }) .focus("end") .run(); break; } } index += 1; } updateAttributes({ item: { ...item, editing: false, }, }); } else { let index = 0; for (const el of editor.getJSON().content) { if (el.type === "codeBlock") { index += 2; } else { break; } } editor .chain() .focus("end") .insertContent([ { type: "slashcommand", attrs: { id: "/edit", label: "/edit" }, }, { type: "text", text: " " }, ]) .run(); updateAttributes({ item: { ...item, editing: true, }, }); await new Promise((resolve) => setTimeout(resolve, 100)); editor.commands.focus("end"); } }} editing={item.id === contextItems[0]?.id} /> ); }; export default Node.create({ name: "codeBlock", group: "block", content: "inline*", atom: true, selectable: true, parseHTML() { return [ { tag: "code-block", }, ]; }, addAttributes() { return { item: { default: "", }, }; }, renderHTML({ HTMLAttributes }) { return ["code-block", mergeAttributes(HTMLAttributes), 0]; }, addNodeView() { return ReactNodeViewRenderer(CodeBlockComponent); }, });