193 lines
5.8 KiB
JavaScript
193 lines
5.8 KiB
JavaScript
import axios from "axios";
|
|
import parsePhoneNumber from "libphonenumber-js";
|
|
import { all, call, put, select, takeLatest } from "redux-saga/effects";
|
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
|
import {
|
|
CONVERSATION_ID_BY_PHONE,
|
|
CONVERSATION_LIST_QUERY,
|
|
CREATE_CONVERSATION,
|
|
GET_CONVERSATION_DETAILS,
|
|
TOGGLE_CONVERSATION_ARCHIVE
|
|
} from "../../graphql/conversations.queries";
|
|
import { INSERT_CONVERSATION_TAG } from "../../graphql/job-conversations.queries";
|
|
import client from "../../utils/GraphQLClient";
|
|
import { selectBodyshop } from "../user/user.selectors";
|
|
import { sendMessageFailure, sendMessageSuccess, setSelectedConversation } from "./messaging.actions";
|
|
import MessagingActionTypes from "./messaging.types";
|
|
|
|
export function* onToggleChatVisible() {
|
|
yield takeLatest(MessagingActionTypes.TOGGLE_CHAT_VISIBLE, toggleChatLogging);
|
|
}
|
|
|
|
export function* toggleChatLogging() {
|
|
try {
|
|
yield logImEXEvent("messaging_toggle_popup");
|
|
} catch (error) {
|
|
console.log("Error in sendMessage saga.", error);
|
|
}
|
|
}
|
|
|
|
export function* onOpenChatByPhone() {
|
|
yield takeLatest(MessagingActionTypes.OPEN_CHAT_BY_PHONE, openChatByPhone);
|
|
}
|
|
|
|
export function* openChatByPhone({ payload }) {
|
|
logImEXEvent("messaging_open_by_phone");
|
|
const { socket, phone_num, jobid } = payload;
|
|
if (!socket || !phone_num) return;
|
|
const p = parsePhoneNumber(phone_num, "CA");
|
|
const bodyshop = yield select(selectBodyshop);
|
|
|
|
try {
|
|
const {
|
|
data: { conversations }
|
|
} = yield client.query({
|
|
query: CONVERSATION_ID_BY_PHONE,
|
|
variables: { phone: p.number },
|
|
fetchPolicy: "no-cache"
|
|
});
|
|
|
|
if (conversations.length === 0) {
|
|
// No conversation exists, create a new one
|
|
const {
|
|
data: {
|
|
insert_conversations: { returning: newConversations }
|
|
}
|
|
} = yield client.mutate({
|
|
mutation: CREATE_CONVERSATION,
|
|
variables: {
|
|
conversation: [
|
|
{
|
|
phone_num: p.number,
|
|
bodyshopid: bodyshop.id,
|
|
job_conversations: jobid ? { data: { jobid: jobid } } : null
|
|
}
|
|
]
|
|
}
|
|
});
|
|
|
|
const createdConversation = newConversations[0]; // Get the newly created conversation
|
|
|
|
// // Emit event for new conversation with full details
|
|
if (socket) {
|
|
socket.emit("conversation-modified", {
|
|
bodyshopId: bodyshop.id,
|
|
type: "conversation-created",
|
|
...createdConversation
|
|
});
|
|
}
|
|
|
|
// Set the newly created conversation as selected
|
|
yield put(setSelectedConversation(createdConversation.id));
|
|
} else if (conversations.length === 1) {
|
|
const conversation = conversations[0];
|
|
|
|
if (conversation.archived) {
|
|
// Conversation is archived, unarchive it in the DB
|
|
const {
|
|
data: { update_conversations_by_pk: updatedConversation }
|
|
} = yield client.mutate({
|
|
mutation: TOGGLE_CONVERSATION_ARCHIVE,
|
|
variables: {
|
|
id: conversation.id,
|
|
archived: false
|
|
}
|
|
});
|
|
|
|
if (socket) {
|
|
socket.emit("conversation-modified", {
|
|
type: "conversation-unarchived",
|
|
conversationId: updatedConversation.id,
|
|
bodyshopId: bodyshop.id,
|
|
archived: false
|
|
});
|
|
}
|
|
|
|
// Update the conversation list in the cache
|
|
const existingConversations = client.cache.readQuery({
|
|
query: CONVERSATION_LIST_QUERY,
|
|
variables: { offset: 0 }
|
|
});
|
|
|
|
client.cache.writeQuery({
|
|
query: CONVERSATION_LIST_QUERY,
|
|
variables: { offset: 0 },
|
|
data: {
|
|
conversations: [
|
|
{
|
|
...conversation,
|
|
archived: false,
|
|
updated_at: new Date().toISOString()
|
|
},
|
|
...(existingConversations?.conversations || [])
|
|
]
|
|
}
|
|
});
|
|
}
|
|
|
|
// Check if the conversation exists in the cache
|
|
const cacheId = client.cache.identify({
|
|
__typename: "conversations",
|
|
id: conversation.id
|
|
});
|
|
|
|
if (!cacheId) {
|
|
// Fetch the conversation details from the database
|
|
const { data } = yield client.query({
|
|
query: GET_CONVERSATION_DETAILS,
|
|
variables: { conversationId: conversation.id }
|
|
});
|
|
|
|
// Write fetched data to the cache
|
|
client.cache.writeQuery({
|
|
query: GET_CONVERSATION_DETAILS,
|
|
variables: { conversationId: conversation.id },
|
|
data
|
|
});
|
|
}
|
|
|
|
// Open the conversation
|
|
yield put(setSelectedConversation(conversation.id));
|
|
|
|
// Check and add job tag if needed
|
|
if (jobid && !conversation.job_conversations.find((jc) => jc.jobid === jobid)) {
|
|
yield client.mutate({
|
|
mutation: INSERT_CONVERSATION_TAG,
|
|
variables: {
|
|
conversationId: conversation.id,
|
|
jobId: jobid
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
// Multiple conversations found
|
|
console.error("ERROR: Multiple conversations found.");
|
|
yield put(setSelectedConversation(null));
|
|
}
|
|
} catch (error) {
|
|
console.error("Error in openChatByPhone saga.", error);
|
|
}
|
|
}
|
|
|
|
export function* onSendMessage() {
|
|
yield takeLatest(MessagingActionTypes.SEND_MESSAGE, sendMessage);
|
|
}
|
|
|
|
export function* sendMessage({ payload }) {
|
|
try {
|
|
const response = yield call(axios.post, "/sms/send", payload);
|
|
if (response.status === 200) {
|
|
yield put(sendMessageSuccess(payload));
|
|
} else {
|
|
yield put(sendMessageFailure(response.data));
|
|
}
|
|
} catch (error) {
|
|
console.log("Error in sendMessage saga.", error);
|
|
yield put(sendMessageFailure(error));
|
|
}
|
|
}
|
|
|
|
export function* messagingSagas() {
|
|
yield all([call(onSendMessage), call(onOpenChatByPhone), call(onToggleChatVisible)]);
|
|
}
|