mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-19 13:33:35 +08:00
Update TerminalSettings.tsx
This commit is contained in:
parent
2a505917e6
commit
e4a487dd4b
@ -37,6 +37,7 @@ export function TerminalSettings({
|
|||||||
docked = false,
|
docked = false,
|
||||||
}: TerminalSettingsProps = {}) {
|
}: TerminalSettingsProps = {}) {
|
||||||
const t = useTranslation()
|
const t = useTranslation()
|
||||||
|
const isWindows = typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('win')
|
||||||
const hostRef = useRef<HTMLDivElement | null>(null)
|
const hostRef = useRef<HTMLDivElement | null>(null)
|
||||||
const terminalRef = useRef<XTermTerminal | null>(null)
|
const terminalRef = useRef<XTermTerminal | null>(null)
|
||||||
const fitRef = useRef<XTermFitAddon | null>(null)
|
const fitRef = useRef<XTermFitAddon | null>(null)
|
||||||
@ -289,6 +290,10 @@ export function TerminalSettings({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{isWindows && (
|
||||||
|
<BashPathSettings isTauri={terminalApi.isAvailable()} />
|
||||||
|
)}
|
||||||
|
|
||||||
{status === 'unavailable' ? (
|
{status === 'unavailable' ? (
|
||||||
<div className="flex flex-1 items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-8 text-center">
|
<div className="flex flex-1 items-center justify-center rounded-[var(--radius-lg)] border border-dashed border-[var(--color-border)] bg-[var(--color-surface-container-low)] p-8 text-center">
|
||||||
<div>
|
<div>
|
||||||
@ -341,3 +346,120 @@ function StatusPill({ status, label }: { status: TerminalStatus; label: string }
|
|||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BashPathSettings({ isTauri }: { isTauri: boolean }) {
|
||||||
|
const t = useTranslation()
|
||||||
|
const [bashPath, setBashPath] = useState<string | null>(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 (
|
||||||
|
<div className="mb-3 rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-surface-container-low)] px-4 py-3">
|
||||||
|
<label className="mb-1.5 block text-sm font-medium text-[var(--color-text-primary)]">
|
||||||
|
{t('settings.terminal.bashPathLabel')}
|
||||||
|
</label>
|
||||||
|
<p className="mb-2 text-xs text-[var(--color-text-tertiary)]">
|
||||||
|
{t('settings.terminal.bashPathDescription')}
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={bashPath || ''}
|
||||||
|
onChange={(e) => { 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)]"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleBrowse}
|
||||||
|
className="inline-flex h-8 items-center gap-1 rounded-[var(--radius-sm)] border border-[var(--color-border)] px-3 text-xs font-medium text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-hover)]"
|
||||||
|
>
|
||||||
|
<span className="material-symbols-outlined text-[16px]">folder_open</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleSave}
|
||||||
|
disabled={saving}
|
||||||
|
className="inline-flex h-8 items-center gap-1 rounded-[var(--radius-sm)] bg-[var(--color-text-primary)] px-3 text-xs font-medium text-[var(--color-surface)] transition-colors hover:opacity-90 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{saved ? t('settings.terminal.bashPathSaved') : t('settings.terminal.bashPathSave')}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={handleReset}
|
||||||
|
disabled={saving || bashPath === null}
|
||||||
|
className="inline-flex h-8 items-center gap-1 rounded-[var(--radius-sm)] border border-[var(--color-border)] px-3 text-xs font-medium text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-hover)] disabled:opacity-50"
|
||||||
|
>
|
||||||
|
{t('settings.terminal.bashPathReset')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{invalid && (
|
||||||
|
<p className="mt-1.5 text-xs text-[var(--color-error)]">
|
||||||
|
{t('settings.terminal.bashPathInvalid')}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user