feat: Setup context menu for message (#6750)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<li v-if="shouldRenderMessage" :class="alignBubble">
|
||||
<div :class="wrapClass">
|
||||
<div :class="wrapClass" @contextmenu="openContextMenu($event)">
|
||||
<div v-tooltip.top-start="messageToolTip" :class="bubbleClass">
|
||||
<bubble-mail-head
|
||||
:email-attributes="contentAttributes.email"
|
||||
@@ -73,12 +73,6 @@
|
||||
:created-at="createdAt"
|
||||
/>
|
||||
</div>
|
||||
<translate-modal
|
||||
v-if="showTranslateModal"
|
||||
:content="data.content"
|
||||
:content-attributes="contentAttributes"
|
||||
@close="onCloseTranslateModal"
|
||||
/>
|
||||
<spinner v-if="isPending" size="tiny" />
|
||||
<div
|
||||
v-if="showAvatar"
|
||||
@@ -114,15 +108,12 @@
|
||||
<div v-if="shouldShowContextMenu" class="context-menu-wrap">
|
||||
<context-menu
|
||||
v-if="isBubble && !isMessageDeleted"
|
||||
:context-menu-position="contextMenuPosition"
|
||||
:is-open="showContextMenu"
|
||||
:show-copy="hasText"
|
||||
:show-delete="hasText || hasAttachments"
|
||||
:show-canned-response-option="isOutgoing && hasText"
|
||||
:menu-position="contextMenuPosition"
|
||||
:message-content="data.content"
|
||||
@toggle="handleContextMenuClick"
|
||||
@delete="handleDelete"
|
||||
@translate="handleTranslate"
|
||||
:enabled-options="contextMenuEnabledOptions"
|
||||
:message="data"
|
||||
@open="openContextMenu"
|
||||
@close="closeContextMenu"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
@@ -145,8 +136,8 @@ import alertMixin from 'shared/mixins/alertMixin';
|
||||
import contentTypeMixin from 'shared/mixins/contentTypeMixin';
|
||||
import { MESSAGE_TYPE, MESSAGE_STATUS } from 'shared/constants/messages';
|
||||
import { generateBotMessageContent } from './helpers/botMessageContentHelper';
|
||||
import { mapGetters } from 'vuex';
|
||||
import TranslateModal from './bubble/TranslateModal.vue';
|
||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||
import { ACCOUNT_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -162,7 +153,6 @@ export default {
|
||||
ContextMenu,
|
||||
Spinner,
|
||||
instagramImageErrorPlaceholder,
|
||||
TranslateModal,
|
||||
},
|
||||
mixins: [alertMixin, messageFormatterMixin, contentTypeMixin],
|
||||
props: {
|
||||
@@ -191,14 +181,10 @@ export default {
|
||||
return {
|
||||
showContextMenu: false,
|
||||
hasImageError: false,
|
||||
showTranslateModal: false,
|
||||
contextMenuPosition: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
getAccount: 'accounts/getAccount',
|
||||
currentAccountId: 'getCurrentAccountId',
|
||||
}),
|
||||
shouldRenderMessage() {
|
||||
return (
|
||||
this.hasAttachments ||
|
||||
@@ -256,6 +242,13 @@ export default {
|
||||
) + botMessageContent
|
||||
);
|
||||
},
|
||||
contextMenuEnabledOptions() {
|
||||
return {
|
||||
copy: this.hasText,
|
||||
delete: this.hasText || this.hasAttachments,
|
||||
cannedResponse: this.isOutgoing && this.hasText,
|
||||
};
|
||||
},
|
||||
contentAttributes() {
|
||||
return this.data.content_attributes || {};
|
||||
},
|
||||
@@ -384,10 +377,6 @@ export default {
|
||||
if (this.isPending || this.isFailed) return false;
|
||||
return !this.sender.type || this.sender.type === 'agent_bot';
|
||||
},
|
||||
contextMenuPosition() {
|
||||
const { message_type: messageType } = this.data;
|
||||
return messageType ? 'right' : 'left';
|
||||
},
|
||||
shouldShowContextMenu() {
|
||||
return !(this.isFailed || this.isPending);
|
||||
},
|
||||
@@ -416,6 +405,10 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.hasImageError = false;
|
||||
bus.$on(BUS_EVENTS.ON_MESSAGE_LIST_SCROLL, this.closeContextMenu);
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off(BUS_EVENTS.ON_MESSAGE_LIST_SCROLL, this.closeContextMenu);
|
||||
},
|
||||
methods: {
|
||||
hasMediaAttachment(type) {
|
||||
@@ -429,37 +422,29 @@ export default {
|
||||
handleContextMenuClick() {
|
||||
this.showContextMenu = !this.showContextMenu;
|
||||
},
|
||||
async handleDelete() {
|
||||
const { conversation_id: conversationId, id: messageId } = this.data;
|
||||
try {
|
||||
await this.$store.dispatch('deleteMessage', {
|
||||
conversationId,
|
||||
messageId,
|
||||
});
|
||||
this.showAlert(this.$t('CONVERSATION.SUCCESS_DELETE_MESSAGE'));
|
||||
this.showContextMenu = false;
|
||||
} catch (error) {
|
||||
this.showAlert(this.$t('CONVERSATION.FAIL_DELETE_MESSSAGE'));
|
||||
}
|
||||
},
|
||||
async retrySendMessage() {
|
||||
await this.$store.dispatch('sendMessageWithData', this.data);
|
||||
},
|
||||
onImageLoadError() {
|
||||
this.hasImageError = true;
|
||||
},
|
||||
handleTranslate() {
|
||||
const { locale } = this.getAccount(this.currentAccountId);
|
||||
const { conversation_id: conversationId, id: messageId } = this.data;
|
||||
this.$store.dispatch('translateMessage', {
|
||||
conversationId,
|
||||
messageId,
|
||||
targetLanguage: locale || 'en',
|
||||
});
|
||||
this.showTranslateModal = true;
|
||||
openContextMenu(e) {
|
||||
if (getSelection().toString()) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
if (e.type === 'contextmenu') {
|
||||
this.$track(ACCOUNT_EVENTS.OPEN_MESSAGE_CONTEXT_MENU);
|
||||
}
|
||||
this.contextMenuPosition = {
|
||||
x: e.pageX || e.clientX,
|
||||
y: e.pageY || e.clientY,
|
||||
};
|
||||
this.showContextMenu = true;
|
||||
},
|
||||
onCloseTranslateModal() {
|
||||
this.showTranslateModal = false;
|
||||
closeContextMenu() {
|
||||
this.showContextMenu = false;
|
||||
this.contextMenuPosition = { x: null, y: null };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -355,6 +355,7 @@ export default {
|
||||
},
|
||||
|
||||
handleScroll(e) {
|
||||
bus.$emit(BUS_EVENTS.ON_MESSAGE_LIST_SCROLL);
|
||||
this.setScrollParams();
|
||||
|
||||
const dataFetchCheck =
|
||||
|
||||
Reference in New Issue
Block a user