forked from 77media/video-flow
更新语言选择功能,将语言选项从简写改为完整名称,优化主题标签选择逻辑,增加错误提示时长和位置,新增智能优化按钮以提升用户体验。
This commit is contained in:
parent
f9a6b48f41
commit
4d2c0b661b
@ -29,7 +29,7 @@ export function CreateToVideo2() {
|
|||||||
const [isFocus, setIsFocus] = useState(false);
|
const [isFocus, setIsFocus] = useState(false);
|
||||||
const [selectedMode, setSelectedMode] = useState<ModeEnum>(ModeEnum.AUTOMATIC);
|
const [selectedMode, setSelectedMode] = useState<ModeEnum>(ModeEnum.AUTOMATIC);
|
||||||
const [selectedResolution, setSelectedResolution] = useState<ResolutionEnum>(ResolutionEnum.HD_720P);
|
const [selectedResolution, setSelectedResolution] = useState<ResolutionEnum>(ResolutionEnum.HD_720P);
|
||||||
const [selectedLanguage, setSelectedLanguage] = useState<string>('en');
|
const [selectedLanguage, setSelectedLanguage] = useState<string>('english');
|
||||||
const [script, setInputText] = useState('');
|
const [script, setInputText] = useState('');
|
||||||
const editorRef = useRef<HTMLDivElement>(null);
|
const editorRef = useRef<HTMLDivElement>(null);
|
||||||
const [runTour, setRunTour] = useState(true);
|
const [runTour, setRunTour] = useState(true);
|
||||||
@ -136,7 +136,8 @@ export function CreateToVideo2() {
|
|||||||
user_id: String(userId),
|
user_id: String(userId),
|
||||||
script: script,
|
script: script,
|
||||||
mode: selectedMode,
|
mode: selectedMode,
|
||||||
resolution: selectedResolution
|
resolution: selectedResolution,
|
||||||
|
language: selectedLanguage
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调用创建剧集API
|
// 调用创建剧集API
|
||||||
@ -244,7 +245,7 @@ export function CreateToVideo2() {
|
|||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
key: 'en',
|
key: 'english',
|
||||||
label: (
|
label: (
|
||||||
<div className="flex items-center justify-between p-1">
|
<div className="flex items-center justify-between p-1">
|
||||||
<span className="text-base">English</span>
|
<span className="text-base">English</span>
|
||||||
@ -252,7 +253,7 @@ export function CreateToVideo2() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'zh',
|
key: 'chinese',
|
||||||
label: (
|
label: (
|
||||||
<div className="flex items-center justify-between p-1">
|
<div className="flex items-center justify-between p-1">
|
||||||
<span className="text-base">Chinese</span>
|
<span className="text-base">Chinese</span>
|
||||||
@ -261,7 +262,7 @@ export function CreateToVideo2() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ja',
|
key: 'japanese',
|
||||||
label: (
|
label: (
|
||||||
<div className="flex items-center justify-between p-1">
|
<div className="flex items-center justify-between p-1">
|
||||||
<span className="text-base">Japanese</span>
|
<span className="text-base">Japanese</span>
|
||||||
@ -270,7 +271,7 @@ export function CreateToVideo2() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'ko',
|
key: 'korean',
|
||||||
label: (
|
label: (
|
||||||
<div className="flex items-center justify-between p-1">
|
<div className="flex items-center justify-between p-1">
|
||||||
<span className="text-base">Korean</span>
|
<span className="text-base">Korean</span>
|
||||||
@ -302,16 +303,11 @@ export function CreateToVideo2() {
|
|||||||
if (loadingIdea) return;
|
if (loadingIdea) return;
|
||||||
setLoadingIdea(true);
|
setLoadingIdea(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setInputText('idea');
|
setInputText(ideaText);
|
||||||
setLoadingIdea(false);
|
setLoadingIdea(false);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStartCreating = () => {
|
|
||||||
setActiveTab('script');
|
|
||||||
setInputText(ideaText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理编辑器聚焦
|
// 处理编辑器聚焦
|
||||||
const handleEditorFocus = () => {
|
const handleEditorFocus = () => {
|
||||||
setIsFocus(true);
|
setIsFocus(true);
|
||||||
|
|||||||
@ -107,7 +107,12 @@ export const ScriptRenderer: React.FC<ScriptRendererProps> = ({ data }) => {
|
|||||||
const handleThemeTagChange = (value: string[]) => {
|
const handleThemeTagChange = (value: string[]) => {
|
||||||
console.log('主题标签更改', value);
|
console.log('主题标签更改', value);
|
||||||
if (value.length > 5) {
|
if (value.length > 5) {
|
||||||
return toast.error('最多可选择5个主题标签');
|
toast.error('最多可选择5个主题标签', {
|
||||||
|
duration: 3000,
|
||||||
|
position: 'top-center',
|
||||||
|
richColors: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
setAddThemeTag(value);
|
setAddThemeTag(value);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import { motion } from "framer-motion";
|
|||||||
import { CharacterTokenExtension } from './CharacterToken';
|
import { CharacterTokenExtension } from './CharacterToken';
|
||||||
import { ShotTitle } from './ShotTitle';
|
import { ShotTitle } from './ShotTitle';
|
||||||
import { ReadonlyText } from './ReadonlyText';
|
import { ReadonlyText } from './ReadonlyText';
|
||||||
|
import { Sparkles } from 'lucide-react';
|
||||||
|
import { toast } from 'sonner';
|
||||||
|
|
||||||
const initialContent = {
|
const initialContent = {
|
||||||
type: 'doc',
|
type: 'doc',
|
||||||
@ -41,6 +43,14 @@ interface ShotEditorProps {
|
|||||||
|
|
||||||
const ShotEditor = React.forwardRef<{ addSegment: () => void, onCharacterClick: (attrs: any) => void }, ShotEditorProps>(function ShotEditor({ onAddSegment, onCharacterClick }, ref) {
|
const ShotEditor = React.forwardRef<{ addSegment: () => void, onCharacterClick: (attrs: any) => void }, ShotEditorProps>(function ShotEditor({ onAddSegment, onCharacterClick }, ref) {
|
||||||
const [segments, setSegments] = useState(initialContent.content);
|
const [segments, setSegments] = useState(initialContent.content);
|
||||||
|
const [isOptimizing, setIsOptimizing] = useState(false);
|
||||||
|
|
||||||
|
const handleSmartPolish = () => {
|
||||||
|
setIsOptimizing(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsOptimizing(false);
|
||||||
|
}, 3000);
|
||||||
|
};
|
||||||
|
|
||||||
const editor = useEditor({
|
const editor = useEditor({
|
||||||
extensions: [
|
extensions: [
|
||||||
@ -86,6 +96,16 @@ const ShotEditor = React.forwardRef<{ addSegment: () => void, onCharacterClick:
|
|||||||
shotCount++;
|
shotCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 不能超过4个分镜
|
||||||
|
if (shotCount >= 4) {
|
||||||
|
toast.error('不能超过4个分镜', {
|
||||||
|
duration: 3000,
|
||||||
|
position: 'top-center',
|
||||||
|
richColors: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
editor.chain().focus('end').insertContent([
|
editor.chain().focus('end').insertContent([
|
||||||
{
|
{
|
||||||
@ -116,8 +136,21 @@ const ShotEditor = React.forwardRef<{ addSegment: () => void, onCharacterClick:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full max-w-3xl mx-auto relative p-[0.5rem] pb-[2.5rem] border border-white/10 rounded-[0.5rem]">
|
<div className="w-full relative p-[0.5rem] pb-[2.5rem] border border-white/10 rounded-[0.5rem]">
|
||||||
<EditorContent editor={editor} />
|
<EditorContent editor={editor} />
|
||||||
|
{/* 智能润色按钮 */}
|
||||||
|
<motion.button
|
||||||
|
onClick={handleSmartPolish}
|
||||||
|
disabled={isOptimizing}
|
||||||
|
className="absolute bottom-3 right-3 flex items-center gap-1.5 px-3 py-1.5
|
||||||
|
bg-purple-500/10 hover:bg-purple-500/20 text-purple-500 rounded-full
|
||||||
|
transition-colors text-xs disabled:opacity-50"
|
||||||
|
whileHover={{ scale: 1.05 }}
|
||||||
|
whileTap={{ scale: 0.95 }}
|
||||||
|
>
|
||||||
|
<Sparkles className="w-3.5 h-3.5" />
|
||||||
|
<span>{isOptimizing ? "优化中..." : "智能优化"}</span>
|
||||||
|
</motion.button>
|
||||||
{/* <motion.button
|
{/* <motion.button
|
||||||
onClick={addSegment}
|
onClick={addSegment}
|
||||||
className="group absolute bottom-[0.5rem] h-8 rounded-full bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 flex items-center justify-center overflow-hidden"
|
className="group absolute bottom-[0.5rem] h-8 rounded-full bg-blue-500/10 text-blue-400 hover:bg-blue-500/20 flex items-center justify-center overflow-hidden"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user