File: //home/arjun/projects/buyercall/buyercall/assets/vue/widgets/CommWidget/components/Chat.vue
<template>
<div>
<ul class="msg-view" v-chat-scroll="scrollOptions">
<li v-for="(message, index) in formattedMessages" :key="index">
<chat-message-me
:themeStyles="themeStyles"
:themeStylesShades="themeStylesShades"
:themeStylesMediumShades="themeStylesMediumShades"
v-if="message.isLead"
:data="message"
></chat-message-me>
<chat-message-other
:themeStyles="themeStyles"
:themeStylesShades="themeStylesShades"
:themeStylesMediumShades="themeStylesMediumShades"
v-if="!message.isLead"
:data="message"
@bubbleclicked="bubbleclicked($event, index)"
></chat-message-other>
</li>
</ul>
<div class="text-area-sec">
<p v-if="agenTyping">Agent typing...</p>
<div class="form-group-chat send">
<input
type="text"
class="form-control-chat"
placeholder="Enter your message"
v-model="chatText"
v-on:keyup.enter="sendMessage"
v-on:keydown="triggerTyping"
/>
<button class="snd" :disabled="!isChatSendButtonActive" @click="sendMessage">
<img :src="ChatSendIcon" />
</button>
</div>
</div>
</div>
</template>
<script>
import ChatSendIcon from "../../../../styles/2021-theme/images/comm_widget/snd-blue.png";
import PhoneSmallIcon from "../../../../styles/2021-theme/images/comm_widget/bc-sml.png";
import * as _ from "lodash";
import ChatMessageMe from "./ChatMessageMe.vue";
import ChatMessageOther from "./ChatMessageOther.vue";
import socket from "../socket";
import { mapGetters, mapActions } from "vuex";
import moment from "moment";
import RasaService from "../../../service/rasaService";
import {
CHAT_SELECT,
CHAT_ACTION_ADD_NEW_MESSAGE,
ROOT_SELECT_PARTNERSHIP_ID,
ROOT_SELECT,
CHAT_ACTION_SET_MESSAGES,
ROOT_SELECT_WIDGET_ID,
} from "../constants";
export default {
directives: {
"chat-scroll": {
inserted: function (el, binding) {
let chatScrollOptions = binding.value;
if (chatScrollOptions.enabled) {
el.scrollTop = el.scrollHeight;
}
},
componentUpdated: function (el, binding) {
let chatScrollOptions = binding.value;
if (chatScrollOptions.enabled && !chatScrollOptions.always) {
el.scrollTop = el.scrollHeight;
}
},
},
},
props: {
themeStyles: {
type: Object,
required: true,
},
themeStylesShades: {
type: Object,
required: true,
},
themeStylesMediumShades: {
type: Object,
required: true,
},
},
components: {
ChatMessageMe,
ChatMessageOther,
},
created() {
if (this.data.chatSessionId === null) {
console.log("authdata", {
welcomeMessage: this.rootState.rasaInitialMessages,
chatOptions: this.data.chatOptions,
widget_id: this.widgetId,
source_id: this.data.source_id,
isLead: true,
partnershipID: this.partnershipId,
userId: this.data.leadId,
userData: this.data.leadData,
partnershipAccountId: this.rootState.partnership_account_id,
channel_id: this.data.channel_id,
assigned_agent_id: this.data.leadData.assigned_agent_id,
});
socket.auth = {
welcomeMessage: this.rootState.rasaInitialMessages,
chatOptions: this.data.chatOptions,
widget_id: this.widgetId,
source_id: this.data.source_id,
isLead: true,
partnershipID: this.partnershipId,
userId: this.data.leadId,
userData: this.data.leadData,
partnershipAccountId: this.rootState.partnership_account_id,
channel_id: this.data.channel_id,
assigned_agent_id: this.data.leadData.assigned_agent_id,
};
socket.connect();
} else {
socket.emit("initial message load lead");
}
socket.on("lead session messages loading", (status) => (this.chatloading = status));
socket.on("lead session messages", (messages) => {
this.bulkAddMessages(messages);
});
socket.on("private message lead", ({ content, from, to, timestamp }) => {
this.addNewMessage({ content, from, to, timestamp });
});
socket.on("agent typing", (typing) => {
this.agenTyping = typing;
});
// socket.on('connect_error', (err) => {
// console.log(err.message); // prints the message associated with the error
// });
},
data() {
return {
chatloading: false,
sendToPerson: null,
chatText: "",
ChatSendIcon,
PhoneSmallIcon,
isSocketConnected: false,
messages: [],
isTyping: false,
typingTimeoutIntervalId: null,
agenTyping: false,
scrollOptions: {
enabled: true,
always: false, // Set to true if you always want to scroll to bottom
smooth: true, // Add smooth scrolling effect if needed
notSmoothOnInit: false, // Set to true if you don't want smooth scrolling initially
},
};
},
mounted() {},
methods: {
triggerTyping(e) {
if (e.key !== "Enter") {
if (this.isTyping === false) {
this.isTyping = true;
socket.emit("lead typing", {
typing: true,
leadID: `${this.data.leadId}`,
});
this.typingTimeoutIntervalId = setTimeout(this.typingStopped, 500);
} else {
clearTimeout(this.typingTimeoutIntervalId);
this.typingTimeoutIntervalId = setTimeout(this.typingStopped, 500);
}
}
console.log(e.key);
},
typingStopped() {
this.isTyping = false;
socket.emit("lead typing", {
typing: false,
leadID: `${this.data.leadId}`,
});
},
finalizeIconAndName({ content, from, to, isLead, timestamp }) {
const createdAt = new Date(timestamp);
const time = moment(createdAt).format("h:mm a");
if (isLead) {
return {
content,
icon: null,
name: "You",
isLead,
time,
};
}
if (from === "") {
return {
content,
icon: this.PhoneSmallIcon,
name: "Buyercall Support",
isLead,
time,
};
}
return {
content,
icon: this.PhoneSmallIcon,
name: "Agent 1",
isLead,
time,
};
},
sendMessage() {
if (this.chatText.length) {
socket.emit("private message lead", {
from: `${this.data.leadId}`,
from_lead: true,
interaction_type: "CHAT_MESSAGE",
to: this.connectedAgent ? this.connectedAgent : "",
content: [this.chatText],
});
if (this.connectedAgent === null) {
RasaService.getRasaResponse({
sender: "id3",
message: this.chatText,
}).then(({ data }) => {
console.log("Rasa response", data);
if (data.length) {
socket.emit("mock rasa lead", {
from: `${this.data.leadId}`,
from_lead: true,
interaction_type: "CHAT_MESSAGE",
to: this.connectedAgent ? this.connectedAgent : "",
content: [this.chatText],
rasaResponse: data,
});
}
});
}
this.chatText = "";
}
},
bubbleclicked(message, index) {
if (index === 0) {
socket.emit("private message lead", {
from: `${this.data.leadId}`,
from_lead: true,
interaction_type: "CHAT_MESSAGE",
to: "",
content: [message],
});
}
},
...mapActions("chat", {
addNewMessage: CHAT_ACTION_ADD_NEW_MESSAGE,
bulkAddMessages: CHAT_ACTION_SET_MESSAGES,
}),
},
computed: {
connectedAgent() {
const agenttMessages = _.filter(
this.data.chatMessages,
({ from }) => from !== `${this.data.leadId}` && from !== ""
);
return agenttMessages.length === 0 ? null : agenttMessages[0].from;
},
isChatSendButtonActive() {
return this.chatText.length ? true : false;
},
...mapGetters("chat", {
data: CHAT_SELECT,
}),
...mapGetters("root", {
partnershipId: ROOT_SELECT_PARTNERSHIP_ID,
rootState: ROOT_SELECT,
widgetId: ROOT_SELECT_WIDGET_ID,
}),
formattedMessages() {
if (this.partnershipId === null) {
return [];
}
const messages = _.map(
this.data.chatMessages,
({ from, to, content, timestamp }) => {
return this.finalizeIconAndName({
content,
from,
to,
isLead: from === `${this.data.leadId}` ? true : false,
timestamp,
});
}
);
return messages;
},
},
destroyed() {
socket.off("private message lead");
},
};
</script>