From 45c4240e49c2738b6f6b545d5c9e1dd80cec3915 Mon Sep 17 00:00:00 2001 From: Patertuck Date: Sat, 29 Nov 2025 11:08:32 +0100 Subject: [PATCH 1/6] try 1 --- src/routes/+page.svelte | 150 ++++++++++++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 21 deletions(-) diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index f7bb50f..59881ae 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -9,6 +9,7 @@ let draggedImage: TierImage | null = null; let draggedFrom: SourceType | null = null; + let activeDropTarget: { tier: SourceType; index: number } | null = null; function handleUpload(event: Event) { const input = event.target as HTMLInputElement; @@ -25,7 +26,13 @@ draggedFrom = from; } - function handleDrop(target: SourceType) { + function handleDragEnd() { + draggedImage = null; + draggedFrom = null; + activeDropTarget = null; + } + + function handleDrop(target: SourceType, index: number) { if (!draggedImage || draggedFrom === null) return; if (draggedFrom === 'uploaded') { @@ -35,13 +42,28 @@ } if (target === 'uploaded') { - uploadedImages = [...uploadedImages, draggedImage]; + const items = [...uploadedImages]; + items.splice(index, 0, draggedImage); + uploadedImages = items; } else { - tierItems[target] = [...tierItems[target], draggedImage]; + const items = [...tierItems[target]]; + items.splice(index, 0, draggedImage); + tierItems[target] = items; } draggedImage = null; draggedFrom = null; + activeDropTarget = null; + } + + function handleEnter(tier: SourceType, index: number) { + activeDropTarget = { tier, index }; + } + + function handleLeave(tier: SourceType, index: number) { + if (activeDropTarget?.tier === tier && activeDropTarget?.index === index) { + activeDropTarget = null; + } } function allowDrop(event: DragEvent) { @@ -58,57 +80,104 @@
- {#each tiers as label, i} + {#each tiers as label, tierLevelIndex}
{label}
handleDrop(i)} > - {#each tierItems[i] as image} - tier item handleDragStart(image, i)} - /> + {#if tierItems[tierLevelIndex].length === 0} +
handleDrop(tierLevelIndex, 0)} + > + Drop items here... +
{:else} -

Drop items here...

- {/each} + {#each tierItems[tierLevelIndex] as image, index (image.id)} + {#if draggedImage?.id !== image.id} + +
handleEnter(tierLevelIndex, index)} + on:dragleave={() => handleLeave(tierLevelIndex, index)} + on:dragover={allowDrop} + on:drop={() => handleDrop(tierLevelIndex, index)} + >
+ {/if} + tier item handleDragStart(image, tierLevelIndex)} + on:dragend={handleDragEnd} + /> + {/each} + + +
handleEnter(tierLevelIndex, tierItems[tierLevelIndex].length)} + on:dragleave={() => handleLeave(tierLevelIndex, tierItems[tierLevelIndex].length)} + on:dragover={allowDrop} + on:drop={() => handleDrop(tierLevelIndex, tierItems[tierLevelIndex].length)} + >
+ {/if}
{/each}
+
handleDrop('uploaded')} + on:drop={() => handleDrop('uploaded', uploadedImages.length)} >

Uploaded Items

- {#each uploadedImages as image} + {#each uploadedImages as image, index (image.id)} + {#if draggedImage?.id !== image.id} +
handleEnter('uploaded', index)} + on:dragleave={() => handleLeave('uploaded', index)} + on:dragover={allowDrop} + on:drop={() => handleDrop('uploaded', index)} + >
+ {/if} uploaded item handleDragStart(image, 'uploaded')} + on:dragend={handleDragEnd} /> - {:else} -

No images uploaded yet.

{/each} +
handleEnter('uploaded', uploadedImages.length)} + on:dragleave={() => handleLeave('uploaded', uploadedImages.length)} + on:dragover={allowDrop} + on:drop={() => handleDrop('uploaded', uploadedImages.length)} + >
@@ -121,3 +190,42 @@ + + From f4d1b6236e06d7a357910c7828bf5de923433ff0 Mon Sep 17 00:00:00 2001 From: Patertuck Date: Sat, 29 Nov 2025 11:14:50 +0100 Subject: [PATCH 2/6] fix items put on left side --- src/routes/+page.svelte | 70 +++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 59881ae..f6cfc35 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -96,16 +96,25 @@ > {#if tierItems[tierLevelIndex].length === 0}
handleEnter(tierLevelIndex, 0)} + on:dragleave={() => handleLeave(tierLevelIndex, 0)} on:dragover={allowDrop} on:drop={() => handleDrop(tierLevelIndex, 0)} > - Drop items here... + {#if activeDropTarget?.tier === tierLevelIndex && activeDropTarget?.index === 0 && draggedImage} + ghost preview + {:else} + Drop items here... + {/if}
{:else} {#each tierItems[tierLevelIndex] as image, index (image.id)} {#if draggedImage?.id !== image.id} -
handleLeave(tierLevelIndex, index)} on:dragover={allowDrop} on:drop={() => handleDrop(tierLevelIndex, index)} - >
+ > + {#if activeDropTarget?.tier === tierLevelIndex && activeDropTarget?.index === index && draggedImage} + ghost preview + {/if} + {/if} + tier item {/each} -
handleLeave(tierLevelIndex, tierItems[tierLevelIndex].length)} on:dragover={allowDrop} on:drop={() => handleDrop(tierLevelIndex, tierItems[tierLevelIndex].length)} - >
+ > + {#if activeDropTarget?.tier === tierLevelIndex && activeDropTarget?.index === tierItems[tierLevelIndex].length && draggedImage} + ghost preview + {/if} + {/if} @@ -159,8 +184,17 @@ on:dragleave={() => handleLeave('uploaded', index)} on:dragover={allowDrop} on:drop={() => handleDrop('uploaded', index)} - > + > + {#if activeDropTarget?.tier === 'uploaded' && activeDropTarget?.index === index && draggedImage} + ghost preview + {/if} + {/if} + uploaded item {/each} +
handleLeave('uploaded', uploadedImages.length)} on:dragover={allowDrop} on:drop={() => handleDrop('uploaded', uploadedImages.length)} - >
+ > + {#if activeDropTarget?.tier === 'uploaded' && activeDropTarget?.index === uploadedImages.length && draggedImage} + ghost preview + {/if} + @@ -203,10 +246,14 @@ background-color 0.2s ease, border-color 0.2s ease; flex-shrink: 0; + + display: flex; + align-items: center; + justify-content: center; } .drop-hover { - width: 24px; + width: 64px; background-color: rgba(74, 222, 128, 0.1); border-color: #4ade80; } @@ -216,9 +263,10 @@ height: 100%; display: flex; align-items: center; - justify-content: center; + justify-content: flex-start; border: 2px dashed #ccc; transition: border-color 0.2s; + padding-left: 4px; } .full-drop-target:hover { @@ -227,5 +275,7 @@ .drop-expand { flex-grow: 1; + justify-content: flex-start; + padding-left: 4px; } From 26892e5e29554854a9058b8010196665baf34bf1 Mon Sep 17 00:00:00 2001 From: Patertuck Date: Wed, 7 Jan 2026 15:01:11 +0100 Subject: [PATCH 3/6] Fix hovering hitbox --- src/routes/+page.svelte | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index f6cfc35..a523a2b 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -117,6 +117,7 @@ {#if draggedImage?.id !== image.id}
handleEnter(tierLevelIndex, index)} on:dragleave={() => handleLeave(tierLevelIndex, index)} @@ -145,6 +146,7 @@
handleEnter(tierLevelIndex, tierItems[tierLevelIndex].length)} on:dragleave={() => handleLeave(tierLevelIndex, tierItems[tierLevelIndex].length)} @@ -179,6 +181,7 @@ {#if draggedImage?.id !== image.id}
handleEnter('uploaded', index)} on:dragleave={() => handleLeave('uploaded', index)} @@ -207,6 +210,7 @@
handleEnter('uploaded', uploadedImages.length)} on:dragleave={() => handleLeave('uploaded', uploadedImages.length)} @@ -236,6 +240,7 @@ \ No newline at end of file