fix: Disable reply editor outside WhatsApp reply window (#13454)

This commit is contained in:
Sivin Varghese
2026-02-17 14:07:36 +05:30
committed by GitHub
parent 39243b9e71
commit c5f6844877
5 changed files with 48 additions and 4 deletions

View File

@@ -830,7 +830,13 @@ useEmitter(BUS_EVENTS.INSERT_INTO_RICH_EDITOR, insertContentIntoEditor);
</script>
<template>
<div ref="editorRoot" class="relative w-full">
<div
ref="editorRoot"
class="relative w-full"
:class="{
'opacity-50 cursor-not-allowed pointer-events-none': disabled,
}"
>
<TagAgents
v-if="showUserMentions && isPrivate"
:search-key="mentionSearchKey"

View File

@@ -122,6 +122,10 @@ export default {
type: Boolean,
default: false,
},
isEditorDisabled: {
type: Boolean,
default: false,
},
},
emits: [
'replaceText',
@@ -130,7 +134,7 @@ export default {
'selectContentTemplate',
'toggleQuotedReply',
],
setup() {
setup(props) {
const { setSignatureFlagForInbox, fetchSignatureFlagFromUISettings } =
useUISettings();
@@ -139,6 +143,9 @@ export default {
const keyboardEvents = {
'$mod+Alt+KeyA': {
action: () => {
// Skip if editor is disabled (e.g., WhatsApp 24-hour window expired)
if (props.isEditorDisabled) return;
// TODO: This is really hacky, we need to replace the file picker component with
// a custom one, where the logic and the component markup is isolated.
// Once we have the custom component, we can remove the hacky logic below.
@@ -146,7 +153,7 @@ export default {
const uploadTriggerButton = document.querySelector(
'#conversationAttachment'
);
uploadTriggerButton.click();
if (uploadTriggerButton) uploadTriggerButton.click();
},
allowOnFocusedInput: true,
},
@@ -177,9 +184,11 @@ export default {
};
},
showAttachButton() {
if (this.isEditorDisabled) return false;
return this.showFileUpload || this.isNote;
},
showAudioRecorderButton() {
if (this.isEditorDisabled) return false;
if (this.isALineChannel) {
return false;
}
@@ -197,6 +206,7 @@ export default {
);
},
showAudioPlayStopButton() {
if (this.isEditorDisabled) return false;
return this.showAudioRecorder && this.isRecordingAudio;
},
isInstagramDM() {
@@ -236,6 +246,7 @@ export default {
}
},
showMessageSignatureButton() {
if (this.isEditorDisabled) return false;
return !this.isOnPrivateNote;
},
sendWithSignature() {
@@ -280,6 +291,7 @@ export default {
<div class="flex justify-between p-3" :class="wrapClass">
<div class="left-wrap">
<NextButton
v-if="!isEditorDisabled"
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_EMOJI_ICON')"
icon="i-ph-smiley-sticker"
slate
@@ -288,6 +300,7 @@ export default {
@click="toggleEmojiPicker"
/>
<FileUpload
v-if="showAttachButton"
ref="uploadRef"
v-tooltip.top-end="$t('CONVERSATION.REPLYBOX.TIP_ATTACH_ICON')"
input-id="conversationAttachment"

View File

@@ -33,6 +33,10 @@ export default {
type: Boolean,
default: false,
},
isEditorDisabled: {
type: Boolean,
default: false,
},
conversationId: {
type: Number,
default: null,
@@ -157,7 +161,7 @@ export default {
<div class="relative">
<NextButton
ghost
:disabled="disabled"
:disabled="disabled || isEditorDisabled"
:class="{
'text-n-violet-9 hover:enabled:!bg-n-violet-3': !showCopilotMenu,
'text-n-violet-9 bg-n-violet-3': showCopilotMenu,

View File

@@ -199,6 +199,11 @@ export default {
return this.$store.getters['inboxes/getInbox'](this.inboxId);
},
messagePlaceHolder() {
if (this.isEditorDisabled) {
return this.isAWhatsAppChannel
? this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED_WHATSAPP')
: this.$t('CONVERSATION.FOOTER.MESSAGING_RESTRICTED');
}
return this.isPrivate
? this.$t('CONVERSATION.FOOTER.PRIVATE_MSG_INPUT')
: this.$t('CONVERSATION.FOOTER.MSG_INPUT');
@@ -210,6 +215,7 @@ export default {
return this.maxLength - this.message.length;
},
isReplyButtonDisabled() {
if (this.isEditorDisabled) return true;
if (this.isATwitterInbox) return true;
if (this.hasAttachments || this.hasRecordedAudio) return false;
@@ -418,6 +424,13 @@ export default {
isDefaultEditorMode() {
return !this.showAudioRecorderEditor && !this.copilot.isActive.value;
},
isEditorDisabled() {
return (
this.isAWhatsAppChannel &&
!this.isOnPrivateNote &&
!this.currentChat.can_reply
);
},
},
watch: {
currentChat(conversation, oldConversation) {
@@ -677,6 +690,9 @@ export default {
// Don't handle paste if compose new conversation modal is open
if (this.newConversationModalActive) return;
// Don't handle paste if editor is disabled
if (this.isEditorDisabled) return;
// Filter valid files (non-zero size)
Array.from(e.clipboardData.files)
.filter(file => file.size > 0)
@@ -1216,6 +1232,7 @@ export default {
(copilot.isActive.value && copilot.isButtonDisabled.value) ||
showAudioRecorderEditor
"
:is-editor-disabled="isEditorDisabled"
:is-message-length-reaching-threshold="isMessageLengthReachingThreshold"
:characters-remaining="charactersRemaining"
:popout-reply-box="popOutReplyBox"
@@ -1292,6 +1309,7 @@ export default {
:placeholder="messagePlaceHolder"
:update-selection-with="updateEditorSelectionWith"
:min-height="4"
:disabled="isEditorDisabled"
enable-variables
:variables="messageVariables"
:signature="messageSignature"
@@ -1367,6 +1385,7 @@ export default {
:is-recording-audio="isRecordingAudio"
:is-send-disabled="isReplyButtonDisabled"
:is-note="isPrivate"
:is-editor-disabled="isEditorDisabled"
:on-file-upload="onFileUpload"
:on-send="onSendReply"
:conversation-type="conversationType"

View File

@@ -190,6 +190,8 @@
"DISABLE_SIGN_TOOLTIP": "Disable signature",
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents",
"MESSAGING_RESTRICTED": "You cannot reply to this conversation",
"MESSAGING_RESTRICTED_WHATSAPP": "You can only reply using a template message due to 24-hour message window restriction",
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
"COPILOT_MSG_INPUT": "Give copilot additional prompts, or ask anything else... Press enter to send follow-up",
"CLICK_HERE": "Click here to update",