mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-09-11 12:25:42 +03:00
Add DiffViewer component and file selection
Enhanced the commit page by adding the DiffViewer component and implementing file selection functionality for the commit message generation. Users can now view diffs per file before committing.
This commit is contained in:
parent
69df2d0408
commit
41d2893fd9
52
src/lib/components/DiffViewer.svelte
Normal file
52
src/lib/components/DiffViewer.svelte
Normal file
@ -0,0 +1,52 @@
|
||||
<script lang="ts">
|
||||
import { create } from '$lib/components/CodeViewer/CodeHighlighter';
|
||||
|
||||
export let diff: string;
|
||||
export let path: string;
|
||||
|
||||
const sanitize = (text: string) => {
|
||||
var element = document.createElement('div');
|
||||
element.innerText = text;
|
||||
return element.innerHTML;
|
||||
};
|
||||
|
||||
let currentDiff = '';
|
||||
let middleDiff = '';
|
||||
let currentOffset = 0;
|
||||
|
||||
$: if (diff) {
|
||||
middleDiff = '';
|
||||
currentDiff = '';
|
||||
currentOffset = 0;
|
||||
let lineClass = '';
|
||||
|
||||
let doc = create(diff, path);
|
||||
doc.highlightRange(0, diff.length, (text, style) => {
|
||||
middleDiff += style ? `<span class=${style}>${sanitize(text)}</span>` : sanitize(text);
|
||||
});
|
||||
|
||||
let diffLines = middleDiff.split('<br>');
|
||||
diffLines.forEach((line, index) => {
|
||||
lineClass = 'lineContext bg-zinc-800';
|
||||
if (index < 4) {
|
||||
lineClass = 'lineDiff bg-zinc-900 text-zinc-500';
|
||||
} else if (line.slice(0, 2) == '@@') {
|
||||
lineClass = 'lineSplit bg-blue-900';
|
||||
} else if (line.slice(0, 1) == '+') {
|
||||
if (!line.includes('+++')) {
|
||||
lineClass = 'lineSplit bg-green-900';
|
||||
}
|
||||
} else if (line.slice(0, 1) == '-') {
|
||||
if (!line.includes('---')) {
|
||||
lineClass = 'lineSplit bg-red-900';
|
||||
}
|
||||
}
|
||||
currentDiff += `<div class="${lineClass}">`;
|
||||
currentDiff += line;
|
||||
currentDiff += '</div>';
|
||||
currentOffset += line.length;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<pre>{@html currentDiff}</pre>
|
@ -6,6 +6,7 @@
|
||||
import toast from 'svelte-french-toast';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { toHumanBranchName } from '$lib/branch';
|
||||
import DiffViewer from '$lib/components/DiffViewer.svelte';
|
||||
|
||||
const api = Api({ fetch });
|
||||
|
||||
@ -43,6 +44,8 @@
|
||||
commitMessage = '';
|
||||
commitSubject = '';
|
||||
filesSelectedForCommit = [];
|
||||
currentDiff = '';
|
||||
currentPath = '';
|
||||
isLoaded = false;
|
||||
});
|
||||
}
|
||||
@ -65,10 +68,20 @@
|
||||
const getBranch = (params: { projectId: string }) => invoke<string>('git_branch', params);
|
||||
|
||||
let gitBranch = <string | undefined>undefined;
|
||||
let gitDiff = <string | undefined>undefined;
|
||||
let gitDiff = <Record<string, string> | undefined>undefined;
|
||||
let generatedMessage = <string | undefined>undefined;
|
||||
let isLoaded = false;
|
||||
|
||||
let currentPath = '';
|
||||
let currentDiff = '';
|
||||
|
||||
function selectPath(path) {
|
||||
if (gitDiff[path]) {
|
||||
currentPath = path;
|
||||
currentDiff = gitDiff[path];
|
||||
}
|
||||
}
|
||||
|
||||
$: if ($project) {
|
||||
if (!isLoaded) {
|
||||
getBranch({ projectId: $project?.id }).then((branch) => {
|
||||
@ -91,10 +104,8 @@
|
||||
const partialDiff = Object.fromEntries(
|
||||
Object.entries(gitDiff).filter(([key]) => filesSelectedForCommit.includes(key))
|
||||
);
|
||||
console.log(partialDiff);
|
||||
// convert to string
|
||||
const diff = Object.values(partialDiff).join('\n').slice(0, 5000); // limit for summary
|
||||
console.log(diff);
|
||||
|
||||
placeholderMessage = 'Summarizing changes...';
|
||||
generatedMessage = 'loading';
|
||||
@ -160,9 +171,11 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="changed-files-list-container mt-2 mb-4">
|
||||
<div class="changed-files-list rounded border font-mono text-zinc-900 border-t-[0.5px] border-r-[0.5px] border-b-[0.5px] border-l-[0.5px] border-gb-700 bg-gb-900">
|
||||
<div
|
||||
class="changed-files-list rounded border font-mono text-zinc-900 border-t-[0.5px] border-r-[0.5px] border-b-[0.5px] border-l-[0.5px] border-gb-700 bg-gb-900"
|
||||
>
|
||||
<div
|
||||
class="mb-2 flex flex-row space-x-2 rounded-t border-b border-b-gb-750 bg-gb-800 p-2 text-zinc-200"
|
||||
>
|
||||
@ -173,20 +186,28 @@
|
||||
<ul class="w-80 truncate px-2 pb-2">
|
||||
{#each $filesStatus as activity}
|
||||
<li class="list-none text-zinc-300">
|
||||
<input
|
||||
type="checkbox"
|
||||
on:click={showMessage}
|
||||
bind:group={filesSelectedForCommit}
|
||||
value={activity.path}
|
||||
/>
|
||||
{activity.status.slice(0, 1)}
|
||||
{shortPath(activity.path)}
|
||||
<div class="flex flex-row space-x-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
on:click={showMessage}
|
||||
bind:group={filesSelectedForCommit}
|
||||
value={activity.path}
|
||||
/>
|
||||
<div>{activity.status.slice(0, 1)}</div>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="cursor-pointer {currentPath == activity.path ? 'text-white' : ''}"
|
||||
on:click={selectPath(activity.path)}
|
||||
>
|
||||
{shortPath(activity.path)}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="commit-input-container" transition:slide={{ duration: 150 }}>
|
||||
<h3 class="mb-2 text-base font-semibold text-zinc-300">Commit Message</h3>
|
||||
<input
|
||||
@ -222,8 +243,9 @@
|
||||
>
|
||||
{/if}
|
||||
{#if !generatedMessage}
|
||||
<a class="cursor-pointer rounded bg-green-800 p-2 text-zinc-50 bg-gradient-to-b from-[#623871] to-[#502E5C] shadow" on:click={fetchCommitMessage}
|
||||
>✨ Generate commit message</a
|
||||
<a
|
||||
class="cursor-pointer rounded bg-green-800 p-2 text-zinc-50 bg-gradient-to-b from-[#623871] to-[#502E5C] shadow"
|
||||
on:click={fetchCommitMessage}>✨ Generate commit message</a
|
||||
>
|
||||
{:else if generatedMessage == 'loading'}
|
||||
<div class="flex flex-col">
|
||||
@ -238,16 +260,12 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="h-full max-h-screen flex-grow overflow-auto p-2 h-100">
|
||||
{#if gitDiff}
|
||||
{#each Object.entries(gitDiff) as [key, value]}
|
||||
{#if key}
|
||||
<div class="p-2">{key}</div>
|
||||
<pre class="bg-zinc-900 p-2">{value}</pre>
|
||||
{/if}
|
||||
{/each}
|
||||
{#if currentDiff}
|
||||
<DiffViewer diff={currentDiff} path={currentPath} />
|
||||
{:else}
|
||||
<div class="text-zinc-400 text-center text-lg p-20">Select a file to view changes.</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- commit message -->
|
||||
|
Loading…
Reference in New Issue
Block a user