Skip to content

Commit 9113e45

Browse files
wip
1 parent f236a51 commit 9113e45

17 files changed

+886
-32
lines changed
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
<script lang="ts">
2+
import { getEnableHighlight } from '$lib/context/enableHighlight.js';
3+
import { getEnableWrap } from '$lib/context/enableWrap.js';
4+
import { getOnAddWidgetClick } from '$lib/context/onAddWidgetClick.js';
5+
import { getWidget } from '$lib/context/widget.js';
6+
import {
7+
checkDiffLineIncludeChange,
8+
DiffLine,
9+
SplitSide,
10+
type DiffFile,
11+
type File
12+
} from '@git-diff-view/core';
13+
import {
14+
addContentBGName,
15+
addLineNumberBGName,
16+
delContentBGName,
17+
delLineNumberBGName,
18+
diffAsideWidthName,
19+
expandContentBGName,
20+
expandLineNumberColorName,
21+
plainContentBGName,
22+
plainLineNumberBGName,
23+
plainLineNumberColorName
24+
} from '@git-diff-view/utils';
25+
import DiffUnifiedAddWidget from './DiffUnifiedAddWidget.svelte';
26+
import DiffContent from './DiffContent.svelte';
27+
import { getEnableAddWidget } from '$lib/context/enableAddWidget.js';
28+
29+
interface Props {
30+
index: number;
31+
diffFile: DiffFile;
32+
lineNumber: number;
33+
}
34+
35+
let props: Props = $props();
36+
37+
const unifiedItem = $derived.by(() => props.diffFile.getUnifiedLine(props.index));
38+
39+
const enableWrap = $derived.by(getEnableWrap());
40+
41+
const widget = $derived.by(getWidget());
42+
43+
const onAddWidgetClick = $derived.by(getOnAddWidgetClick());
44+
45+
const enableHighlight = $derived.by(getEnableHighlight());
46+
47+
const enableAddWidget = $derived.by(getEnableAddWidget());
48+
49+
const currentItemHasHidden = $derived.by(() => unifiedItem?.isHidden);
50+
51+
const currentItemHasChange = $derived.by(() => checkDiffLineIncludeChange(unifiedItem?.diff));
52+
53+
const getCurrentSyntaxLine = () =>
54+
unifiedItem?.newLineNumber
55+
? props.diffFile.getNewSyntaxLine(unifiedItem?.newLineNumber || 0)
56+
: unifiedItem?.oldLineNumber
57+
? props.diffFile.getOldSyntaxLine(unifiedItem?.oldLineNumber || 0)
58+
: undefined;
59+
60+
let currentSyntaxLine = $state(getCurrentSyntaxLine());
61+
62+
const getCurrentPlainLine = () =>
63+
unifiedItem?.newLineNumber
64+
? props.diffFile.getNewPlainLine(unifiedItem?.newLineNumber || 0)
65+
: unifiedItem?.oldLineNumber
66+
? props.diffFile.getOldPlainLine(unifiedItem?.oldLineNumber || 0)
67+
: undefined;
68+
69+
let currentPlainLine = $state(getCurrentPlainLine());
70+
71+
let unSubscribe = { current: () => {} };
72+
73+
$effect(() => {
74+
unSubscribe?.current?.();
75+
76+
const init = () => {
77+
currentSyntaxLine = getCurrentSyntaxLine();
78+
currentPlainLine = getCurrentPlainLine();
79+
};
80+
81+
init();
82+
83+
unSubscribe.current = props.diffFile.subscribe(init);
84+
});
85+
86+
const onClickAddWidget = (lineNumber: number, side: SplitSide) => {
87+
widget.side = side;
88+
widget.lineNumber = lineNumber;
89+
};
90+
</script>
91+
92+
{#if !currentItemHasHidden}
93+
{#if currentItemHasChange}
94+
{#snippet renderOldLine(props: {
95+
index: number;
96+
lineNumber: number;
97+
rawLine: string;
98+
plainLine?: File['plainFile'][number];
99+
syntaxLine?: File['syntaxFile'][number];
100+
diffLine?: DiffLine;
101+
diffFile: DiffFile;
102+
enableWrap: boolean;
103+
enableAddWidget: boolean;
104+
enableHighlight: boolean;
105+
onOpenAddWidget: (lineNumber: number, side: SplitSide) => void;
106+
onAddWidgetClick?: (lineNumber: number, side: SplitSide) => void;
107+
})}
108+
<tr data-line={props.index} data-state="diff" class="diff-line group">
109+
<td
110+
class="diff-line-num sticky left-0 z-[1] w-[1%] min-w-[100px] select-none whitespace-nowrap pl-[10px] pr-[10px] text-right align-top"
111+
style={`
112+
color: var(${plainLineNumberColorName}),
113+
background-color: var(${delLineNumberBGName}),
114+
width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
115+
max-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
116+
min-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
117+
`}
118+
>
119+
{#if props.enableAddWidget}
120+
<DiffUnifiedAddWidget
121+
index={props.index - 1}
122+
lineNumber={props.lineNumber}
123+
diffFile={props.diffFile}
124+
side={SplitSide.old}
125+
onWidgetClick={props.onAddWidgetClick}
126+
onOpenAddWidget={props.onOpenAddWidget}
127+
/>
128+
{/if}
129+
<div class="flex">
130+
<span data-line-old-num={props.lineNumber} class="inline-block w-[50%]">
131+
{props.lineNumber}
132+
</span>
133+
<span class="w-[10px] shrink-0"></span>
134+
<span class="inline-block w-[50%]"></span>
135+
</div>
136+
</td>
137+
<td
138+
class="diff-line-content pr-[10px] align-top"
139+
style={`background-color: var(${delContentBGName}) `}
140+
>
141+
<DiffContent
142+
enableWrap={props.enableWrap}
143+
diffFile={props.diffFile}
144+
enableHighlight={props.enableHighlight}
145+
rawLine={props.rawLine}
146+
diffLine={props.diffLine}
147+
plainLine={props.plainLine}
148+
syntaxLine={props.syntaxLine}
149+
/>
150+
</td>
151+
</tr>
152+
{/snippet}
153+
{#snippet renderNewLine(props: {
154+
index: number;
155+
lineNumber: number;
156+
rawLine: string;
157+
plainLine?: File['plainFile'][number];
158+
syntaxLine?: File['syntaxFile'][number];
159+
diffLine?: DiffLine;
160+
diffFile: DiffFile;
161+
enableWrap: boolean;
162+
enableAddWidget: boolean;
163+
enableHighlight: boolean;
164+
onOpenAddWidget: (lineNumber: number, side: SplitSide) => void;
165+
onAddWidgetClick?: (lineNumber: number, side: SplitSide) => void;
166+
})}
167+
<tr data-line={props.index} data-state="diff" class="diff-line group">
168+
<td
169+
class="diff-line-num sticky left-0 z-[1] w-[1%] min-w-[100px] select-none whitespace-nowrap pl-[10px] pr-[10px] text-right align-top"
170+
style={`
171+
color: var(${plainLineNumberColorName}),
172+
background-color: var(${addLineNumberBGName}),
173+
width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
174+
max-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
175+
min-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2),
176+
`}
177+
>
178+
{#if props.enableAddWidget}
179+
<DiffUnifiedAddWidget
180+
index={props.index - 1}
181+
lineNumber={props.lineNumber}
182+
diffFile={props.diffFile}
183+
side={SplitSide.new}
184+
onWidgetClick={props.onAddWidgetClick}
185+
onOpenAddWidget={props.onOpenAddWidget}
186+
/>
187+
{/if}
188+
<div class="flex">
189+
<span class="inline-block w-[50%]"></span>
190+
<span class="w-[10px] shrink-0"></span>
191+
<span data-line-new-num={props.lineNumber} class="inline-block w-[50%]">
192+
{props.lineNumber}
193+
</span>
194+
</div>
195+
</td>
196+
<td
197+
class="diff-line-content pr-[10px] align-top"
198+
style={` background-color: var(${addContentBGName}) `}
199+
>
200+
<DiffContent
201+
enableWrap={props.enableWrap}
202+
diffFile={props.diffFile}
203+
enableHighlight={props.enableHighlight}
204+
rawLine={props.rawLine}
205+
diffLine={props.diffLine}
206+
plainLine={props.plainLine}
207+
syntaxLine={props.syntaxLine}
208+
/>
209+
</td>
210+
</tr>
211+
{/snippet}
212+
{#if unifiedItem.oldLineNumber}
213+
{@render renderOldLine({
214+
index: props.lineNumber,
215+
enableWrap: enableWrap,
216+
diffFile: props.diffFile,
217+
rawLine: unifiedItem.value || '',
218+
diffLine: unifiedItem.diff,
219+
plainLine: currentPlainLine,
220+
syntaxLine: currentSyntaxLine,
221+
enableHighlight: enableHighlight,
222+
enableAddWidget: enableAddWidget,
223+
lineNumber: unifiedItem.oldLineNumber || 0,
224+
onOpenAddWidget: onClickAddWidget,
225+
onAddWidgetClick
226+
})}
227+
{/if}
228+
{#if unifiedItem.newLineNumber}
229+
{@render renderNewLine({
230+
index: props.lineNumber,
231+
enableWrap: enableWrap,
232+
diffFile: props.diffFile,
233+
rawLine: unifiedItem.value || '',
234+
diffLine: unifiedItem.diff,
235+
plainLine: currentPlainLine,
236+
syntaxLine: currentSyntaxLine,
237+
enableHighlight: enableHighlight,
238+
enableAddWidget: enableAddWidget,
239+
lineNumber: unifiedItem.newLineNumber || 0,
240+
onOpenAddWidget: onClickAddWidget,
241+
onAddWidgetClick
242+
})}
243+
{/if}
244+
{:else}
245+
<tr
246+
data-line={props.lineNumber}
247+
data-state={unifiedItem.diff ? 'diff' : 'plain'}
248+
class="diff-line group"
249+
>
250+
<td
251+
class="diff-line-num sticky left-0 z-[1] w-[1%] min-w-[100px] select-none whitespace-nowrap pl-[10px] pr-[10px] text-right align-top"
252+
style={`
253+
color: var(${unifiedItem?.diff ? plainLineNumberColorName : expandLineNumberColorName}),
254+
background-color: ${
255+
unifiedItem?.diff ? `var(${plainLineNumberBGName})` : `var(${expandContentBGName})`
256+
},
257+
width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2)
258+
max-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2)
259+
min-width: calc(calc(var(${diffAsideWidthName}) + 5px) * 2
260+
`}
261+
>
262+
{#if enableAddWidget && unifiedItem?.diff}
263+
<DiffUnifiedAddWidget
264+
index={props.index}
265+
diffFile={props.diffFile}
266+
lineNumber={unifiedItem?.newLineNumber || 0}
267+
side={SplitSide.new}
268+
onOpenAddWidget={onClickAddWidget}
269+
onWidgetClick={onAddWidgetClick}
270+
/>
271+
{/if}
272+
<div class="flex opacity-[0.5]">
273+
<span data-line-old-num={unifiedItem?.oldLineNumber || 0} class="inline-block w-[50%]">
274+
{unifiedItem?.oldLineNumber || 0}
275+
</span>
276+
<span class="w-[10px] shrink-0"></span>
277+
<span data-line-new-num={unifiedItem?.newLineNumber || 0} class="inline-block w-[50%]">
278+
{unifiedItem?.newLineNumber || 0}
279+
</span>
280+
</div>
281+
</td>
282+
<td
283+
class="diff-line-content pr-[10px] align-top"
284+
style={`
285+
background-color: ${
286+
unifiedItem?.diff ? `var(${plainContentBGName})` : `var(${expandContentBGName})`
287+
}
288+
`}
289+
>
290+
<DiffContent
291+
enableWrap={!!enableWrap}
292+
diffFile={props.diffFile}
293+
enableHighlight={!!enableHighlight}
294+
rawLine={unifiedItem?.value || ''}
295+
diffLine={unifiedItem?.diff}
296+
plainLine={currentPlainLine}
297+
syntaxLine={currentSyntaxLine}
298+
/>
299+
</td>
300+
</tr>
301+
{/if}
302+
{/if}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<script lang="ts">
2+
import { getExtend } from '$lib/context/extend.js';
3+
import { getRenderExtend } from '$lib/context/renderExtend.js';
4+
import { useDomWidth } from '$lib/hooks/useDomWidth.svelte.js';
5+
import { SplitSide, type DiffFile } from '@git-diff-view/core';
6+
7+
interface Props {
8+
index: number;
9+
diffFile: DiffFile;
10+
lineNumber: number;
11+
}
12+
13+
let props: Props = $props();
14+
15+
const extendData = $derived.by(getExtend());
16+
17+
const renderExtend = $derived.by(getRenderExtend());
18+
19+
const unifiedItem = $derived.by(() => props.diffFile.getUnifiedLine(props.index));
20+
21+
const oldExtend = $derived.by(() => extendData?.oldFile?.[unifiedItem?.oldLineNumber || -1]);
22+
23+
const newExtend = $derived.by(() => extendData?.newFile?.[unifiedItem?.newLineNumber || -1]);
24+
25+
const currentIsHidden = $derived.by(() => unifiedItem.isHidden);
26+
27+
const currentIsShow = $derived.by(() =>
28+
Boolean((oldExtend || newExtend) && currentIsHidden && renderExtend)
29+
);
30+
31+
const width = $derived.by(
32+
useDomWidth({
33+
selector: () => '.unified-diff-table-wrapper',
34+
enable: () => currentIsShow
35+
})
36+
);
37+
</script>
38+
39+
{#if currentIsShow}
40+
<tr
41+
data-line={`${props.lineNumber}-extend`}
42+
data-state="extend"
43+
class="diff-line diff-line-extend"
44+
>
45+
<td class="diff-line-extend-content p-0 align-top" colspan={2}>
46+
<div class="diff-line-extend-wrapper sticky left-0 z-[1]" style={`width: ${width}px `}>
47+
{#if width && oldExtend && !!renderExtend}
48+
{@render renderExtend({
49+
diffFile: props.diffFile,
50+
side: SplitSide.old,
51+
data: oldExtend.data,
52+
lineNumber: unifiedItem.oldLineNumber || 0,
53+
onUpdate: () => props.diffFile.notifyAll()
54+
})}
55+
{/if}
56+
{#if width && newExtend && !!renderExtend}
57+
{@render renderExtend({
58+
diffFile: props.diffFile,
59+
side: SplitSide.new,
60+
data: newExtend.data,
61+
lineNumber: unifiedItem.newLineNumber || 0,
62+
onUpdate: () => props.diffFile.notifyAll()
63+
})}
64+
{/if}
65+
</div>
66+
</td>
67+
</tr>
68+
{/if}

0 commit comments

Comments
 (0)