summaryrefslogtreecommitdiff
path: root/apps/web/src/preview/components/context-menu.tsx
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-20 11:31:17 +0200
commit3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch)
tree57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/preview/components/context-menu.tsx
parent729d10592f4e802f91c555c309ff3ba4b119f843 (diff)
downloadopencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/preview/components/context-menu.tsx')
-rw-r--r--apps/web/src/preview/components/context-menu.tsx85
1 files changed, 85 insertions, 0 deletions
diff --git a/apps/web/src/preview/components/context-menu.tsx b/apps/web/src/preview/components/context-menu.tsx
new file mode 100644
index 00000000..fca55d71
--- /dev/null
+++ b/apps/web/src/preview/components/context-menu.tsx
@@ -0,0 +1,85 @@
+"use client";
+
+import {
+ ContextMenuCheckboxItem,
+ ContextMenuContent,
+ ContextMenuItem,
+ ContextMenuSeparator,
+} from "@/components/ui/context-menu";
+import { usePreviewViewport } from "@/preview/components/preview-viewport";
+import { useEditor } from "@/editor/use-editor";
+import type { PreviewOverlayControl } from "@/preview/overlays";
+import { toast } from "sonner";
+
+export function PreviewContextMenu({
+ onToggleFullscreen,
+ containerRef,
+ overlayControls,
+ onOverlayVisibilityChange,
+}: {
+ onToggleFullscreen: () => void;
+ containerRef: React.RefObject<HTMLElement | null>;
+ overlayControls: PreviewOverlayControl[];
+ onOverlayVisibilityChange: (params: {
+ overlayId: string;
+ isVisible: boolean;
+ }) => void;
+}) {
+ const editor = useEditor();
+ const viewport = usePreviewViewport();
+
+ const handleCopySnapshot = async () => {
+ const result = await editor.renderer.copySnapshot();
+
+ if (!result.success) {
+ toast.error("Failed to copy snapshot", {
+ description: result.error ?? "Please try again",
+ });
+ return;
+ }
+ };
+
+ const handleSaveSnapshot = async () => {
+ const result = await editor.renderer.saveSnapshot();
+
+ if (!result.success) {
+ toast.error("Failed to save snapshot", {
+ description: result.error ?? "Please try again",
+ });
+ return;
+ }
+ };
+
+ return (
+ <ContextMenuContent className="w-56" container={containerRef.current}>
+ <ContextMenuItem onClick={viewport.fitToScreen} inset>
+ Fit to screen
+ </ContextMenuItem>
+ <ContextMenuSeparator />
+ <ContextMenuItem onClick={onToggleFullscreen} inset>
+ Full screen
+ </ContextMenuItem>
+ <ContextMenuItem onClick={handleSaveSnapshot} inset>
+ Save snapshot
+ </ContextMenuItem>
+ <ContextMenuItem onClick={handleCopySnapshot} inset>
+ Copy snapshot
+ </ContextMenuItem>
+ {overlayControls.length > 0 ? <ContextMenuSeparator /> : null}
+ {overlayControls.map((overlayControl) => (
+ <ContextMenuCheckboxItem
+ key={overlayControl.id}
+ checked={overlayControl.isVisible}
+ onCheckedChange={(checked) =>
+ onOverlayVisibilityChange({
+ overlayId: overlayControl.id,
+ isVisible: !!checked,
+ })
+ }
+ >
+ {overlayControl.label}
+ </ContextMenuCheckboxItem>
+ ))}
+ </ContextMenuContent>
+ );
+}