diff --git a/apps/desktop/src/plugins/hermes-bots/plugin.js b/apps/desktop/src/plugins/hermes-bots/plugin.js index eff1c26817..02185300a9 100644 --- a/apps/desktop/src/plugins/hermes-bots/plugin.js +++ b/apps/desktop/src/plugins/hermes-bots/plugin.js @@ -8951,6 +8951,10 @@ function HubSkillsSection({ forProfile, onInstalled }) { value: query, onChange: event => setQuery(event.target.value), onKeyDown: event => { + // IME guard: Enter confirming a composed word must not search. + if (event.nativeEvent?.isComposing || event.keyCode === 229) { + return + } if (event.key === 'Enter') { event.preventDefault() void search() @@ -11859,6 +11863,14 @@ function GroupMentionInput({ members, onChange, onSubmitDraft, value, ...inputPr }, onClick: event => refreshToken(event.target), onKeyDown: event => { + // IME composition guard (same as the core composer): Enter here + // confirms the composed Chinese/Japanese/Korean text — it must not + // insert a mention nor submit the draft. nativeEvent.isComposing + // covers Chromium; keyCode 229 covers macOS Chinese IMEs that fire + // Enter after compositionend with isComposing already false. + if (event.nativeEvent?.isComposing || event.keyCode === 229) { + return + } if (open) { if (event.key === 'ArrowDown') { event.preventDefault() @@ -12045,6 +12057,10 @@ function GroupClarifyCard({ entry, members }) { setDrafts(prev => ({ ...prev, [q.qid]: value })) }, onKeyDown: event => { + // IME guard: Enter confirming a composed word must not submit. + if (event.nativeEvent?.isComposing || event.keyCode === 229) { + return + } if (event.key === 'Enter' && questions.length === 1) { event.preventDefault() void submit() diff --git a/apps/desktop/src/plugins/hermes-bots/tests/group-room-ux.test.mjs b/apps/desktop/src/plugins/hermes-bots/tests/group-room-ux.test.mjs index cc32992b95..c52ede26d5 100644 --- a/apps/desktop/src/plugins/hermes-bots/tests/group-room-ux.test.mjs +++ b/apps/desktop/src/plugins/hermes-bots/tests/group-room-ux.test.mjs @@ -31,6 +31,33 @@ test('room composer is a textarea with Enter=submit, Shift+Enter=newline (#89884 assert.match(component, /insert\(options\[active\]\.handle\)/) }) +test('room composer swallows IME composition Enters before submit/mention (#93528)', () => { + // macOS Chinese IME: Enter that confirms a candidate word fires a keydown + // the composer mistook for a send — the message went out mid-composition. + // The guard must run BEFORE the popover branch AND the submit branch, and + // cover both Chromium's isComposing flag and the keyCode 229 legacy + // VK_PROCESSKEY that macOS IMEs emit after compositionend. + const start = source.indexOf('function GroupMentionInput') + const nextFn = source.indexOf('\nfunction ', start + 1) + const component = source.slice(start, nextFn) + + const guard = component.indexOf('event.nativeEvent?.isComposing || event.keyCode === 229') + assert.ok(guard >= 0, 'IME guard present in GroupMentionInput') + const afterGuard = component.slice(guard) + // Guard returns immediately (no mention insert, no submit)... + assert.match(afterGuard.slice(0, 80), /return/) + // ...and it sits before both the popover branch and the submit branch. + assert.ok(afterGuard.indexOf('if (open) {') > 0, 'guard precedes popover branch') + assert.ok(component.indexOf("event.key === 'Enter' && !event.shiftKey") > guard, 'guard precedes submit branch') +}) + +test('clarify free-text input swallows IME composition Enters (#93528)', () => { + const clarify = source.slice(source.indexOf('function GroupClarifyCard'), source.indexOf('function openGroupChat')) + const guard = clarify.indexOf('event.nativeEvent?.isComposing || event.keyCode === 229') + assert.ok(guard >= 0, 'IME guard present in GroupClarifyCard') + assert.ok(clarify.indexOf("event.key === 'Enter' && questions.length === 1") > guard, 'guard precedes submit branch') +}) + test('both room composers wire onSubmitDraft (#89884)', () => { assert.match(source, /onSubmitDraft: submit,/) assert.match(source, /onSubmitDraft: \(\) => submitReply\(id\),/) diff --git a/contributors/emails/quexl1@chinatelecom.cn b/contributors/emails/quexl1@chinatelecom.cn new file mode 100644 index 0000000000..0355895957 --- /dev/null +++ b/contributors/emails/quexl1@chinatelecom.cn @@ -0,0 +1 @@ +ShonnQ