3d2d979197
Build App / compute-version (pull_request) Successful in 3s
Build App / build-macos (pull_request) Successful in 2m19s
Build App / build-linux (pull_request) Successful in 5m3s
Build App / build-windows (pull_request) Successful in 7m34s
Build App / create-tag (pull_request) Has been skipped
Build App / sync-to-github (pull_request) Has been skipped
Terminal layout fixes for the xterm pane: - Stop the terminal grid from clipping its rightmost column / bottom row. The padding was on the element xterm mounts into, which the FitAddon measures; the grid overhang got clipped. Padding now lives on a wrapper and the xterm host fills it with no padding. - Move the STT mic from a floating bottom-left overlay into the status bar (far right). A single useSTT instance bound to the active session now lives in App; Ctrl+Shift+M routes through the store. - Move "Jump to Current" from a floating terminal overlay into the status bar. The active TerminalView surfaces its scroll state and scroll action via the store. - Tighten terminal padding (was 8/12/48/16) now that nothing floats over it, so the terminal claims as much area as possible. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
71 lines
2.3 KiB
TypeScript
71 lines
2.3 KiB
TypeScript
import { useShallow } from "zustand/react/shallow";
|
|
import { useAppState } from "../../store/appState";
|
|
import SttButton from "../terminal/SttButton";
|
|
import type { useSTT } from "../../hooks/useSTT";
|
|
|
|
interface Props {
|
|
stt: ReturnType<typeof useSTT>;
|
|
}
|
|
|
|
export default function StatusBar({ stt }: Props) {
|
|
const {
|
|
projects, sessions, terminalHasSelection, activeSessionId, sttEnabled,
|
|
terminalAtBottom, scrollActiveToBottom,
|
|
} = useAppState(
|
|
useShallow(s => ({
|
|
projects: s.projects,
|
|
sessions: s.sessions,
|
|
terminalHasSelection: s.terminalHasSelection,
|
|
activeSessionId: s.activeSessionId,
|
|
sttEnabled: s.appSettings?.stt?.enabled,
|
|
terminalAtBottom: s.terminalAtBottom,
|
|
scrollActiveToBottom: s.scrollActiveToBottom,
|
|
}))
|
|
);
|
|
const running = projects.filter((p) => p.status === "running").length;
|
|
|
|
return (
|
|
<div className="flex items-center h-6 px-4 bg-[var(--bg-tertiary)] border border-[var(--border-color)] rounded-lg text-xs text-[var(--text-secondary)]">
|
|
<span>
|
|
{projects.length} project{projects.length !== 1 ? "s" : ""}
|
|
</span>
|
|
<span className="mx-2">|</span>
|
|
<span>
|
|
{running} running
|
|
</span>
|
|
<span className="mx-2">|</span>
|
|
<span>
|
|
{sessions.length} terminal{sessions.length !== 1 ? "s" : ""}
|
|
</span>
|
|
{terminalHasSelection && (
|
|
<>
|
|
<span className="mx-2">|</span>
|
|
<span className="text-[var(--accent)]">
|
|
Ctrl+Shift+C: copy trimmed · Ctrl+Shift+Alt+C: copy raw
|
|
</span>
|
|
</>
|
|
)}
|
|
{/* Right-aligned controls: Jump to Current + STT mic */}
|
|
<div className="ml-auto flex items-center gap-3 pl-2">
|
|
{activeSessionId && !terminalAtBottom && (
|
|
<button
|
|
onClick={() => scrollActiveToBottom()}
|
|
className="text-[var(--accent)] hover:text-[var(--accent-hover)] cursor-pointer"
|
|
title="Scroll the terminal to the latest output"
|
|
>
|
|
Jump to Current ↓
|
|
</button>
|
|
)}
|
|
{sttEnabled && activeSessionId && (
|
|
<SttButton
|
|
state={stt.state}
|
|
error={stt.error}
|
|
onToggle={stt.toggle}
|
|
onCancel={stt.cancelRecording}
|
|
/>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|