From ef50a8cd65f6e46f417d143ba6852e5f1af8e3be Mon Sep 17 00:00:00 2001 From: Nithin David <1277421+nithindavid@users.noreply.github.com> Date: Thu, 16 Sep 2021 12:22:05 +0530 Subject: [PATCH] Refactors store --- .../widget/api/conversationPublic.js | 1 - .../store/modules/conversation_new/actions.js | 140 ------------------ .../store/modules/conversationv2/actions.js | 48 ++++++ .../getters.js | 0 .../helpers.js | 31 ---- .../index.js | 9 -- .../mutations.js | 50 +------ .../widget/store/modules/messageV2/actions.js | 83 +++++++++++ .../widget/store/modules/messageV2/getters.js | 3 + .../widget/store/modules/messageV2/helpers.js | 32 ++++ .../widget/store/modules/messageV2/index.js | 23 +++ .../store/modules/messageV2/mutations.js | 49 ++++++ 12 files changed, 239 insertions(+), 230 deletions(-) delete mode 100644 app/javascript/widget/store/modules/conversation_new/actions.js create mode 100644 app/javascript/widget/store/modules/conversationv2/actions.js rename app/javascript/widget/store/modules/{conversation_new => conversationv2}/getters.js (100%) rename app/javascript/widget/store/modules/{conversation_new => conversationv2}/helpers.js (65%) rename app/javascript/widget/store/modules/{conversation_new => conversationv2}/index.js (74%) rename app/javascript/widget/store/modules/{conversation_new => conversationv2}/mutations.js (60%) create mode 100644 app/javascript/widget/store/modules/messageV2/actions.js create mode 100644 app/javascript/widget/store/modules/messageV2/getters.js create mode 100644 app/javascript/widget/store/modules/messageV2/helpers.js create mode 100644 app/javascript/widget/store/modules/messageV2/index.js create mode 100644 app/javascript/widget/store/modules/messageV2/mutations.js diff --git a/app/javascript/widget/api/conversationPublic.js b/app/javascript/widget/api/conversationPublic.js index 02e8b6803..7c0fdbcd4 100644 --- a/app/javascript/widget/api/conversationPublic.js +++ b/app/javascript/widget/api/conversationPublic.js @@ -23,7 +23,6 @@ export default { ); }, - // https://www.chatwoot.com/developers/api#operation/update-a-contact update(inboxIdentifier, contactIdentifier, userObject) { return API.patch( buildUrl(`inboxes/${inboxIdentifier}/contacts/${contactIdentifier}`), diff --git a/app/javascript/widget/store/modules/conversation_new/actions.js b/app/javascript/widget/store/modules/conversation_new/actions.js deleted file mode 100644 index 2d1fcbc09..000000000 --- a/app/javascript/widget/store/modules/conversation_new/actions.js +++ /dev/null @@ -1,140 +0,0 @@ -import { - createConversationAPI, - sendMessageAPI, - sendAttachmentAPI, - // getMessagesAPI, - // toggleTyping, - // setUserLastSeenAt, - getConversationAPI, - getConversationsAPI, -} from 'widget/api/conversation'; - -import { - createTemporaryMessage, - createTemporaryAttachmentMessage, -} from './helpers'; - -// Get activeConversation and pass it down to each action call, to -// target the right converdation -export const actions = { - fetchAllConversations: async ({ commit }) => { - try { - commit('setUIFlag', { isFetching: true }); - const { data } = await getConversationsAPI(); - data.forEach(conversation => { - const { id: conversationId, messages } = conversation; - commit('addConversationEntry', conversation); - commit('addConversationId', conversation.id); - commit('addMessagesEntry', { conversationId, messages }); - commit('addMessageIds', { conversationId, messages }); - }); - } catch (error) { - throw new Error(error); - } finally { - commit('setUIFlag', { isFetching: false }); - } - }, - fetchConversationById: async ({ commit }, params) => { - const { conversationId } = params; - try { - commit('setConversationUIFlag', { isFetching: true }); - const { data } = await getConversationAPI(conversationId); - - const { messages } = data; - commit('updateConversationEntry', data); - commit('addMessagesEntry', { conversationId, messages }); - commit('addMessageIds', { conversationId, messages }); - } catch (error) { - throw new Error(error); - } finally { - commit('setConversationUIFlag', { isFetching: false }); - } - }, - createConversation: async ({ commit }, params) => { - commit('setConversationUIFlag', { isCreating: true }); - try { - const { data } = await createConversationAPI(params); - const { id: conversationId, messages } = data; - - commit('addConversationEntry', data); - commit('addConversationId', conversationId); - commit('addMessagesEntry', { conversationId, messages }); - commit('addMessageIds', { conversationId, messages }); - } catch (error) { - throw new Error(error); - } finally { - commit('setConversationUIFlag', { isCreating: false }); - } - }, - sendMessage: async ({ commit }, params) => { - const { content, conversationId } = params; - const message = createTemporaryMessage({ content }); - const messages = [message]; - commit('addMessagesEntry', { conversationId, messages }); - commit('addMessageIds', { conversationId, messages }); - await sendMessageAPI(content, conversationId); - }, - sendAttachment: async ({ commit }, params) => { - const { - attachment: { thumbUrl, fileType }, - conversationId, - } = params; - const message = createTemporaryAttachmentMessage({ thumbUrl, fileType }); - const messages = [message]; - commit('addMessagesEntry', { conversationId, messages }); - commit('addMessageIds', { conversationId, messages }); - try { - const { data } = await sendAttachmentAPI(params); - commit('updateAttachmentMessageStatus', { - message: data, - tempId: message.id, - }); - } catch (error) { - // Show error - } - }, - // fetchOldConversations: async ({ commit }, { before } = {}) => { - // try { - // commit('setConversationListLoading', true); - // const { data } = await getMessagesAPI({ before }); - // const formattedMessages = getNonDeletedMessages({ messages: data }); - // commit('setMessagesInConversation', formattedMessages); - // commit('setConversationListLoading', false); - // } catch (error) { - // commit('setConversationListLoading', false); - // } - // }, - // clearConversations: ({ commit }) => { - // commit('clearConversations'); - // }, - // addOrUpdateMessage: async ({ commit }, data) => { - // const { id, content_attributes } = data; - // if (content_attributes && content_attributes.deleted) { - // commit('deleteMessage', id); - // return; - // } - // commit('pushMessageToConversation', data); - // }, - // toggleAgentTyping({ commit }, data) { - // commit('toggleAgentTypingStatus', data); - // }, - // toggleUserTyping: async (_, data) => { - // try { - // await toggleTyping(data); - // } catch (error) { - // // IgnoreError - // } - // }, - // setUserLastSeen: async ({ commit, getters: appGetters }) => { - // if (!appGetters.getConversationSize) { - // return; - // } - // const lastSeen = Date.now() / 1000; - // try { - // commit('setMetaUserLastSeenAt', lastSeen); - // await setUserLastSeenAt({ lastSeen }); - // } catch (error) { - // // IgnoreError - // } - // }, -}; diff --git a/app/javascript/widget/store/modules/conversationv2/actions.js b/app/javascript/widget/store/modules/conversationv2/actions.js new file mode 100644 index 000000000..a708c9af7 --- /dev/null +++ b/app/javascript/widget/store/modules/conversationv2/actions.js @@ -0,0 +1,48 @@ +import conversationPublicAPI from 'widget/api/conversationPublic'; + +export const actions = { + fetchAllConversations: async ( + { commit }, + { inboxIdentifier, contactIdentifier } + ) => { + try { + commit('setUIFlag', { isFetching: true }); + const { data } = await conversationPublicAPI.get( + inboxIdentifier, + contactIdentifier + ); + data.forEach(conversation => { + const { id: conversationId, messages } = conversation; + commit('message/addConversationEntry', conversation, { root: true }); + commit('addConversationId', conversation.id); + commit('addMessagesEntry', { conversationId, messages }); + commit('addMessageIdsToConversation', { conversationId, messages }); + }); + } catch (error) { + throw new Error(error); + } finally { + commit('setUIFlag', { isFetching: false }); + } + }, + + createConversation: async ( + { commit }, + { inboxIdentifier, contactIdentifier } + ) => { + commit('setConversationUIFlag', { isCreating: true }); + try { + const params = { inboxIdentifier, contactIdentifier }; + const { data } = await conversationPublicAPI.create(params); + const { id: conversationId, messages } = data; + + commit('addConversationEntry', data); + commit('addConversationId', conversationId); + commit('addMessagesEntry', { conversationId, messages }); + commit('addMessageIds', { conversationId, messages }); + } catch (error) { + throw new Error(error); + } finally { + commit('setConversationUIFlag', { isCreating: false }); + } + }, +}; diff --git a/app/javascript/widget/store/modules/conversation_new/getters.js b/app/javascript/widget/store/modules/conversationv2/getters.js similarity index 100% rename from app/javascript/widget/store/modules/conversation_new/getters.js rename to app/javascript/widget/store/modules/conversationv2/getters.js diff --git a/app/javascript/widget/store/modules/conversation_new/helpers.js b/app/javascript/widget/store/modules/conversationv2/helpers.js similarity index 65% rename from app/javascript/widget/store/modules/conversation_new/helpers.js rename to app/javascript/widget/store/modules/conversationv2/helpers.js index 65f2cfa1d..ba5b1eeea 100644 --- a/app/javascript/widget/store/modules/conversation_new/helpers.js +++ b/app/javascript/widget/store/modules/conversationv2/helpers.js @@ -1,36 +1,5 @@ -import { MESSAGE_TYPE } from 'widget/helpers/constants'; import { isASubmittedFormMessage } from 'shared/helpers/MessageTypeHelper'; -import getUuid from '../../../helpers/uuid'; -export const createTemporaryMessage = ({ attachments, content }) => { - const timestamp = new Date().getTime() / 1000; - return { - id: getUuid(), - content, - attachments, - status: 'in_progress', - created_at: timestamp, - message_type: MESSAGE_TYPE.INCOMING, - }; -}; -export const createTemporaryAttachmentMessage = ({ - thumbUrl, - fileType, - content, -}) => { - const attachment = { - thumb_url: thumbUrl, - data_url: thumbUrl, - file_type: fileType, - status: 'in_progress', - }; - const message = createTemporaryMessage({ - attachments: [attachment], - content, - }); - return message; -}; - const getSenderName = message => (message.sender ? message.sender.name : ''); const shouldShowAvatar = (message, nextMessage) => { diff --git a/app/javascript/widget/store/modules/conversation_new/index.js b/app/javascript/widget/store/modules/conversationv2/index.js similarity index 74% rename from app/javascript/widget/store/modules/conversation_new/index.js rename to app/javascript/widget/store/modules/conversationv2/index.js index 1883e1482..a0e698eec 100755 --- a/app/javascript/widget/store/modules/conversation_new/index.js +++ b/app/javascript/widget/store/modules/conversationv2/index.js @@ -12,15 +12,6 @@ const state = { }, }, }, - messages: { - byId: {}, - allIds: [], - uiFlags: { - byId: { - // 1: { isCreating: false, isPending: false, isDeleting: false }, - }, - }, - }, uiFlags: { allConversationsLoaded: false, isFetching: false, diff --git a/app/javascript/widget/store/modules/conversation_new/mutations.js b/app/javascript/widget/store/modules/conversationv2/mutations.js similarity index 60% rename from app/javascript/widget/store/modules/conversation_new/mutations.js rename to app/javascript/widget/store/modules/conversationv2/mutations.js index a0074260f..05263c07a 100644 --- a/app/javascript/widget/store/modules/conversation_new/mutations.js +++ b/app/javascript/widget/store/modules/conversationv2/mutations.js @@ -48,22 +48,7 @@ export const mutations = { }; }, - addMessagesEntry($state, { conversationId, messages = [] }) { - if (!conversationId) return; - - const allMessages = $state.messages; - const newMessages = messages.reduce( - (obj, message) => ({ - ...obj, - [message.id]: message, - }), - {} - ); - const updatedMessages = { ...allMessages, ...newMessages }; - Vue.set($state.messages, 'byId', updatedMessages); - }, - - addMessageIds($state, { conversationId, messages }) { + addMessageIdsToConversation($state, { conversationId, messages }) { const conversationById = $state.conversations.byId[conversationId]; if (!conversationById) return; @@ -72,23 +57,6 @@ export const mutations = { Vue.set(conversationById, 'messages', updatedMessageIds); }, - updateMessageEntry($state, message) { - const messageId = message.id; - if (!messageId) return; - - const messageById = $state.messages.byId[messageId]; - if (!messageById) return; - if (messageId !== message.id) return; - - Vue.set($state.messages.byId, messageId, { ...message }); - }, - - removeMessageEntry($state, messageId) { - if (!messageId) return; - - Vue.delete($state.messages.byId, messageId); - }, - removeMessageIdFromConversation($state, { conversationId, messageId }) { if (!messageId || !conversationId) return; @@ -99,20 +67,4 @@ export const mutations = { id => id !== messageId ); }, - - removeMessageId($state, messageId) { - if (!messageId) return; - - $state.messages.allIds = $state.messages.allIds.filter( - id => id !== messageId - ); - }, - - setMessageUIFlag($state, { messageId, uiFlags }) { - const flags = $state.messages.uiFlags.byId[messageId]; - $state.messages.uiFlags.byId[messageId] = { - ...flags, - ...uiFlags, - }; - }, }; diff --git a/app/javascript/widget/store/modules/messageV2/actions.js b/app/javascript/widget/store/modules/messageV2/actions.js new file mode 100644 index 000000000..2807ab471 --- /dev/null +++ b/app/javascript/widget/store/modules/messageV2/actions.js @@ -0,0 +1,83 @@ +import MessagePublicAPI from 'widget/api/messagePublic'; +import { refreshActionCableConnector } from '../../helpers/actionCable'; +import { + createTemporaryMessage, + createTemporaryAttachmentMessage, +} from './helpers'; + +export const actions = { + sendMessage: async ({ commit }, params) => { + const { + id: echoId, + content, + conversationId, + inboxIdentifier, + contactIdentifier, + } = params; + const message = createTemporaryMessage({ content }); + const messages = [message]; + commit('addMessagesEntry', { conversationId, messages }); + commit('addMessageIds', { conversationId, messages }); + await MessagePublicAPI.create( + inboxIdentifier, + contactIdentifier, + conversationId, + content, + echoId + ); + }, + + sendAttachment: async ({ commit }, params) => { + const { + attachment: { thumbUrl, fileType }, + conversationId, + } = params; + const message = createTemporaryAttachmentMessage({ + thumbUrl, + fileType, + }); + const messages = [message]; + commit('addMessagesEntry', { conversationId, messages }); + commit('addMessageIds', { conversationId, messages }); + try { + const { data } = await sendAttachmentAPI(params); + commit('updateAttachmentMessageStatus', { + message: data, + tempId: message.id, + }); + } catch (error) { + // Show error + } + }, + update: async ( + { commit, dispatch }, + { email, messageId, submittedValues } + ) => { + commit('toggleUpdateStatus', true); + try { + const { + data: { contact: { pubsub_token: pubsubToken } = {} }, + } = await MessageAPI.update({ + email, + messageId, + values: submittedValues, + }); + commit( + 'conversation/updateMessage', + { + id: messageId, + content_attributes: { + submitted_email: email, + submitted_values: email ? null : submittedValues, + }, + }, + { root: true } + ); + dispatch('contacts/get', {}, { root: true }); + refreshActionCableConnector(pubsubToken); + } catch (error) { + // Ignore error + } + commit('toggleUpdateStatus', false); + }, +}; diff --git a/app/javascript/widget/store/modules/messageV2/getters.js b/app/javascript/widget/store/modules/messageV2/getters.js new file mode 100644 index 000000000..21e9ca458 --- /dev/null +++ b/app/javascript/widget/store/modules/messageV2/getters.js @@ -0,0 +1,3 @@ +export const getters = { + getUIFlags: $state => $state.uiFlags, +}; diff --git a/app/javascript/widget/store/modules/messageV2/helpers.js b/app/javascript/widget/store/modules/messageV2/helpers.js new file mode 100644 index 000000000..6f52ef333 --- /dev/null +++ b/app/javascript/widget/store/modules/messageV2/helpers.js @@ -0,0 +1,32 @@ +import { MESSAGE_TYPE } from 'widget/helpers/constants'; +import getUuid from '../../../helpers/uuid'; + +export const createTemporaryMessage = ({ attachments, content }) => { + const timestamp = new Date().getTime() / 1000; + return { + id: getUuid(), + content, + attachments, + status: 'in_progress', + created_at: timestamp, + message_type: MESSAGE_TYPE.INCOMING, + }; +}; + +export const createTemporaryAttachmentMessage = ({ + thumbUrl, + fileType, + content, +}) => { + const attachment = { + thumb_url: thumbUrl, + data_url: thumbUrl, + file_type: fileType, + status: 'in_progress', + }; + const message = createTemporaryMessage({ + attachments: [attachment], + content, + }); + return message; +}; diff --git a/app/javascript/widget/store/modules/messageV2/index.js b/app/javascript/widget/store/modules/messageV2/index.js new file mode 100644 index 000000000..8565e4093 --- /dev/null +++ b/app/javascript/widget/store/modules/messageV2/index.js @@ -0,0 +1,23 @@ +import { getters } from './getters'; +import { actions } from './actions'; +import { mutations } from './mutations'; + +const state = { + messages: { + byId: {}, + allIds: [], + uiFlags: { + byId: { + // 1: { isCreating: false, isPending: false, isDeleting: false, isUpdating: false }, + }, + }, + }, +}; + +export default { + namespaced: true, + state, + getters, + actions, + mutations, +}; diff --git a/app/javascript/widget/store/modules/messageV2/mutations.js b/app/javascript/widget/store/modules/messageV2/mutations.js new file mode 100644 index 000000000..b69dbaab0 --- /dev/null +++ b/app/javascript/widget/store/modules/messageV2/mutations.js @@ -0,0 +1,49 @@ +import Vue from 'vue'; + +export const mutations = { + addMessagesEntry($state, { messages = [] }) { + const allMessages = $state.messages; + const newMessages = messages.reduce( + (obj, message) => ({ + ...obj, + [message.id]: message, + }), + {} + ); + const updatedMessages = { ...allMessages, ...newMessages }; + Vue.set($state.messages, 'byId', updatedMessages); + }, + + updateMessageEntry($state, message) { + const messageId = message.id; + if (!messageId) return; + + const messageById = $state.messages.byId[messageId]; + if (!messageById) return; + if (messageId !== message.id) return; + + Vue.set($state.messages.byId, messageId, { ...message }); + }, + + removeMessageEntry($state, messageId) { + if (!messageId) return; + + Vue.delete($state.messages.byId, messageId); + }, + + removeMessageId($state, messageId) { + if (!messageId) return; + + $state.messages.allIds = $state.messages.allIds.filter( + id => id !== messageId + ); + }, + + setMessageUIFlag($state, { messageId, uiFlags }) { + const flags = $state.messages.uiFlags.byId[messageId]; + $state.messages.uiFlags.byId[messageId] = { + ...flags, + ...uiFlags, + }; + }, +};