@@ -11,9 +11,15 @@ import { Alert, AlertTitle, AlertDescription } from "./ui/alert";
1111import { ModeToggle } from "./mode-toggle" ;
1212
1313interface Message {
14+ id : number ;
1415 role : string ;
1516 content : string ;
16- id : number ;
17+ }
18+
19+ // Draft messages are used to optmistically update the UI
20+ // before the server responds.
21+ interface DraftMessage extends Omit < Message , "id" > {
22+ id ?: number ;
1723}
1824
1925interface MessageUpdateEvent {
@@ -28,7 +34,7 @@ interface StatusChangeEvent {
2834}
2935
3036export default function ChatInterface ( ) {
31- const [ messages , setMessages ] = useState < Message [ ] > ( [ ] ) ;
37+ const [ messages , setMessages ] = useState < ( Message | DraftMessage ) [ ] > ( [ ] ) ;
3238 const [ loading , setLoading ] = useState < boolean > ( false ) ;
3339 const [ serverStatus , setServerStatus ] = useState < string > ( "unknown" ) ;
3440 const searchParams = useSearchParams ( ) ;
@@ -87,12 +93,18 @@ export default function ChatInterface() {
8793 const data : MessageUpdateEvent = JSON . parse ( event . data ) ;
8894
8995 setMessages ( ( prevMessages ) => {
96+ // Clean up draft messages
97+ const updatedMessages = [ ...prevMessages ] . filter (
98+ ( m ) => m . id !== undefined
99+ ) ;
100+
90101 // Check if message with this ID already exists
91- const existingIndex = prevMessages . findIndex ( ( m ) => m . id === data . id ) ;
102+ const existingIndex = updatedMessages . findIndex (
103+ ( m ) => m . id === data . id
104+ ) ;
92105
93106 if ( existingIndex !== - 1 ) {
94107 // Update existing message
95- const updatedMessages = [ ...prevMessages ] ;
96108 updatedMessages [ existingIndex ] = {
97109 role : data . role ,
98110 content : data . message ,
@@ -102,7 +114,7 @@ export default function ChatInterface() {
102114 } else {
103115 // Add new message
104116 return [
105- ...prevMessages ,
117+ ...updatedMessages ,
106118 {
107119 role : data . role ,
108120 content : data . message ,
@@ -164,6 +176,10 @@ export default function ChatInterface() {
164176
165177 // For raw messages, don't set loading state as it's usually fast
166178 if ( type === "user" ) {
179+ setMessages ( ( prevMessages ) => [
180+ ...prevMessages ,
181+ { role : "user" , content } ,
182+ ] ) ;
167183 setLoading ( true ) ;
168184 }
169185
@@ -263,7 +279,7 @@ export default function ChatInterface() {
263279 </ div >
264280 ) }
265281
266- < MessageList messages = { messages } loading = { loading } />
282+ < MessageList messages = { messages } />
267283 < MessageInput onSendMessage = { sendMessage } disabled = { loading } />
268284 </ main >
269285 </ div >
0 commit comments