clean up of features
This commit is contained in:
@ -5,7 +5,12 @@ export default function AppendClipPanel() {
|
||||
const { additionalClips, addAdditionalClip, removeAdditionalClip, reorderAdditionalClip, videoPath } = useEditorStore();
|
||||
|
||||
const handleAddClip = async () => {
|
||||
const path = await window.electronAPI?.openFile();
|
||||
const path = await window.electronAPI?.openFile({
|
||||
filters: [
|
||||
{ name: 'Video Files', extensions: ['mp4', 'mkv', 'mov', 'avi', 'webm'] },
|
||||
{ name: 'All Files', extensions: ['*'] },
|
||||
],
|
||||
});
|
||||
if (path) {
|
||||
addAdditionalClip(path);
|
||||
}
|
||||
|
||||
@ -5,7 +5,12 @@ export default function BackgroundMusicPanel() {
|
||||
const { backgroundMusic, setBackgroundMusic, updateBackgroundMusic } = useEditorStore();
|
||||
|
||||
const handleLoadMusic = async () => {
|
||||
const path = await window.electronAPI?.openFile();
|
||||
const path = await window.electronAPI?.openFile({
|
||||
filters: [
|
||||
{ name: 'Audio Files', extensions: ['mp3', 'wav', 'm4a', 'flac', 'ogg', 'aac', 'wma'] },
|
||||
{ name: 'All Files', extensions: ['*'] },
|
||||
],
|
||||
});
|
||||
if (path) {
|
||||
setBackgroundMusic({
|
||||
path,
|
||||
|
||||
@ -9,6 +9,19 @@ export default function ExportDialog() {
|
||||
|
||||
const hasCuts = cutRanges.length > 0;
|
||||
|
||||
// Compute set of deleted word indices from cutRanges
|
||||
const getDeletedSet = useCallback(() => {
|
||||
const deletedSet = new Set<number>();
|
||||
for (const range of cutRanges) {
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
if (words[i].start >= range.start && words[i].end <= range.end) {
|
||||
deletedSet.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return deletedSet;
|
||||
}, [cutRanges, words]);
|
||||
|
||||
// Detect if input is audio-only by its extension
|
||||
const audioExtensions = new Set(['.wav', '.mp3', '.flac', '.m4a', '.ogg', '.aac', '.wma']);
|
||||
const inputExt = videoPath ? '.' + videoPath.split('.').pop()?.toLowerCase() : '';
|
||||
@ -46,14 +59,7 @@ export default function ExportDialog() {
|
||||
setIsTranscribingTranscript(true);
|
||||
try {
|
||||
// Compute deleted word set
|
||||
const deletedSet = new Set<number>();
|
||||
for (const range of cutRanges) {
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
if (words[i].start >= range.start && words[i].end <= range.end) {
|
||||
deletedSet.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
const deletedSet = getDeletedSet();
|
||||
|
||||
// Generate content entirely on the frontend — no backend needed
|
||||
let content: string;
|
||||
@ -103,7 +109,7 @@ export default function ExportDialog() {
|
||||
} finally {
|
||||
setIsTranscribingTranscript(false);
|
||||
}
|
||||
}, [videoPath, words, cutRanges, transcriptFormat]);
|
||||
}, [videoPath, words, getDeletedSet, transcriptFormat]);
|
||||
|
||||
const HANDLE_EXPORT_filters = useCallback(() => {
|
||||
const ext = options.format;
|
||||
@ -130,14 +136,7 @@ export default function ExportDialog() {
|
||||
setExportError(null);
|
||||
try {
|
||||
const keepSegments = getKeepSegments();
|
||||
|
||||
const deletedSet = new Set<number>();
|
||||
for (const range of cutRanges) {
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
const w = words[i];
|
||||
if (w.start >= range.start && w.end <= range.end) deletedSet.add(i);
|
||||
}
|
||||
}
|
||||
const deletedSet = getDeletedSet();
|
||||
|
||||
// Map frontend camelCase gain/speed fields to backend snake_case
|
||||
const backendGainRanges = gainRanges.map((r) => ({
|
||||
@ -213,7 +212,7 @@ export default function ExportDialog() {
|
||||
setExportError(err instanceof Error ? err.message : 'Export failed');
|
||||
setExporting(false);
|
||||
}
|
||||
}, [videoPath, options, backendUrl, setExporting, getKeepSegments, cutRanges, muteRanges, gainRanges, speedRanges, globalGainDb, words, HANDLE_EXPORT_filters, additionalClips, backgroundMusic]);
|
||||
}, [videoPath, options, backendUrl, setExporting, getKeepSegments, getDeletedSet, muteRanges, gainRanges, speedRanges, globalGainDb, words, HANDLE_EXPORT_filters, additionalClips, backgroundMusic]);
|
||||
|
||||
return (
|
||||
<div className="p-4 space-y-5">
|
||||
|
||||
@ -287,10 +287,9 @@ export default function WaveformTimeline({
|
||||
const [showAdjustedTimeline, setShowAdjustedTimeline] = useState(false);
|
||||
|
||||
const sourceDuration = duration || waveformDataRef.current?.duration || 0;
|
||||
const timelineCutRanges = showAdjustedTimeline ? cutRanges : [];
|
||||
const { segments: timelineSegments, displayDuration } = useMemo(
|
||||
() => buildTimelineSegments(sourceDuration, timelineCutRanges),
|
||||
[sourceDuration, timelineCutRanges],
|
||||
() => buildTimelineSegments(sourceDuration, showAdjustedTimeline ? cutRanges : []),
|
||||
[sourceDuration, cutRanges, showAdjustedTimeline],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -687,7 +686,6 @@ export default function WaveformTimeline({
|
||||
gainMode,
|
||||
speedMode,
|
||||
selectedZone,
|
||||
showAdjustedTimeline,
|
||||
markInTime,
|
||||
markOutTime,
|
||||
displayDuration,
|
||||
@ -696,6 +694,7 @@ export default function WaveformTimeline({
|
||||
showGainZones,
|
||||
showSpeedZones,
|
||||
timelineSegments,
|
||||
timelineMarkers,
|
||||
]);
|
||||
|
||||
// Keep the ref in sync with the latest drawStaticWaveform closure
|
||||
|
||||
Reference in New Issue
Block a user