mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-13 04:34:21 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a7ac7547f |
No files matched your search
@@ -12,7 +12,8 @@ vi.mock("@/platform/ipc", async (original) => {
|
||||
},
|
||||
};
|
||||
});
|
||||
import { loadLogDetails } from "../logDetails";
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { loadLogDetails, useCommitDetails } from "../logDetails";
|
||||
import { useVcs } from "../store";
|
||||
import { useGitLog } from "../logStore";
|
||||
const commit = (id: string): Commit => ({
|
||||
@@ -92,3 +93,38 @@ describe("commit detail jobs", () => {
|
||||
await Promise.all([first, second]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("useCommitDetails", () => {
|
||||
it("keeps the shown details while a repository refresh reloads them", async () => {
|
||||
const c = commit("kept-on-refresh");
|
||||
const { result, rerender } = renderHook(({ c }) => useCommitDetails(c), { initialProps: { c } });
|
||||
await vi.waitFor(() => expect(result.current.details?.message).toBe("kept-on-refresh"));
|
||||
let finish!: () => void;
|
||||
api.batch.mockImplementationOnce(
|
||||
(_repo: string, ids: string[]) =>
|
||||
new Promise((resolve) => {
|
||||
finish = () =>
|
||||
resolve({
|
||||
status: "ok",
|
||||
data: ids.map(() => ({
|
||||
message: "reloaded",
|
||||
containingBranches: ["main"],
|
||||
signature: "N",
|
||||
signer: "",
|
||||
key: "",
|
||||
fingerprint: "",
|
||||
})),
|
||||
});
|
||||
}),
|
||||
);
|
||||
act(() => useVcs.setState((s) => ({ version: s.version + 1 })));
|
||||
await vi.waitFor(() => expect(api.batch).toHaveBeenCalledTimes(2));
|
||||
expect(result.current.details?.message).toBe("kept-on-refresh");
|
||||
await act(async () => finish());
|
||||
await vi.waitFor(() => expect(result.current.details?.message).toBe("reloaded"));
|
||||
// Another commit shows nothing until its own details arrive.
|
||||
api.batch.mockImplementationOnce(() => new Promise(() => {}));
|
||||
rerender({ c: commit("another") });
|
||||
expect(result.current.details).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -126,20 +126,28 @@ export function useCommitDetails(commit: Commit, enabled = true) {
|
||||
const version = useVcs((s) => s.version);
|
||||
const repo = commitRepo(commit) ?? currentRepo();
|
||||
const refs = refVersions((s) => s[repo ?? ""] ?? 0);
|
||||
const key = `${repo}\0${commit.id}\0${version}\0${refs}`;
|
||||
const [result, setResult] = useState<{ key: string; details: LogDetails | null; error: boolean } | null>(null);
|
||||
const target = `${repo}\0${commit.id}`;
|
||||
const key = `${target}\0${version}\0${refs}`;
|
||||
const [result, setResult] = useState<{
|
||||
target: string;
|
||||
details: LogDetails | null;
|
||||
error: boolean;
|
||||
} | null>(null);
|
||||
useEffect(() => {
|
||||
if (!enabled) return;
|
||||
const controller = new AbortController();
|
||||
void loadLogDetails(commit, controller.signal)
|
||||
.then((details) => {
|
||||
if (!controller.signal.aborted) setResult({ key, details, error: false });
|
||||
if (!controller.signal.aborted) setResult({ target, details, error: false });
|
||||
})
|
||||
.catch(() => {
|
||||
if (!controller.signal.aborted) setResult({ key, details: null, error: true });
|
||||
if (!controller.signal.aborted) setResult({ target, details: null, error: true });
|
||||
});
|
||||
return () => controller.abort();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [key, enabled]);
|
||||
return { details: result?.key === key ? result.details : null, error: result?.key === key && result.error };
|
||||
// A repository refresh reloads the same commit's details: keep showing the last ones until
|
||||
// the new ones arrive, or the section blinks on every refresh.
|
||||
const current = result?.target === target ? result : null;
|
||||
return { details: current?.details ?? null, error: !!current?.error };
|
||||
}
|
||||
Reference in new issue
Block a user