mirror of
https://github.com/open-webui/open-webui
synced 2024-11-06 16:59:42 +00:00
enh: drag ghost
This commit is contained in:
parent
cf24a65caa
commit
73a251fc49
29
src/lib/components/common/DragGhost.svelte
Normal file
29
src/lib/components/common/DragGhost.svelte
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount } from 'svelte';
|
||||||
|
|
||||||
|
export let x;
|
||||||
|
export let y;
|
||||||
|
|
||||||
|
let popupElement = null;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
document.body.appendChild(popupElement);
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
document.body.removeChild(popupElement);
|
||||||
|
document.body.style.overflow = 'unset';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={popupElement}
|
||||||
|
class=" absolute text-white z-[99999]"
|
||||||
|
style="top: {y}px; left: {x}px;"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toast } from 'svelte-sonner';
|
import { toast } from 'svelte-sonner';
|
||||||
import { goto, invalidate, invalidateAll } from '$app/navigation';
|
import { goto, invalidate, invalidateAll } from '$app/navigation';
|
||||||
import { onMount, getContext, createEventDispatcher, tick } from 'svelte';
|
import { onMount, getContext, createEventDispatcher, tick, onDestroy } from 'svelte';
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
@ -32,6 +32,7 @@
|
|||||||
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
import GarbageBin from '$lib/components/icons/GarbageBin.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
|
||||||
|
import DragGhost from '$lib/components/common/DragGhost.svelte';
|
||||||
|
|
||||||
export let chat;
|
export let chat;
|
||||||
export let selected = false;
|
export let selected = false;
|
||||||
@ -89,11 +90,70 @@
|
|||||||
const focusEdit = async (node: HTMLInputElement) => {
|
const focusEdit = async (node: HTMLInputElement) => {
|
||||||
node.focus();
|
node.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let itemElement;
|
||||||
|
|
||||||
|
let drag = false;
|
||||||
|
let x = 0;
|
||||||
|
let y = 0;
|
||||||
|
|
||||||
|
const dragImage = new Image();
|
||||||
|
dragImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
|
||||||
|
|
||||||
|
const onDragStart = (event) => {
|
||||||
|
console.log('Dragging started:', event.target);
|
||||||
|
event.dataTransfer.setDragImage(dragImage, 0, 0);
|
||||||
|
|
||||||
|
drag = true;
|
||||||
|
itemElement.style.opacity = '0.5'; // Optional: Visual cue to show it's being dragged
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDrag = (event) => {
|
||||||
|
x = event.clientX;
|
||||||
|
y = event.clientY;
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDragEnd = (event) => {
|
||||||
|
console.log('Dragging ended:', event.target);
|
||||||
|
drag = false;
|
||||||
|
itemElement.style.opacity = '1'; // Reset visual cue after drag
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (itemElement) {
|
||||||
|
// Event listener for when dragging starts
|
||||||
|
itemElement.addEventListener('dragstart', onDragStart);
|
||||||
|
// Event listener for when dragging occurs (optional)
|
||||||
|
itemElement.addEventListener('drag', onDrag);
|
||||||
|
// Event listener for when dragging ends
|
||||||
|
itemElement.addEventListener('dragend', onDragEnd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if (itemElement) {
|
||||||
|
itemElement.removeEventListener('dragstart', onDragStart);
|
||||||
|
itemElement.removeEventListener('drag', onDrag);
|
||||||
|
itemElement.removeEventListener('dragend', onDragEnd);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ShareChatModal bind:show={showShareChatModal} chatId={chat.id} />
|
<ShareChatModal bind:show={showShareChatModal} chatId={chat.id} />
|
||||||
|
|
||||||
<div class=" w-full pr-2 relative group" draggable="true">
|
{#if drag && x && y}
|
||||||
|
<DragGhost {x} {y}>
|
||||||
|
<div class=" bg-black/50 backdrop-blur-2xl px-2 py-1 rounded-lg">
|
||||||
|
<div>
|
||||||
|
<div class=" text-xs text-gray-500">
|
||||||
|
{chat.title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DragGhost>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div bind:this={itemElement} class=" w-full pr-2 relative group" draggable="true">
|
||||||
{#if confirmEdit}
|
{#if confirmEdit}
|
||||||
<div
|
<div
|
||||||
class=" w-full flex justify-between rounded-xl px-3 py-2 {chat.id === $chatId || confirmEdit
|
class=" w-full flex justify-between rounded-xl px-3 py-2 {chat.id === $chatId || confirmEdit
|
||||||
|
Loading…
Reference in New Issue
Block a user