diff --git a/electron_app/package.json b/electron_app/package.json
index 15e2f7dc3..78b3cb35a 100644
--- a/electron_app/package.json
+++ b/electron_app/package.json
@@ -75,7 +75,7 @@
"electron-packager": "^10.1.2"
},
"dependencies": {
- "@criptext/email-http-client": "^0.8.1",
+ "@criptext/email-http-client": "^0.8.2",
"knex": "^0.14.2",
"sqlite3": "^3.1.13",
"websocket": "^1.0.25"
diff --git a/electron_app/src/DBManager.js b/electron_app/src/DBManager.js
index 89bf1bd80..598fddecf 100644
--- a/electron_app/src/DBManager.js
+++ b/electron_app/src/DBManager.js
@@ -1,5 +1,6 @@
const { db, cleanDataBase, createTables, Table } = require('./models.js');
const { formContactsRow } = require('./utils/dataTableUtils.js');
+const { noNulls } = require('./utils/ObjectUtils');
/* Account
----------------------------- */
@@ -564,16 +565,19 @@ const deleteEmailLabelAndContactByEmailId = (id, optionalEmailToSave) => {
});
};
-const updateEmail = ({ id, key, threadId, date, isMuted, unread }) => {
- const params = {};
- if (key) params.key = key;
- if (threadId) params.threadId = threadId;
- if (date) params.date = date;
- if (typeof unread === 'boolean') params.unread = unread;
- if (typeof isMuted === 'boolean') params.isMuted = isMuted;
+const updateEmail = ({ id, key, threadId, date, isMuted, unread, status }) => {
+ const params = noNulls({
+ key,
+ threadId,
+ date,
+ unread: typeof unread === 'boolean' ? unread : undefined,
+ isMuted: typeof isMuted === 'boolean' ? isMuted : undefined,
+ status
+ });
+ const whereParam = id ? { id } : { key };
return db
.table(Table.EMAIL)
- .where({ id })
+ .where(whereParam)
.update(params);
};
diff --git a/electron_app/src/clientManager.js b/electron_app/src/clientManager.js
index fea9881b1..8001e3ac3 100644
--- a/electron_app/src/clientManager.js
+++ b/electron_app/src/clientManager.js
@@ -64,8 +64,8 @@ class ClientManager {
return client.postKeyBundle(params);
}
- postOpenEvent(params) {
- return client.postOpenEvent(params);
+ postOpenEvent(metadataKeys) {
+ return client.postOpenEvent(metadataKeys);
}
postUser(params) {
diff --git a/electron_app/yarn.lock b/electron_app/yarn.lock
index ef5e957b9..015520446 100644
--- a/electron_app/yarn.lock
+++ b/electron_app/yarn.lock
@@ -96,7 +96,7 @@
lodash "^4.2.0"
to-fast-properties "^2.0.0"
-"@criptext/email-http-client@^0.8.1":
+"@criptext/email-http-client@^0.8.2":
version "0.8.2"
resolved "https://registry.yarnpkg.com/@criptext/email-http-client/-/email-http-client-0.8.2.tgz#6e788b0ea3e2e959b7b6bd46829ede7caaa20ec4"
dependencies:
diff --git a/email_composer/src/containers/Composer.js b/email_composer/src/containers/Composer.js
index a1ba72846..85b237d78 100644
--- a/email_composer/src/containers/Composer.js
+++ b/email_composer/src/containers/Composer.js
@@ -11,7 +11,6 @@ import {
myAccount,
throwError,
updateEmail,
- updateEmailLabel,
saveDraftChanges,
errors,
deleteEmailsByIds,
@@ -26,6 +25,7 @@ import {
} from './../utils/ArrayUtils';
import signal from './../libs/signal';
import {
+ EmailStatus,
formOutgoingEmailFromData,
formDataToEditDraft,
formDataToReply
@@ -280,7 +280,7 @@ class ComposerWrapper extends Component {
this.setState({ status: Status.WAITING });
const { data, to, subject, body } = formOutgoingEmailFromData(
this.state,
- LabelType.draft.id
+ LabelType.sent.id
);
let emailId, key;
try {
@@ -310,15 +310,14 @@ class ComposerWrapper extends Component {
const { metadataKey, date } = res.body;
const threadId = this.state.threadId || res.body.threadId;
key = metadataKey;
- const emailParams = { id: emailId, key, threadId, date };
- await updateEmail(emailParams);
-
- const emailLabelParams = {
- emailId,
- oldLabelId: LabelType.draft.id,
- newLabelId: LabelType.sent.id
+ const emailParams = {
+ id: emailId,
+ key,
+ threadId,
+ date,
+ status: EmailStatus.SENT
};
- await updateEmailLabel(emailLabelParams);
+ await updateEmail(emailParams);
closeComposerWindow(emailId);
} catch (e) {
diff --git a/email_composer/src/utils/EmailUtils.js b/email_composer/src/utils/EmailUtils.js
index d5cad42c7..abc9a66f5 100644
--- a/email_composer/src/utils/EmailUtils.js
+++ b/email_composer/src/utils/EmailUtils.js
@@ -33,6 +33,16 @@ const getCriptextRecipients = (recipients, type) => {
}));
};
+export const EmailStatus = {
+ FAIL: 1,
+ UNSENT: 2,
+ NONE: 3,
+ SENDING: 4,
+ SENT: 5,
+ DELIVERED: 6,
+ READ: 7
+};
+
export const formOutgoingEmailFromData = (composerData, labelId) => {
const recipients = {
to: composerData.toEmails,
@@ -52,7 +62,7 @@ export const formOutgoingEmailFromData = (composerData, labelId) => {
content: body,
preview: removeHTMLTags(body).slice(0, 21),
date: Date.now(),
- status: 1,
+ status: EmailStatus.SENDING,
unread: false,
secure: true,
isMuted: false
diff --git a/email_composer/src/utils/__tests__/__snapshots__/EmailUtils.js.snap b/email_composer/src/utils/__tests__/__snapshots__/EmailUtils.js.snap
index 0ab10c352..08be7ea4c 100644
--- a/email_composer/src/utils/__tests__/__snapshots__/EmailUtils.js.snap
+++ b/email_composer/src/utils/__tests__/__snapshots__/EmailUtils.js.snap
@@ -30,7 +30,7 @@ Object {
"preview": "
",
"secure": true,
- "status": 1,
+ "status": 4,
"subject": "Subject",
"unread": false,
},
diff --git a/email_mailbox/src/actions/index.js b/email_mailbox/src/actions/index.js
index 9cdfcc751..caa67f1ed 100644
--- a/email_mailbox/src/actions/index.js
+++ b/email_mailbox/src/actions/index.js
@@ -20,7 +20,8 @@ import {
selectThreads,
removeThreads,
removeThreadsLabel,
- sendOpenEvent
+ sendOpenEvent,
+ updateStatusThread
} from './threads';
import {
addEmails,
@@ -90,6 +91,7 @@ export {
updateFeedItemSuccess,
updateLabel,
updateLabelSuccess,
+ updateStatusThread,
updateUnreadEmails,
updateUnreadThread,
updateUnreadThreads
diff --git a/email_mailbox/src/actions/threads.js b/email_mailbox/src/actions/threads.js
index c4d91c1bc..7392bec8a 100644
--- a/email_mailbox/src/actions/threads.js
+++ b/email_mailbox/src/actions/threads.js
@@ -106,6 +106,12 @@ export const moveThreads = (threadIds, labelId) => ({
labelId
});
+export const updateStatusThread = (threadId, status) => ({
+ type: Thread.UPDATE_STATUS,
+ threadId,
+ status
+});
+
export const updateUnreadThread = thread => {
return {
type: Thread.UPDATE_UNREAD_THREAD,
@@ -308,8 +314,7 @@ export const sendOpenEvent = threadId => {
const unreadEmails = await getUnreadEmailsByThreadId(threadId);
if (unreadEmails.length > 0) {
const metadataKeys = unreadEmails.map(item => Number(item.key));
- const params = { metadataKeys };
- await postOpenEvent(params);
+ await postOpenEvent(metadataKeys);
}
} catch (e) {
// TO DO
diff --git a/email_mailbox/src/actions/types.js b/email_mailbox/src/actions/types.js
index aa8b975c4..b20b67e9f 100644
--- a/email_mailbox/src/actions/types.js
+++ b/email_mailbox/src/actions/types.js
@@ -18,7 +18,8 @@ export const Thread = {
MOVE_THREADS: 'MOVE_THREADS',
UPDATE_UNREAD_THREADS: 'UPDATE_UNREAD_THREADS',
UPDATE_UNREAD_THREAD: 'UPDATE_UNREAD_THREAD',
- ADD_EMAIL: 'UPDATE_THREAD_EMAIL_IDS'
+ ADD_EMAIL: 'UPDATE_THREAD_EMAIL_IDS',
+ UPDATE_STATUS: 'UPDATE_STATUS'
};
export const Contact = {
diff --git a/email_mailbox/src/components/PanelWrapper.js b/email_mailbox/src/components/PanelWrapper.js
index 57f9f0169..6c06e76c3 100644
--- a/email_mailbox/src/components/PanelWrapper.js
+++ b/email_mailbox/src/components/PanelWrapper.js
@@ -68,9 +68,13 @@ class PanelWrapper extends Component {
}
});
+ addEvent(Event.EMAIL_TRACKING_UPDATE, threadId => {
+ props.onMarkThreadAsOpen(threadId);
+ });
+
addEvent(Event.UPDATE_THREAD_EMAILS, eventParams => {
- const newThreadId = eventParams.threadId;
- props.onLoadEmails(newThreadId);
+ const { threadId } = eventParams;
+ props.onLoadEmails(threadId);
props.onAddEmailToThread({
threadId: this.state.sectionSelected.params.threadIdSelected,
emailId: eventParams.emailId
@@ -178,6 +182,7 @@ class PanelWrapper extends Component {
PanelWrapper.propTypes = {
onAddEmailToThread: PropTypes.func,
onLoadEmails: PropTypes.func,
+ onMarkThreadAsOpen: PropTypes.func,
onLoadThreads: PropTypes.func,
onUpdateOpenedAccount: PropTypes.func,
onUpdateTimestamp: PropTypes.func,
diff --git a/email_mailbox/src/components/ThreadItem.js b/email_mailbox/src/components/ThreadItem.js
index f32fa6a3f..2497a82e8 100644
--- a/email_mailbox/src/components/ThreadItem.js
+++ b/email_mailbox/src/components/ThreadItem.js
@@ -88,7 +88,7 @@ class ThreadItem extends Component {
return ;
case EmailStatus.DELIVERED:
return ;
- case EmailStatus.OPENED:
+ case EmailStatus.READ:
return ;
default:
return null;
diff --git a/email_mailbox/src/containers/Panel.js b/email_mailbox/src/containers/Panel.js
index de39be041..c238ca787 100644
--- a/email_mailbox/src/containers/Panel.js
+++ b/email_mailbox/src/containers/Panel.js
@@ -4,7 +4,8 @@ import {
loadThreads,
updateLabelSuccess,
updateAllFeedItemsAsOlder,
- loadEmails
+ loadEmails,
+ updateStatusThread
} from '../actions';
import PanelWrapper from '../components/PanelWrapper';
import {
@@ -13,6 +14,7 @@ import {
updateAccount
} from '../utils/electronInterface';
import { storeSeenTimestamp } from '../utils/storage';
+import { EmailStatus } from '../utils/const';
const mapStateToProps = state => {
const threadsCount = state.get('threads').size;
@@ -46,6 +48,10 @@ const mapDispatchToProps = dispatch => {
const rejectedLabelIds = defineRejectedLabels(labelId);
dispatch(loadThreads({ ...params, ...rejectedLabelIds }));
},
+ onMarkThreadAsOpen: threadId => {
+ const readStatus = EmailStatus.READ;
+ dispatch(updateStatusThread(threadId, readStatus));
+ },
onUpdateOpenedAccount: async () => {
const opened = true;
const recipientId = myAccount.recipientId;
diff --git a/email_mailbox/src/reducers/__tests__/threads.js b/email_mailbox/src/reducers/__tests__/threads.js
index 568a978c6..a96b20183 100644
--- a/email_mailbox/src/reducers/__tests__/threads.js
+++ b/email_mailbox/src/reducers/__tests__/threads.js
@@ -33,4 +33,26 @@ describe('Set thread state by actions', () => {
const unread = emailUpdated.get('unread');
expect(unread).toBe(false);
});
+
+ it('should set thread param: status, action[UPDATE_STATUS]', () => {
+ const state = initState(threads);
+ const threadId = 1;
+ const newStatus = 2;
+ const action = actions.updateStatusThread(threadId, newStatus);
+ const newState = threadsReducer(state, action);
+ const emailUpdated = newState.get('0');
+ const status = emailUpdated.get('status');
+ expect(status).toBe(newStatus);
+ });
+
+ it('should not set thread param status because is undefined, action[UPDATE_STATUS]', () => {
+ const state = initState(threads);
+ const threadId = 1;
+ const badStatus = undefined;
+ const action = actions.updateStatusThread(threadId, badStatus);
+ const newState = threadsReducer(state, action);
+ const emailUpdated = newState.get('0');
+ const status = emailUpdated.get('status');
+ expect(status).not.toBe(badStatus);
+ });
});
diff --git a/email_mailbox/src/reducers/threads.js b/email_mailbox/src/reducers/threads.js
index d11813a8e..a6fb123f8 100644
--- a/email_mailbox/src/reducers/threads.js
+++ b/email_mailbox/src/reducers/threads.js
@@ -134,7 +134,19 @@ const threads = (state = List([]), action) => {
if (threadItem.get('id') === threadId) {
return thread(threadItem, action);
}
- return thread;
+ return threadItem;
+ });
+ }
+ case Thread.UPDATE_STATUS: {
+ const { status, threadId } = action;
+ if (!threadId || !status) {
+ return state;
+ }
+ return state.map(threadItem => {
+ if (threadItem.get('id') === threadId) {
+ return thread(threadItem, action);
+ }
+ return threadItem;
});
}
default:
@@ -150,6 +162,9 @@ const thread = (state, action) => {
case Thread.ADD_EMAIL: {
return state.set('emailIds', state.get('emailIds').push(action.emailId));
}
+ case Thread.UPDATE_STATUS: {
+ return state.set('status', action.status);
+ }
default:
return state;
}
diff --git a/email_mailbox/src/utils/EmailUtils.js b/email_mailbox/src/utils/EmailUtils.js
index eb8766c3f..7c008e3c9 100644
--- a/email_mailbox/src/utils/EmailUtils.js
+++ b/email_mailbox/src/utils/EmailUtils.js
@@ -1,5 +1,6 @@
import { removeAppDomain, removeHTMLTags } from './StringUtils';
import signal from './../libs/signal';
+import { EmailStatus } from './const';
const getContentMessage = async ({
bodyKey,
@@ -49,7 +50,7 @@ export const formIncomingEmailFromData = async data => {
preview,
subject: data.subject,
date: data.date,
- status: 1,
+ status: EmailStatus.NONE,
unread: true,
secure: true,
isMuted: false
diff --git a/email_mailbox/src/utils/const.js b/email_mailbox/src/utils/const.js
index 3a1722363..61007ca88 100644
--- a/email_mailbox/src/utils/const.js
+++ b/email_mailbox/src/utils/const.js
@@ -48,11 +48,13 @@ export const FeedItemType = {
};
export const EmailStatus = {
- UNSENT: -1,
- NONE: 0,
- SENT: 1,
- DELIVERED: 2,
- OPENED: 3
+ FAIL: 1,
+ UNSENT: 2,
+ NONE: 3,
+ SENDING: 4,
+ SENT: 5,
+ DELIVERED: 6,
+ READ: 7
};
export const SocketCommand = {
diff --git a/email_mailbox/src/utils/electronEventInterface.js b/email_mailbox/src/utils/electronEventInterface.js
index f0f922074..96bb27a95 100644
--- a/email_mailbox/src/utils/electronEventInterface.js
+++ b/email_mailbox/src/utils/electronEventInterface.js
@@ -7,7 +7,8 @@ import {
LabelType,
getContactByEmails,
createFeedItem,
- myAccount
+ myAccount,
+ updateOpenedEmailByKey
} from './electronInterface';
import {
formEmailLabel,
@@ -15,7 +16,7 @@ import {
formIncomingEmailFromData,
getRecipientsFromData
} from './EmailUtils';
-import { SocketCommand, appDomain, FeedItemType } from './const';
+import { SocketCommand, appDomain, EmailStatus } from './const';
const EventEmitter = window.require('events');
const electron = window.require('electron');
@@ -92,18 +93,24 @@ export const handleNewMessageEvent = async ({ rowid, params }) => {
export const handleEmailTrackingUpdate = async ({ rowid, params }) => {
const [metadataKey, recipientId] = [params.metadataKey, params.from];
if (recipientId !== myAccount.recipientId) {
- const contactEmail = `${recipientId}@${appDomain}`;
- const [contact] = await getContactByEmails([contactEmail]);
const [email] = await getEmailByKey(metadataKey);
- const feedItemParams = {
- date: params.date,
- type: FeedItemType.OPENED.value,
- emailId: email.id,
- contactId: contact.id
- };
- await createFeedItem([feedItemParams]);
- await acknowledgeEvents([rowid]);
- emitter.emit(Event.EMAIL_TRACKING_UPDATE);
+ if (email) {
+ await updateOpenedEmailByKey({
+ key: metadataKey,
+ status: EmailStatus.READ
+ });
+ const contactEmail = `${recipientId}@${appDomain}`;
+ const [contact] = await getContactByEmails([contactEmail]);
+ const feedItemParams = {
+ date: params.date,
+ type: params.type,
+ emailId: email.id,
+ contactId: contact.id
+ };
+ await createFeedItem([feedItemParams]);
+ await acknowledgeEvents([rowid]);
+ emitter.emit(Event.EMAIL_TRACKING_UPDATE, email.id);
+ }
}
// To do: Sync this event with my other devices
};
diff --git a/email_mailbox/src/utils/electronInterface.js b/email_mailbox/src/utils/electronInterface.js
index 1bf45640d..ce286ad41 100644
--- a/email_mailbox/src/utils/electronInterface.js
+++ b/email_mailbox/src/utils/electronInterface.js
@@ -237,6 +237,10 @@ export const updateLabel = params => {
return dbManager.updateLabel(params);
};
+export const updateOpenedEmailByKey = ({ key, status }) => {
+ return dbManager.updateEmail({ key, status });
+};
+
export const updateUnreadEmailByThreadId = (threadId, value) => {
return dbManager.updateEmailByThreadId({ threadId, unread: value });
};