Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 62 additions & 32 deletions apps/obsidian/src/components/canvas/utils/convertToDiscourseNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ export const convertToDiscourseNode = async (
}
};

const convertTextShapeToNode = async ({
const convertTextShapeToNode = ({
editor,
shape,
nodeType,
plugin,
canvasFile,
}: ConvertToDiscourseNodeArgs): Promise<TLShapeId | undefined> => {
}: ConvertToDiscourseNodeArgs): TLShapeId | undefined => {
const text = renderPlaintextFromRichText(
editor,
(shape as TLTextShape).props.richText,
Expand All @@ -79,31 +79,54 @@ const convertTextShapeToNode = async ({
return undefined;
}

const createdFile = await createDiscourseNodeFile({
let shapeId: TLShapeId | undefined;

const modal = new ModifyNodeModal(plugin.app, {
nodeTypes: plugin.settings.nodeTypes,
plugin,
nodeType,
text: text.trim(),
});
initialNodeType: nodeType,
initialTitle: text.trim(),
onSubmit: async ({
nodeType: selectedNodeType,
title,
selectedExistingNode,
}) => {
try {
const file =
selectedExistingNode ??
(await createDiscourseNodeFile({
plugin,
nodeType: selectedNodeType,
text: title,
}));

if (!file) {
throw new Error("Failed to create discourse node file");
}

if (!createdFile) {
throw new Error("Failed to create discourse node file");
}
shapeId = await createDiscourseNodeShape({
editor,
shape,
createdFile: file,
nodeType: selectedNodeType,
plugin,
canvasFile,
});

const shapeId = await createDiscourseNodeShape({
editor,
shape,
createdFile,
nodeType,
plugin,
canvasFile,
showToast({
severity: "success",
title: "Shape Converted",
description: `Converted text to ${selectedNodeType.name}`,
targetCanvasId: canvasFile.path,
});
} catch (error) {
console.error("Error creating node from text:", error);
throw error;
}
},
});

showToast({
severity: "success",
title: "Shape Converted",
description: `Converted text to ${nodeType.name}`,
targetCanvasId: canvasFile.path,
});
modal.open();

return shapeId;
};
Expand All @@ -129,28 +152,35 @@ const convertImageShapeToNode = async ({
plugin,
initialNodeType: nodeType,
initialTitle: "",
onSubmit: async ({ nodeType: selectedNodeType, title }) => {
onSubmit: async ({
nodeType: selectedNodeType,
title,
selectedExistingNode,
}) => {
try {
const createdFile = await createDiscourseNodeFile({
plugin,
nodeType: selectedNodeType,
text: title,
});

if (!createdFile) {
const file =
selectedExistingNode ??
(await createDiscourseNodeFile({
plugin,
nodeType: selectedNodeType,
text: title,
}));

if (!file) {
throw new Error("Failed to create discourse node file");
}

let imageSrc: string | undefined;
if (imageFile) {
await embedImageInNode(createdFile, imageFile, plugin);
await embedImageInNode(file, imageFile, plugin);

imageSrc = plugin.app.vault.getResourcePath(imageFile);
}

shapeId = await createDiscourseNodeShape({
editor,
shape,
createdFile,
createdFile: file,
nodeType: selectedNodeType,
plugin,
canvasFile,
Expand Down
9 changes: 9 additions & 0 deletions apps/website/content/obsidian/core-features/canvas.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ Or click on the canvas icon at the top right corner

![Create discourse node](/docs/obsidian/create-discourse-node.gif)

### Converting text and image shapes into discourse nodes

You can convert a tldraw text or image shape into a discourse node directly from the canvas:

1. Right-click on a text or image shape
2. Choose a node type from the "Convert to" submenu
3. A modal opens pre-filled with the text content (or an empty title for images) — edit the title if needed
4. Click "Confirm" to create the discourse node; the original shape is replaced

### Adding existing nodes

**Using node search**
Expand Down
Loading