commit: connect api

This commit is contained in:
Nikita Galaiko 2023-03-29 16:11:41 +02:00
parent 7807296918
commit 831a9c606b
2 changed files with 115 additions and 22 deletions

View File

@ -1,2 +1,11 @@
import { invoke } from '@tauri-apps/api';
export { default as statuses } from './statuses';
export { default as activity } from './activity';
export const commit = (params: {
projectId: string;
message: string;
files: Array<string>;
push: boolean;
}) => invoke<boolean>('git_commit', params);

View File

@ -2,10 +2,16 @@
import type { PageData } from './$types';
import { collapsable } from '$lib/paths';
import { derived, writable } from 'svelte/store';
import { commit } from '$lib/git';
import DiffViewer from '$lib/components/DiffViewer.svelte';
import { error, success } from '$lib/toasts';
import { IconRotateClockwise } from '$lib/components/icons';
export let data: PageData;
const { statuses, diffs } = data;
const { statuses, diffs, user, api, projectId } = data;
let summary = '';
let description = '';
let selectedFiles = $statuses.map(({ path }) => path);
const selectedDiffPath = writable($statuses.at(0)?.path);
@ -14,14 +20,67 @@
([diffs, selectedDiffPath]) => diffs[selectedDiffPath]
);
const onCommit = (e: SubmitEvent) => {
const reset = () => {
summary = '';
description = '';
};
let isCommitting = false;
let isGeneratingCommitMessage = false;
const onCommit = async (e: SubmitEvent) => {
const form = e.target as HTMLFormElement;
const formData = new FormData(form);
const summary = formData.get('summary') as string;
const description = formData.get('description') as string;
const paths = formData.getAll('path') as string[];
// TODO
isCommitting = true;
commit({
projectId,
message: description.length > 0 ? `${summary}\n\n${description}` : summary,
files: paths,
push: false
})
.then(() => {
success('Commit successfull!');
reset();
})
.catch(() => {
error('Failed to commit');
})
.finally(() => {
isCommitting = false;
});
};
const onGenerateCommitMessage = async () => {
if ($user === undefined) return;
const partialDiff = Object.fromEntries(
Object.entries($diffs).filter(([key]) => selectedFiles.includes(key))
);
const diff = Object.values(partialDiff).join('\n').slice(0, 5000);
isGeneratingCommitMessage = true;
api.summarize
.commit($user.access_token, {
diff,
uid: projectId
})
.then((message) => {
if (message === undefined) return;
const firstNewLine = message.indexOf('\n');
summary = firstNewLine > -1 ? message.slice(0, firstNewLine) : message;
description = firstNewLine > -1 ? message.slice(firstNewLine + 1) : '';
})
.catch(() => {
error('Failed to generate commit message');
})
.finally(() => {
isGeneratingCommitMessage = false;
});
};
const onGroupCheckboxClick = (e: Event) => {
@ -33,8 +92,6 @@
}
};
let summary = '';
$: isEnabled = summary.length > 0 && selectedFiles.length > 0;
</script>
@ -47,10 +104,11 @@
<header class="flex w-full items-center py-2 px-4">
<input
type="checkbox"
class="cursor-pointer"
class="cursor-pointer disabled:opacity-50"
on:click={onGroupCheckboxClick}
checked={$statuses.length === selectedFiles.length}
indeterminate={$statuses.length > selectedFiles.length && selectedFiles.length > 0}
disabled={isCommitting || isGeneratingCommitMessage}
/>
<h1 class="m-auto flex">
<span class="w-full text-center">{$statuses.length} changed files</span>
@ -65,7 +123,8 @@
class="flex items-center gap-2 border-gb-700 bg-gb-900"
>
<input
class="ml-4 cursor-pointer py-2"
class="ml-4 cursor-pointer py-2 disabled:opacity-50"
disabled={isCommitting || isGeneratingCommitMessage}
name="path"
type="checkbox"
bind:group={selectedFiles}
@ -73,9 +132,10 @@
/>
<label class="flex w-full" for="path">
<button
disabled={isCommitting || isGeneratingCommitMessage}
on:click|preventDefault={() => ($selectedDiffPath = path)}
type="button"
class="h-full w-full py-2 pr-4 text-left font-mono "
class="h-full w-full py-2 pr-4 text-left font-mono disabled:opacity-50"
use:collapsable={{ value: path, separator: '/' }}
/>
</label>
@ -85,7 +145,8 @@
<input
name="summary"
class="rounded border border-gb-900 bg-gb-800 p-3"
class="rounded border border-gb-900 bg-gb-800 p-3 disabled:opacity-50"
disabled={isGeneratingCommitMessage || isCommitting}
type="text"
placeholder="Summary (required)"
bind:value={summary}
@ -94,25 +155,48 @@
<textarea
name="description"
class="rounded border border-gb-900 bg-gb-800 p-3"
disabled={isGeneratingCommitMessage || isCommitting}
class="rounded border border-gb-900 bg-gb-800 p-3 disabled:opacity-50"
rows="10"
placeholder="Description (optional)"
bind:value={description}
/>
<div class="flex justify-between">
<input
disabled={!isEnabled}
type="submit"
value="Commit changes"
class="rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
/>
{#if isCommitting}
<div
class="flex gap-1 rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
>
<IconRotateClockwise class="h-5 w-5 animate-spin" />
<span>Comitting...</span>
</div>
{:else}
<button
disabled={!isEnabled || isGeneratingCommitMessage}
type="submit"
class="rounded bg-[#2563EB] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
>
Commit changes
</button>
{/if}
<button
type="button"
class="rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg"
>
✨ Generate commit message
</button>
{#if isGeneratingCommitMessage}
<div
class="flex items-center gap-1 rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
>
<IconRotateClockwise class="h-5 w-5 animate-spin" />
<span>Generating commit message...</span>
</div>
{:else}
<button
type="button"
disabled={$user === undefined}
class="rounded bg-gradient-to-b from-[#623871] to-[#502E5C] py-2 px-4 text-lg disabled:cursor-not-allowed disabled:opacity-50"
on:click|preventDefault={onGenerateCommitMessage}
>
✨ Generate commit message
</button>
{/if}
</div>
</form>
</div>