CI/CD
This commit is contained in:
154
ui/src/components/LayerCard.jsx
Normal file
154
ui/src/components/LayerCard.jsx
Normal file
@@ -0,0 +1,154 @@
|
||||
import { GripVertical, Trash2 } from "lucide-react";
|
||||
|
||||
import { postJson } from "../api/controlApi";
|
||||
import { ParameterField } from "./ParameterField";
|
||||
|
||||
export function LayerCard({
|
||||
layer,
|
||||
index,
|
||||
shaders,
|
||||
expanded,
|
||||
isDragging,
|
||||
isDropTarget,
|
||||
onToggleExpanded,
|
||||
onDragStart,
|
||||
onDragEnd,
|
||||
onDragOver,
|
||||
onDrop,
|
||||
onRemove,
|
||||
onLayerParameterChange,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`layer-card${expanded ? " layer-card--expanded" : ""}${isDragging ? " layer-card--dragging" : ""}${isDropTarget ? " layer-card--drop-target" : ""}`}
|
||||
onDragOver={(event) => {
|
||||
event.preventDefault();
|
||||
onDragOver(layer.id);
|
||||
}}
|
||||
onDrop={(event) => {
|
||||
event.preventDefault();
|
||||
onDrop(event, layer.id, index);
|
||||
}}
|
||||
>
|
||||
<div className="layer-card__header">
|
||||
<div className="layer-card__meta">
|
||||
<button
|
||||
type="button"
|
||||
className="layer-card__drag-handle"
|
||||
title="Drag to reorder"
|
||||
aria-label="Drag to reorder"
|
||||
draggable
|
||||
onDragStart={(event) => {
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
event.dataTransfer.setData("text/plain", layer.id);
|
||||
event.stopPropagation();
|
||||
onDragStart(layer.id);
|
||||
}}
|
||||
onDragEnd={(event) => {
|
||||
event.stopPropagation();
|
||||
onDragEnd();
|
||||
}}
|
||||
>
|
||||
<GripVertical size={16} strokeWidth={1.75} />
|
||||
</button>
|
||||
<span className="layer-card__index">{index + 1}</span>
|
||||
<button type="button" className="layer-card__title" onClick={() => onToggleExpanded(layer.id)}>
|
||||
{layer.shaderName}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="layer-card__actions">
|
||||
<label className="toggle toggle--compact">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={Boolean(layer.bypass)}
|
||||
onChange={(event) =>
|
||||
postJson("/api/layers/set-bypass", {
|
||||
layerId: layer.id,
|
||||
bypass: event.target.checked,
|
||||
})
|
||||
}
|
||||
/>
|
||||
<span>Bypass</span>
|
||||
</label>
|
||||
|
||||
<button type="button" onClick={() => onToggleExpanded(layer.id)}>
|
||||
{expanded ? "Hide" : "Controls"}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="icon-button"
|
||||
title="Remove layer"
|
||||
aria-label="Remove layer"
|
||||
onClick={() => onRemove(layer.id)}
|
||||
>
|
||||
<Trash2 size={16} strokeWidth={1.75} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{expanded ? (
|
||||
<div className="layer-card__body">
|
||||
<div className="layer-card__field">
|
||||
<label htmlFor={`shader-${layer.id}`}>Shader</label>
|
||||
<select
|
||||
id={`shader-${layer.id}`}
|
||||
value={layer.shaderId}
|
||||
onChange={(event) =>
|
||||
postJson("/api/layers/set-shader", {
|
||||
layerId: layer.id,
|
||||
shaderId: event.target.value,
|
||||
})
|
||||
}
|
||||
>
|
||||
{shaders.map((shader) => (
|
||||
<option key={shader.id} value={shader.id}>
|
||||
{shader.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{layer.temporal?.enabled ? (
|
||||
<div className="layer-card__field">
|
||||
<label>Temporal</label>
|
||||
<div className="muted">
|
||||
{layer.temporal.historySource} history, requested {layer.temporal.requestedHistoryLength} frame{layer.temporal.requestedHistoryLength === 1 ? "" : "s"}, using {layer.temporal.effectiveHistoryLength}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="layer-card__field">
|
||||
<label>Temporal</label>
|
||||
<div className="muted">Stateless shader</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="layer-card__subheader">
|
||||
<h3>Parameters</h3>
|
||||
<button
|
||||
type="button"
|
||||
disabled={layer.parameters.length === 0}
|
||||
onClick={() => postJson("/api/layers/reset-parameters", { layerId: layer.id })}
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{layer.parameters.length > 0 ? (
|
||||
<div className="parameter-grid">
|
||||
{layer.parameters.map((parameter) => (
|
||||
<ParameterField
|
||||
key={`${layer.id}:${parameter.id}`}
|
||||
parameter={parameter}
|
||||
onParameterChange={(parameterId, value) => onLayerParameterChange(layer.id, parameterId, value)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="muted">This shader does not expose any user parameters.</p>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user