// src/renderer/components/StatusBar.tsx // 인스트루먼트 섀시 하단 — 각인 스타일 상태 표시 + Ollama 오프라인 넛징 import { useState, useEffect } from 'react' import { Box, Typography, Fade, IconButton } from '@mui/material' import CloseIcon from '@mui/icons-material/Close' import { Led } from './ds' import { d3roPalette, d3roFontMono } from '../theme' import { OllamaGuideModal } from './OllamaGuideModal' import type { LLMStatus } from '@shared/types' export function StatusBar(): React.ReactElement { const [llmStatus, setLlmStatus] = useState(null) const [showNudge, setShowNudge] = useState(false) const [guideOpen, setGuideOpen] = useState(false) useEffect(() => { window.electronAPI.llm.getStatus().then((r) => { if (r.success) setLlmStatus(r.data) }) const unsub = window.electronAPI.llm.onStatusChanged((e) => setLlmStatus(e.status)) const interval = setInterval(() => { window.electronAPI.llm.getStatus().then((r) => { if (r.success) setLlmStatus(r.data) }) }, 5000) return () => { unsub(); clearInterval(interval) } }, []) const connected = llmStatus?.connectionState === 'connected' // 오프라인 3초 후 넛징 버블 표시 → 10초 후 자동 숨김 useEffect(() => { if (!connected) { const showTimer = setTimeout(() => setShowNudge(true), 3000) const hideTimer = setTimeout(() => setShowNudge(false), 13000) return () => { clearTimeout(showTimer); clearTimeout(hideTimer) } } setShowNudge(false) return undefined }, [connected]) return ( <> {/* 넛징 버블 */} Ollama가 실행되지 않고 있어요 setShowNudge(false)} sx={{ color: d3roPalette.text.inactive, p: 0, ml: 1 }}> LLM 후처리(번역, 요약 등)를 사용하려면 Ollama가 필요합니다. { setGuideOpen(true); setShowNudge(false) }} sx={{ fontSize: '11px', color: d3roPalette.accent.amber, fontWeight: 700, cursor: 'pointer', '&:hover': { textDecoration: 'underline' }, }} > 설치 안내 보기 → !connected && setGuideOpen(true)} sx={{ fontFamily: d3roFontMono, fontSize: '9px', color: connected ? d3roPalette.text.inactive : d3roPalette.tag.red, letterSpacing: '1px', fontWeight: 700, cursor: connected ? 'default' : 'pointer', '&:hover': connected ? {} : { textDecoration: 'underline' }, }} > {connected ? 'OLLAMA' : 'OFFLINE'} {llmStatus?.activeModel && ( {llmStatus.activeModel.toUpperCase()} )} PRECISION DATA LINK setGuideOpen(false)} /> ) }