import React, { useEffect, useState } from 'react' import { colorSchemes, applyColorScheme } from './colorSchemes' import desktopApi from './desktop/desktopApi' const COLOR_SCHEME_KEY = 'colorScheme' const STREAM_KEY = 'streamOutput' const UI_SCALE_KEY = 'uiScale' const OPEN_DEVTOOLS_ON_STARTUP_KEY = 'openDevToolsOnStartup' const DEFAULT_UI_SCALE = 1 const MIN_UI_SCALE = 0.7 const MAX_UI_SCALE = 1.3 const UI_SCALE_STEP = 0.05 function normalizeUiScale(value) { const numericValue = Number(value) if (!Number.isFinite(numericValue)) { return DEFAULT_UI_SCALE } return Math.min(MAX_UI_SCALE, Math.max(MIN_UI_SCALE, Math.round(numericValue * 100) / 100)) } export default function InterfaceSettings({ streamOutput = false, onStreamOutputChange, }) { const [selectedColorScheme, setSelectedColorScheme] = useState('Default') const [uiScale, setUiScale] = useState(DEFAULT_UI_SCALE) const [openDevToolsOnStartup, setOpenDevToolsOnStartup] = useState(false) useEffect(() => { desktopApi.getSettings().then(settings => { const schemeName = settings.colorScheme || 'Default' const nextUiScale = normalizeUiScale(settings.uiScale) setSelectedColorScheme(schemeName) setUiScale(nextUiScale) setOpenDevToolsOnStartup(settings.openDevToolsOnStartup === true) applyColorScheme(schemeName) desktopApi.applyUiScale(nextUiScale) }) }, []) useEffect(() => { applyColorScheme(selectedColorScheme) }, [selectedColorScheme]) const handleColorSchemeChange = (event) => { const newScheme = event.target.value setSelectedColorScheme(newScheme) desktopApi.setSetting(COLOR_SCHEME_KEY, newScheme) } const persistUiScale = (value) => { const nextScale = normalizeUiScale(value) setUiScale(nextScale) desktopApi.applyUiScale(nextScale) desktopApi.setSetting(UI_SCALE_KEY, nextScale) } const handleUiScaleChange = (event) => { persistUiScale(event.target.value) } const handleUiScaleReset = () => { persistUiScale(DEFAULT_UI_SCALE) } const handleOpenDevToolsOnStartupToggle = () => { const nextValue = !openDevToolsOnStartup setOpenDevToolsOnStartup(nextValue) desktopApi.setSetting(OPEN_DEVTOOLS_ON_STARTUP_KEY, nextValue) } const handleStreamOutputToggle = () => { const nextValue = !streamOutput desktopApi.setSetting(STREAM_KEY, nextValue) if (onStreamOutputChange) { onStreamOutputChange(nextValue) } } return (
Scales the whole interface, including fonts, spacing, and controls. 100% is the default size.
Only applies in Electron development mode. When enabled, Heimgeist opens detached DevTools for new windows and updates currently open windows right away.
Shows assistant replies token by token while they are generating instead of waiting for the full message to finish first.