diff --git a/desktop/src/pages/TerminalSettings.tsx b/desktop/src/pages/TerminalSettings.tsx index ff623074..2a8f47d8 100644 --- a/desktop/src/pages/TerminalSettings.tsx +++ b/desktop/src/pages/TerminalSettings.tsx @@ -37,6 +37,7 @@ export function TerminalSettings({ docked = false, }: TerminalSettingsProps = {}) { const t = useTranslation() + const isWindows = typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('win') const hostRef = useRef(null) const terminalRef = useRef(null) const fitRef = useRef(null) @@ -289,6 +290,10 @@ export function TerminalSettings({ )} + {isWindows && ( + + )} + {status === 'unavailable' ? (
@@ -341,3 +346,120 @@ function StatusPill({ status, label }: { status: TerminalStatus; label: string } ) } + +function BashPathSettings({ isTauri }: { isTauri: boolean }) { + const t = useTranslation() + const [bashPath, setBashPath] = useState(null) + const [saving, setSaving] = useState(false) + const [saved, setSaved] = useState(false) + const [invalid, setInvalid] = useState(false) + + useEffect(() => { + if (!isTauri) return + void terminalApi.getBashPath().then((path) => setBashPath(path)).catch(() => {}) + }, [isTauri]) + + const handleSave = async () => { + const trimmed = bashPath?.trim() || null + setSaving(true) + setInvalid(false) + setSaved(false) + try { + await terminalApi.setBashPath(trimmed) + setBashPath(trimmed) + setSaved(true) + setTimeout(() => setSaved(false), 2000) + } catch { + setInvalid(true) + } finally { + setSaving(false) + } + } + + const handleReset = async () => { + setSaving(true) + setSaved(false) + setInvalid(false) + try { + await terminalApi.setBashPath(null) + setBashPath(null) + setSaved(true) + setTimeout(() => setSaved(false), 2000) + } catch { + // ignore + } finally { + setSaving(false) + } + } + + const handleBrowse = async () => { + if (!isTauri) return + try { + const { open } = await import('@tauri-apps/plugin-dialog') + const selected = await open({ + title: t('settings.terminal.bashPathLabel'), + multiple: false, + filters: [{ + name: 'Bash Executable', + extensions: ['exe', '', 'bat', 'cmd', 'ps1'], + }], + }) + if (selected && typeof selected === 'string') { + setBashPath(selected) + setInvalid(false) + } + } catch { + // user cancelled + } + } + + if (!isTauri) return null + + return ( +
+ +

+ {t('settings.terminal.bashPathDescription')} +

+
+ { setBashPath(e.target.value); setInvalid(false); setSaved(false) }} + placeholder={t('settings.terminal.bashPathLabel')} + className="flex-1 rounded-[var(--radius-sm)] border border-[var(--color-border)] bg-[var(--color-surface)] px-3 py-1.5 text-sm font-mono text-[var(--color-text-primary)] outline-none placeholder:text-[var(--color-text-tertiary)] focus:border-[var(--color-border-focus)]" + /> + + + +
+ {invalid && ( +

+ {t('settings.terminal.bashPathInvalid')} +

+ )} +
+ ) +}