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 'react-i18next' import { useHardware } from '@/hooks/useHardware' import { useVulkan } from '@/hooks/useVulkan' import type { GPU, HardwareData } from '@/hooks/useHardware' import { useEffect } from 'react' import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, DragEndEvent, } from '@dnd-kit/core' import { SortableContext, verticalListSortingStrategy, useSortable, } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { IconGripVertical, IconDeviceDesktopAnalytics, } from '@tabler/icons-react' import { getHardwareInfo } from '@/services/hardware' import { WebviewWindow } from '@tauri-apps/api/webviewWindow' import { formatMegaBytes } from '@/lib/utils' import { windowKey } from '@/constants/windows' // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Route = createFileRoute(route.settings.hardware as any)({ component: Hardware, }) function SortableGPUItem({ gpu, index }: { gpu: GPU; index: number }) { const { attributes, listeners, setNodeRef, transform, transition, isDragging, } = useSortable({ id: gpu.id || index }) const { toggleGPUActivation, gpuLoading } = useHardware() const style = { transform: CSS.Transform.toString(transform), transition, opacity: isDragging ? 0.5 : 1, position: 'relative' as const, zIndex: isDragging ? 1 : 0, } return (
{gpu.name}
} actions={
toggleGPUActivation(index)} />
} />
{formatMegaBytes(gpu.free_vram)} free of{' '} {formatMegaBytes(gpu.total_vram)} } /> {gpu.additional_information?.driver_version || '-'} } /> {gpu.additional_information?.compute_cap || '-'} } />
) } function Hardware() { const { t } = useTranslation() const { hardwareData, setHardwareData, updateCPUUsage, updateRAMAvailable, reorderGPUs, pollingPaused, } = useHardware() const { vulkanEnabled, setVulkanEnabled } = useVulkan() useEffect(() => { getHardwareInfo().then((data) => setHardwareData(data as unknown as HardwareData) ) }, [setHardwareData]) // Set up DnD sensors const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor) ) // Handle drag end event const handleDragEnd = (event: DragEndEvent) => { const { active, over } = event if (over && active.id !== over.id) { // Find the indices of the dragged item and the drop target const oldIndex = hardwareData.gpus.findIndex( (gpu) => gpu.id === active.id ) const newIndex = hardwareData.gpus.findIndex((gpu) => gpu.id === over.id) if (oldIndex !== -1 && newIndex !== -1) { reorderGPUs(oldIndex, newIndex) } } } useEffect(() => { if (pollingPaused) return const intervalId = setInterval(() => { getHardwareInfo().then((data) => { updateCPUUsage(data.cpu.usage) updateRAMAvailable(data.ram.available) }) }, 5000) return () => clearInterval(intervalId) }, [setHardwareData, updateCPUUsage, updateRAMAvailable, 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('common.settings')}

System monitor

{/* OS Information */} {hardwareData.os?.name} } /> {hardwareData.os?.version} } /> {/* CPU Information */} {hardwareData.cpu?.model} } /> {hardwareData.cpu?.arch} } /> {hardwareData.cpu?.cores} } /> {hardwareData.cpu?.instructions.join(', ').length > 0 && ( 6} actions={ {hardwareData.cpu?.instructions?.join(', ')} } /> )} {hardwareData.cpu?.usage > 0 && ( <> {hardwareData.cpu?.usage?.toFixed(2)}% )}
} /> {/* RAM Information */} {formatMegaBytes(hardwareData.ram.total)} } /> {formatMegaBytes(hardwareData.ram?.available)} } /> {hardwareData.ram?.total > 0 && ( <> {( ((hardwareData.ram?.total - hardwareData.ram?.available) / hardwareData.ram?.total) * 100 ).toFixed(2)} % )}
} /> {/* Vulkan Settings */} {hardwareData.gpus.length > 0 && ( { setVulkanEnabled(checked) setTimeout(() => { window.location.reload() }, 500) // Reload after 500ms to apply changes }} />
} /> )} {/* GPU Information */} {!IS_MACOS ? ( {hardwareData.gpus.length > 0 ? ( gpu.id)} strategy={verticalListSortingStrategy} > {hardwareData.gpus.map((gpu, index) => ( ))} ) : ( } /> )} ) : ( <> )}
) }