Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
inference-widgets
/
packages
/widgets
/src
/lib
/components
/InferenceWidget
/shared
/WidgetDropzone
/WidgetDropzone.svelte
<script lang="ts"> | |
import LogInPopover from "../../../LogInPopover/LogInPopover.svelte"; | |
import IconSpin from "../../../Icons/IconSpin.svelte"; | |
import { getBlobFromUrl } from "../../shared/helpers.js"; | |
import { isLoggedIn } from "../../stores.js"; | |
import { createEventDispatcher } from "svelte"; | |
export let accept = "image/*"; | |
export let classNames = ""; | |
export let isLoading = false; | |
export let isDisabled = false; | |
export let imgSrc = ""; | |
export let label = "Drag image file here or click to browse from your device"; | |
const dispatch = createEventDispatcher<{ run: File | Blob; error: string }>(); | |
let fileInput: HTMLInputElement; | |
let isDragging = false; | |
let popOverOpen = false; | |
function onChange() { | |
const file = fileInput.files?.[0]; | |
if (file) { | |
dispatch("run", file); | |
} | |
} | |
async function onDrop(e: DragEvent) { | |
isDragging = false; | |
if (!$isLoggedIn) { | |
popOverOpen = true; | |
return; | |
} | |
const itemList = e.dataTransfer?.items; | |
if (!itemList || isLoading) { | |
return; | |
} | |
const items = Array.from(itemList); | |
const uriItem = items.find((x) => x.kind === "string" && x.type === "text/uri-list"); | |
const fileItem = items.find((x) => x.kind === "file"); | |
if (uriItem) { | |
const url = await new Promise<string>((resolve) => uriItem.getAsString((s) => resolve(s))); | |
const file = await getBlobFromUrl(url); | |
dispatch("run", file); | |
} else if (fileItem) { | |
const file = fileItem.getAsFile(); | |
if (file) { | |
dispatch("run", file); | |
} | |
} else { | |
dispatch("error", "Unrecognized dragged and dropped file or element."); | |
} | |
} | |
</script> | |
<input | |
{accept} | |
bind:this={fileInput} | |
on:change={onChange} | |
disabled={isLoading || isDisabled} | |
style="display: none;" | |
type="file" | |
/> | |
<LogInPopover bind:open={popOverOpen}> | |
<!-- svelte-ignore a11y-click-events-have-key-events --> | |
<div | |
class="relative cursor-pointer rounded border-2 border-dashed px-3 py-7 text-center | |
{isDisabled ? 'pointer-events-none' : ''} | |
{isDragging ? 'border-green-300 bg-green-50 text-green-500' : 'text-gray-500'} | |
{classNames}" | |
on:click={() => { | |
if (!$isLoggedIn) { | |
popOverOpen = true; | |
return; | |
} | |
fileInput.click(); | |
}} | |
on:dragenter={() => { | |
isDragging = true; | |
}} | |
on:dragleave={() => { | |
isDragging = false; | |
}} | |
on:dragover|preventDefault | |
on:drop|preventDefault={onDrop} | |
> | |
{#if !imgSrc && !isDisabled} | |
<span class="pointer-events-none text-sm">{label}</span> | |
{:else} | |
<div class={isDragging ? "pointer-events-none" : ""}> | |
<slot /> | |
</div> | |
{/if} | |
{#if isLoading} | |
<div | |
class="absolute top-1/2 left-1/2 flex h-12 w-12 -translate-x-1/2 -translate-y-1/2 transform items-center justify-center rounded-full border border-gray-100 bg-white shadow" | |
> | |
<IconSpin classNames="text-purple-500 animate-spin h-6 w-6" /> | |
</div> | |
{/if} | |
</div> | |
</LogInPopover> | |