import { useCallback, useEffect, useState } from "react"; import { Download, ExternalLink, Info, Loader2, RefreshCw } from "lucide-react"; import { Button } from "@/components/ui/button"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { getVersion } from "@tauri-apps/api/app"; import { settingsApi } from "@/lib/api"; import { useUpdate } from "@/contexts/UpdateContext"; import { relaunchApp } from "@/lib/updater"; interface AboutSectionProps { isPortable: boolean; } export function AboutSection({ isPortable }: AboutSectionProps) { const { t } = useTranslation(); const [version, setVersion] = useState(null); const [isLoadingVersion, setIsLoadingVersion] = useState(true); const [isDownloading, setIsDownloading] = useState(false); const { hasUpdate, updateInfo, updateHandle, checkUpdate, resetDismiss, isChecking, } = useUpdate(); useEffect(() => { let active = true; const load = async () => { try { const loaded = await getVersion(); if (active) { setVersion(loaded); } } catch (error) { console.error("[AboutSection] Failed to get version", error); if (active) { setVersion(null); } } finally { if (active) { setIsLoadingVersion(false); } } }; void load(); return () => { active = false; }; }, []); const handleOpenReleaseNotes = useCallback(async () => { try { const targetVersion = updateInfo?.availableVersion ?? version ?? ""; const displayVersion = targetVersion.startsWith("v") ? targetVersion : targetVersion ? `v${targetVersion}` : ""; if (!displayVersion) { await settingsApi.openExternal( "https://github.com/farion1231/cc-switch/releases", ); return; } await settingsApi.openExternal( `https://github.com/farion1231/cc-switch/releases/tag/${displayVersion}`, ); } catch (error) { console.error("[AboutSection] Failed to open release notes", error); toast.error( t("settings.openReleaseNotesFailed", { defaultValue: "打开更新日志失败", }), ); } }, [t, updateInfo?.availableVersion, version]); const handleCheckUpdate = useCallback(async () => { if (hasUpdate && updateHandle) { if (isPortable) { try { await settingsApi.checkUpdates(); } catch (error) { console.error("[AboutSection] Portable update failed", error); } return; } setIsDownloading(true); try { resetDismiss(); await updateHandle.downloadAndInstall(); await relaunchApp(); } catch (error) { console.error("[AboutSection] Update failed", error); toast.error( t("settings.updateFailed", { defaultValue: "更新安装失败,已尝试打开下载页面。", }), ); try { await settingsApi.checkUpdates(); } catch (fallbackError) { console.error( "[AboutSection] Failed to open fallback updater", fallbackError, ); } } finally { setIsDownloading(false); } return; } try { const available = await checkUpdate(); if (!available) { toast.success(t("settings.upToDate", { defaultValue: "已是最新版本" })); } } catch (error) { console.error("[AboutSection] Check update failed", error); toast.error( t("settings.checkUpdateFailed", { defaultValue: "检查更新失败,请稍后重试。", }), ); } }, [checkUpdate, hasUpdate, isPortable, resetDismiss, t, updateHandle]); const displayVersion = version ?? t("common.unknown", { defaultValue: "未知" }); return (

{t("common.about")}

{t("settings.aboutHint", { defaultValue: "查看版本信息与更新状态。", })}

CC Switch

{t("common.version")}{" "} {isLoadingVersion ? ( ) : ( `v${displayVersion}` )}

{isPortable ? (

{t("settings.portableMode", { defaultValue: "当前为便携版,更新需手动下载。", })}

) : null}
{hasUpdate && updateInfo ? (

{t("settings.updateAvailable", { defaultValue: "检测到新版本:{{version}}", version: updateInfo.availableVersion, })}

{updateInfo.notes ? (

{updateInfo.notes}

) : null}
) : null}
); }