TdAI / llama.cpp /tools /ui /src /lib /hooks /use-chat-screen-drag-and-drop.svelte.ts
tda45's picture
Upload folder using huggingface_hub (part 8)
15c3607 verified
Raw
History Blame Contribute Delete
1.65 kB
/**
* Drag-and-drop state machine for the ChatScreen.
*
* Tracks pointer enter/leave nesting so the overlay stays visible while the
* cursor traverses child elements, then routes the dropped files either to
* the active message-edit handler (if a message is being edited) or to the
* caller's onDrop callback.
*/
import { getAddFilesHandler, isEditing } from '$lib/stores/chat.svelte';
interface UseChatScreenDragAndDropOptions {
/** Called when the user drops files and no message is being edited. */
onDrop: (files: File[]) => void;
}
export function useChatScreenDragAndDrop(options: UseChatScreenDragAndDropOptions) {
let dragCounter = $state(0);
let isDragOver = $state(false);
function handleDragEnter(event: DragEvent) {
event.preventDefault();
dragCounter++;
if (event.dataTransfer?.types.includes('Files')) {
isDragOver = true;
}
}
function handleDragLeave(event: DragEvent) {
event.preventDefault();
dragCounter--;
if (dragCounter === 0) {
isDragOver = false;
}
}
function handleDragOver(event: DragEvent) {
event.preventDefault();
}
async function handleDrop(event: DragEvent) {
event.preventDefault();
isDragOver = false;
dragCounter = 0;
if (!event.dataTransfer?.files) return;
const files = Array.from(event.dataTransfer.files);
if (isEditing()) {
const handler = getAddFilesHandler();
if (handler) {
handler(files);
return;
}
}
options.onDrop(files);
}
return {
get isDragOver() {
return isDragOver;
},
dragHandlers: {
dragenter: handleDragEnter,
dragleave: handleDragLeave,
dragover: handleDragOver,
drop: handleDrop
}
};
}