close sh;able to save/load projects
This commit is contained in:
@ -1,10 +1,11 @@
|
||||
import { create } from 'zustand';
|
||||
import { temporal } from 'zundo';
|
||||
import type { Word, Segment, DeletedRange, TranscriptionResult } from '../types/project';
|
||||
import type { Word, Segment, DeletedRange, TranscriptionResult, ProjectFile } from '../types/project';
|
||||
|
||||
interface EditorState {
|
||||
videoPath: string | null;
|
||||
videoUrl: string | null;
|
||||
exportedAudioPath: string | null; // path to modified audio from a previous export
|
||||
words: Word[];
|
||||
segments: Segment[];
|
||||
deletedRanges: DeletedRange[];
|
||||
@ -29,6 +30,8 @@ interface EditorState {
|
||||
interface EditorActions {
|
||||
setBackendUrl: (url: string) => void;
|
||||
loadVideo: (path: string) => void;
|
||||
setExportedAudioPath: (path: string | null) => void;
|
||||
saveProject: () => ProjectFile;
|
||||
setTranscription: (result: TranscriptionResult) => void;
|
||||
setCurrentTime: (time: number) => void;
|
||||
setDuration: (duration: number) => void;
|
||||
@ -49,6 +52,7 @@ interface EditorActions {
|
||||
const initialState: EditorState = {
|
||||
videoPath: null,
|
||||
videoUrl: null,
|
||||
exportedAudioPath: null,
|
||||
words: [],
|
||||
segments: [],
|
||||
deletedRanges: [],
|
||||
@ -75,6 +79,27 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
|
||||
setBackendUrl: (url) => set({ backendUrl: url }),
|
||||
|
||||
setExportedAudioPath: (path) => set({ exportedAudioPath: path }),
|
||||
|
||||
saveProject: (): ProjectFile => {
|
||||
const { videoPath, words, segments, deletedRanges, language, exportedAudioPath } = get();
|
||||
if (!videoPath) throw new Error('No video loaded');
|
||||
const now = new Date().toISOString();
|
||||
// Strip globalStartIndex (runtime-only field) before persisting
|
||||
const persistSegments = segments.map(({ globalStartIndex: _drop, ...rest }) => rest);
|
||||
return {
|
||||
version: 1,
|
||||
videoPath,
|
||||
exportedAudioPath: exportedAudioPath ?? undefined,
|
||||
words,
|
||||
segments: persistSegments as unknown as Segment[],
|
||||
deletedRanges,
|
||||
language,
|
||||
createdAt: now, // will be overwritten if we track original creation time later
|
||||
modifiedAt: now,
|
||||
};
|
||||
},
|
||||
|
||||
loadVideo: (path) => {
|
||||
const backend = get().backendUrl;
|
||||
const url = `${backend}/file?path=${encodeURIComponent(path)}`;
|
||||
@ -225,6 +250,7 @@ export const useEditorStore = create<EditorState & EditorActions>()(
|
||||
segments: annotatedSegments,
|
||||
deletedRanges: data.deletedRanges || [],
|
||||
language: data.language || '',
|
||||
exportedAudioPath: data.exportedAudioPath ?? null,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user