import { useEffect } from 'react' import { Badge, Button, Tooltip, TooltipArrow, TooltipContent, TooltipTrigger, } from '@janhq/uikit' import { useAtom, useAtomValue, useSetAtom } from 'jotai' import { FaGithub, FaDiscord } from 'react-icons/fa' import DownloadingState from '@/containers/Layout/BottomBar/DownloadingState' import SystemItem from '@/containers/Layout/BottomBar/SystemItem' import CommandListDownloadedModel from '@/containers/Layout/TopBar/CommandListDownloadedModel' import ProgressBar from '@/containers/ProgressBar' import { appDownloadProgress } from '@/containers/Providers/Jotai' import { showSelectModelModalAtom } from '@/containers/Providers/KeyListener' import ShortCut from '@/containers/Shortcut' import { MainViewState } from '@/constants/screens' import { useActiveModel } from '@/hooks/useActiveModel' import { modelDownloadStateAtom } from '@/hooks/useDownloadState' import useGetSystemResources from '@/hooks/useGetSystemResources' import { useMainViewState } from '@/hooks/useMainViewState' import { serverEnabledAtom } from '@/helpers/atoms/LocalServer.atom' import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom' import { cpuUsageAtom, gpusAtom, ramUtilitizedAtom, } from '@/helpers/atoms/SystemBar.atom' const menuLinks = [ { name: 'Discord', icon: , link: 'https://discord.gg/FTk2MvZwJH', }, { name: 'Github', icon: , link: 'https://github.com/janhq/jan', }, ] const BottomBar = () => { const { activeModel, stateModel } = useActiveModel() const { watch, stopWatching } = useGetSystemResources() const progress = useAtomValue(appDownloadProgress) const downloadedModels = useAtomValue(downloadedModelsAtom) const gpus = useAtomValue(gpusAtom) const cpu = useAtomValue(cpuUsageAtom) const ramUtilitized = useAtomValue(ramUtilitizedAtom) const { setMainViewState } = useMainViewState() const downloadStates = useAtomValue(modelDownloadStateAtom) const setShowSelectModelModal = useSetAtom(showSelectModelModalAtom) const [serverEnabled] = useAtom(serverEnabledAtom) const calculateUtilization = () => { let sum = 0 const util = gpus.map((x) => { return Number(x['utilization']) }) util.forEach((num) => { sum += num }) return sum } useEffect(() => { // Watch for resource update watch() return () => { stopWatching() } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return (
{progress && progress > 0 ? ( ) : null}
{!serverEnabled && ( setShowSelectModelModal((show) => !show)} > My Models )} {stateModel.state === 'start' && stateModel.loading && ( )} {stateModel.state === 'stop' && stateModel.loading && ( )} {!stateModel.loading && downloadedModels.length !== 0 && activeModel?.id && ( )} {downloadedModels.length === 0 && !stateModel.loading && Object.values(downloadStates).length === 0 && ( )}
{gpus.length > 0 && (
{gpus.length > 1 && ( {gpus.map((gpu, index) => (
{gpu.name} {gpu.vram}MB VRAM
{gpu.utilization}%
))}
)}
)} {/* VERSION is defined by webpack, please see next.config.js */} Jan v{VERSION ?? ''}
{menuLinks .filter((link) => !!link) .map((link, i) => (
{link.icon} {link.name}
))}
) } export default BottomBar