81 lines
2.1 KiB
Svelte
81 lines
2.1 KiB
Svelte
<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);
|
|
}, 3000);
|
|
|
|
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]"
|
|
disabled={!($activeDatasetMeta?.unifiedImageSize ?? true)}
|
|
bind:value={width}
|
|
oninput={saveTargetSizeDelayed} />
|
|
<span>×</span>
|
|
<input
|
|
type="number"
|
|
class="text-right max-w-[5em]"
|
|
disabled={!($activeDatasetMeta?.unifiedImageSize ?? true)}
|
|
bind:value={height}
|
|
oninput={saveTargetSizeDelayed} />
|
|
<span>px</span>
|
|
</label>
|