summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/panels/timeline/index.tsx
diff options
context:
space:
mode:
authorMaze <167211895+mazeincoding@users.noreply.github.com>2026-02-23 03:24:02 +0100
committerGitHub <noreply@github.com>2026-02-23 03:24:02 +0100
commit93d1e3383ce47e45157d70f9ba6251239dae6bc2 (patch)
tree1e33a2d7533b65f0e7c8927f03905a1a99937bd1 /apps/web/src/components/editor/panels/timeline/index.tsx
parentfca99d6126c31fbb18ed9f1034cee6f940b040e8 (diff)
downloadopencut-93d1e3383ce47e45157d70f9ba6251239dae6bc2.tar.gz
feat: major editor overhaul (assets, properties, timeline, fonts) (#709)
* feat: major editor overhaul (assets, properties, timeline, fonts) Refactor editor core systems to standardize UI architecture and improve performance. Assets & Properties: - Replace monolithic property items with composable `Section` architecture. - Add specialized sections for Transform, Blending, and Text. - Implement `NumberField` with scrubbing and math evaluation. - Add new ColorPicker with EyeDropper and multiple format support. - Standardize asset panels using new `PanelView` layout. Fonts & Stickers: - Implement custom font atlas/sprite system for high-performance previews. - Add virtualized FontPicker with search and favorites. - Refactor stickers to use a provider-based architecture (icons, emoji, flags, shapes). - Standardize sticker IDs to `provider:value` format. Timeline & Interaction: - Convert bookmarks to rich objects with notes, colors, and duration. - Refactor drag-and-drop to use Command pattern (enabling proper undo/redo). - Add Shift modifier to disable snapping during moves/resizes. - Add new overlays for layout guides and text editing. Renderer: - Add support for multi-line text, custom line-height, and letter-spacing. - Implement global composite operation (blend modes). - Update sticker node to resolve dynamic provider IDs. Infrastructure: - Add storage migrations (v3->v6) for text weights, sticker IDs, and bookmarks. - Update global styles and core UI components (Button, Input, Popover). * add ts-nocheck directive to settings-legacy.tsx to suppress TypeScript errors * fix: correct global composite operation assignment in TextNode to ensure proper blend mode handling * deleted shadcn components with errors * formatting * fix linter issues * migrate from next middleware to proxy * add missing component back * add breadcrumb back * chore: add @radix-ui/react-primitive deps * chore: more deps * chore: add missing env vars to bun-ci * next env
Diffstat (limited to 'apps/web/src/components/editor/panels/timeline/index.tsx')
-rw-r--r--apps/web/src/components/editor/panels/timeline/index.tsx29
1 files changed, 26 insertions, 3 deletions
diff --git a/apps/web/src/components/editor/panels/timeline/index.tsx b/apps/web/src/components/editor/panels/timeline/index.tsx
index 94edc2d0..7e6ff326 100644
--- a/apps/web/src/components/editor/panels/timeline/index.tsx
+++ b/apps/web/src/components/editor/panels/timeline/index.tsx
@@ -47,6 +47,8 @@ import { useTimelineSeek } from "@/hooks/timeline/use-timeline-seek";
import { useTimelineDragDrop } from "@/hooks/timeline/use-timeline-drag-drop";
import { TimelineRuler } from "./timeline-ruler";
import { TimelineBookmarksRow } from "./bookmarks";
+import { useBookmarkDrag } from "@/hooks/timeline/use-bookmark-drag";
+import { useEdgeAutoScroll } from "@/hooks/timeline/use-edge-auto-scroll";
import { useTimelineStore } from "@/stores/timeline-store";
import { useEditor } from "@/hooks/use-editor";
import { useTimelinePlayhead } from "@/hooks/timeline/use-timeline-playhead";
@@ -126,6 +128,17 @@ export function Timeline() {
onSnapPointChange: handleSnapPointChange,
});
+ const {
+ dragState: bookmarkDragState,
+ handleBookmarkMouseDown,
+ lastMouseXRef: bookmarkLastMouseXRef,
+ } = useBookmarkDrag({
+ zoomLevel,
+ scrollRef: tracksScrollRef,
+ snappingEnabled,
+ onSnapPointChange: handleSnapPointChange,
+ });
+
const { handleRulerMouseDown: handlePlayheadRulerMouseDown } =
useTimelinePlayhead({
zoomLevel,
@@ -168,10 +181,18 @@ export function Timeline() {
containerWidth,
);
+ useEdgeAutoScroll({
+ isActive: bookmarkDragState.isDragging,
+ getMouseClientX: () => bookmarkLastMouseXRef.current,
+ rulerScrollRef: tracksScrollRef,
+ tracksScrollRef,
+ contentWidth: dynamicTimelineWidth,
+ });
+
const showSnapIndicator =
snappingEnabled &&
currentSnapPoint !== null &&
- (dragState.isDragging || isResizing);
+ (dragState.isDragging || bookmarkDragState.isDragging || isResizing);
const {
handleTracksMouseDown,
@@ -351,7 +372,7 @@ export function Timeline() {
>
<div
ref={timelineHeaderRef}
- className="bg-background sticky top-0 z-30 flex flex-col"
+ className="bg-background sticky top-0 flex flex-col"
>
<TimelineRuler
zoomLevel={zoomLevel}
@@ -366,6 +387,8 @@ export function Timeline() {
<TimelineBookmarksRow
zoomLevel={zoomLevel}
dynamicTimelineWidth={dynamicTimelineWidth}
+ dragState={bookmarkDragState}
+ onBookmarkMouseDown={handleBookmarkMouseDown}
handleWheel={handleWheel}
handleTimelineContentClick={handleRulerClick}
handleRulerTrackingMouseDown={handleRulerMouseDown}
@@ -433,7 +456,7 @@ export function Timeline() {
/>
</div>
</ContextMenuTrigger>
- <ContextMenuContent className="z-200 w-40">
+ <ContextMenuContent className="w-40">
<ContextMenuItem
icon={<HugeiconsIcon icon={TaskAdd02Icon} />}
onClick={(e) => {