/** * Memory indicator ("OpenIDEA 560M") with a details popup. Unlike IDEA's JVM heap * there is no maximum to measure headroom against, so the widget shows the * footprint of OpenIDEA's own processes and no fill bar; the popup breaks down * OpenIDEA, language servers and other processes. */ import { useEffect, useRef } from "react"; import clsx from "clsx"; import { BarButton, Button, Popup, T } from "@/ui"; import { executeAction } from "@/platform/actions"; import { isTauri, type AppMetrics } from "@/platform/ipc"; import { formatBytes, formatCount, formatMs, formatSize, formatUptime } from "./format"; import { indicatorLabel, indicatorTooltip, memorySections, summarizeMemory } from "./memory"; import { startPolling } from "./poll"; import { METRICS_INTERVAL_MS, refreshMetrics, usePerf } from "./store"; import styles from "./perf.module.css"; import { tx } from "@/platform/i18n"; /** Status bar widget id (hidden by default, toggled from the status bar context menu). */ export const MEMORY_WIDGET = { id: "perf.memory", title: "Memory Indicator", defaultVisible: false } as const; export function MemoryStatus() { const metrics = usePerf((s) => s.metrics); const open = usePerf((s) => s.popupOpen); const ref = useRef(null); useEffect(() => { if (!isTauri()) return; return startPolling(() => void refreshMetrics(), { intervalMs: METRICS_INTERVAL_MS }); }, []); useEffect(() => { if (open) void refreshMetrics(); }, [open]); if (!metrics) return null; const summary = summarizeMemory(metrics); const label = indicatorLabel(summary); const tooltip = indicatorTooltip(summary); return ( <> usePerf.setState({ popupOpen: !open })} > {label} usePerf.setState({ popupOpen: false })} aria-label="Memory and diagnostics" > ); } interface RowProps { label: string; detail?: string | null; value: string; title?: string; indented?: boolean; } function Row({ label, detail, value, title, indented }: RowProps) { return (
{label} {detail && {detail}} {value}
); } export function MemoryDetails({ metrics: m }: { metrics: AppMetrics }) { const error = usePerf((s) => s.error); const s = m.syntax; const summary = summarizeMemory(m); const sections = memorySections(m.memory ?? []); return (
{tx("Memory & Diagnostics")}
{sections.map((sec) => (
{sec.title} {sec.total}
{sec.rows.map((r) => ( 1 ? tx`${r.processes} processes` : undefined} indented /> ))}
))}
Total {formatSize(summary.total)}
{m.heapBytes != null && }
{error &&
{error}
}
); }