'use client' import './globals.css'; import '@/iconfont/iconfont.css'; import { createContext, useContext, useEffect, useState } from 'react'; import { Providers } from '@/components/providers'; import { ConfigProvider, theme } from 'antd'; import CallbackModal from '@/components/common/CallbackModal'; import { useAppStartupAnalytics } from '@/hooks/useAppStartupAnalytics'; import { gaEnabled, gaMeasurementId } from '@/lib/env'; // 创建上下文来传递弹窗控制方法 const CallbackModalContext = createContext<{ setShowCallbackModal: (show: boolean) => void } | null>(null) // Hook 来使用弹窗控制方法 export const useCallbackModal = () => { const context = useContext(CallbackModalContext) if (!context) { throw new Error('useCallbackModal must be used within CallbackModalProvider') } return context } export default function RootLayout({ children, }: { children: React.ReactNode }) { const [showCallbackModal, setShowCallbackModal] = useState(false) const [paymentType, setPaymentType] = useState<'subscription' | 'token'>('subscription') // 应用启动时设置用户GA属性 useAppStartupAnalytics(); const openCallback = async function (ev: MessageEvent) { if (ev.data.type === 'waiting-payment') { setPaymentType(ev.data.paymentType || 'subscription') setShowCallbackModal(true) } } useEffect(() => { window.addEventListener('message', openCallback) return () => { window.removeEventListener('message', openCallback) } }, []) return ( MovieFlow - AI Movie Studio {gaEnabled && ( <>