feat: add an input so the user can go to a specific timestamp (#530)

* feat: add an input so the user can go to a specific timestamp

* fix: use TimeCode type for EditableTimecodeProps

* cleanup

---------

Co-authored-by: Maze Winther <mazewinther@gmail.com>
This commit is contained in:
Zaka
2025-08-15 23:01:18 +02:00
committed by GitHub
co-authored by Maze Winther
parent 033a9aa1bc
commit 7e4cd76762
11 changed files with 76 additions and 77 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
import { create } from "zustand";
import type { PlaybackState, PlaybackControls } from "@/types/playback";
import { useTimelineStore } from "@/stores/timeline-store";
import { useProjectStore } from "./project-store";
import { DEFAULT_FPS, useProjectStore } from "./project-store";
interface PlaybackStore extends PlaybackState, PlaybackControls {
setDuration: (duration: number) => void;
@@ -37,9 +37,9 @@ const startTimer = (store: () => PlaybackStore) => {
// When content completes, pause just before the end so we can see the last frame
const projectFps = useProjectStore.getState().activeProject?.fps;
if (!projectFps)
console.error("Project FPS is not set, assuming 30fps");
console.error("Project FPS is not set, assuming " + DEFAULT_FPS + "fps");
const frameOffset = 1 / (projectFps ?? 30); // Stop 1 frame before end based on project FPS
const frameOffset = 1 / (projectFps ?? DEFAULT_FPS); // Stop 1 frame before end based on project FPS
const stopTime = Math.max(0, effectiveDuration - frameOffset);
state.pause();
@@ -91,7 +91,7 @@ export const usePlaybackStore = create<PlaybackStore>((set, get) => ({
actualContentDuration > 0 ? actualContentDuration : state.duration;
if (effectiveDuration > 0) {
const fps = useProjectStore.getState().activeProject?.fps ?? 30;
const fps = useProjectStore.getState().activeProject?.fps ?? DEFAULT_FPS;
const frameOffset = 1 / fps;
const endThreshold = Math.max(0, effectiveDuration - frameOffset);
+5 -4
View File
@@ -8,6 +8,7 @@ import { generateUUID } from "@/lib/utils";
import { CanvasSize, CanvasMode } from "@/types/editor";
export const DEFAULT_CANVAS_SIZE: CanvasSize = { width: 1920, height: 1080 };
export const DEFAULT_FPS = 30;
const DEFAULT_PROJECT: TProject = {
id: generateUUID(),
@@ -19,7 +20,7 @@ const DEFAULT_PROJECT: TProject = {
backgroundType: "color",
blurIntensity: 8,
bookmarks: [],
fps: 30,
fps: DEFAULT_FPS,
canvasSize: DEFAULT_CANVAS_SIZE,
canvasMode: "preset",
};
@@ -77,7 +78,7 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
if (!activeProject) return;
// Round time to the nearest frame
const fps = activeProject.fps || 30;
const fps = activeProject.fps || DEFAULT_FPS;
const frameTime = Math.round(time * fps) / fps;
const bookmarks = activeProject.bookmarks || [];
@@ -119,7 +120,7 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
if (!activeProject || !activeProject.bookmarks) return false;
// Round time to the nearest frame
const fps = activeProject.fps || 30;
const fps = activeProject.fps || DEFAULT_FPS;
const frameTime = Math.round(time * fps) / fps;
return activeProject.bookmarks.some(
@@ -132,7 +133,7 @@ export const useProjectStore = create<ProjectStore>((set, get) => ({
if (!activeProject || !activeProject.bookmarks) return;
// Round time to the nearest frame
const fps = activeProject.fps || 30;
const fps = activeProject.fps || DEFAULT_FPS;
const frameTime = Math.round(time * fps) / fps;
const updatedBookmarks = activeProject.bookmarks.filter(