diff options
Diffstat (limited to 'apps/web/src/lib')
| -rw-r--r-- | apps/web/src/lib/storage/storage-service.ts | 4 | ||||
| -rw-r--r-- | apps/web/src/lib/storage/types.ts | 1 | ||||
| -rw-r--r-- | apps/web/src/lib/time.ts | 93 |
3 files changed, 98 insertions, 0 deletions
diff --git a/apps/web/src/lib/storage/storage-service.ts b/apps/web/src/lib/storage/storage-service.ts index 0037dbdb..2ff63ac7 100644 --- a/apps/web/src/lib/storage/storage-service.ts +++ b/apps/web/src/lib/storage/storage-service.ts @@ -63,6 +63,8 @@ class StorageService { backgroundColor: project.backgroundColor, backgroundType: project.backgroundType, blurIntensity: project.blurIntensity, + bookmarks: project.bookmarks, + fps: project.fps, }; await this.projectsAdapter.set(project.id, serializedProject); @@ -83,6 +85,8 @@ class StorageService { backgroundColor: serializedProject.backgroundColor, backgroundType: serializedProject.backgroundType, blurIntensity: serializedProject.blurIntensity, + bookmarks: serializedProject.bookmarks, + fps: serializedProject.fps, }; } diff --git a/apps/web/src/lib/storage/types.ts b/apps/web/src/lib/storage/types.ts index b662c164..0cfafd47 100644 --- a/apps/web/src/lib/storage/types.ts +++ b/apps/web/src/lib/storage/types.ts @@ -37,6 +37,7 @@ export interface StorageConfig { export type SerializedProject = Omit<TProject, "createdAt" | "updatedAt"> & { createdAt: string; updatedAt: string; + bookmarks?: number[]; }; // Extend FileSystemDirectoryHandle with missing async iterator methods diff --git a/apps/web/src/lib/time.ts b/apps/web/src/lib/time.ts index df02d837..f24c5961 100644 --- a/apps/web/src/lib/time.ts +++ b/apps/web/src/lib/time.ts @@ -23,3 +23,96 @@ export const formatTimeCode = ( return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}:${frames.toString().padStart(2, "0")}`; } }; + +export const parseTimeCode = ( + timeCode: string, + format: "MM:SS" | "HH:MM:SS" | "HH:MM:SS:CS" | "HH:MM:SS:FF" = "HH:MM:SS:CS", + fps = 30 +): number | null => { + if (!timeCode || typeof timeCode !== "string") return null; + + // Remove any extra whitespace + const cleanTimeCode = timeCode.trim(); + + try { + switch (format) { + case "MM:SS": { + const parts = cleanTimeCode.split(":"); + if (parts.length !== 2) return null; + const [minutes, seconds] = parts.map((part) => parseInt(part, 10)); + if (isNaN(minutes) || isNaN(seconds)) return null; + if (minutes < 0 || seconds < 0 || seconds >= 60) return null; + return minutes * 60 + seconds; + } + + case "HH:MM:SS": { + const parts = cleanTimeCode.split(":"); + if (parts.length !== 3) return null; + const [hours, minutes, seconds] = parts.map((part) => + parseInt(part, 10) + ); + if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) return null; + if ( + hours < 0 || + minutes < 0 || + seconds < 0 || + minutes >= 60 || + seconds >= 60 + ) + return null; + return hours * 3600 + minutes * 60 + seconds; + } + + case "HH:MM:SS:CS": { + const parts = cleanTimeCode.split(":"); + if (parts.length !== 4) return null; + const [hours, minutes, seconds, centiseconds] = parts.map((part) => + parseInt(part, 10) + ); + if ( + isNaN(hours) || + isNaN(minutes) || + isNaN(seconds) || + isNaN(centiseconds) + ) + return null; + if ( + hours < 0 || + minutes < 0 || + seconds < 0 || + centiseconds < 0 || + minutes >= 60 || + seconds >= 60 || + centiseconds >= 100 + ) + return null; + return hours * 3600 + minutes * 60 + seconds + centiseconds / 100; + } + + case "HH:MM:SS:FF": { + const parts = cleanTimeCode.split(":"); + if (parts.length !== 4) return null; + const [hours, minutes, seconds, frames] = parts.map((part) => + parseInt(part, 10) + ); + if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) || isNaN(frames)) + return null; + if ( + hours < 0 || + minutes < 0 || + seconds < 0 || + frames < 0 || + minutes >= 60 || + seconds >= 60 || + frames >= fps + ) + return null; + return hours * 3600 + minutes * 60 + seconds + frames / fps; + } + } + } catch { + return null; + } + + return null; +}; |
