import * as React from "react"; import { motion, AnimatePresence } from "framer-motion"; import { cn } from "@/lib/utils"; import { useTranslation } from "react-i18next"; import { TunnelConfig, startVpn, stopVpn } from "vpn-plugin"; import { useVpnStore } from "@/store/useVpnStore"; import { useEffect } from "react"; import { listen } from "@tauri-apps/api/event"; import VpnControlButton from "@/components/shared/VpnControlButton"; import { useTheme } from "@/ThemeProvider"; import { useSettingsStore } from "@/store/useSettingsStore"; import { useNodesStore } from "@/store/useNodesStore"; import { useAuthStore } from "@/store/useAuthStore"; import { getCachedToken } from "@/lib/api"; export function VpnControl() { const { status, setStatus } = useVpnStore(); const { t } = useTranslation(); const { killSwitch, excludedApps, excludedDomains } = useSettingsStore(); const { getSelectedNode } = useNodesStore(); const isLoggedIn = useAuthStore((s) => s.isLoggedIn); // Подключаем тему const { isDark } = useTheme(); const currentTheme = isDark ? "dark" : "light"; const handleToggle = async () => { // Защита на всякий случай — основной гейт на уровне роута ("/" рендерит // Login, а не Home, пока не вошли), но кнопка не должна работать даже // если это состояние как-то обошли. if (!isLoggedIn) return; try { if (status === "idle") { setStatus("connecting"); // Параметры подключения берём из выбранного на бэкенде узла. const node = getSelectedNode(); const config: TunnelConfig = { address: node.tunnelAddress, prefix: node.tunnelPrefix, dns: node.tunnelDns, mtu: node.tunnelMtu, killswitchEnabled: killSwitch, excludedApps: excludedApps, excludedDomains: excludedDomains, // Есть только если сервер требует `--require-auth`; на инстансах без // этого флага прокси значение просто игнорирует. authToken: getCachedToken() ?? undefined, }; await startVpn(config, node.ipAddress, node.port, node.sni); } else { await stopVpn(); } } catch (error) { console.error("VPN Toggle Error:", error); setStatus("idle"); } }; useEffect(() => { let unlisten: (() => void) | null = null; async function setupListener() { unlisten = await listen<{ status: string }>("status-change", (event) => { const newStatus = event.payload.status as | "idle" | "connecting" | "connected"; if (newStatus) { setStatus(newStatus); } }); } setupListener(); return () => { if (unlisten) unlisten(); }; }, [setStatus]); const isActive = status !== "idle"; const statusMap = { idle: t("disconnected"), connecting: t("connecting"), connected: t("connected"), }; return (

{t("status_label")}

{statusMap[status]}
); }