mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
feat: flow for multiple files - pipeline, tools
This commit is contained in:
@@ -2,33 +2,45 @@
|
||||
import { toDataUrl } from "$lib/core/io";
|
||||
import type { PixelImage } from "$lib/core/types";
|
||||
import { t } from "$lib/i18n/t";
|
||||
import type { InputMode } from "$lib/registry";
|
||||
import type { InputMode, ToolImageFile } from "$lib/registry";
|
||||
import Dropzone from "./Dropzone.svelte";
|
||||
import PartsGrid from "./PartsGrid.svelte";
|
||||
import PreviewTile from "./PreviewTile.svelte";
|
||||
import SchemaTextSource from "./SchemaTextSource.svelte";
|
||||
|
||||
interface Props {
|
||||
mode: InputMode;
|
||||
source: PixelImage | null;
|
||||
sources?: ToolImageFile[];
|
||||
textSource?: string;
|
||||
running?: boolean;
|
||||
fileCount?: number;
|
||||
ontextinput?: (text: string) => void;
|
||||
onrendertext?: () => void;
|
||||
onupload?: (file: File) => void;
|
||||
onuploadmany?: (files: File[]) => void;
|
||||
}
|
||||
let {
|
||||
mode,
|
||||
source,
|
||||
sources = [],
|
||||
textSource = "",
|
||||
running = false,
|
||||
fileCount = 0,
|
||||
ontextinput,
|
||||
onrendertext,
|
||||
onupload,
|
||||
onuploadmany,
|
||||
}: Props = $props();
|
||||
|
||||
const sourceUrl = $derived(source ? toDataUrl(source) : null);
|
||||
const sourceDims = $derived(
|
||||
source ? `${source.width} × ${source.height}` : undefined,
|
||||
source
|
||||
? `${source.width} × ${source.height}` +
|
||||
(fileCount > 1
|
||||
? ` · ${t("sourceCard.countFiles", { count: fileCount })}`
|
||||
: "")
|
||||
: undefined,
|
||||
);
|
||||
|
||||
let dragging = $state(false);
|
||||
@@ -57,8 +69,13 @@
|
||||
function onDrop(e: DragEvent) {
|
||||
e.preventDefault();
|
||||
dragging = false;
|
||||
const file = e.dataTransfer?.files?.[0];
|
||||
if (file) onupload?.(file);
|
||||
pickFiles(Array.from(e.dataTransfer?.files ?? []));
|
||||
}
|
||||
|
||||
function pickFiles(files: File[]) {
|
||||
if (files.length === 0) return;
|
||||
if (files.length > 1 && onuploadmany) onuploadmany(files);
|
||||
else if (files[0]) onupload?.(files[0]);
|
||||
}
|
||||
|
||||
function open() {
|
||||
@@ -106,17 +123,21 @@
|
||||
bind:this={input}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
multiple
|
||||
hidden
|
||||
onchange={(e) => {
|
||||
const file = (e.target as HTMLInputElement).files?.[0];
|
||||
if (file) onupload?.(file);
|
||||
pickFiles(Array.from((e.target as HTMLInputElement).files ?? []));
|
||||
}}
|
||||
/>
|
||||
<img
|
||||
data-testid="source-image"
|
||||
src={sourceUrl}
|
||||
alt={t("sourceCard.alt")}
|
||||
/>
|
||||
{#if sources.length > 1}
|
||||
<PartsGrid files={sources} />
|
||||
{:else}
|
||||
<img
|
||||
data-testid="source-image"
|
||||
src={sourceUrl}
|
||||
alt={t("sourceCard.alt")}
|
||||
/>
|
||||
{/if}
|
||||
{#if dragging}
|
||||
<span class="drop-hint">{t("dropZone.overlayDefault")}</span>
|
||||
{:else}
|
||||
@@ -124,7 +145,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
{:else if mode === "image"}
|
||||
<Dropzone onfile={onupload} />
|
||||
<Dropzone onfile={onupload} onfiles={onuploadmany} />
|
||||
{:else}
|
||||
<span class="empty">{t("sourceCard.noSource")}</span>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user