drag and drop visual
This commit is contained in:
@@ -133,6 +133,7 @@ export function Thread() {
|
||||
dropRef,
|
||||
removeBlock,
|
||||
resetBlocks,
|
||||
dragOver,
|
||||
} = useFileUpload();
|
||||
const [firstTokenReceived, setFirstTokenReceived] = useState(false);
|
||||
const isLargeScreen = useMediaQuery("(min-width: 1024px)");
|
||||
@@ -442,8 +443,18 @@ export function Thread() {
|
||||
|
||||
<div
|
||||
ref={dropRef}
|
||||
className="bg-muted relative z-10 mx-auto mb-8 w-full max-w-3xl rounded-2xl border shadow-xs"
|
||||
className={cn(
|
||||
"bg-muted relative z-10 mx-auto mb-8 w-full max-w-3xl rounded-2xl border shadow-xs transition-all",
|
||||
dragOver ? "border-primary border-2 border-dotted" : "",
|
||||
)}
|
||||
>
|
||||
{dragOver && (
|
||||
<div className="pointer-events-none absolute inset-0 z-20 flex items-center justify-center rounded-2xl bg-black/40">
|
||||
<span className="text-lg font-semibold text-white">
|
||||
Drop file here
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="mx-auto grid max-w-3xl grid-rows-[1fr_auto] gap-2"
|
||||
|
||||
@@ -21,6 +21,8 @@ export function useFileUpload({
|
||||
const [contentBlocks, setContentBlocks] =
|
||||
useState<Base64ContentBlock[]>(initialBlocks);
|
||||
const dropRef = useRef<HTMLDivElement>(null);
|
||||
const [dragOver, setDragOver] = useState(false);
|
||||
const dragCounter = useRef(0);
|
||||
|
||||
const isDuplicate = (file: File, blocks: Base64ContentBlock[]) => {
|
||||
if (file.type === "application/pdf") {
|
||||
@@ -81,14 +83,45 @@ export function useFileUpload({
|
||||
useEffect(() => {
|
||||
if (!dropRef.current) return;
|
||||
|
||||
// Global drag events with counter for robust dragOver state
|
||||
const handleWindowDragEnter = (e: DragEvent) => {
|
||||
if (e.dataTransfer?.types?.includes("Files")) {
|
||||
dragCounter.current++;
|
||||
setDragOver(true);
|
||||
}
|
||||
};
|
||||
const handleWindowDragLeave = (e: DragEvent) => {
|
||||
if (e.dataTransfer?.types?.includes("Files")) {
|
||||
dragCounter.current--;
|
||||
if (dragCounter.current <= 0) {
|
||||
setDragOver(false);
|
||||
dragCounter.current = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
const handleWindowDrop = (e: DragEvent) => {
|
||||
dragCounter.current = 0;
|
||||
setDragOver(false);
|
||||
};
|
||||
const handleWindowDragEnd = (e: DragEvent) => {
|
||||
dragCounter.current = 0;
|
||||
setDragOver(false);
|
||||
};
|
||||
window.addEventListener("dragenter", handleWindowDragEnter);
|
||||
window.addEventListener("dragleave", handleWindowDragLeave);
|
||||
window.addEventListener("drop", handleWindowDrop);
|
||||
window.addEventListener("dragend", handleWindowDragEnd);
|
||||
|
||||
const handleDragOver = (e: DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setDragOver(true);
|
||||
};
|
||||
|
||||
const handleDrop = async (e: DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setDragOver(false);
|
||||
|
||||
if (!e.dataTransfer) return;
|
||||
|
||||
@@ -126,11 +159,13 @@ export function useFileUpload({
|
||||
const handleDragEnter = (e: DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setDragOver(true);
|
||||
};
|
||||
|
||||
const handleDragLeave = (e: DragEvent) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setDragOver(false);
|
||||
};
|
||||
|
||||
const element = dropRef.current;
|
||||
@@ -144,6 +179,11 @@ export function useFileUpload({
|
||||
element.removeEventListener("drop", handleDrop);
|
||||
element.removeEventListener("dragenter", handleDragEnter);
|
||||
element.removeEventListener("dragleave", handleDragLeave);
|
||||
window.removeEventListener("dragenter", handleWindowDragEnter);
|
||||
window.removeEventListener("dragleave", handleWindowDragLeave);
|
||||
window.removeEventListener("drop", handleWindowDrop);
|
||||
window.removeEventListener("dragend", handleWindowDragEnd);
|
||||
dragCounter.current = 0;
|
||||
};
|
||||
}, [contentBlocks]);
|
||||
|
||||
@@ -160,5 +200,6 @@ export function useFileUpload({
|
||||
dropRef,
|
||||
removeBlock,
|
||||
resetBlocks,
|
||||
dragOver,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user