Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/client/review/ReviewPane.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -780,9 +780,14 @@ export function ReviewPane() {
// Clicking a line's content puts the cursor there (the number column starts a range selection instead).
// Fires after onTokenClick on the same click, so it must not close the popover that click opened.
onLineClick: (props: OnLineClickProps | OnDiffLineClickProps, ctx: { item: { id: string } }) => {
if (props.numberColumn) return;
const side = 'annotationSide' in props ? props.annotationSide : 'additions';
const range = { start: props.lineNumber, side, end: props.lineNumber, endSide: side };
if (props.numberColumn) {
// The viewer toggles off a lone selected line pressed again, which is often the cursor's line;
// here that press comments on it like any other line's.
if (!viewerRef.current?.getSelectedLines()) void openDraft({ id: ctx.item.id, range });
return;
}
setSelection({ id: ctx.item.id, range });
setActivePath(pathFromItemId(ctx.item.id));
},
Expand Down
21 changes: 21 additions & 0 deletions test/client/ReviewPane.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const captureOptions = vi.fn<(options: CodeViewOptions<unknown>) => void>();
const captureItems = vi.fn<(items: unknown[]) => void>();
const primeDiffHighlightCache = vi.fn(async (_diff: unknown) => {});
const scrollTo = vi.fn();
let viewerSelection: unknown = null;
vi.mock('@pierre/diffs/react', () => ({
useWorkerPool: () => ({ primeDiffHighlightCache }),
CodeView: forwardRef(function CodeView(
Expand All @@ -50,6 +51,7 @@ vi.mock('@pierre/diffs/react', () => ({
() => ({
getInstance: () => ({ getRenderedItems: () => rendered, render: renderViewer, instanceChanged }),
getItem: (id: string) => rendered.find((r) => r.id === id)?.element ?? null,
getSelectedLines: () => viewerSelection,
scrollTo,
}),
[],
Expand Down Expand Up @@ -188,6 +190,7 @@ beforeEach(() => {
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
installSearchHighlights.mockClear();
rendered = [];
viewerSelection = null;
useStore.setState({
snapshot: null,
loaded: {},
Expand Down Expand Up @@ -878,6 +881,24 @@ describe('ReviewPane scroller effects', () => {
expect(installSearchHighlights.mock.calls[0]![1]).toBe(host.querySelector('.codeview'));
});

it("opens a comment on the cursor's line when its number is pressed, which the viewer reads as unselecting it", async () => {
await act(() => root.render(createElement(ReviewPane)));
await act(() => useStore.setState({ snapshot: snap(changed), draft: null }));
const onLineClick = captureOptions.mock.calls.at(-1)![0].onLineClick as (props: unknown, ctx: unknown) => void;
const ctx = { item: { id: 'diff:a.txt@0' } };
const press = { lineNumber: 2, annotationSide: 'additions', numberColumn: true };
const range = { start: 2, side: 'additions', end: 2, endSide: 'additions' };

// A press that left a selection already opened the composer through onLineSelectionEnd.
viewerSelection = { id: ctx.item.id, range };
await act(() => onLineClick(press, ctx));
expect(useStore.getState().draft).toBeNull();

viewerSelection = null;
await act(() => onLineClick(press, ctx));
expect(useStore.getState().draft).toEqual({ path: 'a.txt', selection: { id: ctx.item.id, range } });
});

it('toggles collapse from the file header while only the checkbox changes viewed state', async () => {
await act(() => root.render(createElement(ReviewPane)));
const file = { kind: 'file' as const, file: { name: 'a.txt', contents: 'x' } };
Expand Down
Loading