117 lines
3.8 KiB
JavaScript
117 lines
3.8 KiB
JavaScript
import { Camera, FolderOpen, RefreshCw, Save } from "lucide-react";
|
|
import { useState } from "react";
|
|
|
|
import { postJson } from "../api/controlApi";
|
|
|
|
export function StackPresetToolbar({
|
|
presetName,
|
|
selectedPresetName,
|
|
stackPresets,
|
|
onPresetNameChange,
|
|
onSelectedPresetNameChange,
|
|
}) {
|
|
const [screenshotQueued, setScreenshotQueued] = useState(false);
|
|
|
|
async function requestScreenshot() {
|
|
setScreenshotQueued(true);
|
|
try {
|
|
await postJson("/api/screenshot", {});
|
|
} finally {
|
|
window.setTimeout(() => setScreenshotQueued(false), 1200);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="panel stack-panel">
|
|
<div className="panel__header stack-panel__header">
|
|
<div>
|
|
<h3>Stack presets</h3>
|
|
<p className="muted">Save or recall the current layer chain.</p>
|
|
</div>
|
|
<div className="stack-panel__actions">
|
|
<button
|
|
type="button"
|
|
className="button-with-icon stack-panel__screenshot"
|
|
onClick={requestScreenshot}
|
|
>
|
|
<Camera size={16} strokeWidth={1.9} aria-hidden="true" />
|
|
<span>{screenshotQueued ? "Queued" : "Screenshot"}</span>
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className="button-with-icon stack-panel__reload"
|
|
onClick={() => postJson("/api/reload", {})}
|
|
>
|
|
<RefreshCw size={16} strokeWidth={1.9} aria-hidden="true" />
|
|
<span>Reload shader</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="stack-panel__grid">
|
|
<div className="toolbar__group">
|
|
<label htmlFor="preset-name">Save stack</label>
|
|
<div className="toolbar__inline">
|
|
<input
|
|
id="preset-name"
|
|
type="text"
|
|
placeholder="Preset name"
|
|
value={presetName}
|
|
onChange={(event) => onPresetNameChange(event.target.value)}
|
|
/>
|
|
<button
|
|
type="button"
|
|
className="button-with-icon"
|
|
disabled={!presetName.trim()}
|
|
onClick={() => {
|
|
const trimmedName = presetName.trim();
|
|
if (!trimmedName) {
|
|
return;
|
|
}
|
|
postJson("/api/stack-presets/save", { presetName: trimmedName });
|
|
onSelectedPresetNameChange(
|
|
trimmedName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""),
|
|
);
|
|
}}
|
|
>
|
|
<Save size={16} strokeWidth={1.9} aria-hidden="true" />
|
|
<span>Save</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="toolbar__group">
|
|
<label htmlFor="preset-select">Recall stack</label>
|
|
<div className="toolbar__inline">
|
|
<select
|
|
id="preset-select"
|
|
value={selectedPresetName}
|
|
onChange={(event) => onSelectedPresetNameChange(event.target.value)}
|
|
>
|
|
{stackPresets.length === 0 ? <option value="">No presets</option> : null}
|
|
{stackPresets.map((preset) => (
|
|
<option key={preset} value={preset}>
|
|
{preset}
|
|
</option>
|
|
))}
|
|
</select>
|
|
<button
|
|
type="button"
|
|
className="button-with-icon"
|
|
disabled={!selectedPresetName}
|
|
onClick={() => {
|
|
if (selectedPresetName) {
|
|
postJson("/api/stack-presets/load", { presetName: selectedPresetName });
|
|
}
|
|
}}
|
|
>
|
|
<FolderOpen size={16} strokeWidth={1.9} aria-hidden="true" />
|
|
<span>Recall</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|