import { createFileRoute } from '@tanstack/react-router' import { route } from '@/constants/routes' import SettingsMenu from '@/containers/SettingsMenu' import HeaderPage from '@/containers/HeaderPage' import { Card, CardItem } from '@/containers/Card' import { Switch } from '@/components/ui/switch' import { Progress } from '@/components/ui/progress' import { useTranslation } from '@/i18n/react-i18next-compat' import { useHardware } from '@/hooks/useHardware' import { useLlamacppDevices } from '@/hooks/useLlamacppDevices' import { useEffect, useState } from 'react' import { IconDeviceDesktopAnalytics } from '@tabler/icons-react' import { getHardwareInfo, getSystemUsage } from '@/services/hardware' import { WebviewWindow } from '@tauri-apps/api/webviewWindow' import { formatMegaBytes } from '@/lib/utils' import { windowKey } from '@/constants/windows' import { toNumber } from '@/utils/number' import { useModelProvider } from '@/hooks/useModelProvider' import { stopAllModels } from '@/services/models' // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Route = createFileRoute(route.settings.hardware as any)({ component: Hardware, }) function Hardware() { const { t } = useTranslation() const [isLoading, setIsLoading] = useState(false) const { hardwareData, systemUsage, setHardwareData, updateSystemUsage, pollingPaused, } = useHardware() const { providers } = useModelProvider() const llamacpp = providers.find((p) => p.provider === 'llamacpp') // Llamacpp devices hook const llamacppDevicesResult = useLlamacppDevices() // Use default values on macOS since llamacpp devices are not relevant const { devices: llamacppDevices, loading: llamacppDevicesLoading, error: llamacppDevicesError, activatedDevices, toggleDevice, fetchDevices, } = IS_MACOS ? { devices: [], loading: false, error: null, activatedDevices: new Set(), toggleDevice: () => {}, fetchDevices: () => {}, } : llamacppDevicesResult // Fetch llamacpp devices when component mounts useEffect(() => { fetchDevices() }, [fetchDevices]) // Fetch initial hardware info and system usage useEffect(() => { setIsLoading(true) Promise.all([ getHardwareInfo() .then((data) => { setHardwareData(data) }) .catch((error) => { console.error('Failed to get hardware info:', error) }), getSystemUsage() .then((data) => { updateSystemUsage(data) }) .catch((error) => { console.error('Failed to get initial system usage:', error) }), ]).finally(() => { setIsLoading(false) }) }, [setHardwareData, updateSystemUsage]) const { getProviderByName } = useModelProvider() // Initialize llamacpp device activations from provider settings useEffect(() => { if (llamacppDevices.length > 0 && activatedDevices.size === 0) { const llamacppProvider = getProviderByName('llamacpp') const currentDeviceSetting = llamacppProvider?.settings.find( (s) => s.key === 'device' )?.controller_props.value as string if (currentDeviceSetting) { const deviceIds = currentDeviceSetting .split(',') .map((device) => device.trim()) .filter((device) => device.length > 0) // Find matching devices by ID const matchingDeviceIds = deviceIds.filter((deviceId) => llamacppDevices.some((device) => device.id === deviceId) ) if (matchingDeviceIds.length > 0) { console.log( `Initializing llamacpp device activations from device setting: "${currentDeviceSetting}"` ) // Update the activatedDevices in the hook const { setActivatedDevices } = useLlamacppDevices.getState() setActivatedDevices(matchingDeviceIds) } } } }, [ llamacppDevices.length, activatedDevices.size, getProviderByName, llamacppDevices, ]) useEffect(() => { if (pollingPaused) return const intervalId = setInterval(() => { getSystemUsage() .then((data) => { updateSystemUsage(data) }) .catch((error) => { console.error('Failed to get system usage:', error) }) }, 5000) return () => clearInterval(intervalId) }, [updateSystemUsage, pollingPaused]) const handleClickSystemMonitor = async () => { try { // Check if system monitor window already exists const existingWindow = await WebviewWindow.getByLabel( windowKey.systemMonitorWindow ) if (existingWindow) { // If window exists, focus it await existingWindow.setFocus() console.log('Focused existing system monitor window') } else { // Create a new system monitor window const monitorWindow = new WebviewWindow(windowKey.systemMonitorWindow, { url: route.systemMonitor, title: 'System Monitor - Jan', width: 900, height: 600, resizable: true, center: true, }) // Listen for window creation monitorWindow.once('tauri://created', () => { console.log('System monitor window created') }) // Listen for window errors monitorWindow.once('tauri://error', (e) => { console.error('Error creating system monitor window:', e) }) } } catch (error) { console.error('Failed to open system monitor window:', error) } } return (
{t('settings:hardware.systemMonitor')}