Skip to content

Commit d3b43a2

Browse files
authored
ENG-485 show "key figure" if it is part of an Embed in the image (#616)
* support embed for key images * support keyImageOption query-builder
1 parent 8dcf664 commit d3b43a2

1 file changed

Lines changed: 55 additions & 14 deletions

File tree

apps/roam/src/utils/calcCanvasNodeSizeAndImg.ts

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,63 @@ const extractFirstImageUrl = (text: string): string | null => {
1616
return result ? result[1] : null;
1717
};
1818

19-
const getFirstImageByUid = (uid: string): string | null => {
20-
const tree = getFullTreeByParentUid(uid);
19+
// Matches embed, embed-path, and embed-children syntax:
20+
// {{[[embed]]: ((block-uid)) }}, {{[[embed-path]]: ((block-uid)) }}, {{[[embed-children]]: ((block-uid)) }}
21+
// Also handles multiple parentheses: {{[[embed]]: ((((block-uid)))) }}
22+
const EMBED_REGEX =
23+
/{{\[\[(?:embed|embed-path|embed-children)\]\]:\s*\(\(+([^)]+?)\)+\)\s*}}/i;
24+
25+
const getBlockReferences = (
26+
uid: string,
27+
// eslint-disable-next-line @typescript-eslint/naming-convention
28+
): { ":block/uid"?: string; ":block/string"?: string }[] => {
29+
const result =
30+
(window.roamAlphaAPI?.pull?.(
31+
"[:block/uid {:block/refs [:block/uid :block/string]}]",
32+
[":block/uid", uid],
33+
) as {
34+
// eslint-disable-next-line @typescript-eslint/naming-convention
35+
[":block/refs"]?: { ":block/uid"?: string; ":block/string"?: string }[];
36+
} | null) || {};
37+
return result[":block/refs"] || [];
38+
};
2139

22-
const findFirstImage = (node: TreeNode): string | null => {
23-
const imageUrl = extractFirstImageUrl(node.text);
24-
if (imageUrl) return imageUrl;
40+
const findFirstImage = (
41+
node: TreeNode,
42+
visited = new Set<string>(),
43+
): string | null => {
44+
if (visited.has(node.uid)) return null;
45+
visited.add(node.uid);
46+
47+
const imageUrl = extractFirstImageUrl(node.text);
48+
if (imageUrl) return imageUrl;
49+
50+
const embedUid = node.text.match(EMBED_REGEX)?.[1];
51+
if (embedUid && !visited.has(embedUid)) {
52+
const embedTree = getFullTreeByParentUid(embedUid);
53+
const embedImageUrl = findFirstImage(embedTree, visited);
54+
if (embedImageUrl) return embedImageUrl;
55+
}
2556

26-
if (node.children) {
27-
for (const child of node.children) {
28-
const childImageUrl = findFirstImage(child);
29-
if (childImageUrl) return childImageUrl;
30-
}
57+
const references = getBlockReferences(node.uid);
58+
for (const reference of references) {
59+
const referenceText = reference[":block/string"] || "";
60+
const referenceImage = extractFirstImageUrl(referenceText);
61+
if (referenceImage) return referenceImage;
62+
}
63+
64+
if (node.children) {
65+
for (const child of node.children) {
66+
const childImageUrl = findFirstImage(child, visited);
67+
if (childImageUrl) return childImageUrl;
3168
}
69+
}
3270

33-
return null;
34-
};
71+
return null;
72+
};
3573

74+
const getFirstImageByUid = (uid: string): string | null => {
75+
const tree = getFullTreeByParentUid(uid);
3676
return findFirstImage(tree);
3777
};
3878

@@ -74,10 +114,11 @@ const calcCanvasNodeSizeAndImg = async ({
74114
const results = await runQuery({
75115
extensionAPI,
76116
parentUid,
117+
// eslint-disable-next-line @typescript-eslint/naming-convention
77118
inputs: { NODETEXT: nodeText, NODEUID: uid },
78119
});
79-
const result = results.allProcessedResults[0]?.text || "";
80-
imageUrl = extractFirstImageUrl(result);
120+
const resultUid = results.allProcessedResults[0]?.uid || "";
121+
imageUrl = getFirstImageByUid(resultUid);
81122
} else {
82123
imageUrl = getFirstImageByUid(uid);
83124
}

0 commit comments

Comments
 (0)