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,7 +1,18 @@
import React, { useEffect, useRef } from 'react';
import MessageBubble from './MessageBubble';
export default function ChatWindow({ messages, loadingHistory, streaming, onSendMessage, onCancel, activeSession, onTogglePanel }) {
export default function ChatWindow({
messages,
loadingHistory,
streaming,
onSendMessage,
onCancel,
activeSession,
onTogglePanel,
onBack,
canGoBack,
loadedModel,
}) {
const bottomRef = useRef(null);
const inputRef = useRef(null);
const [input, setInput] = React.useState('');
@@ -24,15 +35,59 @@ export default function ChatWindow({ messages, loadingHistory, streaming, onSend
}
}
// Trim .gguf for display
const modelLabel = loadedModel ? loadedModel.replace('.gguf', '') : null;
return (
<div className="flex-col flex-1 overflow-hidden" style={{ background: 'var(--bg-base)' }}>
{/* Header */}
<div className="panel-header" style={{ padding: '0 12px 0 20px', justifyContent: 'space-between' }}>
<span className="text-base text-secondary">
{activeSession ? (activeSession.name || activeSession.external_id) : 'No session selected'}
</span>
<button className="btn-icon" onClick={onTogglePanel} title="Session info"></button>
<div className="panel-header" style={{ padding: '0 12px 0 8px', justifyContent: 'space-between' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', minWidth: 0 }}>
{/* Back button */}
{canGoBack && (
<button
className="btn-icon"
onClick={onBack}
title="Go back"
style={{ flexShrink: 0, fontSize: '16px', padding: '4px 8px' }}
></button>
)}
{/* Session name */}
<span className="text-base text-secondary truncate">
{activeSession ? (activeSession.name || activeSession.external_id) : 'New chat'}
</span>
</div>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', flexShrink: 0 }}>
{/* Loaded model pill */}
{modelLabel && (
<span style={{
fontSize: '11px',
color: 'var(--text-muted)',
background: 'var(--bg-elevated)',
border: '1px solid var(--border)',
borderRadius: '999px',
padding: '2px 10px',
maxWidth: '200px',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
}}>
{modelLabel}
</span>
)}
{!modelLabel && (
<span style={{
fontSize: '11px',
color: 'var(--text-muted)',
fontStyle: 'italic',
}}>
No model loaded
</span>
)}
<button className="btn-icon" onClick={onTogglePanel} title="Session info"></button>
</div>
</div>
{/* Message thread */}
@@ -44,7 +99,7 @@ export default function ChatWindow({ messages, loadingHistory, streaming, onSend
gap: '12px',
}}>
<div style={{ fontSize: '32px', opacity: 0.4 }}></div>
<p className="text-base">Select a session or start a new chat</p>
<p className="text-base">Start typing to begin</p>
</div>
)}
@@ -80,8 +135,7 @@ export default function ChatWindow({ messages, loadingHistory, streaming, onSend
value={input}
onChange={e => setInput(e.target.value)}
onKeyDown={handleKeyDown}
disabled={!activeSession}
placeholder={activeSession ? 'Message NexusAI...' : 'Select a session to start chatting'}
placeholder="Message NexusAI..."
rows={1}
style={{
flex: 1,
@@ -115,7 +169,7 @@ export default function ChatWindow({ messages, loadingHistory, streaming, onSend
) : (
<button
onClick={handleSend}
disabled={!activeSession || !input.trim()}
disabled={!input.trim()}
className="btn-primary"
style={{
width: '32px',