summaryrefslogtreecommitdiff
path: root/apps/web/src/hooks
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2025-08-28 22:39:19 +0200
committerMaze Winther <mazewinther@gmail.com>2025-08-28 22:39:19 +0200
commit2d834a49d7d222d7f70ee6b4cf7ab2827b88bb0e (patch)
treedb8a33eb12c6294cc0000caf05c600fe3c33069e /apps/web/src/hooks
parent792fb6cdc06ebcd578d9e27821eb25a7dba9dbd2 (diff)
parenta7d90f7eac90966920c750134d7de9b611b2c38f (diff)
downloadopencut-2d834a49d7d222d7f70ee6b4cf7ab2827b88bb0e.tar.gz
Merge branch 'staging'
Diffstat (limited to 'apps/web/src/hooks')
-rw-r--r--apps/web/src/hooks/use-aspect-ratio.ts12
-rw-r--r--apps/web/src/hooks/use-editor-actions.ts17
-rw-r--r--apps/web/src/hooks/use-keyboard-shortcuts-help.ts8
-rw-r--r--apps/web/src/hooks/use-selection-box.ts16
-rw-r--r--apps/web/src/hooks/use-timeline-element-resize.ts21
5 files changed, 51 insertions, 23 deletions
diff --git a/apps/web/src/hooks/use-aspect-ratio.ts b/apps/web/src/hooks/use-aspect-ratio.ts
index c3fe20c6..b721b74e 100644
--- a/apps/web/src/hooks/use-aspect-ratio.ts
+++ b/apps/web/src/hooks/use-aspect-ratio.ts
@@ -6,7 +6,7 @@ import { DEFAULT_CANVAS_SIZE, useProjectStore } from "@/stores/project-store";
export function useAspectRatio() {
const { canvasPresets } = useEditorStore();
const { activeProject } = useProjectStore();
- const { mediaItems } = useMediaStore();
+ const { mediaFiles } = useMediaStore();
const { tracks } = useTimelineStore();
const canvasSize = activeProject?.canvasSize || DEFAULT_CANVAS_SIZE;
@@ -24,14 +24,14 @@ export function useAspectRatio() {
for (const track of tracks) {
for (const element of track.elements) {
if (element.type === "media") {
- const mediaItem = mediaItems.find(
- (item) => item.id === element.mediaId
+ const mediaFile = mediaFiles.find(
+ (file) => file.id === element.mediaId
);
if (
- mediaItem &&
- (mediaItem.type === "video" || mediaItem.type === "image")
+ mediaFile &&
+ (mediaFile.type === "video" || mediaFile.type === "image")
) {
- return getMediaAspectRatio(mediaItem);
+ return getMediaAspectRatio(mediaFile);
}
}
}
diff --git a/apps/web/src/hooks/use-editor-actions.ts b/apps/web/src/hooks/use-editor-actions.ts
index 81500416..974f9db5 100644
--- a/apps/web/src/hooks/use-editor-actions.ts
+++ b/apps/web/src/hooks/use-editor-actions.ts
@@ -203,6 +203,23 @@ export function useEditorActions() {
);
useActionHandler(
+ "copy-selected",
+ () => {
+ if (selectedElements.length === 0) return;
+ useTimelineStore.getState().copySelected();
+ },
+ undefined
+ );
+
+ useActionHandler(
+ "paste-selected",
+ () => {
+ useTimelineStore.getState().pasteAtTime(currentTime);
+ },
+ undefined
+ );
+
+ useActionHandler(
"toggle-snapping",
() => {
toggleSnapping();
diff --git a/apps/web/src/hooks/use-keyboard-shortcuts-help.ts b/apps/web/src/hooks/use-keyboard-shortcuts-help.ts
index e2cde3b4..29e3c09b 100644
--- a/apps/web/src/hooks/use-keyboard-shortcuts-help.ts
+++ b/apps/web/src/hooks/use-keyboard-shortcuts-help.ts
@@ -63,6 +63,14 @@ const actionDescriptions: Record<
"toggle-snapping": { description: "Toggle snapping", category: "Editing" },
undo: { description: "Undo", category: "History" },
redo: { description: "Redo", category: "History" },
+ "copy-selected": {
+ description: "Copy selected elements",
+ category: "Editing",
+ },
+ "paste-selected": {
+ description: "Paste elements at playhead",
+ category: "Editing",
+ },
};
// Convert key binding format to display format
diff --git a/apps/web/src/hooks/use-selection-box.ts b/apps/web/src/hooks/use-selection-box.ts
index 46e77fa9..87026500 100644
--- a/apps/web/src/hooks/use-selection-box.ts
+++ b/apps/web/src/hooks/use-selection-box.ts
@@ -190,6 +190,22 @@ export function useSelectionBox({
};
}, [selectionBox, selectElementsInBox]);
+ useEffect(() => {
+ if (!selectionBox?.isActive) return;
+
+ const previousBodyUserSelect = document.body.style.userSelect;
+ const container = containerRef.current;
+ const previousContainerUserSelect = container?.style.userSelect ?? "";
+
+ document.body.style.userSelect = "none";
+ if (container) container.style.userSelect = "none";
+
+ return () => {
+ document.body.style.userSelect = previousBodyUserSelect;
+ if (container) container.style.userSelect = previousContainerUserSelect;
+ };
+ }, [selectionBox?.isActive, containerRef]);
+
return {
selectionBox,
handleMouseDown,
diff --git a/apps/web/src/hooks/use-timeline-element-resize.ts b/apps/web/src/hooks/use-timeline-element-resize.ts
index 2875185c..4812459a 100644
--- a/apps/web/src/hooks/use-timeline-element-resize.ts
+++ b/apps/web/src/hooks/use-timeline-element-resize.ts
@@ -9,28 +9,15 @@ interface UseTimelineElementResizeProps {
element: TimelineElement;
track: TimelineTrack;
zoomLevel: number;
- onUpdateTrim: (
- trackId: string,
- elementId: string,
- trimStart: number,
- trimEnd: number
- ) => void;
- onUpdateDuration: (
- trackId: string,
- elementId: string,
- duration: number
- ) => void;
}
export function useTimelineElementResize({
element,
track,
zoomLevel,
- onUpdateTrim,
- onUpdateDuration,
}: UseTimelineElementResizeProps) {
const [resizing, setResizing] = useState<ResizeState | null>(null);
- const { mediaItems } = useMediaStore();
+ const { mediaFiles } = useMediaStore();
const {
updateElementStartTime,
updateElementTrim,
@@ -88,11 +75,11 @@ export function useTimelineElementResize({
// Media elements - check the media type
if (element.type === "media") {
- const mediaItem = mediaItems.find((item) => item.id === element.mediaId);
- if (!mediaItem) return false;
+ const mediaFile = mediaFiles.find((file) => file.id === element.mediaId);
+ if (!mediaFile) return false;
// Images can be extended (static content)
- if (mediaItem.type === "image") {
+ if (mediaFile.type === "image") {
return true;
}