diff --git a/electron_app/src/DBManager.js b/electron_app/src/DBManager.js index 5a5472711..ec9f6fbc0 100644 --- a/electron_app/src/DBManager.js +++ b/electron_app/src/DBManager.js @@ -425,7 +425,7 @@ const baseThreadQuery = ({ Table.CONTACT }.email END)) as fromContactName` ), - db.raw(`max(${Table.EMAIL}.unread) as isUnread`) + db.raw(`max(${Table.EMAIL}.unread) as unread`) ) .from(Table.EMAIL) .leftJoin( diff --git a/email_mailbox/public/labels.json b/email_mailbox/public/labels.json index 15e3b823d..4dd0d6e8d 100644 --- a/email_mailbox/public/labels.json +++ b/email_mailbox/public/labels.json @@ -3,7 +3,8 @@ { "id": 1, "color": "#ffffff", - "text": "Inbox" + "text": "Inbox", + "badge": 1 }, { "id": 2, @@ -13,7 +14,8 @@ { "id": 3, "color": "#ffffff", - "text": "Spam" + "text": "Spam", + "badge": 1 }, { "id": 4, diff --git a/email_mailbox/src/actions/emails.js b/email_mailbox/src/actions/emails.js index b328abde5..854e1ada2 100644 --- a/email_mailbox/src/actions/emails.js +++ b/email_mailbox/src/actions/emails.js @@ -1,10 +1,12 @@ import { Email } from './types'; import { getEmailsByThreadId, + updateUnreadEmailByThreadId, setMuteEmailById, setUnreadEmailById } from '../utils/electronInterface'; import { loadContacts } from './contacts'; +import { updateLabelSuccess } from './labels'; export const addEmails = emails => { return { @@ -81,3 +83,16 @@ export const markEmailUnread = (emailId, valueToSet) => { } }; }; + +export const updateUnreadEmails = (thread, label) => { + return async dispatch => { + try { + await updateUnreadEmailByThreadId(thread.id, thread.unread); + if (label) { + dispatch(updateLabelSuccess(label)); + } + } catch (e) { + // To do + } + }; +}; diff --git a/email_mailbox/src/actions/index.js b/email_mailbox/src/actions/index.js index 1f7e0a79d..248061dd0 100644 --- a/email_mailbox/src/actions/index.js +++ b/email_mailbox/src/actions/index.js @@ -7,13 +7,14 @@ import { filterThreadsByUnread, loadEvents, loadThreads, - markThreadsRead, moveThreads, multiSelectThread, selectThread, removeThread, removeThreadLabel, deselectThreads, + updateUnreadThread, + updateUnreadThreads, searchThreads, selectThreads, removeThreads, @@ -24,7 +25,8 @@ import { loadEmails, markEmailUnread, muteEmail, - muteNotifications + muteNotifications, + updateUnreadEmails } from './emails'; import { addLabels, @@ -65,7 +67,6 @@ export { loadThreads, markEmailUnread, markFeedAsSelected, - markThreadsRead, moveThreads, multiSelectThread, muteEmail, @@ -83,5 +84,8 @@ export { setThreads, toggleMuteFeed, updateLabel, - updateLabelSuccess + updateLabelSuccess, + updateUnreadEmails, + updateUnreadThread, + updateUnreadThreads }; diff --git a/email_mailbox/src/actions/threads.js b/email_mailbox/src/actions/threads.js index 67e0f91eb..f01b826ec 100644 --- a/email_mailbox/src/actions/threads.js +++ b/email_mailbox/src/actions/threads.js @@ -1,5 +1,6 @@ import { Thread } from './types'; import { startLoadSync, stopLoadSync } from './activity'; +import { updateLabelSuccess } from './labels'; import { createEmailLabel, deleteEmailLabel, @@ -106,7 +107,20 @@ export const moveThreads = (threadIds, labelId) => ({ labelId }); -export const markThreadsRead = (threadsParams, read) => { +export const updateUnreadThread = thread => { + return { + type: Thread.UPDATE_UNREAD_THREAD, + thread + }; +}; + +export const updateUnreadThreadsSuccess = (threadsIds, read) => ({ + threadsIds, + read, + type: Thread.UPDATE_UNREAD_THREADS +}); + +export const updateUnreadThreads = (threadsParams, read, label) => { return async dispatch => { try { const storeIds = threadsParams.map(param => param.threadIdStore); @@ -117,7 +131,8 @@ export const markThreadsRead = (threadsParams, read) => { }) ); if (dbReponse) { - dispatch(markThreadsReadSuccess(storeIds, read)); + dispatch(updateUnreadThreadsSuccess(storeIds, read)); + if (label) dispatch(updateLabelSuccess(label)); } } catch (e) { // To do @@ -125,12 +140,6 @@ export const markThreadsRead = (threadsParams, read) => { }; }; -export const markThreadsReadSuccess = (threadsIds, read) => ({ - threadsIds, - read, - type: Thread.UPDATE_UNREAD -}); - export const searchThreads = params => { return async dispatch => { try { diff --git a/email_mailbox/src/actions/types.js b/email_mailbox/src/actions/types.js index b8ecc92b8..2bc422b04 100644 --- a/email_mailbox/src/actions/types.js +++ b/email_mailbox/src/actions/types.js @@ -13,7 +13,8 @@ export const Thread = { REMOVE_THREADS: 'REMOVE_THREADS', SEARCH_THREADS: 'SEARCH_THREADS', MOVE_THREADS: 'MOVE_THREADS', - UPDATE_UNREAD: 'UPDATE_UNREAD_THREADS' + UPDATE_UNREAD_THREADS: 'UPDATE_UNREAD_THREADS', + UPDATE_UNREAD_THREAD: 'UPDATE_UNREAD_THREAD' }; export const Contact = { diff --git a/email_mailbox/src/components/EmailWrapper.js b/email_mailbox/src/components/EmailWrapper.js index 77e1b42e5..51448e89c 100644 --- a/email_mailbox/src/components/EmailWrapper.js +++ b/email_mailbox/src/components/EmailWrapper.js @@ -13,20 +13,6 @@ class EmailWrapper extends Component { }; } - componentDidMount() { - const email = this.props.email; - if (email.unread && (this.state.displayEmail || this.props.staticOpen)) { - this.props.markUnread(); - } - } - - componentWillReceiveProps(nextProps) { - const email = nextProps.email; - if (email.unread && (this.state.displayEmail || this.props.staticOpen)) { - this.props.markUnread(); - } - } - render() { return ( { if (!this.props.staticOpen) { this.setState({ @@ -74,7 +68,6 @@ class EmailWrapper extends Component { EmailWrapper.propTypes = { displayEmail: PropTypes.func, email: PropTypes.object, - markUnread: PropTypes.func, staticOpen: PropTypes.bool }; diff --git a/email_mailbox/src/components/PanelWrapper.js b/email_mailbox/src/components/PanelWrapper.js index 0d9a02e26..5a60164b3 100644 --- a/email_mailbox/src/components/PanelWrapper.js +++ b/email_mailbox/src/components/PanelWrapper.js @@ -38,6 +38,7 @@ class PanelWrapper extends Component { limit: this.props.threadsCount + 1 }); } + this.props.onUpdateUnreadEmails(); }); addEvent(Event.UPDATE_SAVED_DRAFTS, () => { @@ -145,8 +146,9 @@ class PanelWrapper extends Component { PanelWrapper.propTypes = { onLoadThreads: PropTypes.func, - threadsCount: PropTypes.number, - onUpdateOpenedAccount: PropTypes.func + onUpdateOpenedAccount: PropTypes.func, + onUpdateUnreadEmails: PropTypes.func, + threadsCount: PropTypes.number }; export default PanelWrapper; diff --git a/email_mailbox/src/components/Thread.js b/email_mailbox/src/components/Thread.js index d0f14e758..baaa05fae 100644 --- a/email_mailbox/src/components/Thread.js +++ b/email_mailbox/src/components/Thread.js @@ -36,7 +36,15 @@ class Thread extends Component { componentDidMount() { this.props.onLoadEmails(this.props.thread.threadId); - this.props.onMarkRead(this.props.thread, true); + if (this.props.thread.unread) { + this.props.onUpdateUnreadEmails(this.props.thread, false); + } + } + + componentWillUnmount() { + if (this.props.thread.unread) { + this.props.onUpdateUnreadThread(this.props.thread, false); + } } handleRemoveLabel = labelId => { @@ -48,7 +56,8 @@ Thread.propTypes = { emails: PropTypes.object, labels: PropTypes.array, onLoadEmails: PropTypes.func, - onMarkRead: PropTypes.func, + onUpdateUnreadEmails: PropTypes.func, + onUpdateUnreadThread: PropTypes.func, onRemoveThreadLabel: PropTypes.func, thread: PropTypes.object }; diff --git a/email_mailbox/src/components/ThreadItem.js b/email_mailbox/src/components/ThreadItem.js index 4aa2a57bb..6d10e201f 100644 --- a/email_mailbox/src/components/ThreadItem.js +++ b/email_mailbox/src/components/ThreadItem.js @@ -10,8 +10,8 @@ class ThreadItem extends Component { render() { const visibleStyle = this.getStyleVisibilityByMultiselect(); const { + checked, thread, - myClass, onRegionEnter, onRegionLeave, onSelectThread, @@ -20,7 +20,11 @@ class ThreadItem extends Component { } = this.props; return (
{ onSelectThread(thread); }} @@ -253,10 +257,6 @@ HoverMenuItem.propTypes = { tip: PropTypes.string }; -ThreadItem.defaultProps = { - myClass: '' -}; - ThreadItem.propTypes = { color: PropTypes.string, checked: PropTypes.bool, @@ -268,7 +268,6 @@ ThreadItem.propTypes = { letters: PropTypes.string, mailbox: PropTypes.string, multiselect: PropTypes.bool, - myClass: PropTypes.string, onCheckItem: PropTypes.func, onImportantClick: PropTypes.func, onMouseEnterItem: PropTypes.func, diff --git a/email_mailbox/src/components/threaditem.scss b/email_mailbox/src/components/threaditem.scss index 245c1b74c..3ed757a81 100644 --- a/email_mailbox/src/components/threaditem.scss +++ b/email_mailbox/src/components/threaditem.scss @@ -3,6 +3,7 @@ display: flex; flex-direction: row; border-bottom: 1px solid #ebebeb; + color: black; cursor: pointer; padding: 5px; align-items: center; @@ -113,6 +114,33 @@ .match-string{ background-color: #fdfbea; } + + &.thread-read{ + background-color: #f4f4f4;; + font-weight: 300; + + .thread-label-option{ + > div{ + background-color: white; + } + } + } + + &.thread-unread{ + background-color: white; + font-weight: 600; + + .thread-label-option{ + > div{ + background-color: rgb(247, 247, 248); + } + } + } + + &.thread-checked{ + background-color: #fdfbea; + } + } .thread-label-option{ @@ -181,40 +209,6 @@ } } -.thread-read{ - color: black; - background-color: #f4f4f4;; - font-weight: 300; - - .thread-label-option{ - > div{ - background-color: white; - } - } -} - -.thread-read-selected{ - @extend .thread-read; - background-color: #fdfbea; -} - -.thread-unread{ - color: black; - background-color: white; - font-weight: 600; - - .thread-label-option{ - > div{ - background-color: rgb(247, 247, 248); - } - } -} - -.thread-unread-selected{ - @extend .thread-unread; - background-color: #fdfbea; -} - .thread-icons{ display: flex; } diff --git a/email_mailbox/src/containers/Email.js b/email_mailbox/src/containers/Email.js index 4c7448fe7..41d4c2679 100644 --- a/email_mailbox/src/containers/Email.js +++ b/email_mailbox/src/containers/Email.js @@ -9,7 +9,7 @@ import { myAccount, openEmailInComposer } from './../utils/electronInterface'; -import { muteEmail, markEmailUnread } from './../actions/index'; +import { muteEmail } from './../actions/index'; const mapStateToProps = (state, ownProps) => { const email = ownProps.email; @@ -66,10 +66,6 @@ const mapDispatchToProps = (dispatch, ownProps) => { const valueToSet = email.get('isMuted') === 1 ? false : true; dispatch(muteEmail(emailId, valueToSet)); }, - markUnread: () => { - const unreadValue = email.get('unread') ? 0 : 1; - dispatch(markEmailUnread(email.get('id'), unreadValue)); - }, onReplyEmail: ev => { ev.stopPropagation(); const key = email.get('key'); diff --git a/email_mailbox/src/containers/Panel.js b/email_mailbox/src/containers/Panel.js index 66601e648..8ee16dfbc 100644 --- a/email_mailbox/src/containers/Panel.js +++ b/email_mailbox/src/containers/Panel.js @@ -1,7 +1,11 @@ import { connect } from 'react-redux'; -import { loadThreads } from '../actions'; +import { loadThreads, updateLabelSuccess } from '../actions'; import PanelWrapper from '../components/PanelWrapper'; -import { myAccount, updateAccount } from '../utils/electronInterface'; +import { + LabelType, + myAccount, + updateAccount +} from '../utils/electronInterface'; const mapStateToProps = state => { const threadsCount = state.get('threads').size; @@ -19,6 +23,13 @@ const mapDispatchToProps = dispatch => { const opened = true; const recipientId = myAccount.recipientId; updateAccount({ opened, recipientId }); + }, + onUpdateUnreadEmails: () => { + const label = { + id: LabelType.inbox.id, + badgeOperation: +1 + }; + dispatch(updateLabelSuccess(label)); } }; }; diff --git a/email_mailbox/src/containers/Thread.js b/email_mailbox/src/containers/Thread.js index 0c9442b04..aa88a835a 100644 --- a/email_mailbox/src/containers/Thread.js +++ b/email_mailbox/src/containers/Thread.js @@ -1,5 +1,10 @@ import { connect } from 'react-redux'; -import { loadEmails, markThreadsRead, removeThreadLabel } from '../actions'; +import { + loadEmails, + updateUnreadEmails, + updateUnreadThread, + removeThreadLabel +} from '../actions'; import ThreadView from '../components/Thread'; import { List, Map } from 'immutable'; import { LabelType } from '../utils/electronInterface'; @@ -82,14 +87,28 @@ const mapDispatchToProps = (dispatch, ownProps) => { }; return dispatch(removeThreadLabel(threadParams, labelId)); }, - onMarkRead: (thread, read) => { - const threadIds = [ - { - threadIdStore: thread.id, - threadIdDB: thread.threadId - } - ]; - dispatch(markThreadsRead(threadIds, read)); + onUpdateUnreadEmails: (thread, unread) => { + const paramsThread = { + id: thread.threadId, + unread + }; + const labelId = LabelType[ownProps.mailboxSelected].id; + const paramsLabel = + labelId === LabelType.inbox.id || labelId === LabelType.spam.id + ? { + id: labelId, + badgeOperation: -1 + } + : null; + + dispatch(updateUnreadEmails(paramsThread, paramsLabel)); + }, + onUpdateUnreadThread: (thread, unread) => { + const params = { + id: thread.id, + unread + }; + dispatch(updateUnreadThread(params)); } }; }; diff --git a/email_mailbox/src/containers/ThreadHeader.js b/email_mailbox/src/containers/ThreadHeader.js index b6c866c2f..78abe674c 100644 --- a/email_mailbox/src/containers/ThreadHeader.js +++ b/email_mailbox/src/containers/ThreadHeader.js @@ -1,6 +1,7 @@ import { connect } from 'react-redux'; import * as actions from '../actions/index'; import HeaderThreadOptionsWrapper from '../components/HeaderThreadOptionsWrapper'; +import { LabelType } from '../utils/electronInterface'; import { Set } from 'immutable'; const defineOneThreadSelected = (threads, threadId) => { @@ -113,8 +114,19 @@ const mapDispatchToProps = (dispatch, ownProps) => { ); }, onMarkRead: (threadsIds, read) => { - ownProps.onBackOption(); - dispatch(actions.markThreadsRead(threadsIds, read)); + const labelId = LabelType[ownProps.mailboxSelected].id; + const operation = read ? -1 : 1; + const paramsLabel = + labelId === LabelType.inbox.id || labelId === LabelType.spam.id + ? { + id: labelId, + badgeOperation: threadsIds.length * operation + } + : null; + + dispatch(actions.updateUnreadThreads(threadsIds, read, paramsLabel)).then( + () => ownProps.onBackOption() + ); }, onRemoveThreads: threadsIds => { dispatch(actions.removeThreads(threadsIds)).then(() => diff --git a/email_mailbox/src/containers/ThreadItem.js b/email_mailbox/src/containers/ThreadItem.js index 03cde9b38..38fb8b384 100644 --- a/email_mailbox/src/containers/ThreadItem.js +++ b/email_mailbox/src/containers/ThreadItem.js @@ -11,13 +11,6 @@ import { getTwoCapitalLetters } from '../utils/StringUtils'; import { SectionType } from '../utils/const'; import randomcolor from 'randomcolor'; -const getThreadClass = (thread, threadPos, selectedThread) => { - if (thread.get('unread') && threadPos !== selectedThread) { - return thread.get('selected') ? 'thread-unread-selected' : 'thread-unread'; - } - return thread.get('selected') ? 'thread-read-selected' : 'thread-read'; -}; - const defineLabels = (labelIds, labels) => { if (!labels.size) return []; const result = labelIds.toArray().map(labelId => { @@ -29,7 +22,7 @@ const defineLabels = (labelIds, labels) => { const getMailHeader = ownProps => { const thread = ownProps.thread; const ownMailbox = ownProps.mailbox; - if (ownMailbox === 'all' || ownMailbox === 'search') { + if (ownMailbox === 'allmail' || ownMailbox === 'search') { const isSent = thread.get('allLabels').includes(LabelType.sent.id); const isDraft = thread.get('allLabels').includes(LabelType.draft.id); const from = thread.get('fromContactName').first(); @@ -40,7 +33,6 @@ const getMailHeader = ownProps => { }; const mapStateToProps = (state, ownProps) => { - const selectedThread = ownProps.selectedThread; const header = getMailHeader(ownProps); const letters = getTwoCapitalLetters(header); const color = randomcolor({ @@ -55,7 +47,6 @@ const mapStateToProps = (state, ownProps) => { const labels = defineLabels(thread.get('labels'), state.get('labels')); return { - myClass: getThreadClass(thread, ownProps.myIndex, selectedThread), thread: thread.toJS(), color, multiselect: state.get('activities').get('multiselect'), @@ -94,7 +85,6 @@ const mapDispatchToProps = (dispatch, ownProps) => { } else { ownProps.onClickSelectedItem(type, params); } - dispatch(actions.selectThread(threadId)); }, onMultiSelect: (threadId, value) => { dispatch(actions.multiSelectThread(threadId, value)); diff --git a/email_mailbox/src/containers/Threads.js b/email_mailbox/src/containers/Threads.js index ef0552f99..847ad24f8 100644 --- a/email_mailbox/src/containers/Threads.js +++ b/email_mailbox/src/containers/Threads.js @@ -30,7 +30,7 @@ const defineContactType = (labelId, from, to) => { const defineRejectedLabels = labelId => { switch (labelId) { - case LabelType.all.id: + case LabelType.allmail.id: return [LabelType.spam.id, LabelType.trash.id, LabelType.draft.id]; case LabelType.spam.id: case LabelType.trash.id: @@ -46,11 +46,7 @@ const mapStateToProps = (state, ownProps) => { const buttonSyncStatus = defineStatus( state.get('activities').get('isSyncing') ); - const threads = unreadFilter - ? state.get('threads').filter(thread => { - return thread.get('unread'); - }) - : state.get('threads'); + const threads = state.get('threads'); return { buttonSyncStatus, mailboxTitle, diff --git a/email_mailbox/src/reducers/__tests__/__snapshots__/labels.js.snap b/email_mailbox/src/reducers/__tests__/__snapshots__/labels.js.snap index b08d0d97b..6d428b079 100644 --- a/email_mailbox/src/reducers/__tests__/__snapshots__/labels.js.snap +++ b/email_mailbox/src/reducers/__tests__/__snapshots__/labels.js.snap @@ -51,6 +51,7 @@ Immutable.Map { id: 1, color: "#000000", text: "Inbox", + badge: 1, }, } `; @@ -61,6 +62,7 @@ Immutable.Map { id: 1, color: "#ffffff", text: "labelmodified", + badge: 1, }, } `; @@ -71,6 +73,7 @@ Immutable.Map { id: 1, color: "#000000", text: "labelmodified", + badge: 1, }, } `; diff --git a/email_mailbox/src/reducers/__tests__/__snapshots__/threads.js.snap b/email_mailbox/src/reducers/__tests__/__snapshots__/threads.js.snap index 4b29dae82..82b60f356 100644 --- a/email_mailbox/src/reducers/__tests__/__snapshots__/threads.js.snap +++ b/email_mailbox/src/reducers/__tests__/__snapshots__/threads.js.snap @@ -19,7 +19,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -54,7 +54,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -94,7 +94,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -134,7 +134,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -169,7 +169,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -209,7 +209,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -249,7 +249,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -284,7 +284,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -324,7 +324,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -359,7 +359,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, @@ -439,7 +439,7 @@ Immutable.List [ totalAttachments: 1, date: 1516455734588, timesOpened: 2, - unread: false, + unread: true, status: 1, timestamp: 1516455734588, secure: 1, diff --git a/email_mailbox/src/reducers/__tests__/labels.js b/email_mailbox/src/reducers/__tests__/labels.js index 079def764..5b7b586ac 100644 --- a/email_mailbox/src/reducers/__tests__/labels.js +++ b/email_mailbox/src/reducers/__tests__/labels.js @@ -5,6 +5,7 @@ import * as actions from './../../actions/index'; import { Map } from 'immutable'; import file from './../../../public/labels.json'; const labels = file.labels; +const label = labels[0]; jest.mock('./../../utils/electronInterface'); jest.mock('./../../utils/electronEventInterface'); @@ -26,10 +27,11 @@ describe('Label actions:', () => { it('should update label: text and color', () => { const data = Map({ - [labels[0].id]: Map({ - id: labels[0].id, - color: labels[0].color, - text: labels[0].text + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge }) }); const action = actions.updateLabelSuccess({ @@ -43,10 +45,11 @@ describe('Label actions:', () => { it('should update label: color', () => { const data = Map({ - [labels[0].id]: Map({ - id: labels[0].id, - color: labels[0].color, - text: labels[0].text + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge }) }); const action = actions.updateLabelSuccess({ id: 1, color: '#000000' }); @@ -56,10 +59,11 @@ describe('Label actions:', () => { it('should update label: text', () => { const data = Map({ - [labels[0].id]: Map({ - id: labels[0].id, - color: labels[0].color, - text: labels[0].text + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge }) }); const action = actions.updateLabelSuccess({ id: 1, text: 'labelmodified' }); @@ -67,12 +71,43 @@ describe('Label actions:', () => { expect(state).toMatchSnapshot(); }); + it('should update label: add badge', () => { + const data = Map({ + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge + }) + }); + const badgeOperation = +1; + const action = actions.updateLabelSuccess({ id: 1, badgeOperation }); + const state = labelReducer(data, action); + expect(state.get('1').get('badge')).toEqual(2); + }); + + it('should update label: less badge', () => { + const data = Map({ + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge + }) + }); + const badgeOperation = -1; + const action = actions.updateLabelSuccess({ id: 1, badgeOperation }); + const state = labelReducer(data, action); + expect(state.get('1').get('badge')).toEqual(0); + }); + it('should not update label', () => { const data = Map({ - [labels[0].id]: Map({ - id: labels[0].id, - color: labels[0].color, - text: labels[0].text + [label.id]: Map({ + id: label.id, + color: label.color, + text: label.text, + badge: label.badge }) }); const action = actions.updateLabelSuccess({ diff --git a/email_mailbox/src/reducers/labels.js b/email_mailbox/src/reducers/labels.js index 28d39e3d4..1088c7c1d 100644 --- a/email_mailbox/src/reducers/labels.js +++ b/email_mailbox/src/reducers/labels.js @@ -22,7 +22,10 @@ const label = (state, action) => { case Label.UPDATE_SUCCESS: return state.merge({ color: action.label.color ? action.label.color : state.get('color'), - text: action.label.text ? action.label.text : state.get('text') + text: action.label.text ? action.label.text : state.get('text'), + badge: action.label.badgeOperation + ? state.get('badge') + action.label.badgeOperation + : state.get('badge') }); default: return state; diff --git a/email_mailbox/src/reducers/threads.js b/email_mailbox/src/reducers/threads.js index d15a02791..3d83b2815 100644 --- a/email_mailbox/src/reducers/threads.js +++ b/email_mailbox/src/reducers/threads.js @@ -4,6 +4,15 @@ import * as StringUtils from '../utils/StringUtils'; const threads = (state = List([]), action) => { switch (action.type) { + case Thread.UPDATE_UNREAD_THREAD: { + const threadId = action.thread.id; + return state.update( + state.findIndex(item => item.get('id') === threadId), + item => { + return thread(item, action); + } + ); + } case Thread.SELECT: { const newThreads = state .map(thread => thread.set('selected', false)) @@ -41,7 +50,7 @@ const threads = (state = List([]), action) => { timesOpened: 2, timer: 1, totalAttachments: 1, - unread: thread.isUnread ? true : false, + unread: thread.unread ? true : false, selected: false, fromContactName: List(fromContactName.split(',')) }); @@ -108,7 +117,7 @@ const threads = (state = List([]), action) => { return thread.merge({ allLabels, labels }); }); } - case Thread.UPDATE_UNREAD: { + case Thread.UPDATE_UNREAD_THREADS: { return state.map(thread => { if (!action.threadsIds.includes(thread.get('id'))) { return thread; @@ -138,4 +147,14 @@ const threads = (state = List([]), action) => { } }; +const thread = (state, action) => { + switch (action.type) { + case Thread.UPDATE_UNREAD_THREAD: { + return state.set('unread', action.thread.unread); + } + default: + return state; + } +}; + export default threads;