From bd9955d5293e581d05fb55d37f2cb0b9d6f53c8d Mon Sep 17 00:00:00 2001 From: Michael Knaap Date: Wed, 2 Sep 2026 01:00:13 +0200 Subject: [PATCH] =?UTF-8?q?fix(desktop):=20section=20rename=20=E2=80=94=20?= =?UTF-8?q?Escape=20cancels,=20Enter=20commits=20once?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closing the rename field unmounts the input, and the unmount can still fire onBlur, which committed the draft the user had just asked to throw away with Escape. Enter also called commit() directly and then again from blur. Route both through blur with a cancelled flag so the commit runs exactly once and Escape never renames. --- .../plugins/hermes-bots/user-sections-ui.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/plugins/hermes-bots/user-sections-ui.tsx b/apps/desktop/src/plugins/hermes-bots/user-sections-ui.tsx index 86d84670fd..c8d7bc5ca8 100644 --- a/apps/desktop/src/plugins/hermes-bots/user-sections-ui.tsx +++ b/apps/desktop/src/plugins/hermes-bots/user-sections-ui.tsx @@ -19,7 +19,7 @@ import { RowButton, useValue } from '@hermes/plugin-sdk' -import { useState } from 'react' +import { useRef, useState } from 'react' import { $botSections, $renamingSection, renameBotSection, setBotSectionIcon } from './user-sections' @@ -48,11 +48,19 @@ export function UserSectionHeader({ const showIcon = useValue($botSections).find(section => section.id === id)?.icon !== false const renaming = Boolean(id) && renamingId === id const [draft, setDraft] = useState(name) + // Escape must CANCEL. Closing the field unmounts the input, and an unmount + // can still fire its onBlur — which used to commit the draft the user had + // just asked to throw away. Enter goes through blur too, so the commit runs + // once whichever way the field closes. + const cancelled = useRef(false) const commit = () => { + const wasCancelled = cancelled.current + + cancelled.current = false $renamingSection.set(null) - if (id && draft.trim() && draft.trim() !== name) { + if (!wasCancelled && id && draft.trim() && draft.trim() !== name) { renameBotSection(id, draft) } } @@ -91,11 +99,14 @@ export function UserSectionHeader({ onChange={event => setDraft(event.target.value)} onKeyDown={event => { if (event.key === 'Enter') { - commit() + // Blur commits; calling commit() here as well ran it twice. + event.currentTarget.blur() } if (event.key === 'Escape') { - $renamingSection.set(null) + cancelled.current = true + setDraft(name) + event.currentTarget.blur() } }} value={draft}