Skip to content

Commit 8b7a3f9

Browse files
IndependentPanel: Prevent delete bubbling and harden search input
- Stop click/keyboard bubbling from utility group to avoid triggering parent button when interacting with delete controls; add tabIndex=-1 and preventDefault on Enter/Space for accessibility - Remount content on session switch via key to avoid stale scroll/state - Sanitize and clamp search input (strip control chars, max 500) to improve robustness and UX - When deleting the active session, pick the next valid sessionId or clear selection safely - Add focus outline fallback color for the search field to maintain contrast across themes - Guard DeleteButton confirm against rapid re-entry and ensure UI exits confirm state via try/finally Notes: - Did not change config persistence flow (setUserConfig), as it stores partial keys without overwriting others - Did not bound per-session scan size; will revisit only if real perf issues arise
1 parent c2bdd00 commit 8b7a3f9

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

src/components/DeleteButton/index.jsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function DeleteButton({ onConfirm, size, text }) {
1313
const { t } = useTranslation()
1414
const [waitConfirm, setWaitConfirm] = useState(false)
1515
const confirmRef = useRef(null)
16+
const confirmingRef = useRef(false)
1617

1718
useEffect(() => {
1819
if (waitConfirm) confirmRef.current.focus()
@@ -35,11 +36,17 @@ function DeleteButton({ onConfirm, size, text }) {
3536
onBlur={() => {
3637
setWaitConfirm(false)
3738
}}
38-
onClick={(e) => {
39+
onClick={async (e) => {
40+
if (confirmingRef.current) return
3941
e.preventDefault()
4042
e.stopPropagation()
41-
setWaitConfirm(false)
42-
onConfirm()
43+
confirmingRef.current = true
44+
try {
45+
await onConfirm()
46+
} finally {
47+
confirmingRef.current = false
48+
setWaitConfirm(false)
49+
}
4350
}}
4451
>
4552
{t('Confirm')}

src/pages/IndependentPanel/App.jsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,17 @@ function App() {
116116
await setSessionIdSafe(sessions[0].sessionId)
117117
}
118118

119-
const handleSearchChange = (e) => setSearchQuery(e.target.value)
119+
const handleSearchChange = (e) => {
120+
const raw = e?.target?.value ?? ''
121+
const cleaned = Array.from(raw)
122+
.filter((ch) => {
123+
const code = ch.charCodeAt(0)
124+
return code >= 32 || code === 9 || code === 10 || code === 13
125+
})
126+
.join('')
127+
.slice(0, 500)
128+
setSearchQuery(cleaned)
129+
}
120130

121131
// Debounce search input for performance
122132
useEffect(() => {
@@ -234,11 +244,15 @@ function App() {
234244
{session.sessionName}
235245
<span
236246
className="gpt-util-group"
247+
tabIndex={-1}
237248
onClick={(e) => {
238249
e.stopPropagation()
239250
}}
240251
onKeyDown={(e) => {
241-
if (e.key === 'Enter' || e.key === ' ') e.stopPropagation()
252+
if (e.key === 'Enter' || e.key === ' ') {
253+
e.preventDefault()
254+
e.stopPropagation()
255+
}
242256
}}
243257
>
244258
<DeleteButton
@@ -255,7 +269,13 @@ function App() {
255269
}
256270
// Only change active session if the deleted one was active
257271
if (sessionId === deletedId) {
258-
await setSessionIdSafe(updatedSessions[0].sessionId)
272+
const next = updatedSessions.find((s) => s && s.sessionId)
273+
if (next) {
274+
await setSessionIdSafe(next.sessionId)
275+
} else {
276+
setSessionId(null)
277+
setCurrentSession(null)
278+
}
259279
}
260280
}}
261281
/>
@@ -278,7 +298,11 @@ function App() {
278298
</div>
279299
<div className="chat-content">
280300
{renderContent && currentSession && currentSession.conversationRecords && (
281-
<div className="chatgptbox-container" style={{ height: '100%' }}>
301+
<div
302+
key={currentSession.sessionId}
303+
className="chatgptbox-container"
304+
style={{ height: '100%' }}
305+
>
282306
<ConversationCard
283307
session={currentSession}
284308
notClampSize={true}

src/pages/IndependentPanel/styles.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120
}
121121

122122
.search-input:focus-visible {
123-
outline: 2px solid var(--font-active-color);
123+
outline: 2px solid var(--font-active-color, #3b82f6);
124124
outline-offset: 2px;
125125
}
126126

0 commit comments

Comments
 (0)