Make drag & drop behave even better

This commit is contained in:
Mattias Granlund 2023-06-19 16:41:29 +01:00
parent 43309e7849
commit 4fa1f66976
7 changed files with 32 additions and 35 deletions

View File

@ -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",

View File

@ -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:

View File

@ -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>

View File

@ -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">

View File

@ -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

View File

@ -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"
>

View File

@ -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;
}