diff --git a/electron_app/package.json b/electron_app/package.json index 21e8cd7ec..f96e9511e 100644 --- a/electron_app/package.json +++ b/electron_app/package.json @@ -1,6 +1,6 @@ { "name": "criptext", - "version": "0.5.0", + "version": "0.6.0", "author": { "name": "Criptext Inc.", "email": "info@criptext.com", diff --git a/electron_app/src/models.js b/electron_app/src/models.js index ac48c5d5f..fa68b9de4 100644 --- a/electron_app/src/models.js +++ b/electron_app/src/models.js @@ -102,12 +102,12 @@ const createEmailColumns = table => { table.string('subject').notNullable(); table.text('content').notNullable(); table.string('preview', LARGE_STRING_SIZE).notNullable(); - table.timestamp('date').notNullable(); + table.dateTime('date').notNullable(); table.integer('status').notNullable(); table.boolean('unread').notNullable(); table.boolean('secure').notNullable(); table.boolean('isMuted').notNullable(); - table.timestamp('unsendDate'); + table.dateTime('unsendDate'); }; const createEmailLabelColumns = table => { diff --git a/electron_app/src/windows/menu.js b/electron_app/src/windows/menu.js index 9f3487fac..d0474c40d 100644 --- a/electron_app/src/windows/menu.js +++ b/electron_app/src/windows/menu.js @@ -65,6 +65,20 @@ const template = [ label: 'Close', accelerator: 'CmdOrCtrl+W', role: 'close' + }, + { + label: 'Developer', + type: 'submenu', + submenu: [ + { + label: 'Toggle Developer Tools', + accelerator: + process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', + click(item, focusedWindow) { + if (focusedWindow) focusedWindow.webContents.toggleDevTools(); + } + } + ] } ] } @@ -120,7 +134,7 @@ if (process.platform === 'darwin') { ] }); // Window menu. - template[2].submenu.push( + template[3].submenu.push( { type: 'separator' }, diff --git a/email_mailbox/src/actions/emails.js b/email_mailbox/src/actions/emails.js index 069d5ef42..e132f2a19 100644 --- a/email_mailbox/src/actions/emails.js +++ b/email_mailbox/src/actions/emails.js @@ -10,9 +10,8 @@ import { } from '../utils/electronInterface'; import { loadContacts } from './contacts'; import { updateLabelSuccess } from './labels'; -import { EmailStatus, unsentText } from '../utils/const'; +import { EmailStatus } from '../utils/const'; import { getCriptextRecipients } from '../utils/EmailUtils'; -import { removeHTMLTags } from '../utils/StringUtils'; export const addEmails = emails => { return { @@ -124,11 +123,11 @@ export const unsendEmail = params => { await updateEmail({ key, status: EmailStatus.UNSEND, - content: unsentText, - preview: removeHTMLTags(unsentText), + content: '', + preview: '', unsendDate: Date.now() }); - dispatch(unsendEmailOnSuccess(emailId)); + dispatch(unsendEmailOnSuccess(emailId, Date.now())); } } catch (e) { // To do @@ -136,7 +135,8 @@ export const unsendEmail = params => { }; }; -export const unsendEmailOnSuccess = emailId => ({ +export const unsendEmailOnSuccess = (emailId, unsendDate) => ({ type: Email.UNSEND, - emailId + emailId, + unsendDate }); diff --git a/email_mailbox/src/components/ButtonUnsend.js b/email_mailbox/src/components/ButtonUnsend.js index 0b6ea9791..edbe18607 100644 --- a/email_mailbox/src/components/ButtonUnsend.js +++ b/email_mailbox/src/components/ButtonUnsend.js @@ -8,9 +8,9 @@ const ButtonUnsend = props => ( 'button-unsend ' + (props.displayLoading ? 'button-unsend-loading' : 'button-unsend-normal') } - onClick={props.onClick} + onClick={ev => props.onClick(ev)} > - {props.displayLoading ? renderLoading() : renderButton(props.onClick)} + {props.displayLoading ? renderLoading() : renderButton()} ); diff --git a/email_mailbox/src/components/ButtonUnsendWrapper.js b/email_mailbox/src/components/ButtonUnsendWrapper.js index 614ca4b09..af471d039 100644 --- a/email_mailbox/src/components/ButtonUnsendWrapper.js +++ b/email_mailbox/src/components/ButtonUnsendWrapper.js @@ -14,23 +14,23 @@ class ButtonUnsendWrapper extends Component { return ( ); } - onClick = () => { + handleClick = ev => { + if (ev) ev.stopPropagation(); this.setState({ displayLoading: true }); - this.props.onClicked(true); + this.props.onClick(true); }; } ButtonUnsendWrapper.propTypes = { displayPopOver: PropTypes.bool, - onClicked: PropTypes.func, + onClick: PropTypes.func, onTogglePopOver: PropTypes.func }; diff --git a/email_mailbox/src/components/Email.js b/email_mailbox/src/components/Email.js index 289d745d6..a20079e1b 100644 --- a/email_mailbox/src/components/Email.js +++ b/email_mailbox/src/components/Email.js @@ -20,7 +20,7 @@ const renderEmailCollapse = props => (
@@ -99,7 +99,7 @@ const renderEmailExpand = props => (
{props.isFromMe && !props.isUnsend ? ( - + ) : null} ); @@ -62,14 +62,14 @@ class EmailWrapper extends Component { }); }; - setHideView = value => { + handleClickUnsendButton = value => { this.setState( { - hideView: value + hideView: !value }, async () => { await this.props.unsendEmail(); - this.setState({ hideView: !value }); + this.setState({ hideView: value }); } ); }; diff --git a/email_mailbox/src/components/PanelWrapper.js b/email_mailbox/src/components/PanelWrapper.js index 282464fb1..185c83f4c 100644 --- a/email_mailbox/src/components/PanelWrapper.js +++ b/email_mailbox/src/components/PanelWrapper.js @@ -66,7 +66,7 @@ class PanelWrapper extends Component { } }); - addEvent(Event.EMAIL_TRACKING_UPDATE, (threadId, status) => { + addEvent(Event.EMAIL_TRACKING_UPDATE, (threadId, status, date) => { if (status === EmailStatus.OPENED) { props.onMarkThreadAsOpen(threadId); } @@ -84,7 +84,7 @@ class PanelWrapper extends Component { }); } if (isRenderingThread) { - props.onUnsendEmail(threadId); + props.onUnsendEmail(threadId, date); } } }); diff --git a/email_mailbox/src/components/email.scss b/email_mailbox/src/components/email.scss index e01bc4243..4c55d5e2a 100644 --- a/email_mailbox/src/components/email.scss +++ b/email_mailbox/src/components/email.scss @@ -3,24 +3,15 @@ .email-container{ align-items: center; background-color: white; + border: solid 1px #dcdde0; border-radius: 4px; display: flex; - font-family: NunitoSans; margin-bottom: 6px; position: relative; - width: 100%; + width: calc(100% - 2px); &.email-unsend { - i { - color: #d0021b; - } - .button-expand { - border-color: #ff99a5; - } - .email-text { - font-style: italic; - color: #acacac; - } + border: solid 1px #eeb6b7; } hr{ @@ -120,17 +111,9 @@ } .email-container-collapse{ - width: calc(100% - 2px); - - &.email-normal{ - border: solid 1px #dcdde0; - } - - &.email-unsent{ - border: solid 1px rgba(221, 64, 64, 0.48); - + &.email-unsend{ .email-preview-content{ - color: #eea3a3; + color: #eeb6b7; font-style: italic; } } @@ -149,10 +132,15 @@ } .email-container-expand{ - box-shadow: 0 2px 4px 0 rgba(175, 175, 175, 0.35); height: auto; flex-direction: column; + &.email-unsend { + .email-text { + font-style: italic; + } + } + > div{ margin: 0 17px; width: calc(100% - 34px); @@ -210,9 +198,13 @@ font-weight: 200; &[disabled]{ - opacity: 0.2; + opacity: 0.3; pointer-events: none; } + + >div{ + margin: 10px 0; + } } .email-files{ diff --git a/email_mailbox/src/containers/Email.js b/email_mailbox/src/containers/Email.js index 5f813dadc..0e1dd0a0b 100644 --- a/email_mailbox/src/containers/Email.js +++ b/email_mailbox/src/containers/Email.js @@ -10,7 +10,7 @@ import { openEmailInComposer } from './../utils/electronInterface'; import { loadFiles, muteEmail, unsendEmail } from './../actions/index'; -import { EmailStatus } from '../utils/const'; +import { EmailStatus, unsentText } from '../utils/const'; const mapStateToProps = (state, ownProps) => { const email = ownProps.email; @@ -30,6 +30,12 @@ const mapStateToProps = (state, ownProps) => { const letters = getTwoCapitalLetters(senderName || senderEmail || ''); const date = email.date; const files = getFiles(state.get('files'), email.fileTokens); + const preview = + email.status === EmailStatus.UNSEND ? unsentText : email.preview; + const content = + email.status === EmailStatus.UNSEND + ? `Unsent: At ${defineTimeByToday(email.unsendDate)}` + : email.content; const myEmail = { ...email, date: defineTimeByToday(date), @@ -40,7 +46,9 @@ const mapStateToProps = (state, ownProps) => { cc, bcc, color, - letters + letters, + preview, + content }; const isUnsend = email.status === EmailStatus.UNSEND; return { diff --git a/email_mailbox/src/containers/Panel.js b/email_mailbox/src/containers/Panel.js index cf84b7d5f..231ef58a8 100644 --- a/email_mailbox/src/containers/Panel.js +++ b/email_mailbox/src/containers/Panel.js @@ -77,8 +77,8 @@ const mapDispatchToProps = dispatch => { storeSeenTimestamp(); dispatch(updateAllFeedItemsAsOlder()); }, - onUnsendEmail: emailId => { - dispatch(unsendEmailOnSuccess(emailId)); + onUnsendEmail: (emailId, date) => { + dispatch(unsendEmailOnSuccess(emailId, date)); } }; }; diff --git a/email_mailbox/src/reducers/emails.js b/email_mailbox/src/reducers/emails.js index c289b1356..559c69209 100644 --- a/email_mailbox/src/reducers/emails.js +++ b/email_mailbox/src/reducers/emails.js @@ -1,7 +1,6 @@ import { Email } from '../actions/types'; import { Map, fromJS } from 'immutable'; -import { EmailStatus, unsentText } from './../utils/const'; -import { removeHTMLTags } from './../utils/StringUtils'; +import { EmailStatus } from './../utils/const'; const emails = (state = new Map(), action) => { switch (action.type) { @@ -49,9 +48,10 @@ const email = (state, action) => { return ( state && state.merge({ - content: unsentText, - preview: removeHTMLTags(unsentText), - status: EmailStatus.UNSEND + content: '', + preview: '', + status: EmailStatus.UNSEND, + unsendDate: action.unsendDate }) ); } diff --git a/email_mailbox/src/utils/const.js b/email_mailbox/src/utils/const.js index 7675db565..3f0a68000 100644 --- a/email_mailbox/src/utils/const.js +++ b/email_mailbox/src/utils/const.js @@ -2,7 +2,7 @@ import { LabelType } from './electronInterface'; export const appDomain = 'jigl.com'; -export const unsentText = '

This content was unsent

'; +export const unsentText = 'This content was unsent'; export const IconLabels = { [LabelType.inbox.id]: { diff --git a/email_mailbox/src/utils/electronEventInterface.js b/email_mailbox/src/utils/electronEventInterface.js index 422579314..5cf842578 100644 --- a/email_mailbox/src/utils/electronEventInterface.js +++ b/email_mailbox/src/utils/electronEventInterface.js @@ -1,4 +1,3 @@ -/*global process*/ import { acknowledgeEvents, createEmail, @@ -21,10 +20,9 @@ import { validateEmailStatusToSet, checkEmailIsTo } from './EmailUtils'; -import { SocketCommand, appDomain, EmailStatus, unsentText } from './const'; +import { SocketCommand, appDomain, EmailStatus } from './const'; import Messages from './../data/message'; import { MessageType } from './../components/Message'; -import { removeHTMLTags } from './StringUtils'; const EventEmitter = window.require('events'); const electron = window.require('electron'); @@ -56,9 +54,7 @@ export const handleEvent = incomingEvent => { return handlePeerUserNameChanged(incomingEvent); } default: { - return process.env.NODE_ENV === 'development' - ? alert('Unhandled socket command: ', incomingEvent.cmd) - : null; + return; } } }; @@ -139,51 +135,53 @@ const handleNewMessageEvent = async ({ rowid, params }) => { }; const handleEmailTrackingUpdate = async ({ rowid, params }) => { - const [metadataKey, recipientId] = [params.metadataKey, params.from]; + const { date, metadataKey, type } = params; + const recipientId = params.from; const [email] = await getEmailByKey(metadataKey); if (email) { - const content = params.type === EmailStatus.UNSEND ? unsentText : null; - const preview = - params.type === EmailStatus.UNSEND ? removeHTMLTags(unsentText) : null; - const status = validateEmailStatusToSet(email.status, params.type); + const content = type === EmailStatus.UNSEND ? '' : null; + const preview = type === EmailStatus.UNSEND ? '' : null; + const status = validateEmailStatusToSet(email.status, type); + const unsendDate = type === EmailStatus.UNSEND ? date : null; await updateEmail({ key: metadataKey, status, content, - preview + preview, + unsendDate }); const isFromMe = recipientId === myAccount.recipientId; - const isOpened = params.type === EmailStatus.OPENED; + const isOpened = type === EmailStatus.OPENED; if (!isFromMe && isOpened) { const contactEmail = `${recipientId}@${appDomain}`; const [contact] = await getContactByEmails([contactEmail]); const feedItemParams = { - date: params.date, - type: params.type, + date, + type, emailId: email.id, contactId: contact.id }; await createFeedItem([feedItemParams]); } await setEventAsHandled(rowid); - emitter.emit(Event.EMAIL_TRACKING_UPDATE, email.id, params.type); + emitter.emit(Event.EMAIL_TRACKING_UPDATE, email.id, type, date); } }; const handlePeerEmailUnsend = async ({ rowid, params }) => { - const { metadataKey } = params; + const { metadataKey, date } = params; const [email] = await getEmailByKey(metadataKey); if (email) { const status = validateEmailStatusToSet(email.status, params.type); await updateEmail({ key: metadataKey, - content: unsentText, - preview: removeHTMLTags(unsentText), + content: '', + preview: '', status, - unsendDate: Date.now() + unsendDate: date }); await setEventAsHandled(rowid); - emitter.emit(Event.EMAIL_TRACKING_UPDATE, email.id, params.type); + emitter.emit(Event.EMAIL_TRACKING_UPDATE, email.id, params.type, date); } };