diff --git a/messages/en.json b/messages/en.json
index 74b041d..a2469fd 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -914,6 +914,7 @@
"toolShape": "Shape",
"toolDraw": "Draw",
"toolAi": "AI",
+ "panels": "Adjust",
"shapeRectangle": "Rectangle",
"shapeCircle": "Circle",
"shapeLine": "Line",
@@ -1223,6 +1224,8 @@
"transitions": "Transitions",
"font": "Font",
"myWatermark": "My Watermark",
+ "timeline": "Timeline",
+ "preview": "Preview",
"toolsNavLabel": "Studio tools",
"guideMe": "Guide me",
"guideComingSoon": "👋 Guide coming soon!",
diff --git a/messages/fa.json b/messages/fa.json
index 64d9d58..2bf1533 100644
--- a/messages/fa.json
+++ b/messages/fa.json
@@ -914,6 +914,7 @@
"toolShape": "شکل",
"toolDraw": "ترسیم",
"toolAi": "هوش مصنوعی",
+ "panels": "تنظیمات",
"shapeRectangle": "مستطیل",
"shapeCircle": "دایره",
"shapeLine": "خط",
@@ -1223,6 +1224,8 @@
"transitions": "گذارها",
"font": "فونت",
"myWatermark": "واترمارک من",
+ "timeline": "خط زمان",
+ "preview": "پیشنمایش",
"toolsNavLabel": "ابزارهای استودیو",
"guideMe": "راهنماییام کن",
"guideComingSoon": "👋 راهنما بهزودی ارائه میشود!",
diff --git a/src/components/image-editor/ImageEditorLayout.tsx b/src/components/image-editor/ImageEditorLayout.tsx
index 2258ed2..3af6aa6 100644
--- a/src/components/image-editor/ImageEditorLayout.tsx
+++ b/src/components/image-editor/ImageEditorLayout.tsx
@@ -6,8 +6,8 @@ import { AiRemoveBgModal } from "@/components/image-editor/AiRemoveBgModal";
import { ImageCropControls } from "@/components/image-editor/ImageCropControls";
import { ImageEditorRightPanel } from "@/components/image-editor/ImageEditorRightPanel";
import { ImageEditorToolbar } from "@/components/image-editor/ImageEditorToolbar";
+import { ImageEditorMobileLayout } from "@/components/image-editor/ImageEditorMobileLayout";
import { ImageEditorTopBar } from "@/components/image-editor/ImageEditorTopBar";
-import { StudioMobileGate } from "@/components/studio/StudioMobileGate";
import { Toaster } from "@/components/ui/toaster";
import { useImageProjectPersistence } from "@/hooks/useImageProjectPersistence";
import { useIsMobile } from "@/hooks/useIsMobile";
@@ -34,7 +34,14 @@ export function ImageEditorLayout({ projectId }: ImageEditorLayoutProps) {
}
if (isMobile) {
- return ;
+ return (
+
+ );
}
return (
diff --git a/src/components/image-editor/ImageEditorMobileLayout.tsx b/src/components/image-editor/ImageEditorMobileLayout.tsx
new file mode 100644
index 0000000..c988d92
--- /dev/null
+++ b/src/components/image-editor/ImageEditorMobileLayout.tsx
@@ -0,0 +1,135 @@
+"use client";
+
+import { useState, type ComponentProps } from "react";
+import dynamic from "next/dynamic";
+import { SlidersHorizontal } from "lucide-react";
+import { useTranslations } from "next-intl";
+
+import { AiRemoveBgModal } from "@/components/image-editor/AiRemoveBgModal";
+import { ImageCropControls } from "@/components/image-editor/ImageCropControls";
+import { ImageEditorRightPanel } from "@/components/image-editor/ImageEditorRightPanel";
+import {
+ IMAGE_SHAPES,
+ IMAGE_TOOLS,
+} from "@/components/image-editor/ImageEditorToolbar";
+import { ImageEditorTopBar } from "@/components/image-editor/ImageEditorTopBar";
+import { BottomSheet } from "@/components/studio/mobile/BottomSheet";
+import { Toaster } from "@/components/ui/toaster";
+import { useImageEditorStore } from "@/lib/image-editor-store";
+import { cn } from "@/lib/utils";
+
+const ImageEditorCanvas = dynamic(
+ () =>
+ import("@/components/image-editor/canvas/ImageEditorCanvas").then(
+ (mod) => mod.ImageEditorCanvas,
+ ),
+ { ssr: false, loading: () =>
},
+);
+
+type TopBarProps = ComponentProps;
+
+interface Props {
+ projectId?: string;
+ projectName: TopBarProps["projectName"];
+ saveStatus: TopBarProps["saveStatus"];
+ onSaveRetry: TopBarProps["onSaveRetry"];
+}
+
+/**
+ * Phone layout for the Image Editor: canvas fills the viewport, the tool dock
+ * becomes a scrollable bottom bar, and the Adjust/Filters/Layers panel opens as a
+ * bottom sheet. Drawing/selection work via touch (see ImageEditorCanvas).
+ */
+export function ImageEditorMobileLayout({ projectId, projectName, saveStatus, onSaveRetry }: Props) {
+ const t = useTranslations("auto.componentsImageEditorImageEditorToolbar");
+ const activeTool = useImageEditorStore((s) => s.activeTool);
+ const setActiveTool = useImageEditorStore((s) => s.setActiveTool);
+ const setPendingShape = useImageEditorStore((s) => s.setPendingShape);
+ const setAiModalOpen = useImageEditorStore((s) => s.setAiModalOpen);
+ const [panelOpen, setPanelOpen] = useState(false);
+ const [shapeOpen, setShapeOpen] = useState(false);
+
+ return (
+
+
+
+
+
+
+
+
+ {/* Bottom tool bar */}
+
+
+
setPanelOpen(false)}>
+
+
+
+
setShapeOpen(false)} title={t("toolShape")}>
+
+ {IMAGE_SHAPES.map((s) => (
+
+ ))}
+
+
+
+
+
+ );
+}
diff --git a/src/components/image-editor/ImageEditorRightPanel.tsx b/src/components/image-editor/ImageEditorRightPanel.tsx
index b452ebd..4525d71 100644
--- a/src/components/image-editor/ImageEditorRightPanel.tsx
+++ b/src/components/image-editor/ImageEditorRightPanel.tsx
@@ -21,7 +21,7 @@ export function ImageEditorRightPanel() {
const setActivePanelTab = useImageEditorStore((s) => s.setActivePanelTab);
return (
-