@@ -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+ / { { \[ \[ (?: e m b e d | e m b e d - p a t h | e m b e d - c h i l d r e n ) \] \] : \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