feat(electrobun): settings overhaul — fonts, shells, providers, retention, chords
- Settings drawer: responsive width clamp(24rem, 45vw, 50rem) - System font detection: fc-list for UI fonts (preferred sans-serif starred) and mono fonts (Nerd Fonts starred), fallback to hardcoded lists - Scrollback: default 5000, min 1000, step 500 - Shell detection: system.shells RPC, pre-selects $SHELL login shell - Provider enablement: provider.scan gates toggle, unavailable shown as N/A - Session retention: count 0-100 (0=Keep all), age 0-365 (0=Forever) - Chord keybindings: Ctrl+K → Ctrl+S style multi-key sequences, 1s prefix wait, arrow separator display, 26 tests passing
This commit is contained in:
parent
afaa2253de
commit
1de6c93e01
9 changed files with 346 additions and 187 deletions
|
|
@ -8,7 +8,8 @@
|
|||
import ThemeEditor from './ThemeEditor.svelte';
|
||||
import CustomDropdown from '../ui/CustomDropdown.svelte';
|
||||
|
||||
const UI_FONTS = [
|
||||
// Fallback lists — replaced by system detection on mount
|
||||
const FALLBACK_UI_FONTS = [
|
||||
{ value: '', label: 'System Default' },
|
||||
{ value: 'Inter', label: 'Inter' },
|
||||
{ value: 'IBM Plex Sans', label: 'IBM Plex Sans' },
|
||||
|
|
@ -17,7 +18,7 @@
|
|||
{ value: 'Ubuntu', label: 'Ubuntu' },
|
||||
];
|
||||
|
||||
const TERM_FONTS = [
|
||||
const FALLBACK_TERM_FONTS = [
|
||||
{ value: '', label: 'Default (JetBrains Mono)' },
|
||||
{ value: 'JetBrains Mono', label: 'JetBrains Mono' },
|
||||
{ value: 'Fira Code', label: 'Fira Code' },
|
||||
|
|
@ -27,6 +28,9 @@
|
|||
{ value: 'monospace', label: 'monospace' },
|
||||
];
|
||||
|
||||
let uiFontItems = $state(FALLBACK_UI_FONTS.map(f => ({ value: f.value, label: f.label })));
|
||||
let termFontItems = $state(FALLBACK_TERM_FONTS.map(f => ({ value: f.value, label: f.label })));
|
||||
|
||||
// ── Local reactive state ───────────────────────────────────────────────────
|
||||
let themeId = $state<ThemeId>(themeStore.currentTheme);
|
||||
let uiFont = $state(fontStore.uiFontFamily);
|
||||
|
|
@ -35,7 +39,7 @@
|
|||
let termFontSize = $state(fontStore.termFontSize);
|
||||
let cursorStyle = $state('block');
|
||||
let cursorBlink = $state(true);
|
||||
let scrollback = $state(1000);
|
||||
let scrollback = $state(5000);
|
||||
|
||||
interface CustomThemeMeta { id: string; name: string; }
|
||||
let customThemes = $state<CustomThemeMeta[]>([]);
|
||||
|
|
@ -67,8 +71,7 @@
|
|||
|
||||
// ── Dropdown items for CustomDropdown ──────────────────────────────────────
|
||||
let themeItems = $derived(allThemes.map(t => ({ value: t.id, label: t.label, group: t.group })));
|
||||
let uiFontItems = UI_FONTS.map(f => ({ value: f.value, label: f.label }));
|
||||
let termFontItems = TERM_FONTS.map(f => ({ value: f.value, label: f.label }));
|
||||
// uiFontItems and termFontItems are $state — populated by system.fonts on mount
|
||||
let langItems = AVAILABLE_LOCALES.map(l => ({ value: l.tag, label: l.nativeLabel }));
|
||||
|
||||
// ── Actions ────────────────────────────────────────────────────────────────
|
||||
|
|
@ -135,10 +138,35 @@
|
|||
const { settings } = await appRpc.request['settings.getAll']({}).catch(() => ({ settings: {} }));
|
||||
if (settings['cursor_style']) cursorStyle = settings['cursor_style'];
|
||||
if (settings['cursor_blink']) cursorBlink = settings['cursor_blink'] !== 'false';
|
||||
if (settings['scrollback']) scrollback = parseInt(settings['scrollback'], 10) || 1000;
|
||||
if (settings['scrollback']) scrollback = parseInt(settings['scrollback'], 10) || 5000;
|
||||
|
||||
const res = await appRpc.request['themes.getCustom']({}).catch(() => ({ themes: [] }));
|
||||
customThemes = res.themes.map(t => ({ id: t.id, name: t.name }));
|
||||
|
||||
// Detect system fonts
|
||||
try {
|
||||
const fontRes = await appRpc.request['system.fonts']({});
|
||||
if (fontRes.uiFonts.length > 0) {
|
||||
uiFontItems = [
|
||||
{ value: '', label: 'System Default' },
|
||||
...fontRes.uiFonts.map(f => ({
|
||||
value: f.family,
|
||||
label: f.preferred ? `\u2605 ${f.family}` : f.family,
|
||||
})),
|
||||
];
|
||||
}
|
||||
if (fontRes.monoFonts.length > 0) {
|
||||
termFontItems = [
|
||||
{ value: '', label: 'Default (JetBrains Mono)' },
|
||||
...fontRes.monoFonts.map(f => ({
|
||||
value: f.family,
|
||||
label: f.isNerdFont ? `\u2B50 ${f.family}` : f.family,
|
||||
})),
|
||||
];
|
||||
}
|
||||
} catch {
|
||||
// Keep fallback font lists
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -216,8 +244,8 @@
|
|||
|
||||
<h3 class="sh">{t('settings.scrollback')}</h3>
|
||||
<div class="field row">
|
||||
<input type="number" class="num-in" min="100" max="100000" step="100" value={scrollback}
|
||||
onchange={e => persistScrollback(parseInt((e.target as HTMLInputElement).value, 10) || 1000)}
|
||||
<input type="number" class="num-in" min="1000" max="100000" step="500" value={scrollback}
|
||||
onchange={e => persistScrollback(parseInt((e.target as HTMLInputElement).value, 10) || 5000)}
|
||||
aria-label="Scrollback lines" />
|
||||
<span class="hint">{t('settings.scrollbackHint')}</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue