"use client"; import { useState, useRef, useEffect, useMemo } from "react"; import "./style/home-page2.css"; import { usePathname, useRouter } from "next/navigation"; import { Swiper, SwiperSlide } from "swiper/react"; import "swiper/swiper-bundle.css"; // 引入样式 import "swiper/css/effect-coverflow"; import "swiper/css/effect-cube"; import "swiper/css/pagination"; import { Autoplay, EffectCoverflow, EffectCube, Pagination, } from "swiper/modules"; import LazyLoad from "react-lazyload"; import { fetchSubscriptionPlans, SubscriptionPlan } from "@/lib/stripe"; import VideoCoverflow from "@/components/ui/VideoCoverflow"; import { fetchTabsByCode, HomeTabItem } from "@/api/serversetting"; import H5TopBar from "@/components/layout/H5TopBar"; import { useCallbackModal } from "@/app/layout"; import { useDeviceType } from "@/hooks/useDeviceType"; import Footer from "@/components/common/Footer"; /** 视频预加载系统 - 后台静默运行 */ function useVideoPreloader() { /** 预加载单个视频 */ const preloadVideo = (src: string): Promise => { return new Promise((resolve) => { const video = document.createElement("video"); video.muted = true; video.preload = "auto"; // 设置超时,避免某个视频卡住整个预加载过程 const timeout = setTimeout(() => { console.warn(`视频预加载超时: ${src}`); resolve(); }, 10000); // 10秒超时 video.onloadeddata = () => { clearTimeout(timeout); resolve(); }; video.onerror = () => { clearTimeout(timeout); console.warn(`视频预加载失败: ${src}`); resolve(); // 即使失败也继续,不影响其他视频 }; video.src = src; video.load(); }); }; /** 预加载所有视频 */ const preloadAllVideos = async () => { const allVideos = [ // HomeModule1 - 首屏视频(最高优先级) "https://cdn.qikongjian.com/videos/home.mp4", // HomeModule2 - 核心价值视频(高优先级) "https://cdn.qikongjian.com/videos/module2 (1).mp4", "https://cdn.qikongjian.com/videos/module2 (2).mp4", "https://cdn.qikongjian.com/videos/module2 (3).mp4", // HomeModule4 - 制作工序视频(中优先级) "https://cdn.qikongjian.com/videos/module4 (3).mp4", "https://cdn.qikongjian.com/videos/module4 (1).mp4", "https://cdn.qikongjian.com/videos/module4 (4).mp4", "https://cdn.qikongjian.com/videos/module4 (2).mp4", // HomeModule3 - 案例展示视频(低优先级,数量多) "https://cdn.qikongjian.com/videos/show (1).mp4", "https://cdn.qikongjian.com/videos/show (2).mp4", "https://cdn.qikongjian.com/videos/show (3).mp4", "https://cdn.qikongjian.com/videos/show (4).mp4", "https://cdn.qikongjian.com/videos/show (5).mp4", "https://cdn.qikongjian.com/videos/show (6).mp4", "https://cdn.qikongjian.com/videos/show (7).mp4", "https://cdn.qikongjian.com/videos/show (8).mp4", "https://cdn.qikongjian.com/videos/show (9).mp4", "https://cdn.qikongjian.com/videos/show (10).mp4", "https://cdn.qikongjian.com/videos/show (11).mp4", "https://cdn.qikongjian.com/videos/show (12).mp4", "https://cdn.qikongjian.com/videos/show (13).mp4", "https://cdn.qikongjian.com/videos/show (14).mp4", "https://cdn.qikongjian.com/videos/show (15).mp4", ]; try { // 分阶段预加载:先加载关键视频,再加载其他视频 const criticalVideos = allVideos.slice(0, 8); // 前8个是关键视频 const otherVideos = allVideos.slice(8); // 第一阶段:预加载关键视频 for (let i = 0; i < criticalVideos.length; i += 2) { const batch = criticalVideos.slice(i, i + 2); await Promise.all(batch.map(preloadVideo)); } // 第二阶段:后台预加载其他视频 if (otherVideos.length > 0) { // 使用 requestIdleCallback 在浏览器空闲时预加载 const preloadRemaining = () => { let index = 0; const processBatch = () => { if (index >= otherVideos.length) return; const batch = otherVideos.slice( index, Math.min(index + 3, otherVideos.length) ); batch.forEach(preloadVideo); index += batch.length; if (index < otherVideos.length) { requestIdleCallback(processBatch, { timeout: 1000 }); } }; requestIdleCallback(processBatch, { timeout: 1000 }); }; // 如果浏览器不支持 requestIdleCallback,使用 setTimeout if (typeof requestIdleCallback !== "undefined") { preloadRemaining(); } else { setTimeout(() => { for (let i = 0; i < otherVideos.length; i += 3) { const batch = otherVideos.slice(i, i + 3); batch.forEach(preloadVideo); } }, 100); } } } catch (error) { console.error("视频预加载过程中出现错误:", error); } }; // useEffect(() => { // // 使用 requestIdleCallback 在浏览器空闲时开始预加载 // // 如果浏览器不支持,则使用 setTimeout 延迟执行 // if (typeof requestIdleCallback !== "undefined") { // requestIdleCallback(() => preloadAllVideos(), { timeout: 2000 }); // } else { // setTimeout(() => preloadAllVideos(), 100); // } // }, []); // 这个 hook 不需要返回任何值,它只是后台静默运行 return; } export function HomePage2() { // 后台静默预加载视频,不显示任何加载界面 useVideoPreloader(); /** 导航滚动容器与各锚点 */ const containerRef = useRef(null); const sectionRefs = useRef>({ home: null, core: null, cases: null, showreel: null, process: null, pricing: null, footer: null, }); const [menuOpen, setMenuOpen] = useState(false); const [homeTabsPC, setHomeTabsPC] = useState([]); const [homeTabsH5, setHomeTabsH5] = useState([]); const { isMobile } = useDeviceType(); // 旧锚点兼容已移除,完全使用接口 homeTab 渲染 useEffect(() => { let isMounted = true; async function loadTabsBoth() { try { const [pc, h5] = await Promise.all([ fetchTabsByCode('homeTab'), fetchTabsByCode('homeTabH5'), ]); if (!isMounted) return; if (Array.isArray(pc)) setHomeTabsPC(pc); if (Array.isArray(h5)) setHomeTabsH5(h5); } catch { // 忽略错误,保持空态 } } loadTabsBoth(); return () => { isMounted = false; }; }, []); const tabsToRender = isMobile ? homeTabsH5 : homeTabsPC; /** 在容器内平滑滚动到锚点,兼容有固定导航时的微调 */ const scrollToSection = (key: keyof typeof sectionRefs.current) => { try { const container = containerRef.current; const target = sectionRefs.current[key]; if (!container || !target) return; const containerTop = container.getBoundingClientRect().top; const targetTop = target.getBoundingClientRect().top; const currentScrollTop = container.scrollTop; const NAV_OFFSET = 64; // 顶部导航高度微调 const delta = targetTop - containerTop + currentScrollTop - NAV_OFFSET; container.scrollTo({ top: Math.max(delta, 0), behavior: 'smooth' }); setMenuOpen(false); } catch { // 忽略滚动异常 } }; const NavBar = () => { if (tabsToRender.length === 0) return null; useEffect(() => { const handler = () => setMenuOpen((v) => !v); window.addEventListener('home-menu-toggle' as any, handler as any); return () => window.removeEventListener('home-menu-toggle' as any, handler as any); }, []); return (
{/* 桌面端菜单(居中,仅三个项) */}
{tabsToRender.map((tab) => ( ))}
{/* 移动端交由 H5TopBar 控制 */}
); }; return (
{/* 移动端顶部导航(抽屉式) */} { isMobile ? ( scrollToSection(key as any)} />) : () } {/* 动态锚点:来源于服务端 homeTab/homeTabH5 配置,title 作为锚点与标题 */} {tabsToRender.map((tab) => (
(sectionRefs.current as any)[tab.title.toLowerCase()] = el}>
))}
); } /** 首屏 */ function HomeModule1() { const router = useRouter(); return (

Ideas Spark Movies

Unlock the world's first free AI video agent.

Your idea. One click. No cost.

{ if (localStorage.getItem("token")) { router.push("/movies"); } else { router.push("/login"); } }} > Make a Movie
); } /**核心价值 */ function HomeModule2() { const [isMobile, setIsMobile] = useState(true); // 检测屏幕尺寸并设置状态 useEffect(() => { const checkScreenSize = () => { setIsMobile(window.innerWidth < 640); }; // 初始检查 checkScreenSize(); // 监听窗口大小变化 }, []); const videoList = [ { title: "Text to Movie", video: "https://cdn.qikongjian.com/1756559467841_kn9fr9.mp4", }, { title: "Image to Movie", video: "https://cdn.qikongjian.com/1756559467840_m4ijd7.mp4", }, { title: "Template to Movie", video: "https://cdn.qikongjian.com/1756559467836_ij9y54.mp4", }, ]; return (

Just Drop A Thought

Say your idea in a single line, and MovieFlow will bring it to life.

{ // 只播放当前活跃的视频 const activeSlide = swiper.slides[swiper.activeIndex]; const activeVideo = activeSlide?.querySelector("video"); if (activeVideo) { activeVideo.play().catch(() => { // 忽略播放错误 }); } }} onSwiper={(swiper) => { // 初始化时播放第二个视频(索引为1) const secondVideo = swiper.slides[1]?.querySelector("video"); if (secondVideo) { secondVideo.play().catch(() => { // 忽略播放错误 }); } }} > {videoList.map((item, index) => ( ))}
); } /**案例展示 */ function HomeModule3() { const [isMobile, setIsMobile] = useState(true); // 检测屏幕尺寸并设置状态 useEffect(() => { const checkScreenSize = () => { setIsMobile(window.innerWidth < 640); }; // 初始检查 checkScreenSize(); // // 监听窗口大小变化 }, []); // PC端二维数组数据 const pcVideoList = [ [ "https://cdn.qikongjian.com/1756474023656_60twk5.mp4", "https://cdn.qikongjian.com/1756474023644_14n7is.mp4", "https://cdn.qikongjian.com/1756474023648_kocq6z.mp4", "https://cdn.qikongjian.com/1756474023657_w10boo.mp4", "https://cdn.qikongjian.com/1756474023657_nf8799.mp4", "https://cdn.qikongjian.com/1756474230992_vw0ubf.mp4", ], [ "https://cdn.qikongjian.com/1756474023655_pov4c3.mp4", "https://cdn.qikongjian.com/1756474023663_yohi7a.mp4", "https://cdn.qikongjian.com/1756474023661_348dx3.mp4", "https://cdn.qikongjian.com/1756474023683_xlb34s.mp4", "https://cdn.qikongjian.com/1756474230987_63ooji.mp4", ], [ "https://cdn.qikongjian.com/1756474230997_zysje8.mp4", "https://cdn.qikongjian.com/1756474230988_tgqzln.mp4", "https://cdn.qikongjian.com/1756474231007_qneeia.mp4", "https://cdn.qikongjian.com/1756474231008_qyqtka.mp4", "https://cdn.qikongjian.com/1756474231009_vs49d9.mp4", "https://cdn.qikongjian.com/1756474231010_2a48p0.mp4", ], ]; // 移动端一维数组数据(合并所有视频) const mobileVideoList = [ "https://cdn.qikongjian.com/1756474023656_60twk5.mp4", "https://cdn.qikongjian.com/1756474023644_14n7is.mp4", "https://cdn.qikongjian.com/1756474023648_kocq6z.mp4", "https://cdn.qikongjian.com/1756474023657_w10boo.mp4", "https://cdn.qikongjian.com/1756474023657_nf8799.mp4", "https://cdn.qikongjian.com/1756474230992_vw0ubf.mp4", "https://cdn.qikongjian.com/1756474023655_pov4c3.mp4", "https://cdn.qikongjian.com/1756474023663_yohi7a.mp4", "https://cdn.qikongjian.com/1756474023661_348dx3.mp4", "https://cdn.qikongjian.com/1756474023683_xlb34s.mp4", "https://cdn.qikongjian.com/1756474230987_63ooji.mp4", "https://cdn.qikongjian.com/1756474230997_zysje8.mp4", "https://cdn.qikongjian.com/1756474230988_tgqzln.mp4", "https://cdn.qikongjian.com/1756474231007_qneeia.mp4", "https://cdn.qikongjian.com/1756474231008_qyqtka.mp4", "https://cdn.qikongjian.com/1756474231009_vs49d9.mp4", "https://cdn.qikongjian.com/1756474231010_2a48p0.mp4", ]; return (

Ideas Made Real

High-quality films, any style, made with MovieFlow.

{/* 移动端 - 单列布局 */} {isMobile ? (
{/* 上方阴影遮罩 */}
{/* 下方阴影遮罩 */}
{mobileVideoList.map((video, videoIndex) => (
))}
) : ( /* PC端 - 三列网格布局 */
{/* 上方阴影遮罩 */}
{/* 下方阴影遮罩 */}
{pcVideoList.map((column, columnIndex) => (
{column.map((video, videoIndex) => (
))}
))}
)}
); } /**电影制作工序介绍 */ function HomeModule4() { const [activeTab, setActiveTab] = useState(0); const [isMobile, setIsMobile] = useState(true); // 检测屏幕尺寸并设置状态 useEffect(() => { const checkScreenSize = () => { setIsMobile(window.innerWidth < 768); }; // 初始检查 checkScreenSize(); }, []); const processSteps = [ { title: " The Story Agent", description: " From a single thought, it builds entire worlds and compelling plots.", video: "https://cdn.qikongjian.com/videos/module4 (3).mp4", }, { title: " AI Character Agent", description: "Cast your virtual actors. Lock them in once, for the entire story.", video: "https://cdn.qikongjian.com/videos/module4 (1).mp4", }, { title: " The Shot Agent", description: "It translates your aesthetic into art, light, and cinematography for every single shot.", video: "https://cdn.qikongjian.com/videos/module4 (4).mp4", }, { title: " Intelligent Clip Agent", description: "An editing AI drives the final cut, for a story told seamlessly.", video: "https://cdn.qikongjian.com/videos/module4 (2).mp4", }, ]; const handleTabClick = (index: number) => { setActiveTab(index); }; return (

Create Your Way

{isMobile ? ( /* 移动端 - 垂直布局 */
{/* 视频播放区域 */}
{/* 切换tabs */}
{processSteps.map((step, index) => (
handleTabClick(index)} className={`p-3 rounded-xl cursor-pointer transition-all duration-300 border ${ activeTab === index ? "bg-[#262626] border-white/20" : "bg-black border-white/10" }`} >

{step.title}

{step.description}

))}
) : ( /* PC端 - 水平布局 */
{/* 左侧四个切换tab */}
{processSteps.map((step, index) => (
handleTabClick(index)} className={`rounded-2xl cursor-pointer transition-all flex-1 duration-300 border ${ activeTab === index ? "bg-[#262626] border-white/20 hover:border-white/40" : "bg-black border-white/10 hover:border-white/40" } /* 平板及以上 - 使用固定高度,让外层盒子撑起来 */ sm:w-[12rem] /* 小屏笔记本 - 13-15寸适配 */ md:w-[14rem] /* 大屏笔记本 - 16-17寸适配 */ lg:w-[16rem] /* 桌面端 - 21-24寸 */ xl:w-[22rem] /* 大屏显示器 - 27寸+ */ 2xl:w-[32rem]`} >

{step.title}

{step.description}

))}
{/* 右侧视频播放区域 */}
)}
); } /**价格方案 */ function HomeModule5() { const [billingType, setBillingType] = useState<"month" | "year">("year"); const [plans, setPlans] = useState([]); const { setShowCallbackModal } = useCallbackModal(); const pathname = usePathname(); // 从后端获取订阅计划数据 useEffect(() => { const loadPlans = async () => { try { const plansData = await fetchSubscriptionPlans(); setPlans(plansData); } catch (err) { console.error("加载订阅计划失败:", err); } }; loadPlans(); }, []); const pricingPlans = useMemo< { title: string; price: number; originalPrice: number; monthlyPrice: number; discountMsg: string; credits: string; buttonText: string; features: string[]; issubscribed: boolean; }[] >(() => { return plans.map((plan) => { const rawDescription = plan.description ?? ''; let creditsText: string = rawDescription; try { const parsed = JSON.parse(rawDescription) as { period: 'month' | 'year'; content: string }[]; if (Array.isArray(parsed)) { const match = parsed.find((item) => item && item.period === billingType); if (match && typeof match.content === 'string') { creditsText = match.content; } } } catch { // If not valid JSON, keep original string } return { title: plan.display_name || plan.name, price: billingType === "month" ? plan.price_month / 100 : plan.price_year / 100, originalPrice: plan.price_month / 100, monthlyPrice: billingType === "month" ? 0 : Math.round(plan.price_year / 12) / 100, discountMsg: `Saves $${(plan.price_month * 12 - plan.price_year) / 100} by billing yearly!`, credits: creditsText, buttonText: plan.is_free ? "Try For Free" : "Subscribe Now", issubscribed: plan.is_subscribed, features: plan.features || [], }; }); }, [plans, billingType]); const handleSubscribe = async (planName: string) => { localStorage.setItem("callBackUrl", pathname); // 改为直接携带参数打开 pay-redirect,由其内部完成创建与跳转 const url = `/pay-redirect?type=subscription&plan=${encodeURIComponent(planName)}&billing=${encodeURIComponent(billingType)}`; const win = window.open(url, "_blank"); // 通知当前窗口等待支付(显示loading模态框) window.postMessage({ type: 'waiting-payment', paymentType: 'subscription', }, '*'); if (!win) { throw new Error("Unable to open redirect window, please check popup settings"); } }; return (

Create All For Free

Just remove watermark with credits.

{/* 计费切换 */}
{/* 主要价格卡片 */}
{pricingPlans.map((plan, index) => (

{plan.title}

${plan.monthlyPrice || plan.price} / month
{plan.originalPrice !== plan.price ? (
${plan.originalPrice}
) : null}

{plan.credits}

{plan.issubscribed ? ( ) : ( )}

* {plan.discountMsg}

    {plan.features.map((feature, featureIndex) => (
  • {feature}
  • ))}
))}
); }