'use client'; import { ChevronDown, Download, Server } from 'lucide-react'; import { useEffect, useMemo, useState } from 'react'; import { createInstallOptions, type InstallOption } from '@/lib/downloadLinks'; import { fetchLatestReleaseInfo } from '@/lib/latestRelease'; type InstallTabsProps = { lang: 'en' | 'cn'; version: string; }; const downloadLabel = { en: 'Download DBX', cn: '下载 DBX' }; const platformIconPaths = { dark: { 'linux-arm': '/icons/platform/linux.svg', linux: '/icons/platform/linux.svg', 'macos-arm': '/icons/platform/macos.png', 'macos-intel': '/icons/platform/macos.png', windows: '/icons/platform/windows.png', }, light: { 'linux-arm': '/icons/platform/linux.svg', linux: '/icons/platform/linux.svg', 'macos-arm': '/icons/platform/macos-white.png', 'macos-intel': '/icons/platform/macos-white.png', windows: '/icons/platform/windows.png', }, }; function detectPlatformId(): string { if (typeof navigator === 'undefined') return 'macos-arm'; const ua = navigator.userAgent.toLowerCase(); if (ua.includes('win')) return 'windows'; if (ua.includes('linux')) return ua.includes('aarch64') || ua.includes('arm') ? 'linux-arm' : 'linux'; return 'macos-arm'; } function PlatformIcon({ id, size, variant }: { id: string; size: number; variant: 'dark' | 'light' }) { const src = platformIconPaths[variant][id as keyof (typeof platformIconPaths)['dark']]; if (!src) return ; return ; } export function InstallTabs({ lang, version }: InstallTabsProps) { const [downloadVersion, setDownloadVersion] = useState(version); const options = useMemo(() => createInstallOptions(lang, downloadVersion), [lang, downloadVersion]); const [open, setOpen] = useState(false); const [platformId, setPlatformId] = useState('macos-arm'); useEffect(() => { setPlatformId(detectPlatformId()); }, []); useEffect(() => { let active = true; setDownloadVersion(version); fetchLatestReleaseInfo().then((release) => { if (active && release?.version) { setDownloadVersion(release.version); } }); return () => { active = false; }; }, [version]); const primary = useMemo(() => options.find((o) => o.id === platformId) ?? options[0], [options, platformId]); const menuOptions = useMemo(() => options.filter((o) => o.id !== platformId), [options, platformId]); return (
{ if (!event.currentTarget.contains(event.relatedTarget)) { setOpen(false); } }} onMouseEnter={() => setOpen(true)} onMouseLeave={() => setOpen(false)} > setOpen(true)} > {downloadLabel[lang]} {primary.label}
{menuOptions.map((item) => ( {item.label} ))}
); }