feat: 添加目标尺寸组件,支持动态保存和反馈机制
This commit is contained in:
@@ -4,3 +4,11 @@
|
||||
html, body {
|
||||
@apply size-full;
|
||||
}
|
||||
|
||||
input {
|
||||
&[type='number']::-webkit-outer-spin-button,
|
||||
&[type='number']::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
import DatasetName from './meta-form/DatasetName.svelte';
|
||||
import SelectLoraType from './meta-form/SelectLoraType.svelte';
|
||||
import SelectModel from './meta-form/SelectModel.svelte';
|
||||
import TargetSize from './meta-form/TargetSize.svelte';
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-2 px-4 py-4">
|
||||
<DatasetName />
|
||||
<SelectModel />
|
||||
<SelectLoraType />
|
||||
<TargetSize />
|
||||
</div>
|
||||
|
||||
78
src/routes/dataset/meta-form/TargetSize.svelte
Normal file
78
src/routes/dataset/meta-form/TargetSize.svelte
Normal file
@@ -0,0 +1,78 @@
|
||||
<script lang="ts">
|
||||
import { activeDatasetMeta, updateActiveDatasetMeta } from '$lib/stores/dataset';
|
||||
import {
|
||||
createDebouncedTrigger,
|
||||
createSaveFeedbackController,
|
||||
type SaveFeedbackState,
|
||||
} from '$lib/utils/form-save';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
let width = $state<number>(512);
|
||||
let height = $state<number>(512);
|
||||
let saveFeedback = $state<SaveFeedbackState>('idle');
|
||||
|
||||
const feedback = createSaveFeedbackController((state) => {
|
||||
saveFeedback = state;
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
const meta = get(activeDatasetMeta);
|
||||
if (meta?.imageSize) {
|
||||
width = meta.imageSize?.[0] ?? 512;
|
||||
height = meta.imageSize?.[1] ?? 512;
|
||||
}
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
saveLater.cancel();
|
||||
feedback.dispose();
|
||||
});
|
||||
|
||||
async function saveTargetSize(nextWidth: number, nextHeight: number) {
|
||||
const normalizedWidth = Number.isFinite(nextWidth) ? Math.floor(nextWidth) : 0;
|
||||
const normalizedHeight = Number.isFinite(nextHeight) ? Math.floor(nextHeight) : 0;
|
||||
|
||||
if (normalizedWidth <= 0 || normalizedHeight <= 0) {
|
||||
feedback.markNotUpdated();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await updateActiveDatasetMeta({ imageSize: [normalizedWidth, normalizedHeight] });
|
||||
feedback.markUpdated();
|
||||
} catch (error) {
|
||||
console.error('Failed to save target size:', error);
|
||||
feedback.markNotUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
const saveLater = createDebouncedTrigger(() => {
|
||||
void saveTargetSize(width, height);
|
||||
}, 5000);
|
||||
|
||||
function saveTargetSizeDelayed() {
|
||||
saveLater.trigger();
|
||||
}
|
||||
</script>
|
||||
|
||||
<label
|
||||
class={[
|
||||
'input w-fit focus-within:outline-none transition-colors duration-300 ease-out',
|
||||
saveFeedback === 'updated' && 'border-green-500',
|
||||
saveFeedback === 'not-updated' && 'border-red-500',
|
||||
]}>
|
||||
<span class="label min-w-[10em]">Scale To</span>
|
||||
<input
|
||||
type="number"
|
||||
class="text-right max-w-[5em]"
|
||||
bind:value={width}
|
||||
oninput={saveTargetSizeDelayed} />
|
||||
<span>×</span>
|
||||
<input
|
||||
type="number"
|
||||
class="text-right max-w-[5em]"
|
||||
bind:value={height}
|
||||
oninput={saveTargetSizeDelayed} />
|
||||
<span>px</span>
|
||||
</label>
|
||||
Reference in New Issue
Block a user