Compare commits

...

1 commit

Author SHA1 Message Date
Pranav Raj S
ead7a5fc87 feat: Link to a message 2022-11-09 19:11:20 -08:00
7 changed files with 78 additions and 13 deletions

View file

@ -20,11 +20,22 @@ class MessageFinder
conversation_messages.where.not('private = ? OR message_type = ?', true, 2)
end
def messages_in_desc_order
messages.reorder('created_at desc')
end
def current_messages
messages_to_display = messages_in_desc_order
if @params[:before].present?
messages.reorder('created_at desc').where('id < ?', @params[:before].to_i).limit(20).reverse
else
messages.reorder('created_at desc').limit(20).reverse
messages_to_display = messages_to_display.where('id < ?', @params[:before].to_i)
if @params[:after].present? && @params[:after].to_i < @params[:before].to_i - 25
messages_to_display = messages_to_display.where('id >= ?', @params[:after].to_i)
return messages_to_display.reverse
end
end
messages_to_display.limit(20).reverse
end
end

View file

@ -75,9 +75,9 @@ class MessageApi extends ApiClient {
return axios.delete(`${this.url}/${conversationID}/messages/${messageId}`);
}
getPreviousMessages({ conversationId, before }) {
getPreviousMessages({ conversationId, after, before }) {
return axios.get(`${this.url}/${conversationId}/messages`, {
params: { before },
params: { after, before },
});
}
}

View file

@ -1,6 +1,7 @@
<template>
<li
v-if="hasAttachments || data.content || isEmailContentType"
:id="'message' + data.id"
:class="alignBubble"
>
<div :class="wrapClass">
@ -104,8 +105,10 @@
<div v-if="shouldShowContextMenu" class="context-menu-wrap">
<context-menu
v-if="isBubble && !isMessageDeleted"
:id="data.id"
:is-open="showContextMenu"
:show-copy="hasText"
:conversation-id="data.conversation_id"
:show-canned-response-option="isOutgoing"
:menu-position="contextMenuPosition"
:message-content="data.content"

View file

@ -304,8 +304,15 @@ export default {
setSelectedTweet(tweetId) {
this.selectedTweetId = tweetId;
},
onScrollToMessage() {
this.$nextTick(() => this.scrollToBottom());
onScrollToMessage({ messageId = '' } = {}) {
this.$nextTick(() => {
const messageElement = document.getElementById('message' + messageId);
if (messageElement) {
messageElement.scrollIntoView({ behavior: 'smooth' });
} else {
this.scrollToBottom();
}
});
this.makeMessagesRead();
},
showPopoutReplyBox() {

View file

@ -47,6 +47,18 @@
</woot-button>
</woot-dropdown-item>
<woot-dropdown-item>
<woot-button
variant="clear"
size="small"
icon="link"
color-scheme="secondary"
@click="copyLinkToMessage"
>
Copy Permalink
</woot-button>
</woot-dropdown-item>
<woot-dropdown-item>
<woot-button
v-if="showCannedResponseOption"
@ -72,6 +84,8 @@ import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { conversationUrl, frontendURL } from '../../../helper/URLHelper';
import { mapGetters } from 'vuex';
export default {
components: {
@ -101,11 +115,22 @@ export default {
type: Boolean,
default: true,
},
conversationId: {
type: Number,
required: true,
},
id: {
type: Number,
required: true,
},
},
data() {
return { isCannedResponseModalOpen: false };
},
computed: {
...mapGetters({
currentAccountId: 'getCurrentAccountId',
}),
plainTextContent() {
return this.getPlainText(this.messageContent);
},
@ -114,6 +139,19 @@ export default {
handleContextMenuClick() {
this.$emit('toggle', !this.isOpen);
},
async copyLinkToMessage() {
await copyTextToClipboard(
frontendURL(
conversationUrl({
id: this.conversationId,
accountId: this.currentAccountId,
}) +
'?messageId=' +
this.id
)
);
this.showAlert('Link Copied');
},
async handleCopy() {
await copyTextToClipboard(this.plainTextContent);
this.showAlert(this.$t('CONTACT_PANEL.COPY_SUCCESSFUL'));

View file

@ -160,9 +160,15 @@ export default {
) {
return;
}
this.$store.dispatch('setActiveChat', selectedConversation).then(() => {
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE);
});
const { message_id: messageId } = this.$route.query;
this.$store
.dispatch('setActiveChat', {
data: selectedConversation,
after: messageId,
})
.then(() => {
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE, { messageId });
});
} else {
this.$store.dispatch('clearSelectedState');
}

View file

@ -82,15 +82,15 @@ const actions = {
}
},
async setActiveChat({ commit, dispatch }, data) {
async setActiveChat({ commit, dispatch }, { data, after }) {
commit(types.SET_CURRENT_CHAT_WINDOW, data);
commit(types.CLEAR_ALL_MESSAGES_LOADED);
if (data.dataFetched === undefined) {
try {
await dispatch('fetchPreviousMessages', {
conversationId: data.id,
after,
before: data.messages[0].id,
conversationId: data.id,
});
Vue.set(data, 'dataFetched', true);
} catch (error) {