From 4216d6331139f60e91f1ac9c633d3d1416427cde Mon Sep 17 00:00:00 2001
From: Sojan Jose
Date: Tue, 11 Aug 2020 09:57:42 +0530
Subject: [PATCH] feat: Ability to reply to specific tweets (#1117)
Ability to choose a specific tweet to reply to
Fixes #982
Co-authored-by: Pranav Raj S
---
.eslintrc.js | 1 +
app/builders/messages/message_builder.rb | 4 +-
app/javascript/dashboard/api/inbox/message.js | 3 +-
.../widgets/conversation/Message.vue | 45 ++++++++++-
.../widgets/conversation/MessagesView.vue | 77 ++++++++++++++++++-
.../widgets/conversation/ReplyBox.vue | 26 +++++--
.../widgets/conversation/bubble/Actions.vue | 62 +++++++++++++++
.../dashboard/helper/actionCable.js | 1 -
.../dashboard/i18n/locale/en/chatlist.json | 16 ++--
.../i18n/locale/en/conversation.json | 3 +
app/javascript/shared/constants/busEvents.js | 3 +
.../shared/constants/messageTypes.js | 6 ++
.../shared/helpers/MessageFormatter.js | 23 +++++-
.../helpers/specs/MessageFormatter.spec.js | 22 ++++++
app/javascript/shared/mixins/alertMixin.js | 1 -
.../shared/mixins/messageFormatterMixin.js | 4 +-
app/javascript/widget/assets/scss/woot.scss | 4 +
.../widget/components/AgentMessageBubble.vue | 2 +-
.../widget/components/UserMessageBubble.vue | 2 +-
app/models/message.rb | 5 +-
.../twitter/send_on_twitter_service.rb | 14 +++-
spec/factories/messages.rb | 2 +-
.../slack/send_on_slack_service_spec.rb | 2 +-
23 files changed, 290 insertions(+), 38 deletions(-)
create mode 100644 app/javascript/shared/constants/busEvents.js
create mode 100644 app/javascript/shared/constants/messageTypes.js
diff --git a/.eslintrc.js b/.eslintrc.js
index 9b99b9b61..c5cbba917 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -46,5 +46,6 @@ module.exports = {
},
globals: {
__WEBPACK_ENV__: true,
+ bus: true,
},
};
diff --git a/app/builders/messages/message_builder.rb b/app/builders/messages/message_builder.rb
index ff730893c..24f2f3aa6 100644
--- a/app/builders/messages/message_builder.rb
+++ b/app/builders/messages/message_builder.rb
@@ -11,6 +11,7 @@ class Messages::MessageBuilder
@content_type = params[:content_type]
@items = params.to_unsafe_h&.dig(:content_attributes, :items)
@attachments = params[:attachments]
+ @in_reply_to = params.to_unsafe_h&.dig(:content_attributes, :in_reply_to)
end
def perform
@@ -51,7 +52,8 @@ class Messages::MessageBuilder
private: @private,
sender: sender,
content_type: @content_type,
- items: @items
+ items: @items,
+ in_reply_to: @in_reply_to
}
end
end
diff --git a/app/javascript/dashboard/api/inbox/message.js b/app/javascript/dashboard/api/inbox/message.js
index 465095f44..07754fd10 100644
--- a/app/javascript/dashboard/api/inbox/message.js
+++ b/app/javascript/dashboard/api/inbox/message.js
@@ -7,10 +7,11 @@ class MessageApi extends ApiClient {
super('conversations', { accountScoped: true });
}
- create({ conversationId, message, private: isPrivate }) {
+ create({ conversationId, message, private: isPrivate, contentAttributes }) {
return axios.post(`${this.url}/${conversationId}/messages`, {
content: message,
private: isPrivate,
+ content_attributes: contentAttributes,
});
}
diff --git a/app/javascript/dashboard/components/widgets/conversation/Message.vue b/app/javascript/dashboard/components/widgets/conversation/Message.vue
index 8ecf4f7e7..58d283acd 100644
--- a/app/javascript/dashboard/components/widgets/conversation/Message.vue
+++ b/app/javascript/dashboard/components/widgets/conversation/Message.vue
@@ -23,11 +23,27 @@
+
+
+
+
+ {{ sender.available_name || sender.name }}
+
+
@@ -40,6 +56,8 @@ import BubbleImage from './bubble/Image';
import BubbleFile from './bubble/File';
import contentTypeMixin from 'shared/mixins/contentTypeMixin';
import BubbleActions from './bubble/Actions';
+import { MESSAGE_TYPE } from 'shared/constants/messageTypes';
+
export default {
components: {
BubbleActions,
@@ -53,6 +71,10 @@ export default {
type: Object,
required: true,
},
+ isATweet: {
+ type: Boolean,
+ default: false,
+ },
},
data() {
return {
@@ -61,7 +83,10 @@ export default {
},
computed: {
message() {
- return this.formatMessage(this.data.content);
+ return this.formatMessage(this.data.content, this.isATweet);
+ },
+ sender() {
+ return this.data.sender || {};
},
contentType() {
const {
@@ -78,6 +103,9 @@ export default {
isBubble() {
return [0, 1, 3].includes(this.data.message_type);
},
+ isIncoming() {
+ return this.data.message_type === MESSAGE_TYPE.INCOMING;
+ },
hasAttachments() {
return !!(this.data.attachments && this.data.attachments.length > 0);
},
@@ -90,7 +118,7 @@ export default {
return false;
},
sentByMessage() {
- const { sender } = this.data;
+ const { sender } = this;
return this.data.message_type === 1 && !this.isHovered && sender
? {
@@ -128,4 +156,15 @@ export default {
padding: 0;
}
}
+
+.sender--info {
+ display: flex;
+ align-items: center;
+ padding: var(--space-smaller) 0;
+
+ .sender--available-name {
+ font-size: var(--font-size-mini);
+ margin-left: var(--space-smaller);
+ }
+}
diff --git a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue
index 551d82b83..2689fe550 100644
--- a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue
+++ b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue
@@ -5,7 +5,7 @@
:is-contact-panel-open="isContactPanelOpen"
@contactPanelToggle="onToggleContactPanel"
/>
-
+
{{ $t('CONVERSATION.CANNOT_REPLY') }}
+
+
+
+ {{ $t('CONVERSATION.LAST_INCOMING_TWEET') }}
+
+
+ {{ $t('CONVERSATION.REPLYING_TO') }}
+ {{ selectedTweet }}
+
+
+
-
@@ -27,6 +44,7 @@
v-for="message in getReadMessages"
:key="message.id"
:data="message"
+ :is-a-tweet="isATweet"
/>
-
@@ -37,6 +55,7 @@
v-for="message in getUnReadMessages"
:key="message.id"
:data="message"
+ :is-a-tweet="isATweet"
/>
@@ -59,7 +79,6 @@