66 getSession ,
77 deleteSession ,
88} from '../../services/local-session.mjs'
9- import { useEffect , useRef , useState } from 'react'
9+ import { useEffect , useRef , useState , useMemo } from 'react'
1010import './styles.scss'
1111import { useConfig } from '../../hooks/use-config.mjs'
1212import { useTranslation } from 'react-i18next'
@@ -104,28 +104,29 @@ function App() {
104104 await setSessionIdSafe ( sessions [ 0 ] . sessionId )
105105 }
106106
107- // Filter sessions based on search query
108- const filteredSessions = sessions . filter ( ( session ) => {
109- if ( ! searchQuery . trim ( ) ) return true
107+ // Filter sessions based on search query (memoized for performance)
108+ const filteredSessions = useMemo ( ( ) => {
109+ const query = searchQuery . trim ( ) . toLowerCase ( )
110+ if ( ! query ) return sessions
110111
111- const query = searchQuery . toLowerCase ( )
112-
113- // Search in session name
114- if ( session . sessionName && session . sessionName . toLowerCase ( ) . includes ( query ) ) {
115- return true
116- }
112+ return sessions . filter ( ( session ) => {
113+ // Search in session name
114+ if ( session . sessionName && session . sessionName . toLowerCase ( ) . includes ( query ) ) {
115+ return true
116+ }
117117
118- // Search in conversation records
119- if ( session . conversationRecords && Array . isArray ( session . conversationRecords ) ) {
120- return session . conversationRecords . some ( ( record ) => {
121- const questionMatch = record . question && record . question . toLowerCase ( ) . includes ( query )
122- const answerMatch = record . answer && record . answer . toLowerCase ( ) . includes ( query )
123- return questionMatch || answerMatch
124- } )
125- }
118+ // Search in conversation records
119+ if ( session . conversationRecords ) {
120+ return session . conversationRecords . some ( ( record ) => {
121+ const questionMatch = record . question && record . question . toLowerCase ( ) . includes ( query )
122+ const answerMatch = record . answer && record . answer . toLowerCase ( ) . includes ( query )
123+ return questionMatch || answerMatch
124+ } )
125+ }
126126
127- return false
128- } )
127+ return false
128+ } )
129+ } , [ sessions , searchQuery ] )
129130
130131 return (
131132 < div className = "IndependentPanel" >
@@ -145,43 +146,44 @@ function App() {
145146 < hr />
146147 < div className = "search-container" >
147148 < input
148- type = "text "
149+ type = "search "
149150 placeholder = { t ( 'Search conversations...' ) }
150151 value = { searchQuery }
151152 onChange = { ( e ) => setSearchQuery ( e . target . value ) }
152153 className = "search-input"
154+ aria-label = { t ( 'Search' ) }
155+ autoComplete = "off"
153156 />
154157 </ div >
155158 < div className = "chat-list" >
156- { filteredSessions . map (
157- (
158- session ,
159- index , // TODO editable session name
160- ) => (
161- < button
162- key = { index }
163- className = { `normal-button ${ sessionId === session . sessionId ? 'active' : '' } ` }
164- style = "display: flex; align-items: center; justify-content: space-between;"
165- onClick = { ( ) => {
166- setSessionIdSafe ( session . sessionId )
167- } }
168- >
169- { session . sessionName }
170- < span className = "gpt-util-group" >
171- < DeleteButton
172- size = { 14 }
173- text = { t ( 'Delete Conversation' ) }
174- onConfirm = { ( ) =>
175- deleteSession ( session . sessionId ) . then ( ( sessions ) => {
176- setSessions ( sessions )
177- setSessionIdSafe ( sessions [ 0 ] . sessionId )
178- } )
179- }
180- />
181- </ span >
182- </ button >
183- ) ,
184- ) }
159+ { filteredSessions . map ( ( session ) => (
160+ < button
161+ key = { session . sessionId }
162+ className = { `normal-button ${ sessionId === session . sessionId ? 'active' : '' } ` }
163+ style = { {
164+ display : 'flex' ,
165+ alignItems : 'center' ,
166+ justifyContent : 'space-between' ,
167+ } }
168+ onClick = { ( ) => {
169+ setSessionIdSafe ( session . sessionId )
170+ } }
171+ >
172+ { session . sessionName }
173+ < span className = "gpt-util-group" >
174+ < DeleteButton
175+ size = { 14 }
176+ text = { t ( 'Delete Conversation' ) }
177+ onConfirm = { ( ) =>
178+ deleteSession ( session . sessionId ) . then ( ( sessions ) => {
179+ setSessions ( sessions )
180+ setSessionIdSafe ( sessions [ 0 ] . sessionId )
181+ } )
182+ }
183+ />
184+ </ span >
185+ </ button >
186+ ) ) }
185187 </ div >
186188 < hr />
187189 < div className = "chat-sidebar-button-group" >
0 commit comments