diff --git a/components/pages/create-video/CreateInput/ConfigPanel.tsx b/components/pages/create-video/CreateInput/ConfigPanel.tsx index 7a949d8..aba5505 100644 --- a/components/pages/create-video/CreateInput/ConfigPanel.tsx +++ b/components/pages/create-video/CreateInput/ConfigPanel.tsx @@ -3,14 +3,13 @@ import { GlobalOutlined, ClockCircleOutlined, - DownOutlined, - MobileOutlined, - DesktopOutlined, + DownOutlined } from '@ant-design/icons'; import { WandSparkles, RectangleHorizontal, RectangleVertical } from 'lucide-react'; import { Dropdown, Menu, Tooltip } from 'antd'; import { LanguageOptions, VideoDurationOptions } from './config-options'; import type { ConfigOptions, LanguageValue, VideoDurationValue } from './config-options'; +import { PortraitAnimeSelector } from './PortraitAnimeSelector'; interface ConfigPanelProps { /** Current configuration options */ @@ -115,7 +114,7 @@ export const ConfigPanel = ({ {/* Aspect ratio toggles */} -
+
+ + {/* Portrait/Anime selector */} + onConfigChange('pcode', v)} + />
); }; diff --git a/components/pages/create-video/CreateInput/PortraitAnimeSelector.tsx b/components/pages/create-video/CreateInput/PortraitAnimeSelector.tsx new file mode 100644 index 0000000..ce5bfe4 --- /dev/null +++ b/components/pages/create-video/CreateInput/PortraitAnimeSelector.tsx @@ -0,0 +1,130 @@ +"use client"; + +import React, { useEffect, useMemo, useState } from 'react'; +import { Dropdown, Menu } from 'antd'; +import { DownOutlined } from '@ant-design/icons'; +import { fetchSettingByCode } from '@/api/serversetting'; +import type { PortraitAnimeValue } from './config-options'; + +interface PortraitAnimeSelectorProps { + /** Current value: 'portrait' or anime pcode */ + value: PortraitAnimeValue; + /** Change handler */ + onChange: (value: PortraitAnimeValue) => void; + /** Optional class name */ + className?: string; + /** Disabled state */ + disabled?: boolean; +} + +/** + * Portrait/Anime selector with dropdown for Anime subtypes. + * Styled to match VideoCreationForm design. + * @param {PortraitAnimeValue} value - Current value: 'portrait' or anime pcode + * @param {(value: PortraitAnimeValue) => void} onChange - Change handler + * @param {string} [className] - Optional wrapper class + * @param {boolean} [disabled] - Disable interaction when true + * @returns {JSX.Element} + */ +export function PortraitAnimeSelector({ + value, + onChange, + className, + disabled = false, +}: PortraitAnimeSelectorProps) { + const [lastAnimeChoice, setLastAnimeChoice] = useState('STANDARD_V1_734684_116483'); + const [animeOptions, setAnimeOptions] = useState>([]); + + useEffect(() => { + if (value && value !== 'portrait') { + setLastAnimeChoice(value); + } + }, [value]); + + useEffect(() => { + let mounted = true; + (async () => { + const list = await fetchSettingByCode>('comic_config', []); + if (!mounted) return; + if (Array.isArray(list) && list.length > 0) { + setAnimeOptions(list); + setLastAnimeChoice((prev) => (prev === 'STANDARD_V1_734684_116483' ? list[0].pcode : prev)); + } else { + setAnimeOptions([ + { name: 'Korean Comics Long', pcode: 'STANDARD_V1_734684_116483' }, + ]); + } + })(); + return () => { mounted = false; }; + }, []); + + const isPortrait = value === 'portrait'; + const currentAnime = useMemo(() => (value && value !== 'portrait' ? value : lastAnimeChoice), [value, lastAnimeChoice]); + const pcodeToName = useMemo(() => { + const map: Record = {}; + animeOptions.forEach((o) => { map[o.pcode] = o.name; }); + return map; + }, [animeOptions]); + + /** Anime dropdown menu */ + const animeMenu = ( + onChange(key as PortraitAnimeValue)} + items={(animeOptions.length > 0 ? animeOptions : []).map((opt) => ({ + key: opt.pcode, + label: {opt.name}, + }))} + /> + ); + + return ( +
+ {/* Portrait button */} + + + {/* Anime dropdown button */} + + + +
+ ); +} + +export default PortraitAnimeSelector; + diff --git a/components/pages/create-video/CreateInput/README.md b/components/pages/create-video/CreateInput/README.md index b7951a8..89462a9 100644 --- a/components/pages/create-video/CreateInput/README.md +++ b/components/pages/create-video/CreateInput/README.md @@ -6,11 +6,12 @@ Video creation input form with configuration options. ``` CreateInput/ -├── VideoCreationForm.tsx # Main form component -├── ConfigPanel.tsx # Configuration panel with all options -├── config-options.ts # Configuration options and types -├── index.ts # Module exports -└── README.md # This file +├── VideoCreationForm.tsx # Main form component +├── ConfigPanel.tsx # Configuration panel with all options +├── PortraitAnimeSelector.tsx # Portrait/Anime style selector +├── config-options.ts # Configuration options and types +├── index.ts # Module exports +└── README.md # This file ``` ## Components @@ -28,6 +29,7 @@ Configuration panel with unified circular button style: - Auto Script toggle (AI Story Copilot) - Duration selector (8s, 1min, 2min, auto) - Aspect ratio selector (landscape/portrait) +- Portrait/Anime style selector All buttons follow the same design pattern: - Circular buttons with `rounded-full` @@ -36,6 +38,13 @@ All buttons follow the same design pattern: - Active state: `border-cyan-400 bg-cyan-400/10` - Cyan color theme for interactions +### PortraitAnimeSelector +Selector for choosing between Portrait and Anime (comic) styles: +- Portrait mode: realistic portrait style +- Anime mode: comic/anime styles with multiple options (Korean Comics Long, etc.) +- Fetches anime options from server dynamically +- Styled to match other configuration buttons + ## Configuration Options Defined in `config-options.ts`: @@ -46,9 +55,18 @@ interface ConfigOptions { expansion_mode: boolean; // Default: false videoDuration: VideoDurationValue; // Default: 'unlimited' aspect_ratio: AspectRatioValue; // Default: 'VIDEO_ASPECT_RATIO_LANDSCAPE' + pcode: PortraitAnimeValue; // Default: 'portrait' } ``` +### Configuration Options Details + +- **language**: Video output language (14 options: English, Chinese, Japanese, Spanish, etc.) +- **expansion_mode**: AI Story Copilot toggle (auto-generates extended script) +- **videoDuration**: Video length (8s, 1min, 2min, auto) +- **aspect_ratio**: Video orientation (landscape/portrait) +- **pcode**: Visual style (portrait or anime/comic style codes) + ## Usage ```tsx diff --git a/components/pages/create-video/CreateInput/VideoCreationForm.tsx b/components/pages/create-video/CreateInput/VideoCreationForm.tsx index c3fc030..27edadd 100644 --- a/components/pages/create-video/CreateInput/VideoCreationForm.tsx +++ b/components/pages/create-video/CreateInput/VideoCreationForm.tsx @@ -74,7 +74,7 @@ export default function VideoCreationForm() { > {/* Photo Preview Section - Top */} {photos.length > 0 && ( -
+