diff --git a/apps/roam/src/components/SuggestionsBody.tsx b/apps/roam/src/components/SuggestionsBody.tsx index 2c4a542d3..fb3f04acb 100644 --- a/apps/roam/src/components/SuggestionsBody.tsx +++ b/apps/roam/src/components/SuggestionsBody.tsx @@ -19,12 +19,17 @@ import { performHydeSearch } from "../utils/hyde"; import { createBlock } from "roamjs-components/writes"; import getDiscourseContextResults from "~/utils/getDiscourseContextResults"; import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle"; -import findDiscourseNode from "~/utils/findDiscourseNode"; +import findDiscourseNode, { + findDiscourseNodeByTitleAndUid, +} from "~/utils/findDiscourseNode"; import getDiscourseRelations from "~/utils/getDiscourseRelations"; import getDiscourseNodes from "~/utils/getDiscourseNodes"; import normalizePageTitle from "roamjs-components/queries/normalizePageTitle"; import { type RelationDetails } from "~/utils/hyde"; import { getFormattedConfigTree } from "~/utils/discourseConfigRef"; +import { render as renderToast } from "roamjs-components/components/Toast"; +import { getSetting } from "~/utils/extensionSettings"; +import { createReifiedRelation } from "~/utils/createReifiedBlock"; export type DiscourseData = { results: Awaited>; @@ -303,10 +308,80 @@ const SuggestionsBody = ({ }; const handleCreateBlock = async (node: SuggestedNode) => { - await createBlock({ - parentUid: blockUid, - node: { text: `[[${node.text}]]` }, - }); + if (getSetting("use-reified-relations")) { + if (discourseNode === false) { + renderToast({ + id: "suggestions-create-block-error", + content: "Could not identify type of source", + intent: "danger", + timeout: 5000, + }); + return; + } + const selectedNodeType = findDiscourseNodeByTitleAndUid({ + uid: node.uid, + title: node.text, + }); + if (selectedNodeType === false) { + renderToast({ + id: "suggestions-create-block-error", + content: "Could not identify type of target", + intent: "danger", + timeout: 5000, + }); + return; + } + const relevantRelns = validRelations.filter( + (rel) => + (rel.source === selectedNodeType.type && + rel.destination === discourseNode.type) || + (rel.destination === selectedNodeType.type && + rel.source === discourseNode.type), + ); + if (relevantRelns.length) { + if (relevantRelns.length > 1) { + // I don't want to panick the user with this. + // TODO: Maybe think of adding a relation type picker? + console.warn("Picking an arbitrary relation"); + } + const rel = relevantRelns[0]; + try { + if (rel.destination === selectedNodeType.type) + await createReifiedRelation({ + sourceUid: tagUid, + destinationUid: node.uid, + relationBlockUid: rel.id, + }); + else + await createReifiedRelation({ + sourceUid: node.uid, + destinationUid: tagUid, + relationBlockUid: rel.id, + }); + } catch (error) { + console.error("Failed to create reified relation:", error); + renderToast({ + id: "suggestions-create-block-error", + content: "Failed to create relation", + intent: "danger", + timeout: 5000, + }); + return; + } + } else { + renderToast({ + id: "suggestions-create-block-error", + content: "Could not identify a relevant relation", + intent: "danger", + timeout: 5000, + }); + } + } else { + await createBlock({ + parentUid: blockUid, + node: { text: `[[${node.text}]]` }, + }); + } setHydeFilteredNodes((prev) => prev.filter((n) => n.uid !== node.uid)); };