diff --git a/src/App.tsx b/src/App.tsx
index a62f749..9f69d76 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,7 +10,7 @@ import { KeyboardShortcuts } from './components/KeyboardShortcuts';
export default function App() {
const {
- status, messages, sessions, activeSession, isGenerating,
+ status, messages, sessions, activeSession, isGenerating, isLoadingHistory,
sendMessage, abort, switchSession,
authenticated, login, logout, connectError, isConnecting,
} = useGateway();
@@ -77,7 +77,7 @@ export default function App() {
setSidebarOpen(!sidebarOpen)} activeSessionData={sessions.find(s => s.key === activeSession)} onLogout={logout} />
-
+
setShortcutsOpen(false)} />
diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx
index caf58b9..dbd6aa5 100644
--- a/src/components/Chat.tsx
+++ b/src/components/Chat.tsx
@@ -3,13 +3,14 @@ import { ChatMessageComponent } from './ChatMessage';
import { ChatInput } from './ChatInput';
import { TypingIndicator } from './TypingIndicator';
import type { ChatMessage, ConnectionStatus } from '../types';
-import { Bot, ArrowDown } from 'lucide-react';
+import { Bot, ArrowDown, Loader2 } from 'lucide-react';
import { useT } from '../hooks/useLocale';
import { getLocale, type TranslationKey } from '../lib/i18n';
interface Props {
messages: ChatMessage[];
isGenerating: boolean;
+ isLoadingHistory: boolean;
status: ConnectionStatus;
onSend: (text: string, attachments?: Array<{ mimeType: string; fileName: string; content: string }>) => void;
onAbort: () => void;
@@ -63,7 +64,7 @@ function getDateKey(ts: number): string {
/** Threshold in pixels — if the user is within this distance of the bottom, auto-scroll */
const SCROLL_THRESHOLD = 150;
-export function Chat({ messages, isGenerating, status, onSend, onAbort }: Props) {
+export function Chat({ messages, isGenerating, isLoadingHistory, status, onSend, onAbort }: Props) {
const t = useT();
const bottomRef = useRef(null);
const scrollContainerRef = useRef(null);
@@ -128,7 +129,13 @@ export function Chat({ messages, isGenerating, status, onSend, onAbort }: Props)
- {messages.length === 0 && (
+ {messages.length === 0 && isLoadingHistory && (
+
+
+
{t('chat.loadingHistory')}
+
+ )}
+ {messages.length === 0 && !isLoadingHistory && (
diff --git a/src/hooks/useGateway.ts b/src/hooks/useGateway.ts
index ecdd3ff..8a064dc 100644
--- a/src/hooks/useGateway.ts
+++ b/src/hooks/useGateway.ts
@@ -28,6 +28,7 @@ export function useGateway() {
const [sessions, setSessions] = useState
([]);
const [activeSession, setActiveSession] = useState('agent:main:main');
const [isGenerating, setIsGenerating] = useState(false);
+ const [isLoadingHistory, setIsLoadingHistory] = useState(false);
const [authenticated, setAuthenticated] = useState(null); // null = checking
const [connectError, setConnectError] = useState(null);
const [isConnecting, setIsConnecting] = useState(false);
@@ -100,6 +101,7 @@ export function useGateway() {
}, []);
const loadHistory = useCallback(async (sessionKey: string) => {
+ setIsLoadingHistory(true);
try {
const res = await clientRef.current?.send('chat.history', { sessionKey, limit: 100 });
const rawMsgs = res?.messages as Array> | undefined;
@@ -173,6 +175,8 @@ export function useGateway() {
}
} catch {
// Silently ignore history load failures
+ } finally {
+ setIsLoadingHistory(false);
}
}, []);
@@ -388,7 +392,7 @@ export function useGateway() {
}));
return {
- status, messages, sessions: enrichedSessions, activeSession, isGenerating,
+ status, messages, sessions: enrichedSessions, activeSession, isGenerating, isLoadingHistory,
sendMessage, abort, switchSession, loadSessions,
authenticated, login, logout, connectError, isConnecting,
};
diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts
index 8652589..9c7bc80 100644
--- a/src/lib/i18n.ts
+++ b/src/lib/i18n.ts
@@ -31,6 +31,7 @@ const en = {
// Chat
'chat.welcome': 'PinchChat',
'chat.welcomeSub': 'Send a message to get started',
+ 'chat.loadingHistory': 'Loading messages…',
'chat.inputPlaceholder': 'Type a message…',
'chat.inputLabel': 'Message',
'chat.attachFile': 'Attach file',
@@ -106,6 +107,7 @@ const fr: Record = {
'chat.welcome': 'PinchChat',
'chat.welcomeSub': 'Envoyez un message pour commencer',
+ 'chat.loadingHistory': 'Chargement des messages…',
'chat.inputPlaceholder': 'Tapez un message…',
'chat.inputLabel': 'Message',
'chat.attachFile': 'Joindre un fichier',