From 21e1051ae2141348f56184531b5382f5d9c3d7ba Mon Sep 17 00:00:00 2001 From: erikaperugachi Date: Fri, 21 Sep 2018 10:00:37 -0500 Subject: [PATCH] Fix badge. Fix #424 --- electron_app/src/windows/composer.js | 8 +- email_mailbox/src/actions/emails.js | 15 -- email_mailbox/src/actions/index.js | 4 +- email_mailbox/src/actions/labels.js | 131 +++++++--- email_mailbox/src/actions/threads.js | 50 +++- email_mailbox/src/actions/types.js | 5 +- email_mailbox/src/components/LabelEdit.js | 5 - email_mailbox/src/components/PanelWrapper.js | 27 +- email_mailbox/src/components/Thread.js | 13 +- .../src/containers/HeaderThreadOptions.js | 22 +- email_mailbox/src/containers/LabelEdit.js | 27 +- email_mailbox/src/containers/Panel.js | 37 ++- email_mailbox/src/containers/Settings.js | 27 +- email_mailbox/src/containers/Thread.js | 23 +- email_mailbox/src/containers/ThreadItem.js | 3 +- email_mailbox/src/data/message.js | 4 + .../__tests__/__snapshots__/labels.js.snap | 68 +---- .../src/reducers/__tests__/labels.js | 233 +++++++----------- email_mailbox/src/reducers/labels.js | 64 +++-- .../src/utils/electronEventInterface.js | 74 +++--- 20 files changed, 405 insertions(+), 435 deletions(-) diff --git a/electron_app/src/windows/composer.js b/electron_app/src/windows/composer.js index e59456635..91d330830 100644 --- a/electron_app/src/windows/composer.js +++ b/electron_app/src/windows/composer.js @@ -146,7 +146,7 @@ const destroy = async ({ composerId, emailId }) => { oldDraftEmail.id, undefined ); - sendEventToMailbox('update-drafts', { operation: 'less', value: 1 }); + sendEventToMailbox('update-drafts', true); } else if ( type === composerEvents.REPLY || type === composerEvents.REPLY_ALL @@ -175,10 +175,10 @@ const sendEventToMailbox = (eventName, data) => { const saveDraftToDatabase = async (composerId, dataDraft) => { const emailToEdit = globalManager.emailToEdit.get(composerId); const { type, key } = emailToEdit || {}; - let badgeOperation = {}; + let shouldUpdateBadge = false; if ((!type && !key) || type !== composerEvents.EDIT_DRAFT) { await dbManager.createEmail(dataDraft); - badgeOperation = { operation: 'add', value: 1 }; + shouldUpdateBadge = true; } else { const [oldEmail] = await dbManager.getEmailByKey(key); const newEmailId = await dbManager.deleteEmailLabelAndContactByEmailId( @@ -195,7 +195,7 @@ const saveDraftToDatabase = async (composerId, dataDraft) => { return; } } - sendEventToMailbox('update-drafts', badgeOperation); + sendEventToMailbox('update-drafts', shouldUpdateBadge); }; module.exports = { diff --git a/email_mailbox/src/actions/emails.js b/email_mailbox/src/actions/emails.js index 14809e12a..8c51f7eec 100644 --- a/email_mailbox/src/actions/emails.js +++ b/email_mailbox/src/actions/emails.js @@ -2,7 +2,6 @@ import { Email } from './types'; import { getContactByIds, getEmailsByThreadId, - updateUnreadEmailByThreadIds, setMuteEmailById, setUnreadEmailById, updateEmail, @@ -12,7 +11,6 @@ import { } from '../utils/electronInterface'; import { EmailUtils } from '../utils/electronUtilsInterface'; import { loadContacts } from './contacts'; -import { updateLabelSuccess } from './labels'; import { EmailStatus, SocketCommand } from '../utils/const'; import { unsendEmailFiles } from './files'; import { @@ -139,19 +137,6 @@ export const removeEmailsOnSuccess = emailIds => ({ emailIds }); -export const updateUnreadEmails = (thread, label) => { - return async dispatch => { - try { - await updateUnreadEmailByThreadIds([thread.id], thread.unread); - if (label) { - dispatch(updateLabelSuccess(label)); - } - } catch (e) { - // To do - } - }; -}; - export const unsendEmail = params => { return async dispatch => { const { key, emailId, contactIds, unsendDate } = params; diff --git a/email_mailbox/src/actions/index.js b/email_mailbox/src/actions/index.js index 50fa8fb74..6dc0285d6 100644 --- a/email_mailbox/src/actions/index.js +++ b/email_mailbox/src/actions/index.js @@ -36,7 +36,6 @@ import { muteNotifications, removeEmails, removeEmailsOnSuccess, - updateUnreadEmails, unsendEmail, unsendEmailOnSuccess, updateEmailLabels @@ -47,6 +46,7 @@ import { loadLabels, removeLabel, removeLabelOnSuccess, + updateBadgeLabels, updateLabel, updateLabelSuccess } from './labels'; @@ -111,13 +111,13 @@ export { unsendEmailFiles, unsendEmailOnSuccess, updateAllFeedItemsAsOlder, + updateBadgeLabels, updateFeedItemSuccess, updateEmailIdsThread, updateEmailLabels, updateLabel, updateLabelSuccess, updateStatusThread, - updateUnreadEmails, updateUnreadThreads, updateUnreadThreadsSuccess }; diff --git a/email_mailbox/src/actions/labels.js b/email_mailbox/src/actions/labels.js index 1a00677ff..5896501a7 100644 --- a/email_mailbox/src/actions/labels.js +++ b/email_mailbox/src/actions/labels.js @@ -9,28 +9,14 @@ import { updateLabel as updateLabelDB, deleteLabelById } from '../utils/electronInterface'; +import { sendUpdateLabelsErrorMessage } from './../utils/electronEventInterface'; import { SocketCommand } from '../utils/const'; -export const addLabels = labels => { - return { - type: Label.ADD_BATCH, - labels: labels - }; -}; - -export const updateLabelSuccess = label => { - return { - type: Label.UPDATE_SUCCESS, - label: label - }; -}; - -export const addLabel = (label, isByEvent) => { +export const addLabel = label => { return async dispatch => { try { - const [response] = await createLabel(label); - if (response) { - const labelId = response; + const [labelId] = await createLabel(label); + if (labelId) { const { text, color, visible } = label; const labels = { [labelId]: { @@ -41,23 +27,26 @@ export const addLabel = (label, isByEvent) => { visible } }; - if (isByEvent) { - dispatch(addLabels(labels)); - } else { - const eventParams = { - cmd: SocketCommand.PEER_LABEL_CREATED, - params: { color, text } - }; - await postPeerEvent(eventParams); - dispatch(addLabels(labels)); - } + const eventParams = { + cmd: SocketCommand.PEER_LABEL_CREATED, + params: { color: color.replace('#', ''), text } + }; + await postPeerEvent(eventParams); + dispatch(addLabels(labels)); } } catch (e) { - //TO DO + sendUpdateLabelsErrorMessage(); } }; }; +export const addLabels = labels => { + return { + type: Label.ADD_BATCH, + labels + }; +}; + export const loadLabels = () => { return async dispatch => { try { @@ -85,11 +74,31 @@ export const loadLabels = () => { labels[LabelType.draft.id].badge = badgeDraft[0].count; dispatch(addLabels(labels)); } catch (e) { - // TO DO + sendUpdateLabelsErrorMessage(); } }; }; +export const removeLabel = id => { + return async dispatch => { + try { + const response = await deleteLabelById(id); + if (response) { + dispatch(removeLabelOnSuccess(id)); + } + } catch (e) { + sendUpdateLabelsErrorMessage(); + } + }; +}; + +export const removeLabelOnSuccess = labelId => { + return { + type: Label.REMOVE, + labelId + }; +}; + export const updateLabel = ({ id, color, text, visible }) => { return async dispatch => { try { @@ -98,27 +107,69 @@ export const updateLabel = ({ id, color, text, visible }) => { dispatch(updateLabelSuccess({ id, color, text, visible })); } } catch (e) { - // TO DO + sendUpdateLabelsErrorMessage(); } }; }; -export const removeLabel = id => { +export const updateBadgeLabels = labelIds => { return async dispatch => { + if (!labelIds.length) return; try { - const response = await deleteLabelById(id); - if (response) { - dispatch(removeLabelOnSuccess(id)); - } + const labelsFiltered = labelIds.filter(labelId => { + return ( + labelId === LabelType.inbox.id || + labelId === LabelType.spam.id || + labelId === LabelType.draft.id + ); + }); + const labels = await Promise.all( + labelsFiltered.map(async labelId => { + if (labelId === LabelType.inbox.id) { + const rejectedLabelIds = [LabelType.spam.id, LabelType.trash.id]; + const unreadInbox = await getEmailsUnredByLabelId({ + labelId, + rejectedLabelIds + }); + const badgeInbox = unreadInbox.length; + return { + id: String(labelId), + badge: badgeInbox + }; + } else if (labelId === LabelType.spam.id) { + const unreadSpam = await getEmailsUnredByLabelId({ + labelId + }); + const badgeSpam = unreadSpam.length; + return { + id: String(labelId), + badge: badgeSpam + }; + } else if (labelId === LabelType.draft.id) { + const badgeDraft = await getEmailsCounterByLabelId(labelId); + return { + id: String(labelId), + badge: badgeDraft[0].count + }; + } + }) + ); + dispatch(updateBadgeLabelsSuccess(labels)); } catch (e) { - // TO DO + sendUpdateLabelsErrorMessage(); } }; }; +export const updateBadgeLabelsSuccess = labelIds => { + return { + type: Label.UPDATE_BADGE_LABELS, + labelIds + }; +}; -export const removeLabelOnSuccess = labelId => { +export const updateLabelSuccess = label => { return { - type: Label.REMOVE_SUCCESS, - labelId + type: Label.UPDATE, + label }; }; diff --git a/email_mailbox/src/actions/threads.js b/email_mailbox/src/actions/threads.js index 8ef217734..507d47306 100644 --- a/email_mailbox/src/actions/threads.js +++ b/email_mailbox/src/actions/threads.js @@ -1,6 +1,6 @@ import { Thread } from './types'; import { startLoadSync, stopLoadSync } from './activity'; -import { updateLabelSuccess } from './labels'; +import { updateBadgeLabels } from './labels'; import { createEmailLabel, deleteEmailLabel, @@ -10,6 +10,7 @@ import { getEmailsGroupByThreadByParams, getLabelById, getTrashExpiredEmails, + LabelType, postOpenEvent, postPeerEvent, updateEmails, @@ -137,6 +138,7 @@ export const addMoveLabelIdThreads = ({ threadsParams, labelIdToAdd, labelIdToRemove, + currentLabelId, notMove }) => { return async dispatch => { @@ -144,9 +146,12 @@ export const addMoveLabelIdThreads = ({ const threadIds = threadsParams .map(param => param.threadIdDB) .filter(item => item !== null); - const [label] = await getLabelById(labelIdToAdd); - const labelsAdded = [label.text]; - const labelsRemoved = labelIdToRemove ? [labelIdToRemove] : []; + const [labeltoAdd] = await getLabelById(labelIdToAdd); + const labelsAdded = [labeltoAdd.text]; + const [labeltoRemove] = labelIdToRemove + ? await getLabelById(labelIdToRemove) + : [undefined]; + const labelsRemoved = labeltoRemove ? [labeltoRemove.text] : []; const eventParams = { cmd: SocketCommand.PEER_THREAD_LABELS_UPDATE, params: { @@ -174,8 +179,20 @@ export const addMoveLabelIdThreads = ({ return await createEmailLabel(paramsToAdd); }) ); - if (dbReponse && !notMove) { - dispatch(moveThreads(threadIds, labelIdToAdd)); + if (dbReponse) { + let labelIds = []; + if ( + currentLabelId === LabelType.inbox.id && + (labelIdToAdd === LabelType.trash.id || + labelIdToAdd === LabelType.spam.id) + ) + labelIds = [...labelIds, currentLabelId]; + if (labelIdToAdd === LabelType.spam.id) + labelIds = [...labelIds, labelIdToAdd]; + if (labelIds.length) dispatch(updateBadgeLabels(labelIds)); + if (!notMove) { + dispatch(moveThreads(threadIds, labelIdToAdd)); + } } } else { sendUpdateThreadLabelsErrorMessage(); @@ -280,6 +297,9 @@ export const removeLabelIdThreads = (threadsParams, labelId) => { ); if (dbReponse) { dispatch(removeLabelIdThreadsSuccess(threadIds, labelId)); + let labelIds = [LabelType.inbox.id]; + if (labelId === LabelType.spam.id) labelIds = [...labelIds, labelId]; + dispatch(updateBadgeLabels(labelIds)); } } else { sendUpdateThreadLabelsErrorMessage(); @@ -296,7 +316,7 @@ export const removeLabelIdThreadsSuccess = (threadIds, labelId) => ({ labelId }); -export const removeThreads = threadsParams => { +export const removeThreads = (threadsParams, labelId) => { return async dispatch => { try { const emailIds = threadsParams @@ -322,6 +342,9 @@ export const removeThreads = threadsParams => { await deleteEmailsByIds(emailIds); dispatch(removeThreadsSuccess(emailIds)); } + if (labelId === LabelType.spam.id) { + dispatch(updateBadgeLabels([labelId])); + } dispatch(loadFeedItems(true)); } catch (e) { sendRemoveThreadsErrorMessage(); @@ -357,7 +380,7 @@ export const updateUnreadThreadsSuccess = (threadIds, unread) => ({ type: Thread.UPDATE_UNREAD_THREADS }); -export const updateUnreadThreads = (threadsParams, unread, label) => { +export const updateUnreadThreads = (threadsParams, unread, labelId) => { return async dispatch => { try { const threadIds = threadsParams.map(param => param.threadIdDB); @@ -370,7 +393,8 @@ export const updateUnreadThreads = (threadsParams, unread, label) => { const response = await updateUnreadEmailByThreadIds(threadIds, unread); if (response) { dispatch(updateUnreadThreadsSuccess(threadIds, unread)); - if (label) dispatch(updateLabelSuccess(label)); + if (labelId === LabelType.inbox.id || labelId === LabelType.spam.id) + dispatch(updateBadgeLabels([labelId])); } } } catch (e) { @@ -417,7 +441,12 @@ export const loadEvents = () => { }; }; -export const sendOpenEvent = (emailKeysUnread, myEmailKeysUnread, threadId) => { +export const sendOpenEvent = ( + emailKeysUnread, + myEmailKeysUnread, + threadId, + labelId +) => { return async dispatch => { try { let postSuccess = true; @@ -449,6 +478,7 @@ export const sendOpenEvent = (emailKeysUnread, myEmailKeysUnread, threadId) => { } } } + dispatch(updateBadgeLabels([labelId])); } catch (e) { sendOpenEventErrorMessage(); } diff --git a/email_mailbox/src/actions/types.js b/email_mailbox/src/actions/types.js index ff640e72e..571a949e0 100644 --- a/email_mailbox/src/actions/types.js +++ b/email_mailbox/src/actions/types.js @@ -37,8 +37,9 @@ export const Email = { export const Label = { ADD_BATCH: 'ADD_LABELS', - UPDATE_SUCCESS: 'UPDATE_LABEL_SUCCESS', - REMOVE_SUCCESS: 'REMOVE_LABEL_SUCCESS' + UPDATE: 'UPDATE_LABEL', + UPDATE_BADGE_LABELS: 'UPDATE_BADGE_LABELS', + REMOVE: 'REMOVE_LABEL' }; export const FeedItem = { diff --git a/email_mailbox/src/components/LabelEdit.js b/email_mailbox/src/components/LabelEdit.js index 30d83207f..e85739459 100644 --- a/email_mailbox/src/components/LabelEdit.js +++ b/email_mailbox/src/components/LabelEdit.js @@ -1,6 +1,5 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { addEvent, Event } from '../utils/electronEventInterface'; import './labeledit.css'; class LabelEdit extends Component { @@ -10,10 +9,6 @@ class LabelEdit extends Component { addLabel: false, labelToAdd: '' }; - - addEvent(Event.LABEL_CREATED, params => { - this.props.onAddLabel(null, params); - }); } render() { diff --git a/email_mailbox/src/components/PanelWrapper.js b/email_mailbox/src/components/PanelWrapper.js index b0aea4a26..66628acfa 100644 --- a/email_mailbox/src/components/PanelWrapper.js +++ b/email_mailbox/src/components/PanelWrapper.js @@ -144,13 +144,13 @@ class PanelWrapper extends Component { initEventHandlers = props => { addEvent(Event.NEW_EMAIL, emailParams => { - const { emailId, isToMe, labels, threadId } = emailParams; + const { emailId, labels, threadId } = emailParams; const currentSectionType = this.state.sectionSelected.type; const isRenderingMailbox = currentSectionType === SectionType.MAILBOX; const isRenderingThread = currentSectionType === SectionType.THREAD; const currentLabelId = LabelType[this.state.sectionSelected.params.mailboxSelected].id; - const isNewEmailInMailbox = labels.indexOf(currentLabelId) > -1; + const isNewEmailInMailbox = labels.includes(currentLabelId); const currentThreadId = this.state.sectionSelected.params .threadIdSelected; if (isRenderingMailbox && isNewEmailInMailbox) { @@ -165,13 +165,7 @@ class PanelWrapper extends Component { emailIdToAdd: emailId }); } - if (isToMe) { - props.onUpdateUnreadEmailsBadge({ - labelId: LabelType.inbox.id, - operation: 'add', - value: 1 - }); - } + props.onUpdateUnreadEmailsBadge(labels); }); addEvent(Event.REFRESH_THREADS, eventParams => { @@ -187,8 +181,8 @@ class PanelWrapper extends Component { props.onLoadEmails(this.state.sectionSelected.params.threadIdSelected); } if (eventParams) { - const { labelId, operation, value } = eventParams; - props.onUpdateUnreadEmailsBadge({ labelId, operation, value }); + const { labelIds } = eventParams; + props.onUpdateUnreadEmailsBadge(labelIds); } }); @@ -227,11 +221,7 @@ class PanelWrapper extends Component { emailIdsToRemove: [oldEmailId] }); if (!newEmailId && !oldEmailId) { - props.onUpdateUnreadEmailsBadge({ - labelId: LabelType.inbox.id, - operation: 'add', - value: 1 - }); + props.onUpdateUnreadEmailsBadge([LabelType.inbox.id]); } }); @@ -271,10 +261,15 @@ class PanelWrapper extends Component { mailboxPopupType: MAILBOX_POPUP_TYPES.PASSWORD_CHANGED }); }); + + addEvent(Event.LABEL_CREATED, labels => { + this.props.onAddLabels(labels); + }); }; } PanelWrapper.propTypes = { + onAddLabels: PropTypes.func, onLoadEmails: PropTypes.func, onMarkThreadAsOpen: PropTypes.func, onLoadThreads: PropTypes.func, diff --git a/email_mailbox/src/components/Thread.js b/email_mailbox/src/components/Thread.js index 962c89089..b2830d65e 100644 --- a/email_mailbox/src/components/Thread.js +++ b/email_mailbox/src/components/Thread.js @@ -8,10 +8,7 @@ import './thread.css'; class Thread extends Component { componentWillReceiveProps(nextProps) { - if ( - this.props.thread.emailIds > nextProps.emailIds && - !nextProps.emailIds.length - ) { + if (this.props.thread && !nextProps.thread) { this.props.onBackOption(); } else if (this.props.thread.unread) { if ( @@ -36,7 +33,7 @@ class Thread extends Component {
-

{this.props.thread.subject}

+

{this.props.thread ? this.props.thread.subject : ''}

{this.props.labels.map((label, index) => { return (