Skip to content

Commit a9ff656

Browse files
authored
Refactor NodeMenu component to improve async handling and reduce nesting. Introduce early returns and arrow functions for better readability. Implement timeouts for block updates and streamline tag addition logic. (#477)
1 parent 67c327f commit a9ff656

1 file changed

Lines changed: 30 additions & 34 deletions

File tree

apps/roam/src/components/DiscourseNodeMenu.tsx

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -77,40 +77,43 @@ const NodeMenu = ({
7777
textarea.selectionStart,
7878
textarea.selectionEnd,
7979
);
80-
setTimeout(async () => {
80+
81+
// Remove focus from the block to ensure updateBlock works properly
82+
// https://github.com/RoamJS/query-builder/issues/286
83+
document.body.click();
84+
85+
const createNodeAndUpdateBlock = async () => {
8186
const pageName = await getNewDiscourseNodeText({
8287
text: highlighted,
8388
nodeType: nodeUid,
8489
blockUid,
8590
});
86-
87-
if (!pageName) {
88-
return;
89-
}
91+
if (!pageName) return;
9092

9193
const currentBlockText = getTextByBlockUid(blockUid);
9294
const newText = `${currentBlockText.substring(
9395
0,
9496
textarea.selectionStart,
9597
)}[[${pageName}]]${currentBlockText.substring(textarea.selectionEnd)}`;
9698

97-
updateBlock({ text: newText, uid: blockUid });
98-
posthog.capture("Discourse Node: Created via Node Menu", {
99-
nodeType: nodeUid,
100-
text: pageName,
101-
});
102-
103-
createDiscourseNode({
99+
await createDiscourseNode({
104100
text: pageName,
105101
configPageUid: nodeUid,
106102
extensionAPI,
107103
});
108-
});
104+
void updateBlock({ text: newText, uid: blockUid });
105+
posthog.capture("Discourse Node: Created via Node Menu", {
106+
nodeType: nodeUid,
107+
text: pageName,
108+
});
109+
};
110+
// timeout required to ensure the block is updated
111+
setTimeout(() => void createNodeAndUpdateBlock(), 100);
109112
} else {
110113
const tag = menuItem.getAttribute("data-tag") || "";
111114
if (!tag) return;
112115

113-
setTimeout(() => {
116+
const addTagToBlock = () => {
114117
const currentText = textarea.value;
115118
const cursorPos = textarea.selectionStart;
116119
const textToInsert = `#${tag.replace(/^#/, "")} `;
@@ -120,11 +123,13 @@ const NodeMenu = ({
120123
cursorPos,
121124
)}${textToInsert}${currentText.substring(cursorPos)}`;
122125

123-
updateBlock({ text: newText, uid: blockUid });
126+
void updateBlock({ text: newText, uid: blockUid });
124127
posthog.capture("Discourse Tag: Created via Node Menu", {
125128
tag,
126129
});
127-
});
130+
};
131+
// timeout required to ensure the block is updated
132+
setTimeout(() => void addTagToBlock(), 100);
128133
}
129134
onClose();
130135
},
@@ -135,45 +140,36 @@ const NodeMenu = ({
135140
(e: KeyboardEvent) => {
136141
if (!isOpen || e.metaKey || e.ctrlKey) return;
137142
if (e.key === "Shift") {
138-
if (!isInitialTextSelected) {
139-
setShowNodeTypes(true);
140-
}
143+
if (!isInitialTextSelected) setShowNodeTypes(true);
141144
return;
142145
}
143146

147+
const getActiveIndex = () => {
148+
return Number(menuRef.current?.getAttribute("data-active-index"));
149+
};
150+
144151
if (e.key === "ArrowDown") {
145-
const index = Number(
146-
menuRef.current?.getAttribute("data-active-index"),
147-
);
152+
const index = getActiveIndex();
148153
const count = menuRef.current?.childElementCount || 0;
149154
setActiveIndex((index + 1) % count);
150155
} else if (e.key === "ArrowUp") {
151-
const index = Number(
152-
menuRef.current?.getAttribute("data-active-index"),
153-
);
156+
const index = getActiveIndex();
154157
const count = menuRef.current?.childElementCount || 0;
155158
setActiveIndex((index - 1 + count) % count);
156159
} else if (e.key === "Enter") {
157-
const index = Number(
158-
menuRef.current?.getAttribute("data-active-index"),
159-
);
160+
const index = getActiveIndex();
160161
onSelect(index);
161-
// Remove focus from the block to ensure updateBlock works properly
162-
document.body.click();
163162
} else if (e.key === "Escape") {
164163
onClose();
165-
document.body.click();
166164
} else if (shortcuts.has(e.key.toUpperCase())) {
167165
onSelect(indexBySC[e.key.toUpperCase()]);
168-
// Remove focus from the block to ensure updateBlock works properly
169-
document.body.click();
170166
} else {
171167
return;
172168
}
173169
e.stopPropagation();
174170
e.preventDefault();
175171
},
176-
[onSelect, onClose, indexBySC, isOpen, isInitialTextSelected],
172+
[onSelect, onClose, indexBySC, isOpen, isInitialTextSelected, shortcuts],
177173
);
178174

179175
const keyupListener = useCallback(

0 commit comments

Comments
 (0)