From 82f8f76a844db0b6f10bec9a07ac67a45ad5df5a Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 2 Mar 2026 10:36:19 +0100 Subject: [PATCH] feat: mobile gate --- apps/web/src/app/editor/[project_id]/page.tsx | 21 +++--- .../web/src/components/editor/mobile-gate.tsx | 74 +++++++++++++++++++ 2 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 apps/web/src/components/editor/mobile-gate.tsx diff --git a/apps/web/src/app/editor/[project_id]/page.tsx b/apps/web/src/app/editor/[project_id]/page.tsx index 987af7c6..3ec6ddb8 100644 --- a/apps/web/src/app/editor/[project_id]/page.tsx +++ b/apps/web/src/app/editor/[project_id]/page.tsx @@ -16,22 +16,25 @@ import { Onboarding } from "@/components/editor/onboarding"; import { MigrationDialog } from "@/components/editor/dialogs/migration-dialog"; import { usePanelStore } from "@/stores/panel-store"; import { usePasteMedia } from "@/hooks/use-paste-media"; +import { MobileGate } from "@/components/editor/mobile-gate"; export default function Editor() { const params = useParams(); const projectId = params.project_id as string; return ( - -
- -
- + + +
+ +
+ +
+ +
- - -
- + + ); } diff --git a/apps/web/src/components/editor/mobile-gate.tsx b/apps/web/src/components/editor/mobile-gate.tsx new file mode 100644 index 00000000..685ce178 --- /dev/null +++ b/apps/web/src/components/editor/mobile-gate.tsx @@ -0,0 +1,74 @@ +"use client"; + +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { Button } from "../ui/button"; +import { HugeiconsIcon } from "@hugeicons/react"; +import { ArrowLeft01Icon, ArrowRight01Icon } from "@hugeicons/core-free-icons"; +import { useRouter } from "next/navigation"; + +const STORAGE_KEY = "mobile-acknowledged"; + +interface MobileGateProps { + children: React.ReactNode; +} + +export function MobileGate({ children }: MobileGateProps) { + const router = useRouter(); + const [show, setShow] = useState(null); + + useEffect(() => { + const isMobile = window.innerWidth < 1024; + const acknowledged = localStorage.getItem(STORAGE_KEY) === "true"; + setShow(isMobile && !acknowledged); + }, []); + + if (show === null) return null; + if (!show) return <>{children}; + + const handleContinue = () => { + localStorage.setItem(STORAGE_KEY, "true"); + setShow(false); + }; + + const handleGoBack = () => { + router.back(); + }; + + return ( +
+ + +
+
+

+ Desktop only (for now) +

+

+ OpenCut isn't optimized for mobile or iPad yet. Things will break + and the layout will be a mess. Come back on a desktop for the real + experience. +

+
+
+ + +
+
+
+ ); +}