[add] README.md [add] backend/libraries/punk/library.json [add] backend/libraries/punk/stage/19f1e5d2ceaab5fd1f1dc58ff07422388f156610d16dfdea2bdb35a5b9e70813--GeorgeJordac-TheVoiceOfHumanJustice.pdf [add] backend/libraries/punk/stage/85fce554ff7685f7bccb136aff5768e54b9ba8361672fe45dbce599598c4be4b--4_Strings_-_Take_Me_Away_Into_The_Night_Vocal_Radio_Mix_.mp3 [add] backend/libraries/punk/stage/e816ca61aebd84159747d248fedd6d5ff318c471c36bcc31b1ac6bf9aebcd3c1--The_Evolution_of_Cooperation_Robert_Axelrod_liber3.pdf [add] backend/local_rag.py [add] backend/rag/__init__.py [add] backend/rag/corpus_builder.py [add] backend/rag/corpus_enricher.py [add] backend/rag/index_builder.py [add] backend/rag/unified_rag.py [add] dist/assets/index-Cc0DLWqA.css [add] dist/assets/index-DKAz6gtp.js [add] dist/index.html [add] src/LibraryManager.jsx [add] wheelcheck2117/pydantic-2.11.7-py3-none-any.whl [add] wheelcheck274/pydantic-2.7.4-py3-none-any.whl [change] backend/main.py [change] backend/requirements.txt [change] backend/schemas.py [change] electron/main.cjs [change] electron/preload.cjs [change] package.json [change] run.sh [change] src/App.jsx [change] src/InterfaceSettings.jsx [change] src/colorSchemes.js [change] src/main.jsx [change] src/styles.css
102 lines
2.9 KiB
JavaScript
102 lines
2.9 KiB
JavaScript
import React, { useEffect, useState } from 'react'
|
|
import { colorSchemes, applyColorScheme } from './colorSchemes'
|
|
|
|
const COLOR_SCHEME_KEY = 'colorScheme'
|
|
const UI_SCALE_KEY = 'uiScale'
|
|
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() {
|
|
const [selectedColorScheme, setSelectedColorScheme] = useState('Default')
|
|
const [uiScale, setUiScale] = useState(DEFAULT_UI_SCALE)
|
|
|
|
useEffect(() => {
|
|
window.electronAPI.getSettings().then(settings => {
|
|
const schemeName = settings.colorScheme || 'Default'
|
|
setSelectedColorScheme(schemeName)
|
|
setUiScale(normalizeUiScale(settings.uiScale))
|
|
applyColorScheme(schemeName)
|
|
})
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
applyColorScheme(selectedColorScheme)
|
|
}, [selectedColorScheme])
|
|
|
|
const handleColorSchemeChange = (event) => {
|
|
const newScheme = event.target.value
|
|
setSelectedColorScheme(newScheme)
|
|
window.electronAPI.setSetting(COLOR_SCHEME_KEY, newScheme)
|
|
}
|
|
|
|
const persistUiScale = (value) => {
|
|
const nextScale = normalizeUiScale(value)
|
|
setUiScale(nextScale)
|
|
window.electronAPI.setSetting(UI_SCALE_KEY, nextScale)
|
|
}
|
|
|
|
const handleUiScaleChange = (event) => {
|
|
persistUiScale(event.target.value)
|
|
}
|
|
|
|
const handleUiScaleReset = () => {
|
|
persistUiScale(DEFAULT_UI_SCALE)
|
|
}
|
|
|
|
return (
|
|
<div className="settings-content-panel">
|
|
<div className="setting-section">
|
|
<h3>Color Scheme</h3>
|
|
<select
|
|
className="select"
|
|
value={selectedColorScheme}
|
|
onChange={handleColorSchemeChange}
|
|
>
|
|
{Object.keys(colorSchemes).map((schemeName) => (
|
|
<option key={schemeName} value={schemeName}>
|
|
{schemeName}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
<div className="setting-section">
|
|
<h3>UI Scale</h3>
|
|
<div className="setting-control-row">
|
|
<input
|
|
type="range"
|
|
className="range-input"
|
|
min={MIN_UI_SCALE}
|
|
max={MAX_UI_SCALE}
|
|
step={UI_SCALE_STEP}
|
|
value={uiScale}
|
|
onChange={handleUiScaleChange}
|
|
/>
|
|
<span className="setting-value">{Math.round(uiScale * 100)}%</span>
|
|
<button
|
|
type="button"
|
|
className="button"
|
|
onClick={handleUiScaleReset}
|
|
disabled={uiScale === DEFAULT_UI_SCALE}
|
|
>
|
|
Reset
|
|
</button>
|
|
</div>
|
|
<p className="setting-description">
|
|
Scales the whole interface, including fonts, spacing, and controls. 100% is the default size.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|