-
-
-
+
)}
{/* 只在生成过程中或没有分镜图片时使用ProgressiveReveal */}
diff --git a/components/pages/work-flow/use-workflow-data.tsx b/components/pages/work-flow/use-workflow-data.tsx
index 51bfba6..cdb3d29 100644
--- a/components/pages/work-flow/use-workflow-data.tsx
+++ b/components/pages/work-flow/use-workflow-data.tsx
@@ -7,6 +7,7 @@ import { useScriptService } from "@/app/service/Interaction/ScriptService";
import { useUpdateEffect } from '@/app/hooks/useUpdateEffect';
import { LOADING_TEXT_MAP, TaskObject, Status, Stage } from '@/api/DTO/movieEdit';
import { AspectRatioValue } from '@/components/ChatInputBox/AspectRatioSelector';
+import { useDeviceType } from '@/hooks/useDeviceType';
interface UseWorkflowDataProps {
onEditPlanGenerated?: () => void;
@@ -37,6 +38,8 @@ export function useWorkflowData({ onEditPlanGenerated, editingStatus, onExportFa
}
};
+ const { isMobile, isTablet, isDesktop } = useDeviceType();
+
const cutUrl = process.env.NEXT_PUBLIC_CUT_URL_TO || 'https://smartcut.api.movieflow.ai';
console.log('cutUrl', cutUrl);
@@ -158,7 +161,7 @@ export function useWorkflowData({ onEditPlanGenerated, editingStatus, onExportFa
return;
}
// 显示生成剪辑计划进度提示
- emitToastShow({ title: `Generating intelligent editing plan... ${retryCount ? 'Retry Time: ' + retryCount : ''}`, progress: 0 });
+ emitToastShow({ title: isMobile ? 'Preparing for editing...' : `Generating intelligent editing plan... ${retryCount ? 'Retry Time: ' + retryCount : ''}`, progress: 0 });
// 平滑推进到 80%,后续阶段接管
const start = Date.now();
const duration = 3 * 60 * 1000; // 3分钟推进到 80%
@@ -198,7 +201,7 @@ export function useWorkflowData({ onEditPlanGenerated, editingStatus, onExportFa
setIsGenerateEditPlan(false);
// 显示失败提示,并在稍后隐藏
- emitToastShow({ title: 'Editing plan generation failed. Retrying later.', progress: 0 });
+ // emitToastShow({ title: isMobile ? 'Editing plan generation failed. Retrying later.' : 'Editing plan generation failed. Retrying later.', progress: 0 });
setTimeout(() => {
emitToastHide();
setIsLoadingGenerateEditPlan(false);
@@ -419,7 +422,7 @@ export function useWorkflowData({ onEditPlanGenerated, editingStatus, onExportFa
if (analyze_video_total_count > 0 && !isAnalyzing && analyze_video_completed_count !== analyze_video_total_count) {
setIsAnalyzing(true);
// 显示准备剪辑计划的提示
- emitToastShow({ title: 'Preparing intelligent editing plan...', progress: 0 });
+ emitToastShow({ title: isMobile ? 'Preparing for editing...' : 'Preparing intelligent editing plan...', progress: 0 });
}
if (analyze_video_total_count && analyze_video_completed_count === analyze_video_total_count) {
From 2d363b384ddb97278629cd5b314a2804be275645 Mon Sep 17 00:00:00 2001
From: qikongjian
Date: Thu, 25 Sep 2025 19:51:25 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=94=B9=E6=88=90process?=
=?UTF-8?q?.env.NEXT=5FPUBLIC=5FBASE=5FURL?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
lib/server-config.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/server-config.ts b/lib/server-config.ts
index 01767ee..9463fb4 100644
--- a/lib/server-config.ts
+++ b/lib/server-config.ts
@@ -10,7 +10,14 @@
*/
const localPost = async (url: string, data: any): Promise => {
try {
- const response = await fetch(url, {
+ // 使用环境变量中的 BASE_URL(生产要求使用 NEXT_PUBLIC_BASE_URL)
+ const baseUrl = process.env.NEXT_PUBLIC_BASE_URL || '';
+ const isAbsolute = /^https?:\/\//i.test(url);
+ const normalizedBase = baseUrl.replace(/\/$/, '');
+ const normalizedPath = url.startsWith('/') ? url : `/${url}`;
+ const fullUrl = isAbsolute ? url : `${normalizedBase}${normalizedPath}`;
+
+ const response = await fetch(fullUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
From 402d183f8c4064bf98a797c42201c4146a4bc32e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8C=97=E6=9E=B3?=
<7854742+wang_rumeng@user.noreply.gitee.com>
Date: Thu, 25 Sep 2025 20:05:27 +0800
Subject: [PATCH 3/4] =?UTF-8?q?=E2=9A=A0=EF=B8=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
components/pages/work-flow/media-viewer.tsx | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/components/pages/work-flow/media-viewer.tsx b/components/pages/work-flow/media-viewer.tsx
index 501db9d..7a143ed 100644
--- a/components/pages/work-flow/media-viewer.tsx
+++ b/components/pages/work-flow/media-viewer.tsx
@@ -677,9 +677,7 @@ export const MediaViewer = React.memo(function MediaViewer({
)}
{currentSketch.status === 2 && (
)}
{/* 只在生成过程中或没有分镜图片时使用ProgressiveReveal */}
From 1dcaaf2c1193fa83f592b69355397a37c62d6633 Mon Sep 17 00:00:00 2001
From: moux1024 <403053463@qq.com>
Date: Thu, 25 Sep 2025 20:22:39 +0800
Subject: [PATCH 4/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E4=BF=AE=E6=94=B916:9?=
=?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ChatInputBox/AspectRatioSelector.tsx | 84 +++++++++----------
components/ChatInputBox/ChatInputBox.tsx | 3 +-
2 files changed, 44 insertions(+), 43 deletions(-)
diff --git a/components/ChatInputBox/AspectRatioSelector.tsx b/components/ChatInputBox/AspectRatioSelector.tsx
index 97ed5f5..95d4804 100644
--- a/components/ChatInputBox/AspectRatioSelector.tsx
+++ b/components/ChatInputBox/AspectRatioSelector.tsx
@@ -1,8 +1,6 @@
"use client";
-import { Dropdown } from "antd";
import { RectangleHorizontal, RectangleVertical } from "lucide-react";
-import { AspectRatioOptions } from "./types";
export type AspectRatioValue =
| "VIDEO_ASPECT_RATIO_LANDSCAPE"
@@ -22,13 +20,13 @@ interface AspectRatioSelectorProps {
}
/**
- * A reusable aspect ratio selector (landscape/portrait) using Antd Dropdown.
- * Shows an icon and label, and calls onChange when a new ratio is chosen.
+ * Aspect ratio selector using Antd Radio.Group with two options: landscape and portrait.
+ * Uses icons as button content and triggers onChange when selection changes.
* @param {AspectRatioValue} value - current selected value
* @param {(v: AspectRatioValue) => void} onChange - change handler
- * @param {string} [className] - optional className for trigger button
- * @param {string} [placement] - Dropdown placement, default is top
- * @param {string} [dataAlt] - data-alt attribute for the trigger
+ * @param {string} [className] - optional className for wrapper
+ * @param {string} [placement] - kept for backward compatibility (unused)
+ * @param {string} [dataAlt] - data-alt attribute for the wrapper
* @returns {JSX.Element}
*/
export const AspectRatioSelector = ({
@@ -39,45 +37,47 @@ export const AspectRatioSelector = ({
dataAlt = "config-aspect-ratio",
}: AspectRatioSelectorProps) => {
return (
- ({
- key: option.value,
- label: (
-
- {option.value === "VIDEO_ASPECT_RATIO_LANDSCAPE" ? (
-
- ) : (
-
- )}
- {option.label}
-
- ),
- })),
- onClick: ({ key }) => onChange(key as AspectRatioValue),
- }}
- trigger={["click"]}
- placement={placement}
+
-
+
+
);
};
diff --git a/components/ChatInputBox/ChatInputBox.tsx b/components/ChatInputBox/ChatInputBox.tsx
index 04e219e..dd530cd 100644
--- a/components/ChatInputBox/ChatInputBox.tsx
+++ b/components/ChatInputBox/ChatInputBox.tsx
@@ -523,11 +523,12 @@ export function ChatInputBox({ noData }: { noData: boolean }) {
placement="top"
>