chore: Auto-focus editor when replying to a message (#13857)

# Pull Request Template

## Description

This PR adds support to auto-focus the editor when clicking reply to
this message, the editor now automatically receives focus so users can
start typing immediately.

Fixes
https://linear.app/chatwoot/issue/CW-6661/typing-box-not-focused-after-clicking-reply-to-message

## Type of change


- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

### Screencast


https://github.com/user-attachments/assets/c5e77055-3f68-4ad8-934e-cfc465166e8a




## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
This commit is contained in:
Sivin Varghese
2026-03-20 16:59:27 +05:30
committed by GitHub
parent 2b50909d9b
commit 251e9980fd
3 changed files with 17 additions and 2 deletions

View File

@@ -828,6 +828,8 @@ onMounted(() => {
} }
}); });
defineExpose({ focusEditorInputField });
// BUS Event to insert text or markdown into the editor at the // BUS Event to insert text or markdown into the editor at the
// current cursor position. // current cursor position.
// Components using this // Components using this

View File

@@ -99,6 +99,7 @@ export default {
} = useUISettings(); } = useUISettings();
const replyEditor = useTemplateRef('replyEditor'); const replyEditor = useTemplateRef('replyEditor');
const messageEditor = useTemplateRef('messageEditor');
const copilot = useCopilotReply(); const copilot = useCopilotReply();
const shortcutKey = useKbd(['$mod', '+', 'enter']); const shortcutKey = useKbd(['$mod', '+', 'enter']);
@@ -109,6 +110,7 @@ export default {
setQuotedReplyFlagForInbox, setQuotedReplyFlagForInbox,
fetchQuotedReplyFlagFromUISettings, fetchQuotedReplyFlagFromUISettings,
replyEditor, replyEditor,
messageEditor,
copilot, copilot,
shortcutKey, shortcutKey,
}; };
@@ -507,7 +509,7 @@ export default {
); );
this.fetchAndSetReplyTo(); this.fetchAndSetReplyTo();
emitter.on(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.fetchAndSetReplyTo); emitter.on(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.onReplyToMessage);
// A hacky fix to solve the drag and drop // A hacky fix to solve the drag and drop
// Is showing on top of new conversation modal drag and drop // Is showing on top of new conversation modal drag and drop
@@ -522,7 +524,7 @@ export default {
unmounted() { unmounted() {
document.removeEventListener('paste', this.onPaste); document.removeEventListener('paste', this.onPaste);
document.removeEventListener('keydown', this.handleKeyEvents); document.removeEventListener('keydown', this.handleKeyEvents);
emitter.off(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.fetchAndSetReplyTo); emitter.off(BUS_EVENTS.TOGGLE_REPLY_TO_MESSAGE, this.onReplyToMessage);
emitter.off(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, this.addIntoEditor); emitter.off(BUS_EVENTS.INSERT_INTO_NORMAL_EDITOR, this.addIntoEditor);
emitter.off( emitter.off(
BUS_EVENTS.NEW_CONVERSATION_MODAL, BUS_EVENTS.NEW_CONVERSATION_MODAL,
@@ -1191,6 +1193,15 @@ export default {
return false; return false;
}); });
}, },
onReplyToMessage() {
this.fetchAndSetReplyTo();
if (this.inReplyTo) {
this.$nextTick(() => {
const pos = this.isSignatureEnabledForInbox ? 'start' : 'end';
this.messageEditor?.focusEditorInputField(pos);
});
}
},
resetReplyToMessage() { resetReplyToMessage() {
const replyStorageKey = LOCAL_STORAGE_KEYS.MESSAGE_REPLY_TO; const replyStorageKey = LOCAL_STORAGE_KEYS.MESSAGE_REPLY_TO;
LocalStorage.deleteFromJsonStore(replyStorageKey, this.conversationId); LocalStorage.deleteFromJsonStore(replyStorageKey, this.conversationId);
@@ -1313,6 +1324,7 @@ export default {
/> />
<WootMessageEditor <WootMessageEditor
v-else-if="!showAudioRecorderEditor" v-else-if="!showAudioRecorderEditor"
ref="messageEditor"
v-model="message" v-model="message"
:conversation-id="conversationId" :conversation-id="conversationId"
:editor-id="editorStateId" :editor-id="editorStateId"

View File

@@ -32,6 +32,7 @@ const emit = defineEmits(['dismiss']);
xs xs
slate slate
icon="i-lucide-x" icon="i-lucide-x"
class="flex-shrink-0"
@click.stop="emit('dismiss')" @click.stop="emit('dismiss')"
/> />
</div> </div>