From 6427d074b260294cfafdb82ed85f521c634d33d2 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 19:25:24 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/pages/work-flow.tsx | 4 +++- components/pages/work-flow/H5MediaViewer.tsx | 2 +- components/pages/work-flow/thumbnail-grid.tsx | 6 ++---- components/pages/work-flow/use-workflow-data.tsx | 9 ++++++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/components/pages/work-flow.tsx b/components/pages/work-flow.tsx index cecf083..17056f7 100644 --- a/components/pages/work-flow.tsx +++ b/components/pages/work-flow.tsx @@ -138,9 +138,11 @@ const WorkFlow = React.memo(function WorkFlow() { setTimeout(() => { handleTestExportRef.current?.(); }, 0); + + const title = isMobile ? 'editing...' : 'Performing intelligent editing...'; // 显示进度提示并启动超时定时器 - emitToastShow({ title: 'Performing intelligent editing...', progress: 0 }); + emitToastShow({ title: title, progress: 0 }); // 启动自动推进到 90% 的进度(8分钟) if (editingProgressIntervalRef.current) clearInterval(editingProgressIntervalRef.current); editingProgressStartRef.current = Date.now(); diff --git a/components/pages/work-flow/H5MediaViewer.tsx b/components/pages/work-flow/H5MediaViewer.tsx index 8a4940f..6328577 100644 --- a/components/pages/work-flow/H5MediaViewer.tsx +++ b/components/pages/work-flow/H5MediaViewer.tsx @@ -286,7 +286,7 @@ export function H5MediaViewer({ } }; return ( -
+
{scriptData ? ( <> )} {sketch.status === 2 && ( -
-
- -
+
+
⚠️
)} {/* 只在生成过程中或没有分镜图片时使用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" >