Skip to content

Commit 74af52d

Browse files
committed
use solid primitive
1 parent 8d1bb9d commit 74af52d

1 file changed

Lines changed: 19 additions & 30 deletions

File tree

  • js/app/packages/core/component/LexicalMarkdown/plugins/blame-tooltip

js/app/packages/core/component/LexicalMarkdown/plugins/blame-tooltip/BlameTooltip.tsx

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import { ENABLE_GIT_BLAME } from '@core/constant/featureFlags';
33
import { macroIdToEmail, tryMacroId, useDisplayNameParts } from '@core/user';
44
import { formatRelativeTimestamp } from '@entity';
55
import { syncServiceClient } from '@service-sync/client';
6-
import { debounce } from '@solid-primitives/scheduled';
6+
import { createScheduled, debounce } from '@solid-primitives/scheduled';
7+
import { createQuery } from '@tanstack/solid-query';
78
import {
89
createEffect,
9-
createResource,
10+
createMemo,
1011
createSignal,
1112
onCleanup,
1213
Show,
@@ -37,49 +38,37 @@ export function BlameTooltip(props: {
3738
documentId: string;
3839
}) {
3940
const [visible, setVisible] = createSignal(false);
40-
// The nodeId we've actually committed to fetching for. Debounced from the
41-
// raw hovered nodeId so we don't fire a request the instant the cursor
42-
// crosses a text node.
43-
const [armedNodeId, setArmedNodeId] = createSignal<string | null>(null);
4441
let shownAtX = 0;
4542
let shownAtY = 0;
4643
let showTimer: ReturnType<typeof setTimeout> | null = null;
4744

48-
const debouncedArm = debounce((nodeId: string | null) => {
49-
setArmedNodeId(nodeId);
50-
}, FETCH_DELAY_MS);
45+
// Only commits to a new nodeId after FETCH_DELAY_MS of hover stillness.
46+
const scheduled = createScheduled(fn => debounce(fn, FETCH_DELAY_MS));
47+
const queriedNodeId = createMemo<string | null>((prev) => {
48+
const active = props.state.hovering ? props.state.nodeId : null;
49+
return scheduled() ? active : prev;
50+
}, null);
5151

5252
const hide = () => {
53-
debouncedArm.clear();
5453
if (showTimer) clearTimeout(showTimer);
5554
showTimer = null;
56-
setArmedNodeId(null);
5755
setVisible(false);
5856
};
5957

60-
const [blame] = createResource(
61-
() => (ENABLE_GIT_BLAME() ? armedNodeId() : null),
62-
async (nodeId) => {
58+
const query = createQuery(() => ({
59+
queryKey: ['blame', props.documentId, queriedNodeId()],
60+
queryFn: async () => {
6361
const res = await syncServiceClient.getNodeBlame({
6462
documentId: props.documentId,
65-
nodeId,
63+
nodeId: queriedNodeId()!,
6664
});
6765
return res.isOk() ? res.value : null;
68-
}
69-
);
70-
71-
// Drive the fetch — debounced on nodeId only, ignores cursor x/y.
72-
createEffect(() => {
73-
const nodeId = props.state.hovering ? props.state.nodeId : null;
74-
if (nodeId === null) {
75-
debouncedArm.clear();
76-
setArmedNodeId(null);
77-
} else {
78-
debouncedArm(nodeId);
79-
}
80-
});
66+
},
67+
enabled: ENABLE_GIT_BLAME() && queriedNodeId() !== null,
68+
staleTime: Infinity,
69+
}));
8170

82-
// Drive the visibility based on cursor stillness (x/y).
71+
// Drive visibility based on cursor stillness (x/y).
8372
createEffect(() => {
8473
const { hovering, x, y } = props.state;
8574

@@ -103,7 +92,7 @@ export function BlameTooltip(props: {
10392
onCleanup(hide);
10493

10594
return (
106-
<Show when={visible() && blame()?.userId ? blame() : null}>
95+
<Show when={visible() && query.data?.userId ? query.data : null}>
10796
{(b) => (
10897
<div
10998
class="fixed z-50 text-xs text-ink-secondary/70 pointer-events-none"

0 commit comments

Comments
 (0)