feat: optimistic message rendering with send status indicators
- User messages appear instantly with 'sending' state (dimmed, clock icon) - Transitions to 'sent' (checkmark) when server acknowledges - Shows error state (alert icon, retry visible) if send fails - Applied to both primary and secondary sessions
This commit is contained in:
@@ -399,12 +399,14 @@ export function useGateway() {
|
||||
}, [setupClient]);
|
||||
|
||||
const sendMessage = useCallback(async (text: string, attachments?: Array<{ mimeType: string; fileName: string; content: string }>) => {
|
||||
const msgId = 'user-' + Date.now();
|
||||
const userMsg: ChatMessage = {
|
||||
id: 'user-' + Date.now(),
|
||||
id: msgId,
|
||||
role: 'user',
|
||||
content: text,
|
||||
timestamp: Date.now(),
|
||||
blocks: [{ type: 'text', text }],
|
||||
sendStatus: 'sending',
|
||||
};
|
||||
setMessages(prev => [...prev, userMsg]);
|
||||
setIsGenerating(true);
|
||||
@@ -417,8 +419,11 @@ export function useGateway() {
|
||||
idempotencyKey: genIdempotencyKey(),
|
||||
...(attachments && attachments.length > 0 ? { attachments } : {}),
|
||||
});
|
||||
// Mark as sent
|
||||
setMessages(prev => prev.map(m => m.id === msgId ? { ...m, sendStatus: 'sent' as const } : m));
|
||||
} catch {
|
||||
// Failed to send — stop generating indicator
|
||||
// Mark as error and stop generating
|
||||
setMessages(prev => prev.map(m => m.id === msgId ? { ...m, sendStatus: 'error' as const } : m));
|
||||
setIsGenerating(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
@@ -214,12 +214,14 @@ export function useSecondarySession(
|
||||
|
||||
const sendMessage = useCallback(async (text: string, attachments?: Array<{ mimeType: string; fileName: string; content: string }>) => {
|
||||
if (!sessionKeyRef.current) return;
|
||||
const msgId = 'user-' + Date.now();
|
||||
const userMsg: ChatMessage = {
|
||||
id: 'user-' + Date.now(),
|
||||
id: msgId,
|
||||
role: 'user',
|
||||
content: text,
|
||||
timestamp: Date.now(),
|
||||
blocks: [{ type: 'text', text }],
|
||||
sendStatus: 'sending',
|
||||
};
|
||||
setMessages(prev => [...prev, userMsg]);
|
||||
setIsGenerating(true);
|
||||
@@ -230,7 +232,9 @@ export function useSecondarySession(
|
||||
deliver: false,
|
||||
...(attachments && attachments.length > 0 ? { attachments } : {}),
|
||||
});
|
||||
setMessages(prev => prev.map(m => m.id === msgId ? { ...m, sendStatus: 'sent' as const } : m));
|
||||
} catch {
|
||||
setMessages(prev => prev.map(m => m.id === msgId ? { ...m, sendStatus: 'error' as const } : m));
|
||||
setIsGenerating(false);
|
||||
}
|
||||
}, [getClient]);
|
||||
|
||||
Reference in New Issue
Block a user