/* eslint-disable @typescript-eslint/no-explicit-any */ import * as React from 'react' import { useState } from 'react' import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd' import { Gpu } from '@janhq/core' import { Progress, ScrollArea, Switch } from '@janhq/joi' import { useAtom, useAtomValue } from 'jotai' import { atomWithStorage } from 'jotai/utils' import { ChevronDownIcon, GripVerticalIcon } from 'lucide-react' import { twMerge } from 'tailwind-merge' import { useGetHardwareInfo, setActiveGpus, } from '@/hooks/useHardwareManagement' import { toGibibytes } from '@/utils/converter' import { cpuUsageAtom, ramUtilitizedAtom, totalRamAtom, usedRamAtom, } from '@/helpers/atoms/SystemBar.atom' const gpusAtom = atomWithStorage('gpus', [], undefined, { getOnInit: true, }) const Hardware = () => { const { hardware } = useGetHardwareInfo() const [openPanels, setOpenPanels] = useState>({}) const cpuUsage = useAtomValue(cpuUsageAtom) const totalRam = useAtomValue(totalRamAtom) const usedRam = useAtomValue(usedRamAtom) const ramUtilitized = useAtomValue(ramUtilitizedAtom) const [gpus, setGpus] = useAtom(gpusAtom) const togglePanel = (index: number) => { setOpenPanels((prev) => ({ ...prev, [index]: !prev[index], // Toggle the specific panel })) } // Handle switch toggle for GPU activation const handleSwitchChange = async (id: string, isActive: boolean) => { const updatedGpus = gpus.map((gpu) => gpu.id === id ? { ...gpu, activated: isActive } : gpu ) setGpus(updatedGpus) // Call the API to update the active GPUs try { const activeGpuIds = updatedGpus .filter((gpu) => gpu.activated) .map((gpu) => Number(gpu.id)) await setActiveGpus({ gpus: activeGpuIds }) } catch (error) { console.error('Failed to update active GPUs:', error) } } const handleDragEnd = (result: any) => { if (!result.destination) return const reorderedGpus = Array.from(gpus) const [movedGpu] = reorderedGpus.splice(result.source.index, 1) reorderedGpus.splice(result.destination.index, 0, movedGpu) setGpus(reorderedGpus) // Update the atom, which persists to localStorage } React.useEffect(() => { if (hardware?.gpus) { setGpus((prevGpus) => { // Create a map of existing GPUs by UUID for quick lookup const gpuMap = new Map(prevGpus.map((gpu) => [gpu.uuid, gpu])) // Update existing GPUs or add new ones const updatedGpus = hardware.gpus.map((newGpu) => { const existingGpu = gpuMap.get(newGpu.uuid) if (existingGpu) { // Update the GPU properties while keeping the original order return { ...existingGpu, free_vram: newGpu.free_vram, total_vram: newGpu.total_vram, } } // Return the new GPU if not already in the state return newGpu }) // Append GPUs from the previous state that are not in the hardware.gpus // This preserves user-reordered GPUs that aren't present in the new data const remainingGpus = prevGpus.filter( (prevGpu) => !hardware.gpus?.some((gpu) => gpu.uuid === prevGpu.uuid) ) return [...updatedGpus, ...remainingGpus] }) } }, [hardware?.gpus, setGpus]) return (
{/* CPU */}
CPU
{hardware?.cpu.model} | Cores: {hardware?.cpu.cores} | Architecture: {hardware?.cpu.arch}
{cpuUsage}%
{/* RAM */}
RAM
{toGibibytes(usedRam, { hideUnit: true })}GB /{' '} {toGibibytes(totalRam, { hideUnit: true })}GB {hardware?.ram.type && ( <> | Type: {hardware?.ram.type} )}
{ramUtilitized}%
{/* OS */}
OS
{hardware?.os.name} | {hardware?.os.version}
{/* GPUs */} {!isMac && gpus.length > 0 && (
GPUs

{`Enhance model performance by utilizing your device's GPU for acceleration.`}

{(provided) => (
{gpus.map((item, i) => ( {(provided, snapshot) => (
1 && 'last:rounded-t-none', snapshot.isDragging ? 'border-b' : 'border-b-0 last:border-b' )} onClick={() => togglePanel(i)} >
{item.name}
{item.activated && (
{Math.round( ((Number(item.total_vram) - Number(item.free_vram)) / Number(item.total_vram)) * 100 ).toFixed()} %
)}
{item.activated && ( {( (Number(item.total_vram) - Number(item.free_vram)) / 1024 ).toFixed(2)} GB /{' '} )} {( Number(item.total_vram) / 1024 ).toFixed(2)} GB
handleSwitchChange( item.id, e.target.checked ) } />
{openPanels[i] && (
Driver Version
{ item.additional_information ?.driver_version }
Compute Capability
{item.additional_information?.compute_cap}
)}
)} ))} {provided.placeholder}
)}
)}
) } export default Hardware