your personal website on atproto - mirror
blento.app
1<script lang="ts">
2 import { Portal } from 'bits-ui';
3
4 let {
5 processImageFile,
6 isDragOver = $bindable()
7 }: {
8 processImageFile: (file: File) => Promise<void>;
9 isDragOver: boolean;
10 } = $props();
11
12 function handleDragOver(event: DragEvent) {
13 event.preventDefault();
14 event.stopPropagation();
15
16 const dt = event.dataTransfer;
17 if (!dt) return;
18
19 let imageCount = 0;
20 if (dt.items) {
21 for (let i = 0; i < dt.items.length; i++) {
22 const item = dt.items[i];
23 if (item && item.kind === 'file' && item.type.startsWith('image/')) {
24 imageCount++;
25 }
26 }
27 } else if (dt.files) {
28 for (let i = 0; i < dt.files.length; i++) {
29 const file = dt.files[i];
30 if (file?.type.startsWith('image/')) {
31 imageCount++;
32 }
33 }
34 }
35
36 isDragOver = imageCount > 0;
37 }
38 function handleDragLeave(event: DragEvent) {
39 event.preventDefault();
40 event.stopPropagation();
41 isDragOver = false;
42 }
43 async function handleDrop(event: DragEvent) {
44 event.preventDefault();
45 event.stopPropagation();
46 isDragOver = false;
47 if (!event.dataTransfer?.files?.length) return;
48 for (const file of event.dataTransfer.files) {
49 if (file?.type.startsWith('image/')) {
50 await processImageFile(file);
51 }
52 }
53 }
54</script>
55
56<svelte:window ondragover={handleDragOver} ondragleave={handleDragLeave} ondrop={handleDrop} />
57
58{#if isDragOver}
59 <Portal>
60 <div
61 class="bg-base-100/80 dark:bg-base-900/80 text-primary dark:text-base-100 pointer-events-none absolute inset-0 z-[1000] flex items-center justify-center text-4xl font-bold backdrop-blur-md"
62 >
63 Drop file to add it to your message
64 </div>
65 </Portal>
66{/if}