chat client fixes

This commit is contained in:
Storme-bit
2026-04-18 21:21:05 -07:00
parent 44989a2b8b
commit ad5ecb5ff3
10 changed files with 378 additions and 290 deletions

View File

@@ -1,16 +1,18 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useSettings } from '../hooks/useSettings';
import { getServiceHealth } from '../api/orchestration';
import { useModels } from '../hooks/useModels';
import { getModelProps } from '../api/orchestration';
import { getServiceHealth } from '../api/orchestration'; // ← merged
export default function SettingsView({ onNavigate }) {
const { settings, saveSetting, saving } = useSettings();
export default function SettingsView({ onNavigate, onBack, modelProps }) {
const { settings, saveSetting, saving } = useSettings(); // ← single source
return (
<div style={{ display: 'flex', flexDirection: 'column', flex: 1, overflow: 'hidden', background: 'var(--bg-base)' }}>
<div className="panel-header" style={{ padding: '0 24px' }}>
<span className="text-base" style={{ fontWeight: 500, color: 'var(--text-secondary)' }}>Settings</span>
<div className="panel-header" style={{ padding: '0 8px 0 8px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
<button className="btn-icon" onClick={onBack} title="Back" style={{ fontSize: '16px', padding: '4px 8px' }}></button>
<span className="text-base" style={{ fontWeight: 500, color: 'var(--text-secondary)' }}>Settings</span>
</div>
</div>
<div className="flex-1 scroll-y" style={{ padding: '24px' }}>
@@ -49,7 +51,10 @@ export default function SettingsView({ onNavigate }) {
</SettingsSection>
<SettingsSection title="Models">
<ModelsSection />
{/* ← Error boundary wraps ModelsSection only */}
<SettingsSectionErrorBoundary>
<ModelsSection settings={settings} saveSetting={saveSetting} saving={saving} modelProps={modelProps}/>
</SettingsSectionErrorBoundary>
</SettingsSection>
<SettingsSection title="About">
@@ -74,6 +79,34 @@ export default function SettingsView({ onNavigate }) {
);
}
// Error boundary — class component required by React for this pattern
class SettingsSectionErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { error: null };
}
static getDerivedStateFromError(error) {
return { error };
}
render() {
if (this.state.error) {
return (
<SettingsRow
label="Models unavailable"
description={this.state.error.message ?? 'Failed to load model settings'}
action={
<button className="btn-primary" style={{ padding: '5px 10px', fontSize: '12px' }}
onClick={() => this.setState({ error: null })}>
Retry
</button>
}
/>
);
}
return this.props.children;
}
}
function SettingsSection({ title, children }) {
return (
<div style={{ marginBottom: '32px' }}>
@@ -239,15 +272,9 @@ function ServiceHealth() {
);
}
function ModelsSection({ onNavigate }) {
function ModelsSection({ settings, saveSetting, saving, modelProps }) {
const { models, selectedModel, setSelectedModel } = useModels();
const [selectedInfo, setSelectedInfo] = useState(null);
const {settings, saveSetting, saving} = useSettings();
const [modelProps, setModelProps] = useState(null);
useEffect(() => {
getModelProps().then(setModelProps).catch(() => {});
}, []);
// Sync info panel when selection changes
useEffect(() => {
@@ -260,7 +287,7 @@ function ModelsSection({ onNavigate }) {
<SettingsRow
label="Models Folder"
description="Path to folder containing .gguf files"
action={<ModelsFolderSetting />}
action={<ModelsFolderSetting settings={settings} saveSetting={saveSetting} saving={saving}/>}
/>
<NumberSetting
label="Temperature"
@@ -363,8 +390,7 @@ function InfoLine({ label, value, mono }) {
);
}
function ModelsFolderSetting() {
const { settings, saveSetting, saving } = useSettings();
function ModelsFolderSetting({ settings, saveSetting, saving }) {
const [local, setLocal] = useState('');
const [error, setError] = useState(null);