Refactors store
This commit is contained in:
parent
366d8b2def
commit
ef50a8cd65
12 changed files with 239 additions and 230 deletions
|
@ -23,7 +23,6 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
// https://www.chatwoot.com/developers/api#operation/update-a-contact
|
|
||||||
update(inboxIdentifier, contactIdentifier, userObject) {
|
update(inboxIdentifier, contactIdentifier, userObject) {
|
||||||
return API.patch(
|
return API.patch(
|
||||||
buildUrl(`inboxes/${inboxIdentifier}/contacts/${contactIdentifier}`),
|
buildUrl(`inboxes/${inboxIdentifier}/contacts/${contactIdentifier}`),
|
||||||
|
|
|
@ -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
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
};
|
|
|
@ -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 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,36 +1,5 @@
|
||||||
import { MESSAGE_TYPE } from 'widget/helpers/constants';
|
|
||||||
import { isASubmittedFormMessage } from 'shared/helpers/MessageTypeHelper';
|
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 getSenderName = message => (message.sender ? message.sender.name : '');
|
||||||
|
|
||||||
const shouldShowAvatar = (message, nextMessage) => {
|
const shouldShowAvatar = (message, nextMessage) => {
|
|
@ -12,15 +12,6 @@ const state = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
messages: {
|
|
||||||
byId: {},
|
|
||||||
allIds: [],
|
|
||||||
uiFlags: {
|
|
||||||
byId: {
|
|
||||||
// 1: { isCreating: false, isPending: false, isDeleting: false },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
uiFlags: {
|
uiFlags: {
|
||||||
allConversationsLoaded: false,
|
allConversationsLoaded: false,
|
||||||
isFetching: false,
|
isFetching: false,
|
|
@ -48,22 +48,7 @@ export const mutations = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
addMessagesEntry($state, { conversationId, messages = [] }) {
|
addMessageIdsToConversation($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 }) {
|
|
||||||
const conversationById = $state.conversations.byId[conversationId];
|
const conversationById = $state.conversations.byId[conversationId];
|
||||||
if (!conversationById) return;
|
if (!conversationById) return;
|
||||||
|
|
||||||
|
@ -72,23 +57,6 @@ export const mutations = {
|
||||||
Vue.set(conversationById, 'messages', updatedMessageIds);
|
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 }) {
|
removeMessageIdFromConversation($state, { conversationId, messageId }) {
|
||||||
if (!messageId || !conversationId) return;
|
if (!messageId || !conversationId) return;
|
||||||
|
|
||||||
|
@ -99,20 +67,4 @@ export const mutations = {
|
||||||
id => id !== messageId
|
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,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
};
|
83
app/javascript/widget/store/modules/messageV2/actions.js
Normal file
83
app/javascript/widget/store/modules/messageV2/actions.js
Normal file
|
@ -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);
|
||||||
|
},
|
||||||
|
};
|
3
app/javascript/widget/store/modules/messageV2/getters.js
Normal file
3
app/javascript/widget/store/modules/messageV2/getters.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export const getters = {
|
||||||
|
getUIFlags: $state => $state.uiFlags,
|
||||||
|
};
|
32
app/javascript/widget/store/modules/messageV2/helpers.js
Normal file
32
app/javascript/widget/store/modules/messageV2/helpers.js
Normal file
|
@ -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;
|
||||||
|
};
|
23
app/javascript/widget/store/modules/messageV2/index.js
Normal file
23
app/javascript/widget/store/modules/messageV2/index.js
Normal file
|
@ -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,
|
||||||
|
};
|
49
app/javascript/widget/store/modules/messageV2/mutations.js
Normal file
49
app/javascript/widget/store/modules/messageV2/mutations.js
Normal file
|
@ -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,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
Loading…
Reference in a new issue