Commit graph

265 commits

Author SHA1 Message Date
Juan Tejada 2dccde2e58 feat(mail-merge): Add mail merge plugin
Summary:
Adds Mail Merge Plugin
- Adds new table components to component kit
- Adds new extension points to allow dragging and dropping into composer contenteditable and participant fields and customizing participant fields
- Adds new decorators and other misc updates
- #1608

Test Plan: TODO

Reviewers: bengotow, evan

Reviewed By: bengotow, evan

Differential Revision: https://phab.nylas.com/D2895
2016-04-22 18:29:07 -07:00
Evan Morikawa 1920d5db8a fix(win): speed up composer launching 2016-04-22 17:41:22 -07:00
Evan Morikawa 78112563a6 feat(win): faster popout windows
Summary:
This diff is designed to dramatically speed up new window load time for
all window types and reduce memory consumption of our hot windows.

Before this diff, windows loaded in ~3 seconds. They now boot in a couple
hundred milliseconds without requiring to keep hot windows around for
each and every type of popout window we want to load quickly.

One of the largest bottlenecks was the `require`ing and initializing of
everything in `NylasExports`.

I changed `NylasExports` to be entirely lazily-loaded. Drafts and tasks
now register their constructors with a `StoreRegistry` and the
`TaskRegistry`. This lets us explicitly choose a time to activate these
stores in the window initalization instead of whenever nylas-exports
happens to be required first.

Before, NylasExports was required first when components were first
rendering. This made initial render extremely slow and made the proposed
time picker popout slow.

By moving require into the very initial window boot, we can create a new
scheme of hot windows that are "half loaded". All of the expensive
require-ing and store initialization is done. All we need to do is
activate the packages for just the one window.

This means that the hot window scheme needs to fundamentally change from
have fully pre-loaded windows, to having half-loaded empty hot windows
that can get their window props overridden again.

This led to a major refactor of the WindowManager to support this new
window scheme.

Along the way the API of WindowManager was significantly simplifed.
Instead of a bunch of special-cased windows, there are now consistent
interfaces to get and `ensure` windows are created and displayed. This
DRYed up a lot of repeated logic around showing or creating core windows.

This also allowed the consolidation of the core window configurations into
one place for much easier reasoning about what's getting booted up.

When a hot window goes "live" and gets populated, we simply change the
`windowType`. This now re-triggers the loading of all of the packages for
the window. All of the loading time is now just for the packages that
window requires since core Nylas is there thanks to the hot window
mechanism.

Unfortunately loading all of the packages for the composer was still
unnaceptably slow. The major issue was that all of the composer plugins
were taking a long time to process and initialize. The solution was to
have the main composer load first, then trigger another window load
settings change to change the `windowType` that loads in all of the
plugins.

Another major bottleneck was the `RetinaImg` name lookup on disk. This
requires traversing the entire static folder synchronously on boot. This
is now done once when the main window loads and saved in a cache in the
browser process. Any secondary windows simply ask the backend for this
cache and save the filesystem access time.

The Paper Doc below is the current set of manual tests I'm doing to make
sure no window interactions (there are a lot of them!) regressed.

Test Plan: https://paper.dropbox.com/doc/Window-Refactor-UYsgvjgdXgVlTw8nXTr9h

Reviewers: juan, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2916
2016-04-22 13:30:42 -07:00
Ben Gotow 33225f56b0 rename(drafts) DraftStoreProxy => DraftEditingSession 2016-04-19 16:08:58 -07:00
Ben Gotow 7452705c31 refactor(composer): Make session, draft available everywhere
Summary:
Up until now, we've been requiring that every plugin control in the composer take the draftClientId, retreive the session, listen to it, build state from the draft, etc. This is a huge pain and is hard to explain to newcomers becaus it frankly makes no sense.

In 0.3.45 we made it so that the ComposerView always has a non-null draft and session. (It isn't rendered until they're available). In this diff, I just pass those through to all the plugins and remove all the session retrieval cruft.

Almost none of the buttons have state of their own, which I think is appropriate.

They do render on every keystroke, but they were already running code (to recompute their state) on each keystroke and profiling suggests this has no impact.

Prepare for immutable

In preparation for Immutable models, make the draft store proxy returns a !== draft if any changes have been made. This means you can safely know that a draft has changed if `props.draft !== nextProps.draft`

Test Plan: Run tests

Reviewers: juan, evan

Reviewed By: juan, evan

Differential Revision: https://phab.nylas.com/D2902
2016-04-19 16:05:15 -07:00
Dakota Nelson ccaa03e944 Expose ParticipantsTextField through component kit (#1994) 2016-04-18 16:39:08 -07:00
Ben Gotow f85f447141 fix(require): Move more requires to new electron format 2016-04-13 15:35:01 -07:00
Ben Gotow 3cd94e8957 fix(cc/bcc): Make targets bigger, wait longer before declaring focus left 2016-04-06 13:54:39 -07:00
Ben Gotow 34201ff644 fix(collapsed-participants): Resize in correct scenarios 2016-04-05 14:16:24 -07:00
Ben Gotow 646ac9589c fix(composer): Show when rendered, send draft JSON to composer windows 2016-04-04 18:30:50 -07:00
Ben Gotow 2688881ff3 fix(lint): Missing const breaking build 2016-04-04 17:12:59 -07:00
Evan Morikawa db1f651a3e fix(scheduler): add timezone & fix tabbing 2016-04-04 16:06:48 -07:00
Ben Gotow b4434f6617 fix(focus): Remove focusedField in favor of imperative focus, break apart ComposerView
Summary:
- Removes controlled focus in the composer!
  - No React components ever perfom focus in lifecycle methods. Never again.
  - A new `Utils.schedule({action, after, timeout})` helper makes it easy to say "setState or load draft, etc. and then focus"
  - The DraftStore issues a focusDraft action after creating a draft, which causes the MessageList to focus and scroll to the desired composer, which itself decides which field to focus.
  - The MessageList never focuses anything automatically.
- Refactors ComposerView apart — ComposerHeader handles all top fields, DraftSessionContainer handles draft session initialization and exposes props to ComposerView
  - ComposerHeader now uses a KeyCommandRegion (with focusIn and focusOut) to do the expanding and collapsing of the participants fields. May rename that container very soon.
- Removes all CommandRegistry handling of tab and shift-tab. Unless you preventDefault, the browser does it's thing.
- Removes all tabIndexes greater than 1. This is an anti-pattern—assigning everything a tabIndex of 0 tells the browser to move between them based on their order in the DOM, and is almost always what you want.
- Adds "TabGroupRegion" which allows you to create a tab/shift-tabbing group, (so tabbing does not leave the active composer). Can't believe this isn't a browser feature.

Todos:
- Occasionally, clicking out of the composer contenteditable requires two clicks. This is because atomicEdit is restoring selection within the contenteditable and breaking blur.
- Because the ComposerView does not render until it has a draft, we're back to it being white in popout composers for a brief moment. We will fix this another way - all the "return unless draft" statements were untenable.
- Clicking a row in the thread list no longer shifts focus to the message list and focuses the last draft. This will be restored soon.

Test Plan: Broken

Reviewers: juan, evan

Reviewed By: juan, evan

Differential Revision: https://phab.nylas.com/D2814
2016-04-04 15:22:01 -07:00
Evan Morikawa 15ff969e73 feat(calendar): add week view for quick scheduler
Summary: New Calendar

Test Plan: TODO

Reviewers: drew, juan, bengotow

Reviewed By: bengotow

Subscribers: jackie

Differential Revision: https://phab.nylas.com/D2767
2016-04-04 15:05:48 -07:00
Ben Gotow 39768fd9d4 bump(react): 0.13.2 => 0.14.7
Great breakdown of React changes here:
https://github.com/facebook/react/blob/master/CHANGELOG.md#0140-october-7-2015

Due to deprecation warnings, I don't think this will break third-party extensions unless they were doing really bad things.
2016-03-29 01:43:12 -07:00
Ben Gotow 3fa93c2730 fix(composer): Sentry 9688 2016-03-24 17:18:50 -07:00
Juan Tejada 9413459311 fix(styles): Fix styles for attachment and upload items 2016-03-23 17:16:25 -07:00
Dakota Nelson f3250e5395 Add extensibility in composer recipient chips
Summary:
Allow for injection into the composer's list of recipients to indicate
something about each recipient (i.e. for the PGP plugin, allow an
indicator as to whether or not each recipient has a PGP key
available)

Test Plan: Tested locally

Reviewers: juan

Reviewed By: juan

Subscribers: bengotow

Differential Revision: https://phab.nylas.com/D2761
2016-03-22 17:08:54 -07:00
Ben Gotow 92bff6ca5a fix(drafts): Formalize draft factory, add reply "behaviors" #1722
Summary:
This diff implements a behavior change described in https://github.com/nylas/N1/issues/1722.

Reply buttons should prefer to focus an existing draft in reply to the same message, if one is pristine, altering it as necessary to switch between reply / reply-all. If no pristine reply is already there, it creates one.

Reply keyboard shortcuts should do the same, but more strictly - the shortcuts should switch between reply / reply-all for an existing draft regardless of whether it's pristine.

This diff also cleans up the DraftStore and moves all the draft creation itself to a new DraftFactory object. This makes it much easier to see what's going on in the DraftStore, and I also refactored away the "newMessageWithContext" method, which was breaking the logic for Reply vs Forward between a bunch of different helper methods and was hard to follow.

Test Plan: They're all wrecked. Will fix after concept is greenlighted

Reviewers: evan, juan

Reviewed By: juan

Differential Revision: https://phab.nylas.com/D2776
2016-03-22 15:47:51 -07:00
Juan Tejada 96846d4052 feat(download-all): Adds download-all button + style updates, more ES6
Summary:
- Adds initial version of download all button
- Converts attachments plugin to ES6 and adds updated styling
- Updates quoted text button
- #905, #1712

Test Plan: - Unit + manual

Reviewers: evan, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2769
2016-03-21 18:23:26 -07:00
Ben Gotow b5fe01e5d0 fix(composer): Refactor header actions, clean up layout
Summary:
WIP

Remove the mode prop from everywhere, use NylasEnv.isComposerWindow() instead

Test Plan: Run updated tests

Reviewers: drew, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D2766
2016-03-21 11:32:48 -07:00
Ben Gotow 9099542643 fix(quoted-text): div vs blockquote, signature cleanup #1746
Summary:
Previously we always created <blockquote class="gmail_quote"> to wrap quoted text. This is not correct.
Gmail uses blockquotes only when it wants visual indentation, and <div>s to wrap other quoted text, like forwarded
messages which are not displayed indented.

This diff updates N1 to match Gmail exactly. Note that for replies, Gmail actually nests a blockquote.gmail_quote
inside a div.gmail_quote.

I also updated signature handling because it turns out the regexp that was removing existing signatures would blow
away any and all divs until it reached a <blockquote> tag.

Test Plan: See updated specs. Manually tested by creating a thread in Google Inbox and then performing fwd and reply in both N1 and Inbox. Results match.

Reviewers: juan, evan

Reviewed By: evan

Differential Revision: https://phab.nylas.com/D2750
2016-03-17 13:11:00 -07:00
Ben Gotow 1ad2598a50 fix(uploads): Display icon regardless of ext capitalization
Note: In the future we really need to consolidate file-upload.cjsx and attachment-component.cjsx. #1700
2016-03-15 09:31:22 -07:00
Ben Gotow 4593d0a9b1 fix(config): Move account tokens to system keychain
Summary:
This diff also adds an account version number to the config so that the AccountStore can tell whether it should reload accounts (depending on whether it was the instance making tthe changes.)

This diff also fixes a tiny issue where un-opened composers threw an exception if you changed accounts.

Test Plan: New tests

Reviewers: evan, drew, juan

Reviewed By: juan

Subscribers: juan

Differential Revision: https://phab.nylas.com/D2726
2016-03-14 15:14:08 -07:00
Evan Morikawa e77d658a96 fix(composer): focus on the absolute end when clicking near the bottom 2016-02-25 13:31:34 -08:00
Drew Regitsky d5ba162e82 fix(composer-buttons): Fix broken icons on overflow, make buttons wrap 2016-02-25 12:30:20 -08:00
Evan Morikawa 17ea99d2ff fix(error-handling): handle offline for link tracking & read-receipts
Fix offline error handling of link tracking and read receipts

Fix ellipses for tooltips

Allow you to change the title in the error box
2016-02-24 16:06:08 -08:00
Juan Tejada 579d4ad71b fix(signature): Update signature when account is changed in composer
Summary:
- Fixes #1239
- Adds action in composer view to indicate when draft partcipants have
  changed. This seemed like the simplest way to listen for this change without
  adding another extension point
- Updates signature plugin to listen to this action and update signature
  accordingly
- Adds test

Test Plan: - Unit tests

Reviewers: evan, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2614
2016-02-24 00:19:55 -08:00
Evan Morikawa 481dc28585 feat(composer): new composer footer and icon design 2016-02-23 13:42:10 -08:00
Ben Gotow 8168838101 fix(compose): More defensive check when switching from address, see description
This fixes #1341, but is more restrictive:

- You cannot switch From: accounts if the draft was retrieved from the sync engine (authored via Gmail or via another copy of N1. The sync-engine gives drafts a non-null threadId)

- You cannot switch From: accounts if the draft is a forward from an existing thread.

These two restrictions are unfortunately necessary to ensure that we don't have to download attachments we don't have to re-upload them to another account on the sync-engine. We could write code for this in the future but it's going to be gross.
2016-02-19 19:19:43 -08:00
Ben Gotow 7a760ff766 fix(compose): Enable esc-to-cancel from Cannot Send dialog (Fixes #1383) 2016-02-19 18:59:17 -08:00
Evan Morikawa 2658a01e40 fix(composer): fix dissapearing participant bug w/ multiple composers
If you had multiple composers on a single thread, all but the last
composer would lose its participants. This was because once it loaded the
participants would blur and trigger a request to set the participants to
blank. That request was async so by the time it was resolved the draft was
loaded and the request erroneously went through
2016-02-15 18:12:41 -05:00
Evan Morikawa 7edfe3853f fix(messages): fix jumping message list on draft focus
We were erroneously jumping to an individual message when you focused on
it.
2016-02-15 16:34:23 -05:00
Ben Gotow ef40e73108 fix(min-height): Reduce minimum window size to 250px. Fixes #1293 2016-02-10 12:39:13 -08:00
Ben Gotow 8f7795b40f fix(send-action): Make dropdown trigger secondary send actions
We can come up with a new UX for this later, but for now this is important for consistency with the Reply/Reply-All/Forward picker and others in the app that perform actions rather than changing selection. Also makes it possible to choose to "Send and Archive" /without/ making it the future default, which will be nice when there are many you may want infrequently.
2016-02-03 16:27:11 -08:00
Evan Morikawa d4db0737cf feat(error): improve error reporting. Now NylasEnv.reportError
Summary:
The goal is to let us see what plugins are throwing errors on Sentry.

We are using a Sentry `tag` to identify and group plugins and their
errors.

Along the way, I cleaned up the error catching and reporting system. There
was a lot of duplicate error logic (that wasn't always right) and some
legacy Atom error handling.

Now, if you catch an error that we should report (like when handling
extensions), call `NylasEnv.reportError`. This used to be called
`emitError` but I changed it to `reportError` to be consistent with the
ErrorReporter and be a bit more indicative of what it does.

In the production version, the `ErrorLogger` will forward the request to
the `nylas-private-error-reporter` which will report to Sentry.

The `reportError` function also now inspects the stack to determine which
plugin(s) it came from. These are passed along to Sentry.

I also cleaned up the `console.log` and `console.error` code. We were
logging errors multiple times making the console confusing to read. Worse
is that we were logging the `error` object, which would print not the
stack of the actual error, but rather the stack of where the console.error
was logged from. Printing `error.stack` instead shows much more accurate
stack traces.

See changes in the Edgehill repo here: 8c4a86eb7e

Test Plan: Manual

Reviewers: juan, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2509
2016-02-03 18:06:52 -05:00
Bernd Verst 90b1a109b0 Use vertical layout for MessageListHeaders, MessageListNotificationBar, Draft:Footer
Test Plan: No new tests. Visual verification.

Reviewers: bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2514
2016-02-03 14:51:46 -08:00
Ben Gotow 001ccfff43 fix(composer): Attachment check ignores uploads. Fixes #1190 2016-02-02 10:15:20 -08:00
Juan Tejada 7a8e10af0d fix(lint): Fix new eslint rule introduced with babel-eslint upgrade.
See https://phabricator.babeljs.io/T6925
2016-02-01 20:07:36 -08:00
Ben Gotow 12f3ca4f3b fix(dropdown): Open up or down depending on position 2016-01-29 15:52:40 -08:00
Juan Tejada ced31d7f5d fix(electron): Update api usage to require('electron') 2016-01-29 14:24:33 -08:00
Juan Tejada 9a86ce06ed Update file uploads (see details):
- Add uploads field to Message and removes cache from FileUploadsStore
- Updates draft via session from DraftStore
  - This makes everything way cleaner
- This fixes bug when creating draft with uploads and the opening it in
  new window
- Updates specs
2016-01-28 00:33:22 -08:00
Juan Tejada 1d8f56e7f8 Misc fixes for FileUploadStore 2016-01-27 15:38:01 -08:00
Juan Tejada 08ec481739 Fix ComposerView specs 2016-01-27 13:49:34 -08:00
Juan Tejada 63d36a78c3 Inits FileUploadStore from current state in the filesystem
- Removes uploads when draft is deleted
- Misc fixes and renaming
2016-01-26 18:48:58 -08:00
Ben Gotow 752a749da7 More sending fixes - attachments working! 2016-01-26 18:03:01 -08:00
Juan Tejada 7c71576192 Misc fixes for FileUploadStore 2016-01-26 16:58:20 -08:00
Juan Tejada dcb08932c0 Refactor FileUploadStore and composer attachments - WIP 2016-01-26 15:36:38 -08:00
Juan Tejada 1435904f3c Fix when checking if draft is a reply when getting accounts for send 2016-01-26 13:55:26 -08:00
Juan Tejada 324123731a Add ability to select account to send from
- Adds settings option to select default account to send from
2016-01-25 18:20:54 -08:00