feat: add export panel component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
|||||||
|
<script lang="ts" module>
|
||||||
|
// Module-level export so App can call doExport via bind:this
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { startExport } from "$lib/api";
|
||||||
|
import {
|
||||||
|
currentFile, cursor, clips, spread, shortSide, portraitRatio,
|
||||||
|
cropCenter, format, label, category, clipName, profile,
|
||||||
|
hwEncode,
|
||||||
|
exportStatus, exportCompleted, exportTotal, subprofiles
|
||||||
|
} from "$lib/stores";
|
||||||
|
|
||||||
|
const CATEGORIES = ["", "Human", "Animal", "Vehicle", "Tool", "Music", "Nature", "Sport", "Other"];
|
||||||
|
const RATIOS = ["Off", "9:16", "4:5", "1:1"];
|
||||||
|
|
||||||
|
export async function doExport(folderSuffix: string = "") {
|
||||||
|
if (!$currentFile) return;
|
||||||
|
$exportStatus = "running";
|
||||||
|
$exportCompleted = 0;
|
||||||
|
$exportTotal = $clips;
|
||||||
|
|
||||||
|
const req = {
|
||||||
|
input_path: `${$currentFile.root}/${$currentFile.path}`,
|
||||||
|
cursor: $cursor,
|
||||||
|
name: $clipName || $currentFile.name.replace(/\.[^.]+$/, ""),
|
||||||
|
clips: $clips,
|
||||||
|
spread: $spread,
|
||||||
|
short_side: $shortSide,
|
||||||
|
portrait_ratio: $portraitRatio,
|
||||||
|
crop_center: $cropCenter,
|
||||||
|
format: $format,
|
||||||
|
label: $label,
|
||||||
|
category: $category,
|
||||||
|
profile: $profile,
|
||||||
|
folder_suffix: folderSuffix,
|
||||||
|
encoder: $hwEncode ? "h264_nvenc" : "libx264",
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await startExport(req);
|
||||||
|
} catch (e) {
|
||||||
|
$exportStatus = "error";
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="export-panel">
|
||||||
|
<div class="row">
|
||||||
|
<button onclick={() => doExport()} disabled={$exportStatus === "running"}>
|
||||||
|
Export{#if $exportStatus === "running"} ({$exportCompleted}/{$exportTotal}){/if}
|
||||||
|
</button>
|
||||||
|
{#each $subprofiles as sub}
|
||||||
|
<button onclick={() => doExport(sub)} title="Export {sub}">
|
||||||
|
{sub}
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label>Clips <input type="number" bind:value={$clips} min="1" max="99" /></label>
|
||||||
|
<label>Spread <input type="number" bind:value={$spread} min="2" max="8" step="0.5" /></label>
|
||||||
|
<label>Size <input type="number" bind:value={$shortSide} min="0" max="4320" step="64" /></label>
|
||||||
|
<label>Ratio
|
||||||
|
<select bind:value={$portraitRatio}>
|
||||||
|
{#each RATIOS as r}
|
||||||
|
<option value={r === "Off" ? null : r}>{r}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<label>Label <input type="text" bind:value={$label} /></label>
|
||||||
|
<label>Category
|
||||||
|
<select bind:value={$category}>
|
||||||
|
{#each CATEGORIES as c}
|
||||||
|
<option value={c}>{c || "---"}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label>Format
|
||||||
|
<select bind:value={$format}>
|
||||||
|
<option>MP4</option>
|
||||||
|
<option>WebP sequence</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label><input type="checkbox" bind:checked={$hwEncode} /> GPU</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.export-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
label { display: flex; align-items: center; gap: 2px; }
|
||||||
|
input[type="number"] { width: 50px; background: #2d2d2d; color: #e0e0e0; border: 1px solid #444; }
|
||||||
|
input[type="text"] { width: 120px; background: #2d2d2d; color: #e0e0e0; border: 1px solid #444; }
|
||||||
|
select { background: #2d2d2d; color: #e0e0e0; border: 1px solid #444; }
|
||||||
|
button { background: #0066cc; color: white; border: none; padding: 4px 12px; cursor: pointer; }
|
||||||
|
button:disabled { background: #444; }
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user