@nkzw/codiff-core 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/components/ReviewCodeView.d.ts +2 -2
- package/dist/app/hooks/useCodeViewAnnotations.d.ts +3 -0
- package/dist/app/hooks/useCodeViewPlaceholderFile.d.ts +2 -0
- package/dist/app/hooks/useReviewState.d.ts +2 -2
- package/dist/lib/app-types.d.ts +10 -2
- package/dist/lib/identifier-navigation.d.ts +1 -0
- package/dist/lib/narrative-walkthrough.d.ts +1 -0
- package/dist/lib/review-comments.d.ts +1 -0
- package/dist/lib/review-identity.d.ts +3 -0
- package/dist/react.mjs +195 -88
- package/dist/style.css +17 -4
- package/package.json +5 -5
|
@@ -39,7 +39,7 @@ type HeaderReviewDiffBlock = {
|
|
|
39
39
|
selected?: boolean;
|
|
40
40
|
};
|
|
41
41
|
export type ReviewDiffBlock = FileReviewDiffBlock | HeaderReviewDiffBlock;
|
|
42
|
-
export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle, blocks, bottomInset, codeQualityFindings, collapsed, comments, commitMetadata, diffLineHeight, diffStyle, disableWorkerPool,
|
|
42
|
+
export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle, blocks, bottomInset, codeQualityFindings, collapsed, comments, commitMetadata, diffLineHeight, diffStyle, disableWorkerPool, expandedReviewKeys, files, focusCommentId, focusCommentRequest, forceExpandedPaths, gitIdentity, hunkNavigation, initialMarkdownPreviewSectionIds, isReadOnly, itemVersionByKey, keymap, loadingSectionIds, onActiveBlockChange, onAskCodex, onCommentDraftChange, onCreateComment, onDeleteComment, onFindDefinitions, onLoadImageContent, onLoadSection, onLoadSectionContents, onOpenDefinition, onOpenFile, onRefreshMarkdown, onResolveThread, onSaveCommentEdit, onSelectPathFromScroll, onSubmitComment, onToggleCollapsed, onToggleViewed, onUpdateComment, onUpdateSourceDescription, onUpdateSourceTitle, onUploadSourceDescriptionAsset, reviewIdentityByPath, scrollTarget, searchQuery, selectedPath, showSourceDescription, showWhitespace, source, sourceDescriptionActions, sourceDescriptionFooter, supportsReviewCommentActions, theme, viewed, walkthroughNotes, wordWrap, }: {
|
|
43
43
|
activeSearchMatch: DiffSearchMatch | null;
|
|
44
44
|
agentId: 'codex' | 'claude' | 'opencode' | 'pi';
|
|
45
45
|
agentLabel: string;
|
|
@@ -53,7 +53,7 @@ export declare function ReviewCodeView({ activeSearchMatch, agentId, agentLabel,
|
|
|
53
53
|
diffLineHeight?: number;
|
|
54
54
|
diffStyle: CodiffDiffStyle;
|
|
55
55
|
disableWorkerPool?: boolean;
|
|
56
|
-
|
|
56
|
+
expandedReviewKeys?: ReadonlySet<string>;
|
|
57
57
|
files: ReadonlyArray<ChangedFile>;
|
|
58
58
|
focusCommentId: string | null;
|
|
59
59
|
focusCommentRequest: number;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LineAnnotation } from '@pierre/diffs';
|
|
2
|
+
import type { ReviewAnnotationMetadata } from '../../lib/app-types.ts';
|
|
3
|
+
export declare function useCodeViewAnnotations(): (id: string, key: string, annotations: Array<LineAnnotation<ReviewAnnotationMetadata>>) => LineAnnotation<ReviewAnnotationMetadata>[];
|
|
@@ -7,11 +7,11 @@ type UseReviewFileStateOptions = {
|
|
|
7
7
|
export declare function useReviewFileState({ initialSelectedPath, onViewedChange, }?: UseReviewFileStateOptions): {
|
|
8
8
|
bumpItemVersion: (key: string) => void;
|
|
9
9
|
collapsed: Set<string>;
|
|
10
|
-
|
|
10
|
+
expandedReviewKeys: Set<string>;
|
|
11
11
|
itemVersionByKey: Record<string, number>;
|
|
12
12
|
selectedPath: string | null;
|
|
13
13
|
setCollapsed: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
|
|
14
|
-
|
|
14
|
+
setExpandedReviewKeys: import("react").Dispatch<import("react").SetStateAction<Set<string>>>;
|
|
15
15
|
setItemVersionByKey: import("react").Dispatch<import("react").SetStateAction<Record<string, number>>>;
|
|
16
16
|
setSelectedPath: import("react").Dispatch<import("react").SetStateAction<string | null>>;
|
|
17
17
|
setViewed: import("react").Dispatch<import("react").SetStateAction<Record<string, string>>>;
|
package/dist/lib/app-types.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ type WalkthroughHeaderAnnotationMetadata = {
|
|
|
31
31
|
type: 'walkthrough-header';
|
|
32
32
|
};
|
|
33
33
|
export type ReviewAnnotationMetadata = CodeQualityAnnotationMetadata | ImagePreviewAnnotationMetadata | MarkdownPreviewAnnotationMetadata | ReviewCommentAnnotationMetadata | WalkthroughHeaderAnnotationMetadata;
|
|
34
|
-
export type CodeViewInstance = NonNullable<ReturnType<CodeViewHandle<ReviewAnnotationMetadata>['getInstance']>>;
|
|
34
|
+
export type CodeViewInstance = NonNullable<ReturnType<CodeViewHandle<ReviewAnnotationMetadata, undefined>['getInstance']>>;
|
|
35
35
|
export type DiffSearchMatch = {
|
|
36
36
|
filePath: string;
|
|
37
37
|
itemId: string;
|
|
@@ -52,6 +52,14 @@ export type ReviewScrollTarget = {
|
|
|
52
52
|
request: number;
|
|
53
53
|
};
|
|
54
54
|
export type ReviewIdentity = {
|
|
55
|
+
coverage?: {
|
|
56
|
+
allHunkIds: ReadonlyArray<string>;
|
|
57
|
+
file: {
|
|
58
|
+
fingerprint: string;
|
|
59
|
+
key: string;
|
|
60
|
+
};
|
|
61
|
+
hunkIds: ReadonlyArray<string>;
|
|
62
|
+
};
|
|
55
63
|
fingerprint: string;
|
|
56
64
|
key: string;
|
|
57
65
|
};
|
|
@@ -106,7 +114,7 @@ export type WalkthroughNote = {
|
|
|
106
114
|
};
|
|
107
115
|
export type SourceSession = {
|
|
108
116
|
collapsed: Set<string>;
|
|
109
|
-
|
|
117
|
+
expandedReviewKeys: Set<string>;
|
|
110
118
|
/** Populated by a generated or pre-authored narrative walkthrough document. */
|
|
111
119
|
narrativeWalkthrough?: NarrativeWalkthrough | null;
|
|
112
120
|
reviewComments: ReadonlyArray<ReviewComment>;
|
|
@@ -3,6 +3,7 @@ export type IdentifierAtOffset = {
|
|
|
3
3
|
start: number;
|
|
4
4
|
};
|
|
5
5
|
export declare const isNavigableIdentifierToken: (text: string) => boolean;
|
|
6
|
+
export declare const clearIdentifierNavigationWrappers: (root: ParentNode) => void;
|
|
6
7
|
export declare const applyIdentifierNavigationState: (renderedItems: ReadonlyArray<{
|
|
7
8
|
element: HTMLElement;
|
|
8
9
|
}>, active: boolean) => void;
|
|
@@ -42,6 +42,7 @@ export declare const formatWalkthroughFileLineRows: (items: ReadonlyArray<{
|
|
|
42
42
|
deleted: number;
|
|
43
43
|
path: string;
|
|
44
44
|
}>, maxVisibleFiles?: number) => ReadonlyArray<WalkthroughFileLineRow>;
|
|
45
|
+
export declare const getUncoveredWalkthroughReviewIdentity: (file: ChangedFile, view: WalkthroughView, showWhitespace: boolean) => import("./app-types.ts").ReviewIdentity;
|
|
45
46
|
export declare const getUncoveredWalkthroughFiles: (files: ReadonlyArray<ChangedFile>, view: WalkthroughView, showWhitespace: boolean) => ReadonlyArray<ChangedFile>;
|
|
46
47
|
export declare const getUncoveredWalkthroughFileLineItems: (files: ReadonlyArray<ChangedFile>, view: WalkthroughView, showWhitespace: boolean) => ReadonlyArray<{
|
|
47
48
|
added: number;
|
|
@@ -29,5 +29,6 @@ export declare const getCommentKey: (comment: Pick<ReviewComment, 'anchor' | 'li
|
|
|
29
29
|
export declare const getReviewCommentsDigest: (comments: ReadonlyArray<ReviewComment>) => string;
|
|
30
30
|
export declare const buildReviewCommentsMarkdown: (files: ReadonlyArray<ChangedFile>, comments: ReadonlyArray<ReviewComment>, showWhitespace: boolean, prefix?: string) => string;
|
|
31
31
|
export declare const getReviewCommentsFromState: (state: RepositoryState) => ReadonlyArray<ReviewComment>;
|
|
32
|
+
export declare const getRefreshedReviewComments: (state: RepositoryState, currentComments: ReadonlyArray<ReviewComment>) => ReadonlyArray<ReviewComment>;
|
|
32
33
|
export declare const getVisibleReviewComments: (comments: ReadonlyArray<ReviewComment>, showOutdated: boolean) => ReadonlyArray<ReviewComment>;
|
|
33
34
|
export declare const shouldDiscardReviewCommentOnEscape: (body: string, confirmDiscard?: (message: string) => boolean) => boolean;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ChangedFile } from '../types.ts';
|
|
2
2
|
import type { ReviewIdentity } from './app-types.ts';
|
|
3
3
|
export declare const getFileReviewIdentity: (file: ChangedFile) => ReviewIdentity;
|
|
4
|
+
export declare const getWalkthroughReviewKeyPrefix: (path: string) => string;
|
|
5
|
+
export declare const getSectionReviewHunkIds: (file: ChangedFile, section: ChangedFile['sections'][number]) => ReadonlyArray<string>;
|
|
6
|
+
export declare const getWalkthroughReviewIdentity: (file: ChangedFile, hunkIds: ReadonlyArray<string>) => ReviewIdentity;
|
|
4
7
|
export declare const getReviewIdentity: (file: ChangedFile, identityByPath?: ReadonlyMap<string, ReviewIdentity>) => ReviewIdentity;
|
|
5
8
|
export declare const isReviewIdentityViewed: (viewed: Readonly<Record<string, string>>, identity: ReviewIdentity) => boolean;
|
|
6
9
|
export declare const updateReviewIdentityViewed: (viewed: Readonly<Record<string, string>>, identity: ReviewIdentity, currentlyViewed: boolean) => Record<string, string>;
|
package/dist/react.mjs
CHANGED
|
@@ -1505,7 +1505,7 @@ const parseSectionDiffWithOptions = (file, section, showWhitespace) => {
|
|
|
1505
1505
|
}
|
|
1506
1506
|
else if (section.patch.trim().length === 0) fileDiff = createEmptyFileDiff(file, section);
|
|
1507
1507
|
else {
|
|
1508
|
-
const parsedFileDiff = parsePatchFiles(section.patch)[0]?.files[0];
|
|
1508
|
+
const parsedFileDiff = parsePatchFiles(section.patch, cacheKey)[0]?.files[0];
|
|
1509
1509
|
if (parsedFileDiff) {
|
|
1510
1510
|
const loaded = parsedFileDiff.isPartial ? getLoadedSectionContents(file, section) : void 0;
|
|
1511
1511
|
let hydrated = null;
|
|
@@ -3887,11 +3887,10 @@ const wrapIdentifierNavigationText = (root) => {
|
|
|
3887
3887
|
};
|
|
3888
3888
|
const applyIdentifierNavigationState = (renderedItems, active) => {
|
|
3889
3889
|
for (const { element } of renderedItems) {
|
|
3890
|
-
element.toggleAttribute(definitionModifierAttribute, active);
|
|
3891
3890
|
const root = element.shadowRoot;
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
if (
|
|
3891
|
+
const enabled = active && !hasActiveTextSelection(root);
|
|
3892
|
+
element.toggleAttribute(definitionModifierAttribute, enabled);
|
|
3893
|
+
if (root && enabled) wrapIdentifierNavigationText(root);
|
|
3895
3894
|
}
|
|
3896
3895
|
};
|
|
3897
3896
|
const getIdentifierAtOffset = (text, offset) => {
|
|
@@ -3945,18 +3944,46 @@ const getFileReviewIdentity = (file) => ({
|
|
|
3945
3944
|
fingerprint: file.fingerprint,
|
|
3946
3945
|
key: file.path
|
|
3947
3946
|
});
|
|
3947
|
+
const getWalkthroughReviewKeyPrefix = (path) => `walkthrough:${JSON.stringify(path)}:`;
|
|
3948
|
+
const getHunkViewedKey = (path, hunkId) => `${getWalkthroughReviewKeyPrefix(path)}${JSON.stringify(hunkId)}`;
|
|
3949
|
+
const getSectionReviewHunkIds = (file, section) => {
|
|
3950
|
+
const ids = getSectionWalkthroughHunks(file, section).map((hunk) => hunk.id);
|
|
3951
|
+
return ids.length > 0 ? ids : [section.id];
|
|
3952
|
+
};
|
|
3953
|
+
const getWalkthroughReviewIdentity = (file, hunkIds) => ({
|
|
3954
|
+
coverage: {
|
|
3955
|
+
allHunkIds: file.sections.flatMap((section) => getSectionReviewHunkIds(file, section)),
|
|
3956
|
+
file: getFileReviewIdentity(file),
|
|
3957
|
+
hunkIds
|
|
3958
|
+
},
|
|
3959
|
+
fingerprint: file.fingerprint,
|
|
3960
|
+
key: `${getWalkthroughReviewKeyPrefix(file.path)}${JSON.stringify(hunkIds)}`
|
|
3961
|
+
});
|
|
3948
3962
|
const getReviewIdentity = (file, identityByPath) => identityByPath?.get(file.path) ?? getFileReviewIdentity(file);
|
|
3949
|
-
const isReviewIdentityViewed = (viewed, identity) =>
|
|
3963
|
+
const isReviewIdentityViewed = (viewed, identity) => {
|
|
3964
|
+
const { coverage } = identity;
|
|
3965
|
+
return coverage ? viewed[coverage.file.key] === coverage.file.fingerprint || coverage.hunkIds.length > 0 && coverage.hunkIds.every((id) => viewed[getHunkViewedKey(coverage.file.key, id)] === coverage.file.fingerprint) : viewed[identity.key] === identity.fingerprint;
|
|
3966
|
+
};
|
|
3950
3967
|
const updateReviewIdentityViewed = (viewed, identity, currentlyViewed) => {
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3968
|
+
const next = { ...viewed };
|
|
3969
|
+
const { coverage } = identity;
|
|
3970
|
+
if (coverage) {
|
|
3971
|
+
const { allHunkIds, file, hunkIds } = coverage;
|
|
3972
|
+
if (viewed[file.key] === file.fingerprint) for (const id of allHunkIds) next[getHunkViewedKey(file.key, id)] = file.fingerprint;
|
|
3973
|
+
for (const id of hunkIds) {
|
|
3974
|
+
const key = getHunkViewedKey(file.key, id);
|
|
3975
|
+
if (currentlyViewed) delete next[key];
|
|
3976
|
+
else next[key] = file.fingerprint;
|
|
3977
|
+
}
|
|
3978
|
+
if (allHunkIds.length > 0 && allHunkIds.every((id) => next[getHunkViewedKey(file.key, id)] === file.fingerprint)) next[file.key] = file.fingerprint;
|
|
3979
|
+
else delete next[file.key];
|
|
3954
3980
|
return next;
|
|
3955
3981
|
}
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3982
|
+
const prefix = getWalkthroughReviewKeyPrefix(identity.key);
|
|
3983
|
+
for (const key of Object.keys(next)) if (key.startsWith(prefix)) delete next[key];
|
|
3984
|
+
if (currentlyViewed) delete next[identity.key];
|
|
3985
|
+
else next[identity.key] = identity.fingerprint;
|
|
3986
|
+
return next;
|
|
3960
3987
|
};
|
|
3961
3988
|
const updateReviewIdentityCollapsed = (collapsed, identity, currentlyCollapsed) => {
|
|
3962
3989
|
const next = new Set(collapsed);
|
|
@@ -4011,6 +4038,7 @@ const highlightTextContainer = (container, normalizedQuery, activeMatch) => {
|
|
|
4011
4038
|
const applySearchHighlights = (renderedItems, query, activeMatch) => {
|
|
4012
4039
|
const normalizedQuery = query.trim().toLowerCase();
|
|
4013
4040
|
for (const { element, id } of renderedItems) for (const root of getSearchableRoots(element)) {
|
|
4041
|
+
if (normalizedQuery) clearIdentifierNavigationWrappers(root);
|
|
4014
4042
|
clearSearchHighlights(root);
|
|
4015
4043
|
if (!normalizedQuery) continue;
|
|
4016
4044
|
const matchForItem = activeMatch && activeMatch.itemId === id ? activeMatch : null;
|
|
@@ -4024,6 +4052,45 @@ const getSourceKey = (source) => source.type === "commit" ? `commit:${source.ref
|
|
|
4024
4052
|
const getShortRef = (ref) => ref.slice(0, 7);
|
|
4025
4053
|
const getSourceLabel = (source) => source.type === "commit" ? getShortRef(source.ref) : source.type === "branch" || source.type === "branch-diff" ? `Branch vs ${source.ref}` : source.type === "branch-working-tree" ? `Local + branch vs ${source.ref}` : source.type === "range" ? rangeLabel(source) : source.type === "pull-request" ? source.number ? `${source.provider === "gitlab" ? "MR" : "PR"} #${source.number}` : source.provider === "gitlab" ? "Merge request" : "Pull request" : "Uncommitted";
|
|
4026
4054
|
//#endregion
|
|
4055
|
+
//#region app/hooks/useCodeViewAnnotations.ts
|
|
4056
|
+
function useCodeViewAnnotations() {
|
|
4057
|
+
const [getAnnotations] = useState(() => {
|
|
4058
|
+
const cache = /* @__PURE__ */ new Map();
|
|
4059
|
+
return (id, key, annotations) => {
|
|
4060
|
+
const previous = cache.get(id);
|
|
4061
|
+
if (previous?.key === key) return previous.annotations;
|
|
4062
|
+
cache.set(id, {
|
|
4063
|
+
annotations,
|
|
4064
|
+
key
|
|
4065
|
+
});
|
|
4066
|
+
return annotations;
|
|
4067
|
+
};
|
|
4068
|
+
});
|
|
4069
|
+
return getAnnotations;
|
|
4070
|
+
}
|
|
4071
|
+
//#endregion
|
|
4072
|
+
//#region app/hooks/useCodeViewPlaceholderFile.ts
|
|
4073
|
+
function useCodeViewPlaceholderFile() {
|
|
4074
|
+
const [getPlaceholderFile] = useState(() => {
|
|
4075
|
+
const files = /* @__PURE__ */ new Map();
|
|
4076
|
+
return (name, contents = " ") => {
|
|
4077
|
+
const cacheKey = `placeholder:${contents.length}:${name}`;
|
|
4078
|
+
let file = files.get(cacheKey);
|
|
4079
|
+
if (!file) {
|
|
4080
|
+
file = {
|
|
4081
|
+
cacheKey,
|
|
4082
|
+
contents,
|
|
4083
|
+
lang: "text",
|
|
4084
|
+
name
|
|
4085
|
+
};
|
|
4086
|
+
files.set(cacheKey, file);
|
|
4087
|
+
}
|
|
4088
|
+
return file;
|
|
4089
|
+
};
|
|
4090
|
+
});
|
|
4091
|
+
return getPlaceholderFile;
|
|
4092
|
+
}
|
|
4093
|
+
//#endregion
|
|
4027
4094
|
//#region app/components/DefinitionPopover.tsx
|
|
4028
4095
|
function DefinitionPopover({ anchor, getDestination, identifier, onClose, onOpen, result }) {
|
|
4029
4096
|
const popoverRef = useRef(null);
|
|
@@ -4308,6 +4375,7 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4308
4375
|
if (coveredSyntheticSectionIds.has(section.id)) return null;
|
|
4309
4376
|
const hunkIds = getSectionHunkIds(file, section);
|
|
4310
4377
|
if (hunkIds.length === 0) return coveredSectionIds.has(section.id) ? null : {
|
|
4378
|
+
hunkIds: [section.id],
|
|
4311
4379
|
identity: section.id,
|
|
4312
4380
|
section
|
|
4313
4381
|
};
|
|
@@ -4315,11 +4383,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4315
4383
|
if (uncoveredHunkIds.length === 0) return null;
|
|
4316
4384
|
const identity = `${section.id}:${uncoveredHunkIds.join(",")}`;
|
|
4317
4385
|
if (uncoveredHunkIds.length === hunkIds.length) return {
|
|
4386
|
+
hunkIds: uncoveredHunkIds,
|
|
4318
4387
|
identity,
|
|
4319
4388
|
section
|
|
4320
4389
|
};
|
|
4321
4390
|
const patch = filterPatchToHunkIds(section.patch, section.id, uncoveredHunkIds);
|
|
4322
4391
|
return patch ? {
|
|
4392
|
+
hunkIds: uncoveredHunkIds,
|
|
4323
4393
|
identity,
|
|
4324
4394
|
section: {
|
|
4325
4395
|
...section,
|
|
@@ -4327,6 +4397,13 @@ const getUncoveredWalkthroughSection = (file, section, coveredHunkIds, coveredSe
|
|
|
4327
4397
|
}
|
|
4328
4398
|
} : null;
|
|
4329
4399
|
};
|
|
4400
|
+
const getUncoveredWalkthroughReviewIdentity = (file, view, showWhitespace) => {
|
|
4401
|
+
const coveredHunkIds = walkthroughCoveredHunkIds(view);
|
|
4402
|
+
const coveredSectionIds = walkthroughCoveredSectionIds(view);
|
|
4403
|
+
const coveredSyntheticSectionIds = walkthroughCoveredSyntheticSectionIds(view);
|
|
4404
|
+
const hunkIds = getVisibleDiffSections(file, showWhitespace).flatMap(({ section }) => getUncoveredWalkthroughSection(file, section, coveredHunkIds, coveredSectionIds, coveredSyntheticSectionIds)?.hunkIds ?? []);
|
|
4405
|
+
return getWalkthroughReviewIdentity(file, hunkIds);
|
|
4406
|
+
};
|
|
4330
4407
|
const getUncoveredWalkthroughFiles = (files, view, showWhitespace) => {
|
|
4331
4408
|
const coveredHunkIds = walkthroughCoveredHunkIds(view);
|
|
4332
4409
|
const coveredSectionIds = walkthroughCoveredSectionIds(view);
|
|
@@ -4973,7 +5050,7 @@ function DiffLineCountBadge({ ariaLabelPrefix, className = "codiff-line-count",
|
|
|
4973
5050
|
//#endregion
|
|
4974
5051
|
//#region app/components/ReviewCodeView.tsx
|
|
4975
5052
|
const emptyMarkdownPreviewSectionIds = /* @__PURE__ */ new Set();
|
|
4976
|
-
const
|
|
5053
|
+
const emptyExpandedReviewKeys = /* @__PURE__ */ new Set();
|
|
4977
5054
|
const markdownPreviewPlugins = [frontmatterPlugin(), imagePlugin({
|
|
4978
5055
|
disableImageResize: true,
|
|
4979
5056
|
disableImageSettingsButton: true
|
|
@@ -5185,28 +5262,48 @@ const formatBytes = (size) => {
|
|
|
5185
5262
|
}
|
|
5186
5263
|
return `${size} B`;
|
|
5187
5264
|
};
|
|
5188
|
-
function MarkdownPreview({ contents, editable,
|
|
5189
|
-
|
|
5190
|
-
|
|
5265
|
+
function MarkdownPreview({ cacheKey, contents, editable, heightCache, onEditorRef, onLayoutReady, path, sectionId }) {
|
|
5266
|
+
const contentRef = useRef(null);
|
|
5267
|
+
const [ready, setReady] = useState(false);
|
|
5268
|
+
const measure = useCallback((reportedHeight) => {
|
|
5269
|
+
const content = contentRef.current;
|
|
5270
|
+
if (!content?.isConnected || content.querySelector(".codiff-markdown-editor-message:not(.error), .codiff-readonly-markdown-loading")) return;
|
|
5271
|
+
const height = content.getBoundingClientRect().height || reportedHeight;
|
|
5272
|
+
if (height == null || height <= 0) return;
|
|
5273
|
+
setReady(true);
|
|
5274
|
+
if (heightCache.get(cacheKey) !== height) {
|
|
5275
|
+
heightCache.set(cacheKey, height);
|
|
5276
|
+
onLayoutReady(sectionId);
|
|
5277
|
+
}
|
|
5191
5278
|
}, [
|
|
5192
|
-
|
|
5279
|
+
cacheKey,
|
|
5280
|
+
heightCache,
|
|
5193
5281
|
onLayoutReady,
|
|
5194
5282
|
sectionId
|
|
5195
5283
|
]);
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
}
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
className:
|
|
5208
|
-
|
|
5209
|
-
|
|
5284
|
+
useLayoutEffect(() => {
|
|
5285
|
+
const content = contentRef.current;
|
|
5286
|
+
if (!content) return;
|
|
5287
|
+
const observer = new ResizeObserver(() => measure());
|
|
5288
|
+
observer.observe(content);
|
|
5289
|
+
measure();
|
|
5290
|
+
return () => observer.disconnect();
|
|
5291
|
+
}, [measure]);
|
|
5292
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5293
|
+
style: { minHeight: ready ? void 0 : heightCache.get(cacheKey) },
|
|
5294
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
5295
|
+
className: `codiff-markdown-preview${editable ? " editable" : ""}`,
|
|
5296
|
+
ref: contentRef,
|
|
5297
|
+
children: editable ? /* @__PURE__ */ jsx(RepositoryMarkdownEditor, {
|
|
5298
|
+
onHeightChange: measure,
|
|
5299
|
+
path,
|
|
5300
|
+
ref: (editor) => onEditorRef(sectionId, editor)
|
|
5301
|
+
}) : /* @__PURE__ */ jsx(ReadOnlyMarkdown, {
|
|
5302
|
+
ariaLabel: `Preview ${path}`,
|
|
5303
|
+
className: "codiff-markdown-preview-editor",
|
|
5304
|
+
onHeightChange: measure,
|
|
5305
|
+
value: contents
|
|
5306
|
+
})
|
|
5210
5307
|
})
|
|
5211
5308
|
});
|
|
5212
5309
|
}
|
|
@@ -6604,8 +6701,11 @@ const getHunkSelectionRange = (hunk) => {
|
|
|
6604
6701
|
} : null;
|
|
6605
6702
|
};
|
|
6606
6703
|
const isSameSelection = (a, b) => a.start === b.start && a.end === b.end && a.side === b.side;
|
|
6607
|
-
function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle = false, blocks, bottomInset = codeViewLayout.paddingBottom, codeQualityFindings = [], collapsed, comments, commitMetadata, diffLineHeight = 20, diffStyle, disableWorkerPool = false,
|
|
6704
|
+
function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedToggle = false, blocks, bottomInset = codeViewLayout.paddingBottom, codeQualityFindings = [], collapsed, comments, commitMetadata, diffLineHeight = 20, diffStyle, disableWorkerPool = false, expandedReviewKeys = emptyExpandedReviewKeys, files, focusCommentId, focusCommentRequest, forceExpandedPaths, gitIdentity, hunkNavigation, initialMarkdownPreviewSectionIds = emptyMarkdownPreviewSectionIds, isReadOnly = false, itemVersionByKey, keymap, loadingSectionIds, onActiveBlockChange, onAskCodex, onCommentDraftChange, onCreateComment, onDeleteComment, onFindDefinitions, onLoadImageContent, onLoadSection, onLoadSectionContents, onOpenDefinition, onOpenFile, onRefreshMarkdown, onResolveThread = noopResolveThread, onSaveCommentEdit, onSelectPathFromScroll, onSubmitComment, onToggleCollapsed, onToggleViewed, onUpdateComment, onUpdateSourceDescription, onUpdateSourceTitle, onUploadSourceDescriptionAsset, reviewIdentityByPath, scrollTarget, searchQuery, selectedPath, showSourceDescription = true, showWhitespace, source, sourceDescriptionActions, sourceDescriptionFooter, supportsReviewCommentActions, theme = "system", viewed, walkthroughNotes, wordWrap }) {
|
|
6608
6705
|
const codeViewRef = useRef(null);
|
|
6706
|
+
const getPlaceholderFile = useCodeViewPlaceholderFile();
|
|
6707
|
+
const getAnnotations = useCodeViewAnnotations();
|
|
6708
|
+
const [markdownPreviewHeights] = useState(() => /* @__PURE__ */ new Map());
|
|
6609
6709
|
const markdownEditorRefs = useRef(/* @__PURE__ */ new Map());
|
|
6610
6710
|
const refreshingMarkdownSectionsRef = useRef(/* @__PURE__ */ new Set());
|
|
6611
6711
|
const deferredTimersRef = useRef(/* @__PURE__ */ new Set());
|
|
@@ -6713,12 +6813,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6713
6813
|
}
|
|
6714
6814
|
}],
|
|
6715
6815
|
collapsed: false,
|
|
6716
|
-
file:
|
|
6717
|
-
cacheKey: `walkthrough-header:${block.id}`,
|
|
6718
|
-
contents: " ",
|
|
6719
|
-
lang: "text",
|
|
6720
|
-
name: headerId
|
|
6721
|
-
},
|
|
6816
|
+
file: getPlaceholderFile(headerId),
|
|
6722
6817
|
id: headerId,
|
|
6723
6818
|
type: "file",
|
|
6724
6819
|
version: getItemVersion(`${block.id}:walkthrough-header`)
|
|
@@ -6729,7 +6824,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6729
6824
|
const reviewIdentity = block.reviewIdentity ?? getReviewIdentity(file, reviewIdentityByPath);
|
|
6730
6825
|
const reviewKey = reviewIdentity.key;
|
|
6731
6826
|
const isViewed = isReviewIdentityViewed(viewed, reviewIdentity);
|
|
6732
|
-
const isCollapsed = !forceExpandedPaths.has(file.path) && !
|
|
6827
|
+
const isCollapsed = !forceExpandedPaths.has(file.path) && !expandedReviewKeys.has(reviewKey) && (isViewed || collapsed.has(reviewKey) || isGeneratedWalkthroughFile(file));
|
|
6733
6828
|
const visibleSections = getVisibleDiffSections(file, showWhitespace);
|
|
6734
6829
|
const lineCount = getDiffLineCountFromVisibleSections(visibleSections);
|
|
6735
6830
|
const sections = isCollapsed ? visibleSections.slice(0, 1) : visibleSections;
|
|
@@ -6823,12 +6918,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6823
6918
|
}
|
|
6824
6919
|
}],
|
|
6825
6920
|
collapsed: isCollapsed,
|
|
6826
|
-
file:
|
|
6827
|
-
cacheKey: `image-preview:${file.fingerprint}:${section.id}`,
|
|
6828
|
-
contents: " ",
|
|
6829
|
-
lang: "text",
|
|
6830
|
-
name: file.path
|
|
6831
|
-
},
|
|
6921
|
+
file: getPlaceholderFile(file.path),
|
|
6832
6922
|
id,
|
|
6833
6923
|
type: "file",
|
|
6834
6924
|
version: getItemVersion(`${reviewVersionPrefix}:image:${sectionStateVersionKey}:${imagePreviewLayoutPassBySection[section.id] ?? 0}`)
|
|
@@ -6839,7 +6929,12 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6839
6929
|
const markdownPreviewAddedLinesDigest = getAddedLinesDigest(markdownPreview.addedLines);
|
|
6840
6930
|
const markdownPreviewLayoutKey = `${section.id}:${markdownPreview.contents.length}:${markdownPreviewAddedLinesDigest}`;
|
|
6841
6931
|
nextItems.push({
|
|
6842
|
-
annotations:
|
|
6932
|
+
annotations: getAnnotations(id, JSON.stringify([
|
|
6933
|
+
markdownPreview.contents,
|
|
6934
|
+
markdownPreviewAddedLinesDigest,
|
|
6935
|
+
canEditMarkdown,
|
|
6936
|
+
fileCommentAnnotations
|
|
6937
|
+
]), [...fileCommentAnnotations, {
|
|
6843
6938
|
lineNumber: 1,
|
|
6844
6939
|
metadata: {
|
|
6845
6940
|
addedLines: markdownPreview.addedLines,
|
|
@@ -6850,14 +6945,9 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6850
6945
|
sectionId: section.id,
|
|
6851
6946
|
type: "markdown-preview"
|
|
6852
6947
|
}
|
|
6853
|
-
}],
|
|
6948
|
+
}]),
|
|
6854
6949
|
collapsed: isCollapsed,
|
|
6855
|
-
file:
|
|
6856
|
-
cacheKey: `markdown-preview:${section.newFile?.cacheKey ?? file.fingerprint}:${markdownPreview.contents.length}:${markdownPreviewAddedLinesDigest}`,
|
|
6857
|
-
contents: " ",
|
|
6858
|
-
lang: "text",
|
|
6859
|
-
name: file.path
|
|
6860
|
-
},
|
|
6950
|
+
file: getPlaceholderFile(file.path),
|
|
6861
6951
|
id,
|
|
6862
6952
|
type: "file",
|
|
6863
6953
|
version: getItemVersion(`${reviewVersionPrefix}:markdown:${sectionStateVersionKey}:${markdownPreviewLayoutKey}:${markdownPreviewLayoutPassBySection[section.id] ?? 0}`)
|
|
@@ -6891,8 +6981,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6891
6981
|
commentsBySection,
|
|
6892
6982
|
diffLineHeight,
|
|
6893
6983
|
diffStyle,
|
|
6894
|
-
|
|
6984
|
+
expandedReviewKeys,
|
|
6895
6985
|
forceExpandedPaths,
|
|
6986
|
+
getAnnotations,
|
|
6987
|
+
getPlaceholderFile,
|
|
6896
6988
|
imagePreviewLayoutPassBySection,
|
|
6897
6989
|
isReadOnly,
|
|
6898
6990
|
itemVersionByKey,
|
|
@@ -6911,16 +7003,12 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
6911
7003
|
if (items.length > 0 || !sourceDescriptionItemId) return items;
|
|
6912
7004
|
return [{
|
|
6913
7005
|
collapsed: true,
|
|
6914
|
-
file:
|
|
6915
|
-
cacheKey: sourceDescriptionItemId,
|
|
6916
|
-
contents: "",
|
|
6917
|
-
lang: "text",
|
|
6918
|
-
name: shouldShowCommitMessage ? "commit-message.md" : "source-description.md"
|
|
6919
|
-
},
|
|
7006
|
+
file: getPlaceholderFile(shouldShowCommitMessage ? "commit-message.md" : "source-description.md", ""),
|
|
6920
7007
|
id: sourceDescriptionItemId,
|
|
6921
7008
|
type: "file"
|
|
6922
7009
|
}];
|
|
6923
7010
|
}, [
|
|
7011
|
+
getPlaceholderFile,
|
|
6924
7012
|
items,
|
|
6925
7013
|
shouldShowCommitMessage,
|
|
6926
7014
|
sourceDescriptionItemId
|
|
@@ -7583,30 +7671,44 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7583
7671
|
]);
|
|
7584
7672
|
useEffect(() => {
|
|
7585
7673
|
if (!onFindDefinitions) return;
|
|
7674
|
+
let pointerDown = false;
|
|
7586
7675
|
const updateDefinitionModifierState = (active) => {
|
|
7587
7676
|
if (definitionModifierActiveRef.current === active) return;
|
|
7588
7677
|
definitionModifierActiveRef.current = active;
|
|
7589
7678
|
updateRenderedIdentifierNavigation(active);
|
|
7590
7679
|
};
|
|
7591
7680
|
const handleModifierChange = (event) => {
|
|
7592
|
-
updateDefinitionModifierState(isPrimaryModifier(event));
|
|
7681
|
+
updateDefinitionModifierState(isPrimaryModifier(event) && !pointerDown);
|
|
7593
7682
|
};
|
|
7594
7683
|
const handleModifierPointer = (event) => {
|
|
7595
|
-
|
|
7684
|
+
pointerDown = (event.buttons & 1) !== 0;
|
|
7685
|
+
updateDefinitionModifierState(isPrimaryModifier(event) && !pointerDown);
|
|
7686
|
+
};
|
|
7687
|
+
const handleSelectionChange = () => {
|
|
7688
|
+
updateRenderedIdentifierNavigation(definitionModifierActiveRef.current);
|
|
7689
|
+
};
|
|
7690
|
+
const clearDefinitionModifierState = () => {
|
|
7691
|
+
pointerDown = false;
|
|
7692
|
+
updateDefinitionModifierState(false);
|
|
7596
7693
|
};
|
|
7597
|
-
const clearDefinitionModifierState = () => updateDefinitionModifierState(false);
|
|
7598
7694
|
window.addEventListener("keydown", handleModifierChange);
|
|
7599
7695
|
window.addEventListener("keyup", handleModifierChange);
|
|
7600
7696
|
window.addEventListener("pointerdown", handleModifierPointer);
|
|
7601
7697
|
window.addEventListener("pointermove", handleModifierPointer);
|
|
7698
|
+
window.addEventListener("pointerup", handleModifierPointer);
|
|
7699
|
+
window.addEventListener("pointercancel", clearDefinitionModifierState);
|
|
7602
7700
|
window.addEventListener("blur", clearDefinitionModifierState);
|
|
7701
|
+
document.addEventListener("selectionchange", handleSelectionChange);
|
|
7603
7702
|
return () => {
|
|
7604
7703
|
clearDefinitionModifierState();
|
|
7605
7704
|
window.removeEventListener("keydown", handleModifierChange);
|
|
7606
7705
|
window.removeEventListener("keyup", handleModifierChange);
|
|
7607
7706
|
window.removeEventListener("pointerdown", handleModifierPointer);
|
|
7608
7707
|
window.removeEventListener("pointermove", handleModifierPointer);
|
|
7708
|
+
window.removeEventListener("pointerup", handleModifierPointer);
|
|
7709
|
+
window.removeEventListener("pointercancel", clearDefinitionModifierState);
|
|
7609
7710
|
window.removeEventListener("blur", clearDefinitionModifierState);
|
|
7711
|
+
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
7610
7712
|
};
|
|
7611
7713
|
}, [onFindDefinitions, updateRenderedIdentifierNavigation]);
|
|
7612
7714
|
const invalidateDefinitionLookup = useCallback(() => {
|
|
@@ -7720,9 +7822,10 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7720
7822
|
}) : null;
|
|
7721
7823
|
}
|
|
7722
7824
|
if (annotation.metadata.type === "markdown-preview") return /* @__PURE__ */ jsx(MarkdownPreview, {
|
|
7825
|
+
cacheKey: `${sourceKey}:${item.id}`,
|
|
7723
7826
|
contents: annotation.metadata.contents,
|
|
7724
7827
|
editable: annotation.metadata.editable,
|
|
7725
|
-
|
|
7828
|
+
heightCache: markdownPreviewHeights,
|
|
7726
7829
|
onEditorRef: setMarkdownEditorRef,
|
|
7727
7830
|
onLayoutReady: markMarkdownPreviewLayoutReady,
|
|
7728
7831
|
path: annotation.metadata.path,
|
|
@@ -7764,6 +7867,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7764
7867
|
itemMetadata,
|
|
7765
7868
|
keymap,
|
|
7766
7869
|
markMarkdownPreviewLayoutReady,
|
|
7870
|
+
markdownPreviewHeights,
|
|
7767
7871
|
markImagePreviewLayoutReady,
|
|
7768
7872
|
markCommentLayoutChanged,
|
|
7769
7873
|
onAskCodex,
|
|
@@ -7777,6 +7881,7 @@ function ReviewCodeView({ activeSearchMatch, agentId, agentLabel, allowViewedTog
|
|
|
7777
7881
|
replyToThread,
|
|
7778
7882
|
setMarkdownEditorRef,
|
|
7779
7883
|
source,
|
|
7884
|
+
sourceKey,
|
|
7780
7885
|
supportsReviewCommentActions
|
|
7781
7886
|
]);
|
|
7782
7887
|
const handleScroll = useCallback((_scrollTop, viewer) => {
|
|
@@ -8455,10 +8560,7 @@ const getFocusedRunDiffs = (item, files) => resolveWalkthroughHunkRuns(item, fil
|
|
|
8455
8560
|
return focused ? [{
|
|
8456
8561
|
file: focused,
|
|
8457
8562
|
note: getWalkthroughRunNote(item, run),
|
|
8458
|
-
reviewIdentity:
|
|
8459
|
-
fingerprint: focused.fingerprint,
|
|
8460
|
-
key: `walkthrough:${run.key}`
|
|
8461
|
-
}
|
|
8563
|
+
reviewIdentity: getWalkthroughReviewIdentity(run.resolved.file, run.hunks.flatMap((hunk) => hunk.kind === "synthetic" ? getSectionReviewHunkIds(run.resolved.file, run.resolved.section) : [hunk.id]))
|
|
8462
8564
|
}] : [];
|
|
8463
8565
|
});
|
|
8464
8566
|
const getWalkthroughNavigationKeyDirection = (event) => {
|
|
@@ -8572,10 +8674,7 @@ const createSupportBlocks = (files, selected, walkthroughView, showWhitespace) =
|
|
|
8572
8674
|
id: blockId,
|
|
8573
8675
|
itemIdPrefix: blockId,
|
|
8574
8676
|
note: "Not included in the generated walkthrough.",
|
|
8575
|
-
reviewIdentity:
|
|
8576
|
-
fingerprint: file.fingerprint,
|
|
8577
|
-
key: blockId
|
|
8578
|
-
}
|
|
8677
|
+
reviewIdentity: getUncoveredWalkthroughReviewIdentity(files.find((candidate) => candidate.path === file.path), walkthroughView, showWhitespace)
|
|
8579
8678
|
});
|
|
8580
8679
|
}
|
|
8581
8680
|
return blocks;
|
|
@@ -9492,7 +9591,7 @@ function useReviewCommentDrafts({ canCreateComment = true, comments, onCommentFi
|
|
|
9492
9591
|
//#region app/hooks/useReviewState.ts
|
|
9493
9592
|
function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {}) {
|
|
9494
9593
|
const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
|
|
9495
|
-
const [
|
|
9594
|
+
const [expandedReviewKeys, setExpandedReviewKeys] = useState(() => /* @__PURE__ */ new Set());
|
|
9496
9595
|
const [itemVersionByKey, setItemVersionByKey] = useState({});
|
|
9497
9596
|
const [selectedPath, setSelectedPath] = useState(initialSelectedPath);
|
|
9498
9597
|
const [viewed, setViewed] = useState({});
|
|
@@ -9505,11 +9604,11 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9505
9604
|
return {
|
|
9506
9605
|
bumpItemVersion,
|
|
9507
9606
|
collapsed,
|
|
9508
|
-
|
|
9607
|
+
expandedReviewKeys,
|
|
9509
9608
|
itemVersionByKey,
|
|
9510
9609
|
selectedPath,
|
|
9511
9610
|
setCollapsed,
|
|
9512
|
-
|
|
9611
|
+
setExpandedReviewKeys,
|
|
9513
9612
|
setItemVersionByKey,
|
|
9514
9613
|
setSelectedPath,
|
|
9515
9614
|
setViewed,
|
|
@@ -9520,9 +9619,9 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9520
9619
|
else next.add(reviewKey);
|
|
9521
9620
|
return next;
|
|
9522
9621
|
});
|
|
9523
|
-
|
|
9622
|
+
setExpandedReviewKeys((current) => {
|
|
9524
9623
|
const next = new Set(current);
|
|
9525
|
-
if (isCollapsed
|
|
9624
|
+
if (isCollapsed) next.add(reviewKey);
|
|
9526
9625
|
else next.delete(reviewKey);
|
|
9527
9626
|
return next;
|
|
9528
9627
|
});
|
|
@@ -9534,12 +9633,20 @@ function useReviewFileState({ initialSelectedPath = null, onViewedChange } = {})
|
|
|
9534
9633
|
onViewedChange?.(next);
|
|
9535
9634
|
return next;
|
|
9536
9635
|
});
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9636
|
+
const fileKey = reviewIdentity.coverage?.file.key ?? file.path;
|
|
9637
|
+
const prefix = getWalkthroughReviewKeyPrefix(fileKey);
|
|
9638
|
+
const clearRelatedKeys = (current) => new Set([...current].filter((key) => key !== fileKey && (reviewIdentity.coverage ? key !== reviewIdentity.key : !key.startsWith(prefix))));
|
|
9639
|
+
if (reviewIdentity.coverage || reviewIdentity.key === file.path) {
|
|
9640
|
+
setCollapsed(clearRelatedKeys);
|
|
9641
|
+
setExpandedReviewKeys(clearRelatedKeys);
|
|
9642
|
+
} else {
|
|
9643
|
+
setCollapsed((current) => updateReviewIdentityCollapsed(current, reviewIdentity, isViewed));
|
|
9644
|
+
setExpandedReviewKeys((current) => {
|
|
9645
|
+
const next = new Set(current);
|
|
9646
|
+
next.delete(reviewIdentity.key);
|
|
9647
|
+
return next;
|
|
9648
|
+
});
|
|
9649
|
+
}
|
|
9543
9650
|
bumpItemVersion(reviewIdentity.key);
|
|
9544
9651
|
}, [bumpItemVersion, onViewedChange]),
|
|
9545
9652
|
viewed
|
|
@@ -9572,13 +9679,13 @@ const defaultConfigTemplate = {
|
|
|
9572
9679
|
keymap: {
|
|
9573
9680
|
"askAgent": "Mod+Alt+Enter",
|
|
9574
9681
|
"closeSearch": "Escape",
|
|
9575
|
-
"commandBar": "Mod+
|
|
9682
|
+
"commandBar": "Mod+k",
|
|
9576
9683
|
"diffSearch": "Mod+f",
|
|
9577
9684
|
"discardComment": "Escape",
|
|
9578
9685
|
"fileFilter": "Mod+p",
|
|
9579
9686
|
"nextHunk": ["Ctrl+ArrowDown", "j"],
|
|
9580
9687
|
"nextSearchMatch": "Enter",
|
|
9581
|
-
"openFile": "Mod+
|
|
9688
|
+
"openFile": "Mod+Shift+o",
|
|
9582
9689
|
"prevHunk": ["Ctrl+ArrowUp", "k"],
|
|
9583
9690
|
"prevSearchMatch": "Shift+Enter",
|
|
9584
9691
|
"shortcutsHelp": "Shift+?",
|
|
@@ -9732,7 +9839,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
|
|
|
9732
9839
|
}, [keymap, toggleSidebar]);
|
|
9733
9840
|
const sidebarMode = Boolean(initialMode && onModeChange) && initialMode ? initialMode : uncontrolledSidebarMode;
|
|
9734
9841
|
const [treeScrollTarget, setTreeScrollTarget] = useState(null);
|
|
9735
|
-
const { bumpItemVersion, collapsed,
|
|
9842
|
+
const { bumpItemVersion, collapsed, expandedReviewKeys, itemVersionByKey, selectedPath, setSelectedPath, toggleCollapsed, toggleViewed, viewed } = useReviewFileState({ initialSelectedPath: snapshot.files[0]?.path ?? null });
|
|
9736
9843
|
const { resizeSidebar, sidebarWidth } = useResizableSidebar({
|
|
9737
9844
|
collapseThreshold: 80,
|
|
9738
9845
|
onCollapse: () => {
|
|
@@ -10107,7 +10214,7 @@ function ReviewSurface({ commenting, externalUrl, gitIdentity = null, initialMod
|
|
|
10107
10214
|
diffLineHeight,
|
|
10108
10215
|
diffStyle: snapshot.preferences.diffStyle,
|
|
10109
10216
|
disableWorkerPool: true,
|
|
10110
|
-
|
|
10217
|
+
expandedReviewKeys,
|
|
10111
10218
|
focusCommentId,
|
|
10112
10219
|
focusCommentRequest,
|
|
10113
10220
|
gitIdentity,
|
package/dist/style.css
CHANGED
|
@@ -2807,6 +2807,10 @@ form._multiFieldForm_sre1d_1628 {
|
|
|
2807
2807
|
padding-left: 20px;
|
|
2808
2808
|
}
|
|
2809
2809
|
|
|
2810
|
+
.mdx-editor .mdx-editor-content li > ul, .mdx-editor .mdx-editor-content li > ol {
|
|
2811
|
+
margin-block: 0;
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2810
2814
|
.mdx-editor-content li {
|
|
2811
2815
|
margin: 0;
|
|
2812
2816
|
padding-left: 2px;
|
|
@@ -5797,6 +5801,10 @@ html[data-codiff-platform="darwin"] .sidebar {
|
|
|
5797
5801
|
background: var(--sidebar-vibrancy-tint);
|
|
5798
5802
|
}
|
|
5799
5803
|
|
|
5804
|
+
.app-shell.command-bar-open > :not(.command-bar-overlay) {
|
|
5805
|
+
filter: blur(4px);
|
|
5806
|
+
}
|
|
5807
|
+
|
|
5800
5808
|
.merge-request-nav-button {
|
|
5801
5809
|
color: var(--muted);
|
|
5802
5810
|
cursor: pointer;
|
|
@@ -8601,7 +8609,6 @@ diffs-container .review-comment-thread {
|
|
|
8601
8609
|
}
|
|
8602
8610
|
|
|
8603
8611
|
.command-bar-overlay, .open-review-source-overlay {
|
|
8604
|
-
backdrop-filter: blur(4px);
|
|
8605
8612
|
background: #ffffff47;
|
|
8606
8613
|
justify-content: center;
|
|
8607
8614
|
align-items: flex-start;
|
|
@@ -8611,6 +8618,10 @@ diffs-container .review-comment-thread {
|
|
|
8611
8618
|
inset: 0;
|
|
8612
8619
|
}
|
|
8613
8620
|
|
|
8621
|
+
.open-review-source-overlay {
|
|
8622
|
+
backdrop-filter: blur(4px);
|
|
8623
|
+
}
|
|
8624
|
+
|
|
8614
8625
|
.command-bar-overlay {
|
|
8615
8626
|
z-index: 100;
|
|
8616
8627
|
}
|
|
@@ -8638,6 +8649,7 @@ diffs-container .review-comment-thread {
|
|
|
8638
8649
|
flex-direction: column;
|
|
8639
8650
|
width: min(520px, 90vw);
|
|
8640
8651
|
max-height: 400px;
|
|
8652
|
+
padding-top: 6px;
|
|
8641
8653
|
display: flex;
|
|
8642
8654
|
overflow: hidden;
|
|
8643
8655
|
}
|
|
@@ -8645,15 +8657,16 @@ diffs-container .review-comment-thread {
|
|
|
8645
8657
|
.command-bar-input {
|
|
8646
8658
|
color: var(--text);
|
|
8647
8659
|
corner-shape: squircle;
|
|
8648
|
-
font:
|
|
8660
|
+
font: 13px/1.35 var(--font-sans);
|
|
8649
8661
|
background: #7f7f7f1a;
|
|
8650
8662
|
border: 0;
|
|
8651
8663
|
border-radius: 16px;
|
|
8652
8664
|
outline: none;
|
|
8653
8665
|
width: calc(100% - 20px);
|
|
8654
8666
|
height: 34px;
|
|
8655
|
-
|
|
8656
|
-
|
|
8667
|
+
min-height: 34px;
|
|
8668
|
+
margin: 4px 10px 8px;
|
|
8669
|
+
padding: 0 10px;
|
|
8657
8670
|
}
|
|
8658
8671
|
|
|
8659
8672
|
.command-bar-input:focus {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nkzw/codiff-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "A fast diff viewer.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@nkzw/mdx-editor": "^1.0.
|
|
54
|
+
"@nkzw/mdx-editor": "^1.0.3",
|
|
55
55
|
"@nkzw/use-relative-time": "^1.2.3",
|
|
56
56
|
"@phosphor-icons/react": "^2.1.10",
|
|
57
|
-
"@pierre/diffs": "1.
|
|
57
|
+
"@pierre/diffs": "1.4.2",
|
|
58
58
|
"@pierre/trees": "1.0.0-beta.6",
|
|
59
59
|
"@radix-ui/react-slot": "^1.3.3",
|
|
60
60
|
"class-variance-authority": "^0.7.1",
|
|
61
61
|
"ghostty-web": "^0.4.0",
|
|
62
|
-
"lucide-react": "^1.
|
|
63
|
-
"valibot": "^1.
|
|
62
|
+
"lucide-react": "^1.46.0",
|
|
63
|
+
"valibot": "^1.5.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"react": "^19.2.0",
|