Merge pull request #1184 from gitbutlerapp/refactor

extract CommitDialog
This commit is contained in:
Nikita Galaiko 2023-09-11 08:34:15 +02:00 committed by GitHub
commit bc7a18c4ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 166 additions and 140 deletions

View File

@ -1,9 +1,7 @@
<script lang="ts">
import * as toasts from '$lib/toasts';
import { userStore } from '$lib/stores/user';
import type { BaseBranch, Branch, File } from '$lib/vbranches/types';
import type { BaseBranch, Branch } from '$lib/vbranches/types';
import { getContext, onMount } from 'svelte';
import { IconAISparkles } from '$lib/icons';
import { Button, Link, Modal, Tooltip } from '$lib/components';
import IconKebabMenu from '$lib/icons/IconKebabMenu.svelte';
import CommitCard from './CommitCard.svelte';
@ -15,7 +13,6 @@
import { quintOut } from 'svelte/easing';
import { crossfade, fade } from 'svelte/transition';
import { flip } from 'svelte/animate';
import { invoke } from '@tauri-apps/api/tauri';
import type { getCloudApiClient } from '$lib/api/cloud/api';
import Scrollbar from '$lib/components/Scrollbar.svelte';
import IconNewBadge from '$lib/icons/IconNewBadge.svelte';
@ -30,6 +27,7 @@
import IconButton from '$lib/components/IconButton.svelte';
import IconBackspace from '$lib/icons/IconBackspace.svelte';
import { sortLikeFileTree } from '$lib/vbranches/filetree';
import CommitDialog from './CommitDialog.svelte';
const [send, receive] = crossfade({
duration: (d) => Math.sqrt(d * 200),
@ -62,16 +60,12 @@
const user = userStore;
const userSettings = getContext<SettingsStore>(SETTINGS_CONTEXT);
let commitMessage: string;
$: remoteCommits = branch.commits.filter((c) => c.isRemote);
$: localCommits = branch.commits.filter((c) => !c.isRemote);
$: messageRows = Math.min(Math.max(commitMessage ? commitMessage.split('\n').length : 0, 1), 10);
let allExpanded: boolean | undefined;
let isPushing = false;
let meatballButton: HTMLDivElement;
let textAreaInput: HTMLTextAreaElement;
let viewport: Element;
let contents: Element;
let rsViewport: HTMLElement;
@ -82,10 +76,6 @@
const dzType = 'text/hunk';
const laneWidthKey = 'laneWidth:';
function commit() {
branchController.commitBranch(branch.id, commitMessage);
}
function push() {
if (localCommits[0]?.id) {
isPushing = true;
@ -142,58 +132,6 @@
commitDialogShown = false;
}
export function git_get_config(params: { key: string }) {
return invoke<string>('git_get_global_config', params);
}
let annotateCommits = true;
function checkCommitsAnnotated() {
git_get_config({ key: 'gitbutler.utmostDiscretion' }).then((value) => {
annotateCommits = value ? value === '0' : true;
});
}
$: checkCommitsAnnotated();
let isGeneratingCommigMessage = false;
function trimNonLetters(input: string): string {
const regex = /^[^a-zA-Z]+|[^a-zA-Z]+$/g;
const trimmedString = input.replace(regex, '');
return trimmedString;
}
async function generateCommitMessage(files: File[]) {
const diff = files
.map((f) => f.hunks)
.flat()
.map((h) => h.diff)
.flat()
.join('\n')
.slice(0, 5000);
if ($user === null) return;
isGeneratingCommigMessage = true;
cloud.summarize
.commit($user.access_token, {
diff,
uid: projectId
})
.then(({ message }) => {
const firstNewLine = message.indexOf('\n');
const summary = firstNewLine > -1 ? message.slice(0, firstNewLine).trim() : message;
const description = firstNewLine > -1 ? message.slice(firstNewLine + 1).trim() : '';
commitMessage = trimNonLetters(
description.length > 0 ? `${summary}\n\n${description}` : summary
);
})
.catch(() => {
toasts.error('Failed to generate commit message');
})
.finally(() => {
isGeneratingCommigMessage = false;
});
}
// We have to create this manually for now.
// TODO: Use document.body.addEventListener to avoid having to use backdrop
let popupMenu = new BranchLanePopupMenu({
@ -340,82 +278,15 @@
</div>
{#if commitDialogShown}
<div
class="flex w-full flex-col border-t border-light-400 bg-light-200 dark:border-dark-400 dark:bg-dark-800"
transition:slide={{ duration: 150 }}
>
{#if annotateCommits}
<div class="bg-blue-400 p-2 text-sm text-white">
GitButler will be the committer of this commit.
<a
target="_blank"
rel="noreferrer"
class="font-bold"
href="https://docs.gitbutler.com/features/virtual-branches/committer-mark"
>Learn more</a
>
</div>
{/if}
<div class="flex items-center">
<textarea
bind:this={textAreaInput}
bind:value={commitMessage}
on:dblclick|stopPropagation
class="flex-grow cursor-text resize-none overflow-x-auto overflow-y-auto border border-white bg-white p-2 font-mono text-dark-700 outline-none focus:border-purple-600 focus:ring-0 dark:border-dark-500 dark:bg-dark-700 dark:text-light-400"
placeholder="Your commit message here"
rows={messageRows}
required
/>
</div>
<div class="flex flex-grow justify-end gap-2 p-3 px-5">
<div>
{#if cloudEnabled && $user}
<Button
disabled={isGeneratingCommigMessage}
tabindex={-1}
kind="outlined"
class="text-light-500"
height="small"
id="generate-ai-message"
icon={IconAISparkles}
loading={isGeneratingCommigMessage}
on:click={() => generateCommitMessage(branch.files)}
>
<span class="text-light-700">Generate message</span>
</Button>
{:else}
<Tooltip
label="Summary generation requres that you are logged in and have cloud sync enabled for the project"
>
<Button
disabled={true}
tabindex={-1}
kind="outlined"
class="text-light-500"
height="small"
icon={IconAISparkles}
loading={isGeneratingCommigMessage}
>
<span class="text-light-700">Generate message</span>
</Button>
</Tooltip>
{/if}
</div>
<Button
class="w-20"
height="small"
color="purple"
id="commit-to-branch"
on:click={() => {
if (commitMessage) commit();
commitMessage = '';
commitDialogShown = false;
}}
>
Commit
</Button>
</div>
</div>
<CommitDialog
on:close={() => (commitDialogShown = false)}
{projectId}
{branchController}
{branch}
{cloudEnabled}
{cloud}
user={$user}
/>
{/if}
</div>
</div>

View File

@ -0,0 +1,155 @@
<script lang="ts">
import * as toasts from '$lib/toasts';
import { slide } from 'svelte/transition';
import { invoke } from '@tauri-apps/api/tauri';
import type { BranchController } from '$lib/vbranches/branchController';
import type { Branch, File } from '$lib/vbranches/types';
import type { getCloudApiClient } from '$lib/api/cloud/api';
import type { User } from '$lib/api/cloud';
import { Button, Tooltip } from '$lib/components';
import { IconAISparkles } from '$lib/icons';
import { createEventDispatcher } from 'svelte';
export let projectId: string;
export let branchController: BranchController;
export let branch: Branch;
export let cloudEnabled: boolean;
export let cloud: ReturnType<typeof getCloudApiClient>;
export let user: User | null;
const dispatch = createEventDispatcher<{ close: null }>();
let commitMessage: string;
$: messageRows = Math.min(Math.max(commitMessage ? commitMessage.split('\n').length : 0, 1), 10);
function commit() {
branchController.commitBranch(branch.id, commitMessage);
}
export function git_get_config(params: { key: string }) {
return invoke<string>('git_get_global_config', params);
}
let annotateCommits = true;
function checkCommitsAnnotated() {
git_get_config({ key: 'gitbutler.utmostDiscretion' }).then((value) => {
annotateCommits = value ? value === '0' : true;
});
}
$: checkCommitsAnnotated();
let isGeneratingCommigMessage = false;
function trimNonLetters(input: string): string {
const regex = /^[^a-zA-Z]+|[^a-zA-Z]+$/g;
const trimmedString = input.replace(regex, '');
return trimmedString;
}
async function generateCommitMessage(files: File[]) {
const diff = files
.map((f) => f.hunks)
.flat()
.map((h) => h.diff)
.flat()
.join('\n')
.slice(0, 5000);
if (user === null) return;
isGeneratingCommigMessage = true;
cloud.summarize
.commit(user.access_token, {
diff,
uid: projectId
})
.then(({ message }) => {
const firstNewLine = message.indexOf('\n');
const summary = firstNewLine > -1 ? message.slice(0, firstNewLine).trim() : message;
const description = firstNewLine > -1 ? message.slice(firstNewLine + 1).trim() : '';
commitMessage = trimNonLetters(
description.length > 0 ? `${summary}\n\n${description}` : summary
);
})
.catch(() => {
toasts.error('Failed to generate commit message');
})
.finally(() => {
isGeneratingCommigMessage = false;
});
}
</script>
<div
class="flex w-full flex-col border-t border-light-400 bg-light-200 dark:border-dark-400 dark:bg-dark-800"
transition:slide={{ duration: 150 }}
>
{#if annotateCommits}
<div class="bg-blue-400 p-2 text-sm text-white">
GitButler will be the committer of this commit.
<a
target="_blank"
rel="noreferrer"
class="font-bold"
href="https://docs.gitbutler.com/features/virtual-branches/committer-mark">Learn more</a
>
</div>
{/if}
<div class="flex items-center">
<textarea
bind:value={commitMessage}
on:dblclick|stopPropagation
class="flex-grow cursor-text resize-none overflow-x-auto overflow-y-auto border border-white bg-white p-2 font-mono text-dark-700 outline-none focus:border-purple-600 focus:ring-0 dark:border-dark-500 dark:bg-dark-700 dark:text-light-400"
placeholder="Your commit message here"
rows={messageRows}
required
/>
</div>
<div class="flex flex-grow justify-end gap-2 p-3 px-5">
<div>
{#if cloudEnabled && user}
<Button
disabled={isGeneratingCommigMessage}
tabindex={-1}
kind="outlined"
class="text-light-500"
height="small"
id="generate-ai-message"
icon={IconAISparkles}
loading={isGeneratingCommigMessage}
on:click={() => generateCommitMessage(branch.files)}
>
<span class="text-light-700">Generate message</span>
</Button>
{:else}
<Tooltip
label="Summary generation requres that you are logged in and have cloud sync enabled for the project"
>
<Button
disabled={true}
tabindex={-1}
kind="outlined"
class="text-light-500"
height="small"
icon={IconAISparkles}
loading={isGeneratingCommigMessage}
>
<span class="text-light-700">Generate message</span>
</Button>
</Tooltip>
{/if}
</div>
<Button
class="w-20"
height="small"
color="purple"
id="commit-to-branch"
on:click={() => {
if (commitMessage) commit();
commitMessage = '';
dispatch('close');
}}
>
Commit
</Button>
</div>
</div>