fix: disable download button while running jobs, auto run generator jobs

This commit is contained in:
2026-09-12 18:22:05 +05:00
parent 35df076732
commit 0c2de3f191
5 changed files with 44 additions and 54 deletions
+18 -7
View File
@@ -16,7 +16,13 @@
## Мелочи всякие ## Мелочи всякие
- [ ] сгенерировать или найти файлы для ручной проверки `A. Краевые PNG-файлы` - [x] сгенерировать или найти файлы для ручной проверки `A. Краевые PNG-файлы`
- [ ] обдумать объединение пар `inputMode + source` и `resultKind + result` в
единую структуру, позволит упростить некоторые вещи - например
`sourceValue` \ `resultValue` в `SchemaPreview.svelte`
- [ ] Рассмотреть необходимость всех этих пропсов в `SchemaPreview.svelte` они
дублируют друг друга `ontextsource`, `onrendertext`, `oncopytext`,
`ondownloadtxt`, `ondownload`,
- [ ] Переделать внешний вид инструментов без настроек, например Remove alpha - [ ] Переделать внешний вид инструментов без настроек, например Remove alpha
channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым. channel PNG "remove-alpha-channel-png". Сейчас выглядит слишком пустым.
- [ ] Убрать описание формата в отображении исходник\результат - это должно быть - [ ] Убрать описание формата в отображении исходник\результат - это должно быть
@@ -31,14 +37,14 @@
паспортом, семейства с кириллицей) паспортом, семейства с кириллицей)
- [ ] Посмотреть темную тему - слишком темная и слишком много оттенка (убавить c - [ ] Посмотреть темную тему - слишком темная и слишком много оттенка (убавить c
в hct?) в hct?)
- [ ] на картинке результате при работе дергается высота надписи (высота иконки) - [x] на картинке результате при работе дергается высота надписи (высота иконки)
- [x] Глянуть что за ошибка (воспроизвелось на blur-png, в том числе и повторно) - [x] Глянуть что за ошибка (воспроизвелось на blur-png, в том числе и повторно)
[баг в хроме](https://issues.chromium.org/issues/556160936) [баг в хроме](https://issues.chromium.org/issues/556160936)
`Uncaught TypeError: Cannot read properties of undefined (reading 'startTime')` `Uncaught TypeError: Cannot read properties of undefined (reading 'startTime')`
`at et.reportAllChanges (anonymous:2:19429)` `at et.reportAllChanges (anonymous:2:19429)`
- [ ] сделать загрузку картинки исходника по ctrl+v и drag-and-drop (dropzone) - [ ] сделать загрузку картинки исходника по ctrl+v и drag-and-drop (dropzone)
- [x] не работают генераторы картинок (create-empty-png) - [x] не работают генераторы картинок (create-empty-png)
- [ ] генераторы работают не автоматически - требуется нажать кнопку generate - [x] генераторы работают не автоматически - требуется нажать кнопку generate
(create-empty-png) (create-empty-png)
- [ ] square-mask-png - проверить работу - параметры неверно считаются. width - - [ ] square-mask-png - проверить работу - параметры неверно считаются. width -
100, height - 100, x - 100, y - 100, обрезает 50% на 50% картинку 100, height - 100, x - 100, y - 100, обрезает 50% на 50% картинку
@@ -56,9 +62,9 @@
- [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop, - [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop,
удаление, добавление инструментов. переход один инструмент - pipeline без удаление, добавление инструментов. переход один инструмент - pipeline без
перезагрузки перезагрузки
- [ ] Слаги инструментов (`*-png`) — надо обдумать, возможно что ссылки\маршруты - [ ] Слаги инструментов (`*-png`) — надо переименовть, они работают с любыми
должны быть с png, а названия инструментов - без. Это упростит названия изображениями. Надо сделать отдельный интерфейс маппинга инструмент ->
инструментов и сделает их более понятными ссылка
## Переезд ## Переезд
@@ -184,7 +190,12 @@
9. **`png-info` (детальная информация о PNG)** — оценка M/L. Отложен из 9. **`png-info` (детальная информация о PNG)** — оценка M/L. Отложен из
миграции. Отдельный райз: exif-теги, редактирование, структурированный вывод; миграции. Отдельный райз: exif-теги, редактирование, структурированный вывод;
нужен свой отдельный случай в UI, не «ещё один text/verdict». нужен свой отдельный случай в UI, не «ещё один text/verdict». возможно нужна
вообще отдельная страница, несовместимая с другими инструментами: 1) она
работает не с изображением, а с мета данными из файла, 2) она не может быть
частью цепочки, т.к. результат не является изображением, 3) если надо
изменить теги, никакого форматирования и изменения в изображение вносить не
надо, только в мета информацияю
10. **Region-инструменты** (censor/erase/pixelate-area/blur-area/sharpen-area/ 10. **Region-инструменты** (censor/erase/pixelate-area/blur-area/sharpen-area/
reverse-area) — ждут UI выделения области на превью. Из reverse-area) — ждут UI выделения области на превью. Из
+9 -26
View File
@@ -1,32 +1,20 @@
<script lang="ts"> <script lang="ts">
import { Upload } from "@lucide/svelte";
import DownloadButton from "./ui/DownloadButton.svelte"; import DownloadButton from "./ui/DownloadButton.svelte";
import { Sparkles, Upload } from "@lucide/svelte";
interface Props { interface Props {
inputMode: "image" | "text" | "none"; inputMode: "image" | "text" | "none";
canDownload: boolean; canDownload: boolean;
running: boolean; running: boolean;
onupload: (file: File) => void; onupload: (file: File) => void;
ongenerate: () => void;
ondownload: () => void; ondownload: () => void;
} }
let { let { inputMode, canDownload, running, onupload, ondownload }: Props =
inputMode, $props();
canDownload,
running,
onupload,
ongenerate,
ondownload,
}: Props = $props();
</script> </script>
<div class="actions"> <div class="actions">
{#if inputMode === "none"} {#if inputMode === "image"}
<button class="btn generate" onclick={ongenerate} disabled={running}>
<Sparkles size={14} />
{running ? "Generating…" : "Generate"}
</button>
{:else if inputMode === "image"}
<label class="btn upload"> <label class="btn upload">
<Upload size={14} /> Open image <Upload size={14} /> Open image
<input <input
@@ -40,7 +28,11 @@
</label> </label>
{/if} {/if}
{#if canDownload} {#if canDownload}
<DownloadButton label="Download result" onclick={ondownload} /> <DownloadButton
label="Download result"
onclick={ondownload}
disabled={running}
/>
{/if} {/if}
</div> </div>
@@ -62,15 +54,6 @@
color: var(--color-text-muted); color: var(--color-text-muted);
cursor: pointer; cursor: pointer;
} }
.generate {
background: var(--color-main);
border-color: var(--color-main);
color: var(--color-background);
}
.generate:disabled {
opacity: 0.6;
cursor: default;
}
.upload input { .upload input {
display: none; display: none;
} }
+11 -16
View File
@@ -17,7 +17,6 @@
running?: boolean; running?: boolean;
error?: string; error?: string;
onupload: (file: File) => void; onupload: (file: File) => void;
ongenerate?: () => void;
ontextsource?: (text: string) => void; ontextsource?: (text: string) => void;
onrendertext?: () => void; onrendertext?: () => void;
oncopytext?: () => void; oncopytext?: () => void;
@@ -35,7 +34,6 @@
running = false, running = false,
error = "", error = "",
onupload, onupload,
ongenerate,
ontextsource, ontextsource,
onrendertext, onrendertext,
oncopytext, oncopytext,
@@ -43,16 +41,16 @@
ondownload, ondownload,
}: Props = $props(); }: Props = $props();
const isGenerator = $derived(inputMode === "none"); const sourceValue = $derived.by(() => {
const sourceValue = $derived( switch (inputMode) {
isGenerator case "none":
? "—" return "—";
: inputMode === "text" case "text":
? "text" return "text";
: source case "image":
? `${source.width} × ${source.height} px` return source ? `${source.width} × ${source.height} px` : "—";
: "—", }
); });
const resultValue = $derived( const resultValue = $derived(
resultKind === "image" resultKind === "image"
? result ? result
@@ -77,15 +75,12 @@
</script> </script>
<div class="panel-head"> <div class="panel-head">
<span class="label" <span class="label">PREVIEW PANEL</span>
>{isGenerator ? "GENERATOR / RESULT" : "SOURCE / RESULT"}</span
>
<SchemaActions <SchemaActions
{inputMode} {inputMode}
canDownload={hasResult} canDownload={hasResult}
{running} {running}
{onupload} {onupload}
ongenerate={ongenerate ?? (() => {})}
{ondownload} {ondownload}
/> />
</div> </div>
+3 -3
View File
@@ -8,12 +8,12 @@
import { execute } from "$lib/executor"; import { execute } from "$lib/executor";
import { t } from "$lib/i18n/t"; import { t } from "$lib/i18n/t";
import type { FileResult, ToolEntry } from "$lib/registry"; import type { FileResult, ToolEntry } from "$lib/registry";
import { downloadZip } from "$lib/zip";
import { import {
defaultSchemaParams, defaultSchemaParams,
sanitizeSchemaParams, sanitizeSchemaParams,
type ToolSchema, type ToolSchema,
} from "$lib/registry-schema"; } from "$lib/registry-schema";
import { downloadZip } from "$lib/zip";
interface Props { interface Props {
tool: ToolEntry; tool: ToolEntry;
@@ -142,7 +142,8 @@
}); });
$effect(() => { $effect(() => {
if (inputMode !== "image" || !source || !started) return; // TODO: can any edge case start infinite loop?
if (!started) return;
void values; void values;
debouncedRun(); debouncedRun();
return () => debouncedRun.cancel(); return () => debouncedRun.cancel();
@@ -187,7 +188,6 @@
{running} {running}
{error} {error}
onupload={handleFile} onupload={handleFile}
ongenerate={run}
ontextsource={(textValue) => { ontextsource={(textValue) => {
textSource = textValue; textSource = textValue;
}} }}
@@ -5,8 +5,9 @@
interface Props { interface Props {
label: string; label: string;
onclick?: () => void; onclick?: () => void;
disabled?: boolean;
} }
let { label, onclick }: Props = $props(); let { label, onclick, disabled = false }: Props = $props();
</script> </script>
<Button icon={Download} {label} {onclick} /> <Button icon={Download} {label} {onclick} {disabled} />