mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-11-23 03:26:36 +03:00
Make drag & drop behave even better
This commit is contained in:
parent
43309e7849
commit
4fa1f66976
@ -74,7 +74,7 @@
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"svelte": "~3.55.1",
|
||||
"svelte-check": "^3.0.1",
|
||||
"svelte-dnd-action": "github:gitbutlerapp/svelte-dnd-action#daeabaf6b34207c4ff6c487c0eb090b4bc6032c5",
|
||||
"svelte-dnd-action": "github:gitbutlerapp/svelte-dnd-action#1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3",
|
||||
"svelte-floating-ui": "^1.5.2",
|
||||
"svelte-french-toast": "^1.0.3",
|
||||
"svelte-loadable-store": "^1.2.3",
|
||||
|
@ -176,8 +176,8 @@ devDependencies:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.3(postcss-load-config@4.0.1)(postcss@8.4.21)(svelte@3.55.1)
|
||||
svelte-dnd-action:
|
||||
specifier: github:gitbutlerapp/svelte-dnd-action#daeabaf6b34207c4ff6c487c0eb090b4bc6032c5
|
||||
version: github.com/gitbutlerapp/svelte-dnd-action/daeabaf6b34207c4ff6c487c0eb090b4bc6032c5(svelte@3.55.1)
|
||||
specifier: github:gitbutlerapp/svelte-dnd-action#1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3
|
||||
version: github.com/gitbutlerapp/svelte-dnd-action/1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3(svelte@3.55.1)
|
||||
svelte-floating-ui:
|
||||
specifier: ^1.5.2
|
||||
version: 1.5.2
|
||||
@ -4290,9 +4290,9 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
github.com/gitbutlerapp/svelte-dnd-action/daeabaf6b34207c4ff6c487c0eb090b4bc6032c5(svelte@3.55.1):
|
||||
resolution: {tarball: https://codeload.github.com/gitbutlerapp/svelte-dnd-action/tar.gz/daeabaf6b34207c4ff6c487c0eb090b4bc6032c5}
|
||||
id: github.com/gitbutlerapp/svelte-dnd-action/daeabaf6b34207c4ff6c487c0eb090b4bc6032c5
|
||||
github.com/gitbutlerapp/svelte-dnd-action/1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3(svelte@3.55.1):
|
||||
resolution: {tarball: https://codeload.github.com/gitbutlerapp/svelte-dnd-action/tar.gz/1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3}
|
||||
id: github.com/gitbutlerapp/svelte-dnd-action/1e2aa65f5f8f6cdfbeaa88c37e96eef93857c3b3
|
||||
name: svelte-dnd-action
|
||||
version: 0.9.22
|
||||
peerDependencies:
|
||||
|
@ -7,13 +7,13 @@
|
||||
export let data: PageData;
|
||||
let branches = data.branchData;
|
||||
|
||||
// We only want the tray to update on finalized changes.
|
||||
function onFinalize(e: CustomEvent<Branch[]>) {
|
||||
branches = e.detail;
|
||||
function handleNewBranch(e: CustomEvent<Branch[]>) {
|
||||
branches.push(...e.detail);
|
||||
branches = branches;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex max-w-full">
|
||||
<div class="flex w-full max-w-full">
|
||||
<Tray bind:branches />
|
||||
<Board {branches} on:finalize={onFinalize} />
|
||||
<Board {branches} on:newBranch={handleNewBranch} />
|
||||
</div>
|
||||
|
@ -18,10 +18,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function handleNewBranch(e: CustomEvent<Branch[]>) {
|
||||
branches.push(...e.detail);
|
||||
}
|
||||
|
||||
function handleEmpty() {
|
||||
const emptyIndex = branches.findIndex((item) => !item.files || item.files.length == 0);
|
||||
if (emptyIndex != -1) {
|
||||
@ -32,7 +28,7 @@
|
||||
|
||||
<div
|
||||
id="branch-lanes"
|
||||
class="flex max-w-full flex-shrink flex-grow snap-x items-start gap-x-4 overflow-x-auto overflow-y-hidden bg-light-800 p-4 dark:bg-dark-700"
|
||||
class="flex max-w-full flex-shrink flex-grow items-start gap-x-4 overflow-x-auto overflow-y-hidden bg-light-800 p-4 dark:bg-dark-700"
|
||||
use:dndzone={{
|
||||
items: branches,
|
||||
types: ['branch'],
|
||||
@ -46,9 +42,9 @@
|
||||
on:finalize={handleDndEvent}
|
||||
>
|
||||
{#each branches.filter((c) => c.active) as { id, name, files, description } (id)}
|
||||
<Lane {name} {description} bind:files on:empty={handleEmpty} />
|
||||
<Lane {name} {description} {files} on:empty={handleEmpty} />
|
||||
{/each}
|
||||
<NewBranchDropZone on:finalize={handleNewBranch} />
|
||||
<NewBranchDropZone on:newBranch />
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import { flip } from 'svelte/animate';
|
||||
import { dndzone } from 'svelte-dnd-action';
|
||||
import type { DndEvent } from 'svelte-dnd-action/typings';
|
||||
import { File, Hunk } from './types';
|
||||
@ -41,6 +40,7 @@
|
||||
if (files.length == 0) {
|
||||
dispatch('empty');
|
||||
}
|
||||
files = files;
|
||||
}
|
||||
|
||||
function updateTextArea(): void {
|
||||
@ -79,7 +79,7 @@
|
||||
on:finalize={handleDndEvent}
|
||||
>
|
||||
{#each files.filter((x) => x.hunks) as file, idx (file.id)}
|
||||
<FileCard bind:file on:empty={handleEmpty} />
|
||||
<FileCard filepath={file.path} bind:hunks={file.hunks} on:empty={handleEmpty} />
|
||||
{/each}
|
||||
<div
|
||||
data-dnd-ignore
|
||||
|
@ -1,23 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { dndzone } from 'svelte-dnd-action';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { formatDistanceToNow, compareDesc } from 'date-fns';
|
||||
import type { DndEvent } from 'svelte-dnd-action/typings';
|
||||
import type { File, Hunk } from './types';
|
||||
import type { Hunk } from './types';
|
||||
import { Differ } from '$lib/components';
|
||||
import { line, type DiffArray } from '$lib/diff';
|
||||
import { diff } from '$lib';
|
||||
|
||||
export let file: File;
|
||||
export let filepath: string;
|
||||
export let hunks: Hunk[];
|
||||
let zoneEl: HTMLElement;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let expanded = true;
|
||||
|
||||
function handleDndEvent(e: CustomEvent<DndEvent<Hunk>>) {
|
||||
file.hunks = e.detail.items;
|
||||
file.hunks.sort((itemA, itemB) => compareDesc(itemA.modifiedAt, itemB.modifiedAt));
|
||||
if (e.type == 'finalize' && file.hunks.length == 0) dispatch('empty');
|
||||
hunks = e.detail.items;
|
||||
hunks.sort((itemA, itemB) => compareDesc(itemA.modifiedAt, itemB.modifiedAt));
|
||||
if (e.type == 'finalize' && hunks.length == 0) dispatch('empty');
|
||||
hunks = hunks;
|
||||
}
|
||||
|
||||
function diffStringToDiffArray(diffStr: string): DiffArray {
|
||||
@ -51,9 +52,9 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<div
|
||||
class="flex-grow overflow-hidden text-ellipsis whitespace-nowrap font-bold"
|
||||
title={file.path}
|
||||
title={filepath}
|
||||
>
|
||||
{file.path}
|
||||
{filepath}
|
||||
</div>
|
||||
<div
|
||||
on:click={() => (expanded = !expanded)}
|
||||
@ -80,18 +81,19 @@
|
||||
|
||||
<div
|
||||
class="hunk-change-container flex flex-col gap-2 rounded"
|
||||
bind:this={zoneEl}
|
||||
use:dndzone={{
|
||||
items: file.hunks,
|
||||
items: hunks,
|
||||
zoneTabIndex: -1,
|
||||
autoAriaDisabled: true,
|
||||
types: ['hunk', file.path],
|
||||
receives: [file.path]
|
||||
types: ['hunk', filepath],
|
||||
receives: [filepath]
|
||||
}}
|
||||
on:consider={handleDndEvent}
|
||||
on:finalize={handleDndEvent}
|
||||
>
|
||||
{#if expanded}
|
||||
{#each file.hunks || [] as hunk (hunk.id)}
|
||||
{#each hunks || [] as hunk (hunk.id)}
|
||||
<div
|
||||
class="changed-hunk flex w-full flex-col gap-1 rounded bg-light-700 p-2 text-dark-100 dark:bg-dark-600 dark:text-light-400"
|
||||
>
|
||||
|
@ -9,7 +9,6 @@
|
||||
let items: Branch[] = [];
|
||||
|
||||
function handleDndFinalize(e: CustomEvent<DndEvent<Branch | File | Hunk>>) {
|
||||
console.log(e);
|
||||
const newItems = e.detail.items;
|
||||
const branchItems = newItems.filter((item) => item instanceof Branch) as Branch[];
|
||||
|
||||
@ -24,7 +23,7 @@
|
||||
}
|
||||
|
||||
if (e.type == 'finalize') {
|
||||
dispatch('finalize', branchItems);
|
||||
dispatch('newBranch', branchItems);
|
||||
items = [];
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user