Skip to content

Commit 534c936

Browse files
Add search functionality to Independent Panel chat history
Co-authored-by: PeterDaveHello <[email protected]>
1 parent 3768a06 commit 534c936

File tree

8 files changed

+115
-31
lines changed

8 files changed

+115
-31
lines changed

src/_locales/en/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "Delete Conversation",
9898
"Clear conversations": "Clear conversations",
9999
"Settings": "Settings",
100+
"Search": "Search",
101+
"Search conversations...": "Search conversations...",
100102
"Feature Pages": "Feature Pages",
101103
"Keyboard Shortcuts": "Keyboard Shortcuts",
102104
"Open Conversation Page": "Open Conversation Page",

src/_locales/es/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "Eliminar conversación",
9898
"Clear conversations": "Borrar todas las conversaciones",
9999
"Settings": "Configuración",
100+
"Search": "Buscar",
101+
"Search conversations...": "Buscar conversaciones...",
100102
"Feature Pages": "Páginas de características",
101103
"Keyboard Shortcuts": "Atajos de teclado",
102104
"Open Conversation Page": "Abrir página de conversación independiente",

src/_locales/fr/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "Supprimer la conversation",
9898
"Clear conversations": "Effacer les conversations",
9999
"Settings": "Paramètres",
100+
"Search": "Rechercher",
101+
"Search conversations...": "Rechercher dans les conversations...",
100102
"Feature Pages": "Pages de fonctionnalités",
101103
"Keyboard Shortcuts": "Raccourcis clavier",
102104
"Open Conversation Page": "Ouvrir la page de conversation",

src/_locales/ja/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "会話を削除",
9898
"Clear conversations": "会話をクリア",
9999
"Settings": "設定",
100+
"Search": "検索",
101+
"Search conversations...": "会話を検索...",
100102
"Feature Pages": "機能ページ",
101103
"Keyboard Shortcuts": "キーボードショートカット",
102104
"Open Conversation Page": "会話ページを開く",

src/_locales/zh-hans/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "删除对话",
9898
"Clear conversations": "清空记录",
9999
"Settings": "设置",
100+
"Search": "搜索",
101+
"Search conversations...": "搜索聊天记录...",
100102
"Feature Pages": "功能页",
101103
"Keyboard Shortcuts": "快捷键设置",
102104
"Open Conversation Page": "打开独立对话页",

src/_locales/zh-hant/main.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"Delete Conversation": "刪除對話",
9898
"Clear conversations": "清空對話記錄",
9999
"Settings": "設定",
100+
"Search": "搜尋",
101+
"Search conversations...": "搜尋對話記錄...",
100102
"Feature Pages": "功能頁面",
101103
"Keyboard Shortcuts": "快速鍵設定",
102104
"Open Conversation Page": "開啟獨立對話頁面",

src/pages/IndependentPanel/App.jsx

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
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'
1010
import './styles.scss'
1111
import { useConfig } from '../../hooks/use-config.mjs'
1212
import { useTranslation } from 'react-i18next'
@@ -25,6 +25,7 @@ function App() {
2525
const [sessionId, setSessionId] = useState(null)
2626
const [currentSession, setCurrentSession] = useState(null)
2727
const [renderContent, setRenderContent] = useState(false)
28+
const [searchQuery, setSearchQuery] = useState('')
2829
const currentPort = useRef(null)
2930

3031
const setSessionIdSafe = async (sessionId) => {
@@ -103,6 +104,30 @@ function App() {
103104
await setSessionIdSafe(sessions[0].sessionId)
104105
}
105106

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
111+
112+
return sessions.filter((session) => {
113+
// Search in session name
114+
if (session.sessionName && session.sessionName.toLowerCase().includes(query)) {
115+
return true
116+
}
117+
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+
}
126+
127+
return false
128+
})
129+
}, [sessions, searchQuery])
130+
106131
return (
107132
<div className="IndependentPanel">
108133
<div className="chat-container">
@@ -119,36 +144,46 @@ function App() {
119144
</button>
120145
</div>
121146
<hr />
147+
<div className="search-container">
148+
<input
149+
type="search"
150+
placeholder={t('Search conversations...')}
151+
value={searchQuery}
152+
onChange={(e) => setSearchQuery(e.target.value)}
153+
className="search-input"
154+
aria-label={t('Search')}
155+
autoComplete="off"
156+
/>
157+
</div>
122158
<div className="chat-list">
123-
{sessions.map(
124-
(
125-
session,
126-
index, // TODO editable session name
127-
) => (
128-
<button
129-
key={index}
130-
className={`normal-button ${sessionId === session.sessionId ? 'active' : ''}`}
131-
style="display: flex; align-items: center; justify-content: space-between;"
132-
onClick={() => {
133-
setSessionIdSafe(session.sessionId)
134-
}}
135-
>
136-
{session.sessionName}
137-
<span className="gpt-util-group">
138-
<DeleteButton
139-
size={14}
140-
text={t('Delete Conversation')}
141-
onConfirm={() =>
142-
deleteSession(session.sessionId).then((sessions) => {
143-
setSessions(sessions)
144-
setSessionIdSafe(sessions[0].sessionId)
145-
})
146-
}
147-
/>
148-
</span>
149-
</button>
150-
),
151-
)}
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+
))}
152187
</div>
153188
<hr />
154189
<div className="chat-sidebar-button-group">
@@ -165,7 +200,7 @@ function App() {
165200
</div>
166201
<div className="chat-content">
167202
{renderContent && currentSession && currentSession.conversationRecords && (
168-
<div className="chatgptbox-container" style="height:100%;">
203+
<div className="chatgptbox-container" style={{ height: '100%' }}>
169204
<ConversationCard
170205
session={currentSession}
171206
notClampSize={true}

src/pages/IndependentPanel/styles.scss

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
width: 60px;
7272
}
7373

74+
.chat-sidebar.collapsed .search-container {
75+
display: none;
76+
}
77+
7478
.chat-sidebar:hover,
7579
.chat-sidebar:not(.collapsed) {
7680
min-width: 250px;
@@ -85,6 +89,39 @@
8589
gap: 15px;
8690
}
8791

92+
.search-container {
93+
padding: 0;
94+
background-color: var(--theme-color);
95+
}
96+
97+
.search-input {
98+
width: 100%;
99+
min-height: 40px;
100+
padding: 8px 12px;
101+
border: 1px solid var(--theme-border-color);
102+
border-radius: 5px;
103+
background-color: var(--theme-color);
104+
color: var(--font-color);
105+
font-size: 14px;
106+
font-family: 'Cairo', sans-serif;
107+
box-sizing: border-box;
108+
line-height: 1.2;
109+
}
110+
111+
.search-input::placeholder {
112+
color: var(--font-color);
113+
opacity: 0.6;
114+
}
115+
116+
.search-input:focus {
117+
border-color: var(--font-active-color);
118+
}
119+
120+
.search-input:focus-visible {
121+
outline: 2px solid var(--font-active-color);
122+
outline-offset: 2px;
123+
}
124+
88125
.chat-list {
89126
display: flex;
90127
flex-direction: column;

0 commit comments

Comments
 (0)