chat client fixes
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import ChatWindow from './components/ChatWindow';
|
||||
import InfoPanel from './components/InfoPanel';
|
||||
import Sidebar from './components/Sidebar';
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
import HomeView from './components/HomeView';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { getModelProps } from './api/orchestration';
|
||||
|
||||
/*** View Panels*** */
|
||||
import AllChatsView from './components/AllChatsView';
|
||||
@@ -17,13 +19,30 @@ import { useChat } from './hooks/useChat';
|
||||
import { useModels } from './hooks/useModels';
|
||||
import { useProjects } from './hooks/useProjects';
|
||||
|
||||
// Views where back nav makes sense, and where they go back to
|
||||
const BACK_MAP = {
|
||||
'chat': 'home',
|
||||
'all-chats': 'home',
|
||||
'all-projects': 'home',
|
||||
'settings': 'home',
|
||||
'project': 'all-projects',
|
||||
'memory': 'settings',
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const [leftOpen, setLeftOpen] = useState(true);
|
||||
const [leftOpen, setLeftOpen] = useState(false); // collapsed on home
|
||||
const [rightOpen, setRightOpen] = useState(false);
|
||||
const { models, selectedModel, setSelectedModel } = useModels();
|
||||
const [view, setView] = useState('chat')
|
||||
const [view, setView] = useState('home');
|
||||
const [viewHistory, setViewHistory] = useState([]);
|
||||
const [activeProject, setActiveProject] = useState(null);
|
||||
const {projects, refreshProjects} = useProjects();
|
||||
const { projects, refreshProjects } = useProjects();
|
||||
|
||||
// Lifted model props — available to header + SettingsView
|
||||
const [modelProps, setModelProps] = useState(null);
|
||||
useEffect(() => {
|
||||
getModelProps().then(setModelProps).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const {
|
||||
sessions,
|
||||
@@ -46,17 +65,49 @@ export default function App() {
|
||||
lastModel,
|
||||
} = useChat({ activeSession, appendMessage, updateLastMessage, refreshSessions });
|
||||
|
||||
function navigate(nextView) {
|
||||
setViewHistory(prev => [...prev, view]);
|
||||
setView(nextView);
|
||||
// Expand sidebar when leaving home
|
||||
if (view === 'home') setLeftOpen(true);
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (viewHistory.length > 0) {
|
||||
const prev = viewHistory[viewHistory.length - 1];
|
||||
setViewHistory(h => h.slice(0, -1));
|
||||
setView(prev);
|
||||
if (prev === 'home') setLeftOpen(false);
|
||||
} else {
|
||||
// Fallback to BACK_MAP
|
||||
const dest = BACK_MAP[view] ?? 'home';
|
||||
setView(dest);
|
||||
if (dest === 'home') setLeftOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSendMessage(text) {
|
||||
sendMessage(text, selectedModel, activeSession?.project_id ?? null);
|
||||
}
|
||||
|
||||
function handleSessionsChange(deletedSession){
|
||||
if(deletedSession?.external_id === activeSession?.external_id){
|
||||
function handleSessionsChange(deletedSession) {
|
||||
if (deletedSession?.external_id === activeSession?.external_id) {
|
||||
selectSession(null);
|
||||
}
|
||||
refreshSessions();
|
||||
}
|
||||
|
||||
// Home: create session, navigate to chat, then send after a tick
|
||||
function handleHomeSend(text) {
|
||||
createSession();
|
||||
setViewHistory(prev => [...prev, 'home']);
|
||||
setView('chat');
|
||||
setLeftOpen(true);
|
||||
setTimeout(() => {
|
||||
sendMessage(text, selectedModel, null);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
async function handleNewProjectChat() {
|
||||
const newSession = {
|
||||
external_id: uuidv4(),
|
||||
@@ -64,70 +115,90 @@ export default function App() {
|
||||
isNew: true,
|
||||
project_id: activeProject?.id ?? null,
|
||||
};
|
||||
// Optimistically set active session then navigate
|
||||
setSessions(prev => [newSession, ...prev]);
|
||||
selectSession(newSession);
|
||||
setView('chat');
|
||||
// After first message saves, project assignment will be written via updateSession
|
||||
navigate('chat');
|
||||
}
|
||||
|
||||
const canGoBack = view !== 'home';
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
height: '100vh',
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<div style={{ display: 'flex', height: '100vh', overflow: 'hidden' }}>
|
||||
<Sidebar
|
||||
sessions={sessions}
|
||||
activeSession={activeSession}
|
||||
onSelectSession={selectSession}
|
||||
onNewChat={createSession}
|
||||
onNewProject={()=> setView('all-projects')}
|
||||
onSelectSession={session => { selectSession(session); navigate('chat'); }}
|
||||
onNewChat={() => { createSession(); navigate('chat'); }}
|
||||
onNewProject={() => navigate('all-projects')}
|
||||
isOpen={leftOpen}
|
||||
onToggle={() => setLeftOpen(o => !o)}
|
||||
onSessionsChange={handleSessionsChange}
|
||||
onNavigate={setView}
|
||||
onNavigate={navigate}
|
||||
projects={projects}
|
||||
onProjectsChange={refreshProjects}
|
||||
onSelectProject={setActiveProject}
|
||||
/>
|
||||
|
||||
{view === 'home' && (
|
||||
<HomeView
|
||||
onSendMessage={handleHomeSend}
|
||||
loadedModel={modelProps?.modelAlias ?? null}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'chat' && (
|
||||
<ChatWindow
|
||||
messages={messages}
|
||||
loadingHistory={loadingHistory}
|
||||
streaming={streaming}
|
||||
activeSession={activeSession}
|
||||
onSendMessage={handleSendMessage}
|
||||
onCancel={cancelStream}
|
||||
onTogglePanel={() => setRightOpen(o => !o)}
|
||||
/>
|
||||
<ChatWindow
|
||||
messages={messages}
|
||||
loadingHistory={loadingHistory}
|
||||
streaming={streaming}
|
||||
activeSession={activeSession}
|
||||
onSendMessage={handleSendMessage}
|
||||
onCancel={cancelStream}
|
||||
onTogglePanel={() => setRightOpen(o => !o)}
|
||||
onBack={goBack}
|
||||
canGoBack={canGoBack}
|
||||
loadedModel={modelProps?.modelAlias ?? null}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'all-chats' && (
|
||||
<AllChatsView
|
||||
onSelectSession={session => {selectSession(session); setView('chat');}}
|
||||
/>
|
||||
onBack={goBack}
|
||||
onSelectSession={session => { selectSession(session); navigate('chat'); }}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'all-projects' && (
|
||||
<AllProjectsView onProjectsChange={refreshProjects}/>
|
||||
<AllProjectsView
|
||||
onBack={goBack}
|
||||
onProjectsChange={refreshProjects}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'settings' && <SettingsView onNavigate={setView} />}
|
||||
{view === 'settings' && (
|
||||
<SettingsView
|
||||
onNavigate={navigate}
|
||||
onBack={goBack}
|
||||
modelProps={modelProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'project' && activeProject && (
|
||||
<ProjectView
|
||||
project={activeProject}
|
||||
onNavigate={setView}
|
||||
onNavigate={navigate}
|
||||
onBack={goBack}
|
||||
onSelectSession={selectSession}
|
||||
onNewProjectChat={handleNewProjectChat}
|
||||
/>
|
||||
)}
|
||||
|
||||
{view === 'memory' && <MemoryView onNavigate={setView} />}
|
||||
|
||||
{view === 'memory' && (
|
||||
<MemoryView
|
||||
onNavigate={navigate}
|
||||
onBack={goBack}
|
||||
/>
|
||||
)}
|
||||
|
||||
<InfoPanel
|
||||
isOpen={rightOpen}
|
||||
@@ -138,7 +209,6 @@ export default function App() {
|
||||
onModelChange={setSelectedModel}
|
||||
lastModel={lastModel}
|
||||
lastTokenCount={lastTokenCount}
|
||||
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user