Repository navigation
Expand file tree
/
Copy pathpullRequestDiff.logic.ts
More file actions
54 lines (48 loc) · 1.9 KB
/
Copy pathpullRequestDiff.logic.ts
File metadata and controls
54 lines (48 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import type { FileDiffMetadata } from "@pierre/diffs";
import type { PullRequestDiffSide } from "@t3tools/contracts";
/** Only rendered hunks can anchor comments; list others off-diff. */
export function isLineInFileDiff(
file: FileDiffMetadata,
side: PullRequestDiffSide,
line: number,
): boolean {
return file.hunks.some((hunk) =>
side === "left"
? line >= hunk.deletionStart && line < hunk.deletionStart + hunk.deletionCount
: line >= hunk.additionStart && line < hunk.additionStart + hunk.additionCount,
);
}
export type DiffFoldOverride = "expanded" | "folded" | null;
/** The reader's own fold choice per file. It is absolute, so a Viewed mark loading later keeps it. */
export type FileDiffFoldChoices = ReadonlyMap<string, boolean>;
/**
* A reader's own choice wins. Otherwise the toolbar decides, and a file still marked Viewed
* starts folded. Fold all and Expand all clear the choices, so later pages follow the toolbar.
*/
export function isFileDiffCollapsed(
fileKey: string,
foldOverride: DiffFoldOverride,
choices: FileDiffFoldChoices,
viewed = false,
): boolean {
return choices.get(fileKey) ?? (foldOverride === "folded" || viewed);
}
export function withFileDiffFold(
choices: FileDiffFoldChoices,
fileKey: string,
collapsed: boolean,
): FileDiffFoldChoices {
if (choices.get(fileKey) === collapsed) return choices;
return new Map(choices).set(fileKey, collapsed);
}
export function getFileViewedRange<T extends { readonly fileKey: string }>(
files: ReadonlyArray<T>,
fileKey: string,
anchorFileKey: string | null,
): ReadonlyArray<T> {
const index = files.findIndex((file) => file.fileKey === fileKey);
if (index === -1) return [];
const anchorIndex = files.findIndex((file) => file.fileKey === anchorFileKey);
if (anchorIndex === -1) return files.slice(index, index + 1);
return files.slice(Math.min(index, anchorIndex), Math.max(index, anchorIndex) + 1);
}