diff --git a/packages/studio/src/index.ts b/packages/studio/src/index.ts index 5ead3f48b..73d710490 100644 --- a/packages/studio/src/index.ts +++ b/packages/studio/src/index.ts @@ -10,13 +10,12 @@ export { PlayerControls, Timeline, PreviewPanel, - AgentActivityTrack, useTimelinePlayer, usePlayerStore, liveTime, formatTime, } from "./player"; -export type { AgentActivity, TimelineElement, ActiveEdits } from "./player"; +export type { TimelineElement, ZoomMode } from "./player"; // Editor export { SourceEditor } from "./components/editor/SourceEditor"; diff --git a/packages/studio/src/player/components/Timeline.tsx b/packages/studio/src/player/components/Timeline.tsx index 8fdb50cb3..8f79f4145 100644 --- a/packages/studio/src/player/components/Timeline.tsx +++ b/packages/studio/src/player/components/Timeline.tsx @@ -163,7 +163,6 @@ export const Timeline = memo(function Timeline({ onSeek, onDrillDown }: Timeline const timelineReady = usePlayerStore((s) => s.timelineReady); const selectedElementId = usePlayerStore((s) => s.selectedElementId); const setSelectedElementId = usePlayerStore((s) => s.setSelectedElementId); - const activeEdits = usePlayerStore((s) => s.activeEdits); const playheadRef = useRef(null); const containerRef = useRef(null); const [hoveredClip, setHoveredClip] = useState(null); @@ -348,8 +347,6 @@ export const Timeline = memo(function Timeline({ onSeek, onDrillDown }: Timeline const isComposition = !!el.compositionSrc; const clipKey = `${el.id}-${i}`; const isHovered = hoveredClip === clipKey; - const activeEdit = activeEdits[el.id]; - const isBeingEdited = !!activeEdit; return (
- {/* Agent ownership dot */} - {el.agentColor && ( -
- )} - {/* Editing glow pulse */} - {/* Agent editing indicator — cursor on the clip */} - {isBeingEdited && ( - <> -
- {/* Agent name badge above clip */} -
- {/* Mini cursor arrow */} - - - - - {activeEdit.agentId} - -
- - )} void; setCurrentTime: (time: number) => void; @@ -40,8 +39,17 @@ interface PlayerState { setTimelineReady: (ready: boolean) => void; setElements: (elements: TimelineElement[]) => void; setSelectedElementId: (id: string | null) => void; - setActiveEdits: (edits: ActiveEdits) => void; + setEditRange: (start: number | null, end: number | null) => void; + setEditMode: (active: boolean) => void; updateElementStart: (elementId: string, newStart: number) => void; + updateElementDuration: (elementId: string, newDuration: number) => void; + updateElementTrack: (elementId: string, newTrack: number) => void; + updateElement: ( + elementId: string, + updates: Partial>, + ) => void; + setZoomMode: (mode: ZoomMode) => void; + setPixelsPerSecond: (pps: number) => void; reset: () => void; } @@ -65,21 +73,42 @@ export const usePlayerStore = create((set) => ({ timelineReady: false, elements: [], selectedElementId: null, - activeEdits: {}, playbackRate: 1, + zoomMode: "fit", + pixelsPerSecond: 100, + editRangeStart: null, + editRangeEnd: null, + editMode: false, setIsPlaying: (playing) => set({ isPlaying: playing }), setPlaybackRate: (rate) => set({ playbackRate: rate }), - setCurrentTime: (time) => set({ currentTime: time }), - setDuration: (duration) => set({ duration }), + setZoomMode: (mode) => set({ zoomMode: mode }), + setPixelsPerSecond: (pps) => set({ pixelsPerSecond: Math.max(10, pps) }), + setCurrentTime: (time) => set({ currentTime: Number.isFinite(time) ? time : 0 }), + setDuration: (duration) => set({ duration: Number.isFinite(duration) ? duration : 0 }), setTimelineReady: (ready) => set({ timelineReady: ready }), setElements: (elements) => set({ elements }), setSelectedElementId: (id) => set({ selectedElementId: id }), - setActiveEdits: (edits) => set({ activeEdits: edits }), + setEditRange: (start, end) => set({ editRangeStart: start, editRangeEnd: end }), + setEditMode: (active) => set({ editMode: active, editRangeStart: null, editRangeEnd: null }), updateElementStart: (elementId, newStart) => set((state) => ({ elements: state.elements.map((el) => (el.id === elementId ? { ...el, start: newStart } : el)), })), + updateElementDuration: (elementId, newDuration) => + set((state) => ({ + elements: state.elements.map((el) => + el.id === elementId ? { ...el, duration: newDuration } : el, + ), + })), + updateElementTrack: (elementId, newTrack) => + set((state) => ({ + elements: state.elements.map((el) => (el.id === elementId ? { ...el, track: newTrack } : el)), + })), + updateElement: (elementId, updates) => + set((state) => ({ + elements: state.elements.map((el) => (el.id === elementId ? { ...el, ...updates } : el)), + })), reset: () => set({ isPlaying: false, @@ -88,6 +117,5 @@ export const usePlayerStore = create((set) => ({ timelineReady: false, elements: [], selectedElementId: null, - activeEdits: {}, }), }));