UI improvements, moved file name and moved buttons left
This commit is contained in:
@ -21,6 +21,7 @@ import {
|
||||
Scissors,
|
||||
VolumeX,
|
||||
SlidersHorizontal,
|
||||
Gauge,
|
||||
FilePlus2,
|
||||
RefreshCw,
|
||||
Grid3x3,
|
||||
@ -40,6 +41,7 @@ export default function App() {
|
||||
cutRanges,
|
||||
muteRanges,
|
||||
gainRanges,
|
||||
speedRanges,
|
||||
globalGainDb,
|
||||
silenceTrimGroups,
|
||||
transcriptionModel,
|
||||
@ -55,14 +57,18 @@ export default function App() {
|
||||
addCutRange,
|
||||
addMuteRange,
|
||||
addGainRange,
|
||||
addSpeedRange,
|
||||
} = useEditorStore();
|
||||
|
||||
const [activePanel, setActivePanel] = useState<Panel>(null);
|
||||
const [whisperModel, setWhisperModel] = useState('base');
|
||||
useEffect(() => { if (transcriptionModel) setWhisperModel(transcriptionModel); }, [transcriptionModel]);
|
||||
const [cutMode, setCutMode] = useState(false);
|
||||
const [muteMode, setMuteMode] = useState(false);
|
||||
const [gainMode, setGainMode] = useState(false);
|
||||
const [gainModeDb, setGainModeDb] = useState(3);
|
||||
const [speedMode, setSpeedMode] = useState(false);
|
||||
const [speedModeValue, setSpeedModeValue] = useState(1.25);
|
||||
const [showReprocessConfirm, setShowReprocessConfirm] = useState(false);
|
||||
const [showUnsavedPrompt, setShowUnsavedPrompt] = useState(false);
|
||||
const [pendingProceedAction, setPendingProceedAction] = useState<(() => Promise<void>) | null>(null);
|
||||
@ -79,6 +85,7 @@ export default function App() {
|
||||
cutRanges,
|
||||
muteRanges,
|
||||
gainRanges,
|
||||
speedRanges,
|
||||
globalGainDb,
|
||||
silenceTrimGroups,
|
||||
transcriptionModel,
|
||||
@ -93,6 +100,7 @@ export default function App() {
|
||||
cutRanges,
|
||||
muteRanges,
|
||||
gainRanges,
|
||||
speedRanges,
|
||||
globalGainDb,
|
||||
silenceTrimGroups,
|
||||
transcriptionModel,
|
||||
@ -112,6 +120,7 @@ export default function App() {
|
||||
cutRanges: data.cutRanges || [],
|
||||
muteRanges: data.muteRanges || [],
|
||||
gainRanges: data.gainRanges || [],
|
||||
speedRanges: data.speedRanges || [],
|
||||
globalGainDb: typeof data.globalGainDb === 'number' ? data.globalGainDb : 0,
|
||||
silenceTrimGroups: data.silenceTrimGroups || [],
|
||||
transcriptionModel: data.transcriptionModel ?? null,
|
||||
@ -138,6 +147,7 @@ export default function App() {
|
||||
setCutMode(false);
|
||||
setMuteMode(false);
|
||||
setGainMode(false);
|
||||
setSpeedMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -217,6 +227,7 @@ export default function App() {
|
||||
setCutMode(false);
|
||||
setMuteMode(false);
|
||||
setGainMode(false);
|
||||
setSpeedMode(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -315,6 +326,7 @@ export default function App() {
|
||||
setCutMode(!cutMode);
|
||||
setMuteMode(false); // Exit mute mode
|
||||
setGainMode(false); // Exit gain mode
|
||||
setSpeedMode(false); // Exit speed mode
|
||||
}
|
||||
};
|
||||
|
||||
@ -330,6 +342,7 @@ export default function App() {
|
||||
setMuteMode(!muteMode);
|
||||
setCutMode(false); // Exit cut mode
|
||||
setGainMode(false); // Exit gain mode
|
||||
setSpeedMode(false); // Exit speed mode
|
||||
}
|
||||
};
|
||||
|
||||
@ -343,6 +356,21 @@ export default function App() {
|
||||
setGainMode(!gainMode);
|
||||
setCutMode(false);
|
||||
setMuteMode(false);
|
||||
setSpeedMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSpeed = () => {
|
||||
if (selectedWordIndices.length > 0) {
|
||||
const sorted = [...selectedWordIndices].sort((a, b) => a - b);
|
||||
const startTime = words[sorted[0]].start;
|
||||
const endTime = words[sorted[sorted.length - 1]].end;
|
||||
addSpeedRange(startTime, endTime, speedModeValue);
|
||||
} else {
|
||||
setSpeedMode(!speedMode);
|
||||
setCutMode(false);
|
||||
setMuteMode(false);
|
||||
setGainMode(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -413,19 +441,8 @@ export default function App() {
|
||||
return (
|
||||
<div className="h-screen flex flex-col bg-editor-bg overflow-hidden">
|
||||
{/* Top bar */}
|
||||
<header className="h-12 flex items-center justify-between px-4 border-b border-editor-border shrink-0">
|
||||
<div className="flex items-center gap-3">
|
||||
<Film className="w-5 h-5 text-editor-accent" />
|
||||
<span className="text-sm font-medium truncate max-w-[300px]">
|
||||
{videoPath.split(/[\\/]/).pop()}
|
||||
</span>
|
||||
{transcriptionModel && (
|
||||
<span className="px-2 py-0.5 rounded border border-editor-border bg-editor-surface text-[10px] uppercase tracking-wide text-editor-text-muted">
|
||||
Model: {transcriptionModel}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<header className="h-12 flex items-center px-4 border-b border-editor-border shrink-0">
|
||||
<div className="flex items-center gap-0.5">
|
||||
<ToolbarButton
|
||||
icon={<FilePlus2 className="w-4 h-4" />}
|
||||
label="New"
|
||||
@ -477,6 +494,24 @@ export default function App() {
|
||||
title="Gain dB for new gain zones"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<ToolbarButton
|
||||
icon={<Gauge className="w-4 h-4" />}
|
||||
label="Speed Zone"
|
||||
onClick={handleSpeed}
|
||||
active={speedMode}
|
||||
/>
|
||||
<input
|
||||
type="number"
|
||||
min={0.25}
|
||||
max={4}
|
||||
step={0.05}
|
||||
value={speedModeValue}
|
||||
onChange={(e) => setSpeedModeValue(Math.max(0.25, Math.min(4, Number(e.target.value) || 1)))}
|
||||
className="w-16 px-1.5 py-1 text-xs bg-editor-surface border border-editor-border rounded text-editor-text focus:outline-none focus:border-editor-accent"
|
||||
title="Playback rate for new speed zones"
|
||||
/>
|
||||
</div>
|
||||
<ToolbarButton
|
||||
icon={<Grid3x3 className="w-4 h-4" />}
|
||||
label="Zones"
|
||||
@ -495,7 +530,7 @@ export default function App() {
|
||||
<select
|
||||
value={whisperModel}
|
||||
onChange={(e) => setWhisperModel(e.target.value)}
|
||||
className="bg-transparent text-xs text-editor-text focus:outline-none"
|
||||
className="bg-editor-surface text-xs text-editor-text focus:outline-none [color-scheme:dark]"
|
||||
title="Transcription model"
|
||||
>
|
||||
<optgroup label="Multilingual">
|
||||
@ -521,7 +556,7 @@ export default function App() {
|
||||
onClick={handleReprocessProject}
|
||||
disabled={isTranscribing || !videoPath}
|
||||
title="Reprocess transcript with selected model"
|
||||
className="flex items-center gap-1 px-2 py-1 rounded text-xs text-editor-text-muted hover:text-editor-text hover:bg-editor-bg disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
className="flex items-center gap-1 px-2 py-1 rounded text-xs text-editor-text hover:bg-editor-bg disabled:opacity-40 disabled:cursor-not-allowed"
|
||||
>
|
||||
<RefreshCw className={`w-3 h-3 ${isTranscribing ? 'animate-spin' : ''}`} />
|
||||
Reprocess
|
||||
@ -562,6 +597,16 @@ export default function App() {
|
||||
|
||||
{/* Transcript */}
|
||||
<div className="w-1/2 border-l border-editor-border flex flex-col min-h-0">
|
||||
{videoPath && (
|
||||
<div className="flex items-center gap-2 px-3 py-1.5 border-b border-editor-border shrink-0 bg-editor-surface/50">
|
||||
<span className="text-xs font-medium truncate text-editor-text">{videoPath.split(/[\/]/).pop()}</span>
|
||||
{transcriptionModel && (
|
||||
<span className="px-1.5 py-0.5 rounded border border-editor-border bg-editor-surface text-[10px] uppercase tracking-wide text-editor-text-muted shrink-0">
|
||||
{transcriptionModel}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{isTranscribing ? (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-5">
|
||||
{/* Animated waveform */}
|
||||
@ -588,6 +633,8 @@ export default function App() {
|
||||
muteMode={muteMode}
|
||||
gainMode={gainMode}
|
||||
gainModeDb={gainModeDb}
|
||||
speedMode={speedMode}
|
||||
speedModeValue={speedModeValue}
|
||||
/>
|
||||
) : (
|
||||
<div className="flex-1 flex items-center justify-center text-editor-text-muted text-sm">
|
||||
@ -599,7 +646,14 @@ export default function App() {
|
||||
|
||||
{/* Waveform timeline */}
|
||||
<div className="h-32 border-t border-editor-border shrink-0">
|
||||
<WaveformTimeline cutMode={cutMode} muteMode={muteMode} gainMode={gainMode} gainModeDb={gainModeDb} />
|
||||
<WaveformTimeline
|
||||
cutMode={cutMode}
|
||||
muteMode={muteMode}
|
||||
gainMode={gainMode}
|
||||
gainModeDb={gainModeDb}
|
||||
speedMode={speedMode}
|
||||
speedModeValue={speedModeValue}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user