Function bodies 405 total
useExport function · typescript · L207-L481 (275 LOC)src/hooks/useExport.ts
export function useExport(): UseExportReturn {
const [isExporting, setIsExporting] = useState(false);
const [progress, setProgress] = useState<ExportProgress | null>(null);
const [exportErrorStr, setExportErrorStr] = useState<string | null>(null);
const [exportOutputPath, setExportOutputPath] = useState<string | null>(null);
const [exportFileSize, setExportFileSize] = useState<number | null>(null);
// Deserialize error for external consumption
const exportError = deserializeError(exportErrorStr);
// Show error toast when export fails
useEffect(() => {
if (exportError) {
toast.error(exportError.message, {
description: exportError.details,
action: exportError.recoverable
? {
label: "Dismiss",
onClick: () => {
// Auto-dismiss
},
}
: undefined,
});
}
}, [exportError]);
/**
* Convert active words into export segments.
* Groups consecutiresolutionToTuple function · typescript · L486-L497 (12 LOC)src/hooks/useExport.ts
function resolutionToTuple(resolution: string): [number, number] | null {
switch (resolution) {
case "1080p":
return [1920, 1080];
case "2k":
return [2560, 1440];
case "4k":
return [3840, 2160];
default:
return null;
}
}useKeyboardShortcuts function · typescript · L31-L67 (37 LOC)src/hooks/useKeyboardShortcuts.ts
export function useKeyboardShortcuts() {
const { undo, redo, pastStates, futureStates } = useTemporalStore();
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
// Platform detection: Mac uses metaKey (Cmd), Windows/Linux use ctrlKey
const isMac = /mac|iphone|ipad|ipod/i.test(navigator.platform);
const modifierKey = isMac ? e.metaKey : e.ctrlKey;
// Check for Z key with modifier
if (modifierKey && e.key === "z") {
// Prevent browser's native undo (e.g., in input fields)
e.preventDefault();
if (e.shiftKey) {
// Redo: Cmd+Shift+Z or Ctrl+Shift+Z
if (futureStates.length > 0) {
redo();
}
} else {
// Undo: Cmd+Z or Ctrl+Z
if (pastStates.length > 0) {
undo();
}
}
}
};
// Add listener to window for global keyboard handling
window.addEventListener("keydown", handleKeyDown);
// Cleanup: remove liuseProjectAutosave function · typescript · L30-L133 (104 LOC)src/hooks/useProjectAutosave.ts
export function useProjectAutosave({
projectData,
projectPath,
enabled = true,
onSave,
onError,
}: AutosaveOptions) {
const lastSavedHash = useRef<string>("");
const lastManualSaveTime = useRef<number>(Date.now());
const hasPendingChanges = useRef(false);
// Compute hash of project data for change detection
const computeHash = useCallback((): string => {
const data = projectData();
if (!data) return "";
return JSON.stringify(data);
}, [projectData]);
// Manual save call (updates timestamp to prevent immediate autosave)
const markManualSave = useCallback(() => {
lastManualSaveTime.current = Date.now();
lastSavedHash.current = computeHash();
hasPendingChanges.current = false;
}, [computeHash]);
// Autosave function
const autosave = useCallback(async () => {
const data = projectData();
if (!data) return;
// Check if changes since last save
const currentHash = JSON.stringify(data);
if (currentHash === lastSavedadjustSegmentToProject function · typescript · L49-L58 (10 LOC)src/hooks/useProjectTimeline.ts
function adjustSegmentToProject(
segment: Segment,
projectOffset: number
): Segment {
return {
...segment,
startTime: segment.startTime + projectOffset,
endTime: segment.endTime + projectOffset,
};
}adjustWordToProject function · typescript · L63-L72 (10 LOC)src/hooks/useProjectTimeline.ts
function adjustWordToProject(
word: TranscriptionWord,
projectOffset: number
): TranscriptionWord {
return {
...word,
startTime: word.startTime + projectOffset,
endTime: word.endTime + projectOffset,
};
}useProjectTimeline function · typescript · L94-L162 (69 LOC)src/hooks/useProjectTimeline.ts
export function useProjectTimeline(clips: VideoClip[]): ProjectTimeline {
const result = useMemo(() => {
// Sort clips by order
const sortedClips = [...clips].sort((a, b) => a.order - b.order);
// Calculate clip boundaries
const boundaries: ClipBoundary[] = [];
let currentTime = 0;
for (const clip of sortedClips) {
boundaries.push({
clipId: clip.id,
clipName: clip.name || clip.fileName,
projectTime: currentTime,
duration: clip.duration,
endTime: currentTime + clip.duration,
});
currentTime += clip.duration;
}
// Adjust all segments to project time
const allSegments: Segment[] = [];
for (const clip of sortedClips) {
const boundary = boundaries.find((b) => b.clipId === clip.id);
if (boundary) {
for (const segment of clip.segments) {
allSegments.push(
adjustSegmentToProject(segment, boundary.projectTime)
);
}
}
}
Source: Repobility analyzer · https://repobility.com
projectToClipTime function · typescript · L171-L174 (4 LOC)src/hooks/useProjectTimeline.ts
export function projectToClipTime(
projectTime: number,
clipBoundaries: ClipBoundary[]
): { clipId: string; clipTime: number } | null {clipToProjectTime function · typescript · L195-L205 (11 LOC)src/hooks/useProjectTimeline.ts
export function clipToProjectTime(
clipId: string,
clipTime: number,
clipBoundaries: ClipBoundary[]
): number | null {
const clip = clipBoundaries.find((b) => b.clipId === clipId);
if (!clip) return null;
return clip.projectTime + clipTime;
}getClipAtTime function · typescript · L214-L221 (8 LOC)src/hooks/useProjectTimeline.ts
export function getClipAtTime(
projectTime: number,
clipBoundaries: ClipBoundary[]
): ClipBoundary | null {
return clipBoundaries.find(
(b) => projectTime >= b.projectTime && projectTime < b.endTime
) || null;
}useRecentProjects function · typescript · L92-L98 (7 LOC)src/hooks/useRecentProjects.ts
export function useRecentProjects() {
const store = useRecentProjectsStore();
// Load on first mount
// Note: This could be moved to App.tsx if needed
return store;
}useTauriCommand function · typescript · L58-L95 (38 LOC)src/hooks/useTauriCommand.ts
export function useTauriCommand<T = unknown>(
options: UseCommandOptions<T>
): CommandState<T> {
const { command, args: defaultArgs, onSuccess, onError } = options;
const [data, setData] = useState<T | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const execute = useCallback(
async (args?: Record<string, unknown>) => {
setIsLoading(true);
setError(null);
try {
const result = await invoke<T>(command, args || defaultArgs);
setData(result);
onSuccess?.(result);
return result;
} catch (err) {
const errorMsg = String(err);
setError(errorMsg);
onError?.(errorMsg);
throw err;
} finally {
setIsLoading(false);
}
},
[command, defaultArgs, onSuccess, onError]
);
const reset = useCallback(() => {
setData(null);
setIsLoading(false);
setError(null);
}, []);
return { data, useTauriMutation function · typescript · L123-L152 (30 LOC)src/hooks/useTauriCommand.ts
export function useTauriMutation<T = unknown>(
options: UseMutationOptions<T>
): MutationState<T> {
const { command, onSuccess, onError } = options;
const [isMutating, setIsMutating] = useState(false);
const [error, setError] = useState<string | null>(null);
const execute = useCallback(
async (args: Record<string, unknown>) => {
setIsMutating(true);
setError(null);
try {
const result = await invoke<T>(command, args);
onSuccess?.(result);
return result;
} catch (err) {
const errorMsg = String(err);
setError(errorMsg);
onError?.(errorMsg);
throw err;
} finally {
setIsMutating(false);
}
},
[command, onSuccess, onError]
);
return { execute, isMutating, error };
}useTauriBatch function · typescript · L185-L213 (29 LOC)src/hooks/useTauriCommand.ts
export function useTauriBatch<T = unknown>(
options: BatchOptions
): BatchState<T> {
const { command, onSuccess, onError } = options;
const [isBatching, setIsBatching] = useState(false);
const [error, setError] = useState<string | null>(null);
const execute = useCallback(
async (items: T[]) => {
setIsBatching(true);
setError(null);
try {
await invoke(command, { items });
onSuccess?.();
} catch (err) {
const errorMsg = String(err);
setError(errorMsg);
onError?.(errorMsg);
throw err;
} finally {
setIsBatching(false);
}
},
[command, onSuccess, onError]
);
return { execute, isBatching, error };
}useTauriEvent function · typescript · L51-L109 (59 LOC)src/hooks/useTauriEvent.ts
export function useTauriEvent<T = unknown>(
eventName: string,
options: UseEventOptions<T> = {}
): EventState<T> {
const { defaultValue, onEvent, enabled = true } = options;
const [data, setData] = useState<T | null>(defaultValue ?? null);
const [isListening, setIsListening] = useState(false);
// Use ref for onEvent to avoid re-subscribing when callback changes
const onEventRef = useRef(onEvent);
onEventRef.current = onEvent;
useEffect(() => {
if (!enabled) return;
let unlisten: UnlistenFn | null = null;
let isCancelled = false;
const listenPromise = listen<T>(eventName, (event) => {
if (isCancelled) return;
setData(event.payload);
onEventRef.current?.(event.payload);
});
listenPromise
.then((fn) => {
if (isCancelled) {
fn(); // Already unmounted, clean up immediately
return;
}
unlisten = fn;
setIsListening(true);
})
.catch((err) => {
if (!isCanPowered by Repobility — scan your code at https://repobility.com
useTauriEvents function · typescript · L127-L158 (32 LOC)src/hooks/useTauriEvent.ts
export function useTauriEvents<T = unknown>(
handlers: EventHandlers<T>,
enabled = true
): boolean {
const [isListening, setIsListening] = useState(false);
useEffect(() => {
if (!enabled) return;
const unlisteners: Promise<UnlistenFn>[] = [];
Object.entries(handlers).forEach(([eventName, handler]) => {
const promise = listen<T>(eventName, (event) => {
handler(event.payload);
});
unlisteners.push(promise);
});
Promise.all(unlisteners).then(() => {
setIsListening(true);
});
return () => {
Promise.all(unlisteners).then((fns) => {
fns.forEach((fn) => fn());
});
setIsListening(false);
};
}, [handlers, enabled]);
return isListening;
}useCommandWithEvents function · typescript · L205-L257 (53 LOC)src/hooks/useTauriEvent.ts
export function useCommandWithEvents<TData = unknown, TProgress = number>(
options: CommandWithEventOptions<TData, TProgress>
) {
const {
command,
progressEvent,
completeEvent,
errorEvent,
onProgress,
onComplete,
onError,
} = options;
const [isRunning, setIsRunning] = useState(false);
// Listen to progress events
useTauriEvent<TProgress>(progressEvent, {
onEvent: (progress) => {
onProgress?.(progress);
},
});
// Listen to complete events
useTauriEvent<TData>(completeEvent || "", {
onEvent: (data) => {
setIsRunning(false);
onComplete?.(data);
},
});
// Listen to error events
useTauriEvent<string>(errorEvent || "", {
onEvent: (error) => {
setIsRunning(false);
onError?.(error);
},
});
const execute = useCallback(
async (args?: Record<string, unknown>) => {
setIsRunning(true);
try {
await invoke(command, args);
} catch (err) {
setIsRunninguseTauriLoad function · typescript · L48-L86 (39 LOC)src/hooks/useTauriLoad.ts
export function useTauriLoad<T = unknown>(
options: UseLoadOptions<T>
): LoadState<T> {
const {
loadOnMount = true,
defaultValue,
onSuccess,
onError,
...commandOptions
} = options;
const { data, isLoading, error, execute } = useTauriCommand<T>({
...commandOptions,
onSuccess,
onError,
});
const [isInitialLoadDone, setIsInitialLoadDone] = useState(!loadOnMount);
useEffect(() => {
if (loadOnMount && !isInitialLoadDone) {
execute()
.then(() => setIsInitialLoadDone(true))
.catch(() => setIsInitialLoadDone(true));
}
}, [loadOnMount, execute, isInitialLoadDone]);
const reload = useCallback(async () => {
await execute();
}, [execute]);
return {
data: (data ?? defaultValue) as T,
isLoading,
error,
reload,
isInitialLoadDone,
};
}useTauriAutoRefresh function · typescript · L108-L134 (27 LOC)src/hooks/useTauriLoad.ts
export function useTauriAutoRefresh<T = unknown>(
options: UseAutoRefreshOptions<T>
): LoadState<T> {
const { eventName, ...loadOptions } = options;
const { data, isLoading, error, reload, isInitialLoadDone } =
useTauriLoad<T>(loadOptions);
useEffect(() => {
if (!eventName) return;
const unlisten = listen(eventName, () => {
reload();
});
return () => {
unlisten.then((fn) => fn());
};
}, [eventName, reload]);
return {
data: (data ?? loadOptions.defaultValue) as T,
isLoading,
error,
reload,
isInitialLoadDone,
};
}useTauriMutation function · typescript · L46-L85 (40 LOC)src/hooks/useTauriMutation.ts
export function useTauriMutation<TData = unknown, TVariables = void>(
options: UseMutationOptions<TData, TVariables>
): MutationState<TData, TVariables> {
const { command, onSuccess, onError, onSettled } = options;
const [isMutating, setIsMutating] = useState(false);
const [error, setError] = useState<string | null>(null);
const [data, setData] = useState<TData | null>(null);
const execute = useCallback(
async (variables: TVariables): Promise<TData> => {
setIsMutating(true);
setError(null);
try {
const result = await invoke<TData>(command, variables as Record<string, unknown>);
setData(result);
onSuccess?.(result, variables);
onSettled?.(result, null, variables);
return result;
} catch (err) {
const errorMsg = String(err);
setError(errorMsg);
onError?.(errorMsg, variables);
onSettled?.(undefined, errorMsg, variables);
throw err;
} finally {
setIsMutatiuseTauriBatchMutation function · typescript · L115-L154 (40 LOC)src/hooks/useTauriMutation.ts
export function useTauriBatchMutation<TData = unknown, TItem = unknown>(
options: UseBatchMutationOptions<TData>
): BatchMutationState<TData, TItem> {
const { command, onProgress, onSuccess, onError } = options;
const [isMutating, setIsMutating] = useState(false);
const [error, setError] = useState<string | null>(null);
const [progress, setProgress] = useState({ completed: 0, total: 0 });
const execute = useCallback(
async (items: TItem[]): Promise<TData[]> => {
setIsMutating(true);
setError(null);
setProgress({ completed: 0, total: items.length });
try {
const results: TData[] = [];
for (const item of items) {
const result = await invoke<TData>(command, { item });
results.push(result);
setProgress((prev) => ({ ...prev, completed: prev.completed + 1 }));
onProgress?.(results.length, items.length);
}
onSuccess?.(results);
return results;
} catch (err) {
useTemporalStore function · typescript · L54-L56 (3 LOC)src/hooks/useTemporalStore.ts
export function useTemporalStore(): TemporalState<PartialTranscriptState> {
return useStore(useTranscriptStore.temporal, (state) => state);
}useTranscription function · typescript · L52-L161 (110 LOC)src/hooks/useTranscription.ts
export function useTranscription(): UseTranscriptionResult {
const [isTranscribing, setIsTranscribing] = useState(false);
const [progress, setProgress] = useState(0);
const [stage, setStage] = useState("");
const [words, setWords] = useState<TranscriptionWord[]>([]);
const [fullText, setFullText] = useState("");
const [clipId, setClipId] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
// Listen for progress updates
useTauriEvent<TranscriptionProgress>("transcription-progress", {
onEvent: (data) => {
setProgress(data.progress);
setStage(data.stage);
},
});
// Listen for completion
useTauriEvent<{
clip_id: string;
words: Array<{
id: string;
word: string;
start_time: number;
end_time: number;
confidence: number;
}>;
full_text: string;
language: string;
processing_time: number;
}>("transcription-complete", {
onEvent: (data) => {
// ConverMethodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
useWordSelection function · typescript · L66-L253 (188 LOC)src/hooks/useWordSelection.ts
export function useWordSelection(
options: UseWordSelectionOptions = {}
): WordSelectionReturn {
const { onWordSelect, onMultiSelect } = options;
const [selectedRangeWords, setSelectedRangeWords] = useState<string[]>([]);
const [lastSelectedWord, setLastSelectedWord] = useState<string | null>(null);
// Track word index map for range selection
const wordIndexMapRef = useRef<Map<string, number>>(new Map());
/**
* Clear window selection
*/
const clearSelection = useCallback(() => {
const selection = window.getSelection();
if (selection) {
selection.removeAllRanges();
}
setSelectedRangeWords([]);
}, []);
/**
* Handle mouse up - detect drag selection
*/
const handleMouseUp = useCallback(() => {
const selection = window.getSelection();
if (!selection || selection.isCollapsed) {
// No range selection, clear previous drag selection
setSelectedRangeWords([]);
return;
}
try {
const range = selecgetTextNodes function · typescript · L175-L187 (13 LOC)src/hooks/useWordSelection.ts
function getTextNodes(element: Element): Text[] {
const textNodes: Text[] = [];
const walker = document.createTreeWalker(
element,
NodeFilter.SHOW_TEXT,
null
);
let node;
while ((node = walker.nextNode())) {
textNodes.push(node as Text);
}
return textNodes;
}cn function · typescript · L20-L22 (3 LOC)src/lib/utils.ts
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}createProject function · typescript · L19-L36 (18 LOC)src/models/Project.ts
export function createProject(
name: string = "Untitled Project",
videoClips: VideoClip[] = [],
exportSettings: ExportSettings = DEFAULT_EXPORT_SETTINGS
): Project {
const now = new Date();
const totalDuration = videoClips.reduce((sum, clip) => sum + clip.duration, 0);
return {
id: generateId(),
name,
createdAt: now,
updatedAt: now,
videoClips,
totalDuration,
exportSettings: { ...exportSettings },
};
}updateProjectClips function · typescript · L45-L54 (10 LOC)src/models/Project.ts
export function updateProjectClips(project: Project, clips: VideoClip[]): Project {
const totalDuration = clips.reduce((sum, clip) => sum + clip.duration, 0);
return {
...project,
videoClips: clips,
totalDuration,
updatedAt: new Date(),
};
}addVideoClip function · typescript · L63-L68 (6 LOC)src/models/Project.ts
export function addVideoClip(project: Project, clip: VideoClip): Project {
const maxOrder = Math.max(-1, ...project.videoClips.map((c) => c.order));
const newClip = { ...clip, order: maxOrder + 1 };
return updateProjectClips(project, [...project.videoClips, newClip]);
}removeVideoClip function · typescript · L77-L80 (4 LOC)src/models/Project.ts
export function removeVideoClip(project: Project, clipId: string): Project {
const clips = project.videoClips.filter((c) => c.id !== clipId);
return updateProjectClips(project, clips);
}reorderVideoClips function · typescript · L89-L108 (20 LOC)src/models/Project.ts
export function reorderVideoClips(project: Project, clipIds: string[]): Project {
const clipMap = new Map(project.videoClips.map((c) => [c.id, c]));
const clips: VideoClip[] = [];
for (let i = 0; i < clipIds.length; i++) {
const clip = clipMap.get(clipIds[i]);
if (clip) {
clips.push({ ...clip, order: i });
}
}
// Add any clips not in the clipIds list
for (const clip of project.videoClips) {
if (!clipIds.includes(clip.id)) {
clips.push({ ...clip, order: clips.length });
}
}
return updateProjectClips(project, clips);
}Repobility — the code-quality scanner for AI-generated software · https://repobility.com
updateExportSettings function · typescript · L117-L126 (10 LOC)src/models/Project.ts
export function updateExportSettings(
project: Project,
settings: Partial<ExportSettings>
): Project {
return {
...project,
exportSettings: { ...project.exportSettings, ...settings },
updatedAt: new Date(),
};
}isProjectWithinDurationLimit function · typescript · L135-L140 (6 LOC)src/models/Project.ts
export function isProjectWithinDurationLimit(
project: Project,
maxDuration: number = 3600
): boolean {
return project.totalDuration <= maxDuration;
}createFillerWordSegment function · typescript · L20-L39 (20 LOC)src/models/Segment.ts
export function createFillerWordSegment(
clipId: string,
startTime: number,
endTime: number,
content: string,
confidence: number
): Segment {
return {
id: generateId(),
clipId,
startTime,
endTime,
duration: endTime - startTime,
type: "filler_word",
content,
confidence,
isActive: false, // Grayed out by default
manuallyEdited: false,
};
}createSilenceSegment function · typescript · L50-L67 (18 LOC)src/models/Segment.ts
export function createSilenceSegment(
clipId: string,
startTime: number,
endTime: number,
confidence: number
): Segment {
return {
id: generateId(),
clipId,
startTime,
endTime,
duration: endTime - startTime,
type: "silence",
confidence,
isActive: false, // Grayed out by default
manuallyEdited: false,
};
}toggleSegment function · typescript · L75-L81 (7 LOC)src/models/Segment.ts
export function toggleSegment(segment: Segment): Segment {
return {
...segment,
isActive: !segment.isActive,
manuallyEdited: true,
};
}setSegmentActive function · typescript · L90-L96 (7 LOC)src/models/Segment.ts
export function setSegmentActive(segment: Segment, isActive: boolean): Segment {
return {
...segment,
isActive,
manuallyEdited: true,
};
}segmentOverlaps function · typescript · L106-L112 (7 LOC)src/models/Segment.ts
export function segmentOverlaps(
segment: Segment,
startTime: number,
endTime: number
): boolean {
return segment.startTime < endTime && segment.endTime > startTime;
}isTimeInSegment function · typescript · L121-L123 (3 LOC)src/models/Segment.ts
export function isTimeInSegment(segment: Segment, time: number): boolean {
return time >= segment.startTime && time <= segment.endTime;
}Source: Repobility analyzer · https://repobility.com
getSegmentsAtTime function · typescript · L132-L134 (3 LOC)src/models/Segment.ts
export function getSegmentsAtTime(segments: Segment[], time: number): Segment[] {
return segments.filter((s) => isTimeInSegment(s, time));
}sortSegmentsByTime function · typescript · L142-L144 (3 LOC)src/models/Segment.ts
export function sortSegmentsByTime(segments: Segment[]): Segment[] {
return [...segments].sort((a, b) => a.startTime - b.startTime);
}mergeOverlappingSegments function · typescript · L152-L182 (31 LOC)src/models/Segment.ts
export function mergeOverlappingSegments(segments: Segment[]): Segment[] {
const sorted = sortSegmentsByTime(segments);
const merged: Segment[] = [];
for (const segment of sorted) {
const last = merged[merged.length - 1];
if (
last &&
last.type === segment.type &&
last.isActive === segment.isActive &&
last.endTime >= segment.startTime
) {
// Merge with previous segment (create new object for immutability)
const mergedSegment: Segment = {
...last,
endTime: Math.max(last.endTime, segment.endTime),
duration: Math.max(last.endTime, segment.endTime) - last.startTime,
confidence: last.confidence !== undefined && segment.confidence !== undefined
? Math.max(last.confidence, segment.confidence)
: last.confidence ?? segment.confidence,
};
merged[merged.length - 1] = mergedSegment;
} else {
// Add new segment
merged.push({ ...segment });
}
}
return mergecreateContentSegment function · typescript · L193-L209 (17 LOC)src/models/Segment.ts
export function createContentSegment(
startTime: number,
endTime: number,
clipId?: string
): Segment {
return {
id: `content-${startTime}-${endTime}`,
clipId: clipId || "",
startTime,
endTime,
duration: endTime - startTime,
type: "content",
content: "Active",
isActive: true, // Active by definition
manuallyEdited: false,
};
}getSegmentLabel function · typescript · L217-L222 (6 LOC)src/models/Segment.ts
export function getSegmentLabel(segment: Segment): string {
if (segment.type === "filler_word") {
return segment.content || "Filler Word";
}
return "Silence";
}createVideoClip function · typescript · L19-L39 (21 LOC)src/models/VideoClip.ts
export function createVideoClip(
filePath: string,
fileName: string,
fileSize: number,
metadata: VideoMetadata
): VideoClip {
return {
id: generateId(),
filePath,
fileName,
fileSize,
duration: metadata.duration,
resolution: metadata.resolution,
fps: metadata.fps,
codec: metadata.codec,
order: 0,
segments: [],
processingStatus: "pending",
transcriptStatus: "none",
};
}updateClipStatus function · typescript · L49-L59 (11 LOC)src/models/VideoClip.ts
export function updateClipStatus(
clip: VideoClip,
status: VideoClip["processingStatus"],
errorMessage?: string
): VideoClip {
return {
...clip,
processingStatus: status,
errorMessage: status === "error" ? errorMessage : undefined,
};
}updateClipSegments function · typescript · L68-L74 (7 LOC)src/models/VideoClip.ts
export function updateClipSegments(clip: VideoClip, segments: Segment[]): VideoClip {
return {
...clip,
segments,
processingStatus: "completed",
};
}Powered by Repobility — scan your code at https://repobility.com
getRemovedDuration function · typescript · L82-L86 (5 LOC)src/models/VideoClip.ts
export function getRemovedDuration(clip: VideoClip): number {
return clip.segments
.filter((s) => !s.isActive)
.reduce((sum, s) => sum + (s.duration ?? (s.endTime - s.startTime)), 0);
}getEditedDuration function · typescript · L94-L96 (3 LOC)src/models/VideoClip.ts
export function getEditedDuration(clip: VideoClip): number {
return clip.duration - getRemovedDuration(clip);
}getSegmentsByType function · typescript · L105-L110 (6 LOC)src/models/VideoClip.ts
export function getSegmentsByType(
clip: VideoClip,
type: "filler_word" | "silence"
): Segment[] {
return clip.segments.filter((s) => s.type === type);
}