import { useState, useEffect, useRef } from 'react'; import { getVersion } from '@tauri-apps/api/app'; import { Globe, ChevronDown, Download, X, Loader2 } from 'lucide-react'; import { checkForUpdatesOnStartup, installUpdate, type UpdateCheckResult } from '../utils/updater'; import { StartupLogo } from './StartupLogo'; import '../styles/StartupPage.css'; type Locale = 'en' | 'zh'; interface StartupPageProps { onOpenProject: () => void; onCreateProject: () => void; onOpenRecentProject?: (projectPath: string) => void; onProfilerMode?: () => void; onLocaleChange?: (locale: Locale) => void; recentProjects?: string[]; locale: string; } const LANGUAGES = [ { code: 'en', name: 'English' }, { code: 'zh', name: '中文' } ]; export function StartupPage({ onOpenProject, onCreateProject, onOpenRecentProject, onProfilerMode, onLocaleChange, recentProjects = [], locale }: StartupPageProps) { const [showLogo, setShowLogo] = useState(true); const [hoveredProject, setHoveredProject] = useState(null); const [appVersion, setAppVersion] = useState(''); const [showLangMenu, setShowLangMenu] = useState(false); const [updateInfo, setUpdateInfo] = useState(null); const [showUpdateBanner, setShowUpdateBanner] = useState(false); const [isInstalling, setIsInstalling] = useState(false); const langMenuRef = useRef(null); useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (langMenuRef.current && !langMenuRef.current.contains(e.target as Node)) { setShowLangMenu(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); useEffect(() => { getVersion().then(setAppVersion).catch(() => setAppVersion('1.0.0')); }, []); // 启动时检查更新 useEffect(() => { checkForUpdatesOnStartup().then((result) => { if (result.available) { setUpdateInfo(result); setShowUpdateBanner(true); } }); }, []); const translations = { en: { title: 'ESEngine Editor', subtitle: 'Professional Game Development Tool', openProject: 'Open Project', createProject: 'Create Project', profilerMode: 'Profiler Mode', recentProjects: 'Recent Projects', noRecentProjects: 'No recent projects', comingSoon: 'Coming Soon', updateAvailable: 'New version available', updateNow: 'Update Now', installing: 'Installing...', later: 'Later' }, zh: { title: 'ESEngine 编辑器', subtitle: '专业游戏开发工具', openProject: '打开项目', createProject: '创建新项目', profilerMode: '性能分析模式', recentProjects: '最近的项目', noRecentProjects: '没有最近的项目', comingSoon: '即将推出', updateAvailable: '发现新版本', updateNow: '立即更新', installing: '正在安装...', later: '稍后' } }; const handleInstallUpdate = async () => { setIsInstalling(true); const success = await installUpdate(); if (!success) { setIsInstalling(false); } // 如果成功,应用会重启,不需要处理 }; const t = translations[locale as keyof typeof translations] || translations.en; const versionText = locale === 'zh' ? `版本 ${appVersion}` : `Version ${appVersion}`; const handleLogoComplete = () => { setShowLogo(false); }; return (
{showLogo && }

{t.title}

{t.subtitle}

{t.recentProjects}

{recentProjects.length === 0 ? (

{t.noRecentProjects}

) : (
    {recentProjects.map((project, index) => (
  • setHoveredProject(project)} onMouseLeave={() => setHoveredProject(null)} onClick={() => onOpenRecentProject?.(project)} style={{ cursor: onOpenRecentProject ? 'pointer' : 'default' }} >
    {project.split(/[\\/]/).pop()}
    {project}
  • ))}
)}
{/* 更新提示条 */} {showUpdateBanner && updateInfo?.available && (
{t.updateAvailable}: v{updateInfo.version}
)}
{versionText} {onLocaleChange && (
{showLangMenu && (
{LANGUAGES.map(lang => ( ))}
)}
)}
); }