verified hotkeys
This commit is contained in:
@ -12,6 +12,8 @@ import type {
|
||||
SilenceDetectionRange,
|
||||
SilenceTrimSettings,
|
||||
SilenceTrimGroup,
|
||||
TimelineMarker,
|
||||
Chapter,
|
||||
} from '../types/project';
|
||||
|
||||
interface EditorState {
|
||||
@ -27,6 +29,7 @@ interface EditorState {
|
||||
speedRanges: SpeedRange[];
|
||||
globalGainDb: number;
|
||||
silenceTrimGroups: SilenceTrimGroup[];
|
||||
timelineMarkers: TimelineMarker[];
|
||||
transcriptionModel: string | null;
|
||||
language: string;
|
||||
|
||||
@ -89,6 +92,10 @@ interface EditorActions {
|
||||
settings: SilenceTrimSettings;
|
||||
}) => { groupId: string; appliedCount: number };
|
||||
removeSilenceTrimGroup: (groupId: string) => void;
|
||||
addTimelineMarker: (time: number, label?: string, color?: string) => void;
|
||||
updateTimelineMarker: (id: string, updates: Partial<TimelineMarker>) => void;
|
||||
removeTimelineMarker: (id: string) => void;
|
||||
getChapters: () => Chapter[];
|
||||
setTranscribing: (active: boolean, progress?: number, status?: string) => void;
|
||||
setExporting: (active: boolean, progress?: number) => void;
|
||||
setZonePreviewPaddingSeconds: (seconds: number) => void;
|
||||
@ -122,6 +129,7 @@ const initialState: EditorState = {
|
||||
speedRanges: [],
|
||||
globalGainDb: 0,
|
||||
silenceTrimGroups: [],
|
||||
timelineMarkers: [],
|
||||
transcriptionModel: null,
|
||||
language: '',
|
||||
currentTime: 0,
|
||||
@ -182,7 +190,7 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
setTranscriptionModel: (model) => set({ transcriptionModel: model }),
|
||||
|
||||
saveProject: (): ProjectFile => {
|
||||
const { videoPath, words, segments, cutRanges, muteRanges, gainRanges, speedRanges, globalGainDb, silenceTrimGroups, transcriptionModel, language, exportedAudioPath } = get();
|
||||
const { videoPath, words, segments, cutRanges, muteRanges, gainRanges, speedRanges, globalGainDb, silenceTrimGroups, timelineMarkers, transcriptionModel, language, exportedAudioPath } = get();
|
||||
if (!videoPath) throw new Error('No video loaded');
|
||||
const now = new Date().toISOString();
|
||||
// Strip globalStartIndex (runtime-only field) before persisting.
|
||||
@ -204,6 +212,7 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
speedRanges,
|
||||
globalGainDb,
|
||||
silenceTrimGroups,
|
||||
timelineMarkers,
|
||||
language,
|
||||
createdAt: now, // will be overwritten if we track original creation time later
|
||||
modifiedAt: now,
|
||||
@ -453,6 +462,40 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
});
|
||||
},
|
||||
|
||||
addTimelineMarker: (time, label, color) => {
|
||||
const { timelineMarkers } = get();
|
||||
const newMarker: TimelineMarker = {
|
||||
id: `marker_${nextRangeId++}`,
|
||||
time,
|
||||
label: label || `Marker ${timelineMarkers.length + 1}`,
|
||||
color: color || '#6366f1',
|
||||
};
|
||||
set({ timelineMarkers: [...timelineMarkers, newMarker].sort((a, b) => a.time - b.time) });
|
||||
},
|
||||
|
||||
updateTimelineMarker: (id, updates) => {
|
||||
const { timelineMarkers } = get();
|
||||
set({
|
||||
timelineMarkers: timelineMarkers
|
||||
.map((m) => (m.id === id ? { ...m, ...updates } : m))
|
||||
.sort((a, b) => a.time - b.time),
|
||||
});
|
||||
},
|
||||
|
||||
removeTimelineMarker: (id) => {
|
||||
const { timelineMarkers } = get();
|
||||
set({ timelineMarkers: timelineMarkers.filter((m) => m.id !== id) });
|
||||
},
|
||||
|
||||
getChapters: () => {
|
||||
const { timelineMarkers } = get();
|
||||
return timelineMarkers.map((m) => ({
|
||||
markerId: m.id,
|
||||
label: m.label,
|
||||
startTime: m.time,
|
||||
}));
|
||||
},
|
||||
|
||||
setTranscribing: (active, progress, status) =>
|
||||
set({
|
||||
isTranscribing: active,
|
||||
@ -587,6 +630,7 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
speedRanges: data.speedRanges || [],
|
||||
globalGainDb: typeof data.globalGainDb === 'number' ? data.globalGainDb : 0,
|
||||
silenceTrimGroups: data.silenceTrimGroups || [],
|
||||
timelineMarkers: data.timelineMarkers || [],
|
||||
transcriptionModel: data.transcriptionModel ?? null,
|
||||
language: data.language || '',
|
||||
exportedAudioPath: data.exportedAudioPath ?? null,
|
||||
|
||||
Reference in New Issue
Block a user