mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-17 23:14:03 +01:00
Add diff viewer to git commit dialog (#374)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
39
src-web/components/core/Editor/DiffViewer.css
Normal file
39
src-web/components/core/Editor/DiffViewer.css
Normal file
@@ -0,0 +1,39 @@
|
||||
.cm-wrapper.cm-multiline .cm-mergeView {
|
||||
@apply h-full w-full overflow-auto pr-0.5;
|
||||
|
||||
.cm-mergeViewEditors {
|
||||
@apply w-full min-h-full;
|
||||
}
|
||||
|
||||
.cm-mergeViewEditor {
|
||||
@apply w-full min-h-full relative;
|
||||
|
||||
.cm-collapsedLines {
|
||||
@apply bg-none bg-surface border border-border py-1 mx-0.5 text-text opacity-80 hover:opacity-100 rounded cursor-default;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
@apply pl-1.5;
|
||||
}
|
||||
.cm-changedLine {
|
||||
/* Round top corners only if previous line is not a changed line */
|
||||
&:not(.cm-changedLine + &) {
|
||||
@apply rounded-t;
|
||||
}
|
||||
/* Round bottom corners only if next line is not a changed line */
|
||||
&:not(:has(+ .cm-changedLine)) {
|
||||
@apply rounded-b;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let content grow and disable individual scrolling for sync */
|
||||
.cm-editor {
|
||||
@apply h-auto relative !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
@apply overflow-visible !important;
|
||||
}
|
||||
}
|
||||
64
src-web/components/core/Editor/DiffViewer.tsx
Normal file
64
src-web/components/core/Editor/DiffViewer.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { yaml } from '@codemirror/lang-yaml';
|
||||
import { syntaxHighlighting } from '@codemirror/language';
|
||||
import { MergeView } from '@codemirror/merge';
|
||||
import { EditorView } from '@codemirror/view';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import './DiffViewer.css';
|
||||
import { readonlyExtensions, syntaxHighlightStyle } from './extensions';
|
||||
|
||||
interface Props {
|
||||
/** Original/previous version (left side) */
|
||||
original: string;
|
||||
/** Modified/current version (right side) */
|
||||
modified: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function DiffViewer({ original, modified, className }: Props) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const viewRef = useRef<MergeView | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
// Clean up previous instance
|
||||
viewRef.current?.destroy();
|
||||
|
||||
const sharedExtensions = [
|
||||
yaml(),
|
||||
syntaxHighlighting(syntaxHighlightStyle),
|
||||
...readonlyExtensions,
|
||||
EditorView.lineWrapping,
|
||||
];
|
||||
|
||||
viewRef.current = new MergeView({
|
||||
a: {
|
||||
doc: original,
|
||||
extensions: sharedExtensions,
|
||||
},
|
||||
b: {
|
||||
doc: modified,
|
||||
extensions: sharedExtensions,
|
||||
},
|
||||
parent: containerRef.current,
|
||||
collapseUnchanged: { margin: 2, minSize: 3 },
|
||||
highlightChanges: false,
|
||||
gutter: true,
|
||||
orientation: 'a-b',
|
||||
revertControls: undefined,
|
||||
});
|
||||
|
||||
return () => {
|
||||
viewRef.current?.destroy();
|
||||
viewRef.current = null;
|
||||
};
|
||||
}, [original, modified]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={classNames('cm-wrapper cm-multiline h-full w-full', className)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user