Summary: Just a small patch to address bad messaging
Test Plan: Run one new test!
Reviewers: jackie, juan
Reviewed By: jackie, juan
Differential Revision: https://phab.nylas.com/D3000
Summary:
ChangeFolder/ChangeLabel still need to call super.isDependentOnTask!
Formalize "retrieve latest models" part of the performLocal process, ensure that it's always /inside/ the transaction that is going to write the changes. This ensures that queueing two tasks for the same thread at the same time don't cause a race...
...condition between the two tasks (end result is currently arbitrary!)
Add "move to label" mail rule to go alongside "Add Label"
Test Plan: All broken... willfix.
Reviewers: juan, evan, jackie
Reviewed By: evan, jackie
Differential Revision: https://phab.nylas.com/D2999
Summary:
This diff introduces several updates to mail merge to improve the procedure for sending a list of drafts.
Specifically, sending mass email will now:
- Clear mail merge metadata on the drafts that will actually be sent
- Upload attached files only /once/, and reuse those files on the drafts that will actually be sent
- Minimize database writes for new drafts being created
- Will queue a SendManyDraftsTask that will subsequently queue the necessary SendDraftTasks and keep track of them, and notify of any failed tasks
TODO:
- Add state to MailMerge plugin for failed sends and ability to attempt to re send them
Test Plan: - TODO
Reviewers: evan, bengotow, jackie
Reviewed By: bengotow, jackie
Subscribers: jackie
Differential Revision: https://phab.nylas.com/D2973
Summary:
- Simplify undoManager to just maintain the undo/redo history items
- DraftEditingSession manages snapshotting state of draft, hack allows it to also save selection (still hoping to eventually put selection in body HTML as markers)
- Switch from `debounce` to `throttle` style behavior so typing for along time followed by undo doesn't undo away your entire block.
This resolves two issues:
+ Changes to participant fields are no longer undoable because they go straight to the session.
+ Changes to metadata weren't undoable.
Test Plan: Tests WIP
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2956
Summary:
Moves all reading / writing of config file to the main process,
to avoid needing to write code to lock across processes. This should also
be more efficient than re-loading the file in all processes when it's
saved.
Test Plan: Run tests
Reviewers: evan, jackie
Reviewed By: evan, jackie
Differential Revision: https://phab.nylas.com/D2963
Summary:
- Add some docs to Table components
- Updates Table components to use a TableDataSource instead of accessing arrays, cleans up code a bit
- Add enzyme lib to have a cleaner and simpler api to write tests for React Components
- Updates decorators to extend from the BaseComponent instead of vanilla Component, this way instance methods are still available on composed components
Test Plan: - Unit tests
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2941
Summary: Adds CSV imports, proper styles to mail merge plugin and fixes a handful of bugs
Test Plan: TODO
Reviewers: bengotow, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2925
Office 365 likes to format email addresses as follows:
Last Name, First Name (Some Description) <email@address.org>
This causes Contact.firstName() (and hence sometimes displayName()) to return
"Last Name," which looks a bit odd in the message/thread views.
The intent of the commit is to correctly parse these names so that (using the
above example):
- firstName = "First Name"
- lastName = "Last Name (Some Description)"
- fullName = "First Name Last Name (Some Description)"
These behavioral changes only impact names containing a ','.
I don't know that this really provides exhaustive coverage of Office 365, and
keeping the description as part of the last name is not completely guilt free,
but it's not any worse than the previous state of affairs which also has
the description in the same field but combined instead with (misplaced)
first name data.
Summary:
Keymaps & menus CSON => JSON, remove AtomKeymaps, CommandRegistry use of CSS selectors, use Mousetrap instead
Important Notes:
- The `application:` prefix is reserved for commands which are handled in the application process. Don't use it for other things. You will not receive the events in the window.
- Maintaining dynamic menus seems to come with quite an overhead, because Electron updates the entire menu every time. In the future, we'll need https://github.com/electron/electron/issues/528 to really make things nice. I will be tracking this upstream.
- The format for keyboard shortcuts has changed. `cmd-X` is now `command+shift+x`
Test Plan: Run tests
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2917
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
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
Summary:
Adds a new unified "Spam" folder and a unified "Unread" view,
which shows all the messages in your inbox which are unread.
Test Plan: Run tests
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2901
Summary:
- Use a sub-select query with much better performance to display the thread list
- Perform analyze on tables after launch
The new query is:
```
SELECT `Thread`.`data` FROM `Thread` WHERE `Thread`.`id` IN (SELECT `id` FROM `ThreadCategory` AS `M26` WHERE `M26`.`value` IN ('9m9ks71k06n5rmx82kgues09p','9s9k25q6j1krjgpkovbcjm7d','13b7ufruoymvih07ki0uahlto','dtmhlzz6phr47zp512knhjgf8','16dvjb84bszfh15kgfrjj37i3','aclwmgncdqjfibp51bvgbeik','17qad7jhbp6tozog3klm5zagt','4x4bkbawiq825u4eu3aus8tll','7axr9f5f1lzpwm2rw2ghkirhq','dsnn660af0pmou2gg3nstga8a','361qr5rva1ieby2r0ec3sn0bm','10fyvba7pjyjgeyr5i65i1zri') AND `M26`.`in_all_mail` = 1 ORDER BY `M26`.`last_message_received_timestamp` DESC LIMIT 200 OFFSET 0) ORDER BY `Thread`.`last_message_received_timestamp` DESC;
`
0|0|0|SEARCH TABLE Thread USING INDEX Thread_id (id=?)
0|0|0|EXECUTE LIST SUBQUERY 1
1|0|0|SCAN TABLE Thread-Category AS M26 USING COVERING INDEX ThreadFancyIndex
1|0|0|EXECUTE LIST SUBQUERY 2
0|0|0|USE TEMP B-TREE FOR (only on 200 result items)
```
Which is twice as performant as:
```
SELECT `Thread`.`data` FROM `Thread` INNER JOIN `ThreadCategory` AS `M26` ON `M26`.`id` = `Thread`.`id` WHERE `M26`.`value` IN ('9m9ks71k06n5rmx82kgues09p','9s9k25q6j1krjgpkovbcjm7d','13b7ufruoymvih07ki0uahlto','dtmhlzz6phr47zp512knhjgf8','16dvjb84bszfh15kgfrjj37i3','aclwmgncdqjfibp51bvgbeik','17qad7jhbp6tozog3klm5zagt','4x4bkbawiq825u4eu3aus8tll','7axr9f5f1lzpwm2rw2ghkirhq','361qr5rva1ieby2r0ec3sn0bm','10fyvba7pjyjgeyr5i65i1zri') AND `M26`.`in_all_mail` = 1 ORDER BY `M26`.`last_message_received_timestamp` DESC LIMIT 200 OFFSET 0;
0|0|1|SCAN TABLE Thread-Category AS M26 USING COVERING INDEX ThreadFancyIndex
0|0|0|EXECUTE LIST SUBQUERY 1
0|1|0|SEARCH TABLE Thread USING INDEX Thread_id (id=?)
```
Test Plan: Broken!
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2869
Summary:
- This diff also restructures the search package in a few ways:
- Rename package to `thread-search` instead of `search-bar`
- Move SearchQuerySubscription and SearchMailboxPerspective inside
package. This allows SearchQuerySubscription to have access to
SearchActions in a clean way and keeps all of the search related code
in 1 package
- Remove SearchMailboxPerspetcive from mailbox-perspective.coffee
- Adds temporary spinner while we get a new design for it
Test Plan: - TODO
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2868
Summary: Moved events into metadata. Removed a lot of code
Test Plan: todo
Reviewers: juan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2866
Summary:
The TaskQueue does it's own throttling and has it's own processQueue retry timeout, no need for longPollConnected
Remove dead code (OfflineError)
Rename long connection state to status so we don't ask for `state.state`
Remove long poll actions related to online/offline in favor of exposing connection state through NylasSyncStatusStore
Consoliate notifications and account-error-heaer into a single package and organize files into sidebar vs. header.
Update the DeveloperBarStore to query the sync status store for long poll statuses
Test Plan: All existing tests pass
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2835
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
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
Summary: after refactoring some things last week and spending time futsing with coffeescript, I’m pretty convinced it’s worth moving important parts of the app to ES6 to be able to use ESLint as part of our dev workflow
Test Plan: Run existing tests, tested manually. Did not convert the tests in this diff, breaking one part at a time!
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2768
Summary:
- Applies code changes that we discussed with @bengotow when debugging
#1327
- Minor refactoring and reorganization + update specs
Test Plan: - Unit tests
Reviewers: evan, bengotow
Reviewed By: bengotow
Subscribers: bengotow
Differential Revision: https://phab.nylas.com/D2612
Summary:
This is a critical patch that fixes two problems with the task queue:
1. Tasks in Status: Retry are retried the next time processQueue is run,
which could be pretty much immediately. Certain scenarios lead to tasks
running in a hard loop forever.
2. Returning Task.Status.Retry set the retry flags on the task but did not
schedule the queue to be processed again. So if only a single item in the
queue was present, it might never be retried again until the user performed
another action.
Test Plan: Where did the specs for TaskQueue go? There aren't many... need to write more.
Reviewers: evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2762
Summary:
The old approach we were using to track unread counts by category was really complicated because it involved computing changes to counts in javascript and then syncing them back to the database, from each process that was making queries. Rather than try to fix that, this diff moves us to a new approach where the counts are maintained by executing a query before and after threads are modified to unapply / reapply them from the counters. Doing this in the database in the same transactions as the thread modifications themselves ensures the counts are internally consistent with the Threads table.
This SQL approach is also able to compute initial counts way faster - initializing totals and unreads in a 1GB edgehill.db in about 1 second on my machine.
Test Plan: All old tests removed, new tests coming
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2757
Summary:
Fix specs
Fix responding to mailto, files at launch
It's super important that `window:loaded` is /not/ sent from index.js because `loadSettings.bootstrapScript` is async and nothing is actually loaded yet. This was causing the app to dispatch the mailto:// links into the main window before a DraftStore existed.
I think this was necessary at one point because we had NylasWindows not using a bootstrapScript? Should not be here anymore...
Test Plan: Run a few new tests
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2737
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
Summary:
This diff replaces "finalizeSessionBeforeSending" with a
plugin hook that is bidirectional and allows us to put the draft in
the "ready to send" state every time we save it, and restore it to
the "ready to edit" state every time a draft session is created to
edit it.
This diff also significantly restructures the draft tasks:
1. SyncbackDraftUploadsTask:
- ensures that `uploads` are converted to `files` and that any
existing files on the draft are part of the correct account.
1. SyncbackDraftTask:
- saves the draft, nothing else.
3. SendDraftTask
- sends the draft, nothing else.
- deletes the entire uploads directory for the draft
Test Plan: WIP
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2753
Summary: Shortens and simplifies UI variables so that unused variables are no longer present.
Test Plan: Tested locally.
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2738
Summary:
- Was not properly updating the references to snoozed categories when
accounts were added or removed
- Update whenCategoriesReady to make sure we listen until category syncing has concluded (Move inside CategoryStore)
- #1676, #1658
Test Plan: - TODO
Reviewers: evan, drew, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2723
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
- Specifically, when dragging from the sent perspective, we should not
allow the sent label to be removed.
- If moved to trash or spam, `all mail` will be correctly removed from
the thread, but it will keep sent label
- Show sent MailLabel on the threads
Summary:
- In Gmail all threads /must/ belong to either All Mail, Trash and Spam, and
they are mutually exclusive, so we need to make sure that any add/remove
label operation still guarantees that constraint
- Update ChangeLabelsTask to modify the set of labels to add and remove
based on this rule
- Update tasksFor archiving, moving to trash and moving to spam so they
don't affect any other labels in the thread, as gmail does.
- Removing from view /will/ remove any current labels, but will also
move between all mail and trash as needed
- Remove Inbox, Trash and Spam from the CategoryPicker, as Gmail does
Test Plan: - Unit tests
Reviewers: drew, evan, bengotow
Reviewed By: drew, evan, bengotow
Differential Revision: https://phab.nylas.com/D2715
Summary:
Snooze should wait for categories on all accounts
Fix authPlugin to rembmer `plugin+accountId`, not pluginId, add specs
categories() returned [], categories(acctId) returned {}
dry up sync worker, fetch metadata before anything else
Test Plan: Run tests
Reviewers: drew, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2693
Summary:
Previously, we have saved drafts back to the user's provider through the sync engine. There are a handful of very serious edge case issues we're working to solve that are creating a bad user experience. (#933, #1175, #1504, #1237)
For now, we're going to change the behavior of N1 to mitagate these issues.
- If you create a draft in N1, we will not sync it to other mail clients while you're working on it.
- If you enable send later, we'll start syncing the draft to the server as before.
- If you created the draft in another client, we'll sync the draft to the server as before.
Fix specs
Test Plan: Run specs
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2706
Summary:
- FixedPopover now correctly adjusts itself when overflowing outside
window, in all directions
- Updates styles
- Adds specs
- Remove Popover and popover.less, and refactor all code that used it in
favor of the new FixedPopover
Test Plan: Unit tests
Reviewers: drew, evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2697
Summary:
Fixes an issue with sending where certain conditions could result in a
duplicated message.
Fixes task dependency logic for draft syncback and send. Changes `createdAt`
on tasks to instead be `sequentialId`, assigned when the task is queued, to
track order of enqueueing. Renames `isDependentTask` => `isDependentOnTask`
and adds comments for clarity.
Test Plan:
Specs updated. Might be good to add some later to test this particular
edge case.
Reviewers: juan, evan, bengotow
Reviewed By: evan, bengotow
Differential Revision: https://phab.nylas.com/D2681
Summary:
- Separate gmail's remove-from-view and delete behaviors and write logic
for each of those
- Remove MailboxPerspective::{canArchiveThreads, canTrashThreads,
removeThreads} and some unecessary code in TaskFactory
- Instead, add MailboxPerspective::tasksForRemovingFromPerspective (I
know its a bit of a mouthful)
- I initially tried to put all of the logic for each execution path
inside the TaskFactory by checking perspective types, but it made
more sense to use the polymorphism already in place for the different
perspective types.
- There is a default delete/remove-from-view behavior which is
configurable via simple ruleset objects. The gmail behavior is
configured in this way.
- Update swipe css classes based on destination of threads
- Fixes#1460:
- Update logic to display archive/trash buttons and context menu options correctly
when selected threads can be archived/trashed (not based on
perspective)
- Same for swiping
- Add a bunch of specs
- Convert some code to ES6
- TODO write some docs for new functions
Test Plan: Unit tests
Reviewers: drew, evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2682
Summary:
- Setting the locale in moment was not sufficient to actually use the
correct localized formats.
- Moment provides localized format via the formats : 'L', 'LL', 'll',
etc. See: http://momentjs.com/docs/#/displaying/format/
- Updates to set our date formats based on localized formats:
- Unfortunately, localized formats always contain the year, so I
manually removed the year from our short format.
- Actually fixes: #1515
- Fixes bug where setting nextWeek or thisWeekend returned incorrect
date if the current day was saturday or sunday
- Add specs
Test Plan: Unit tests
Reviewers: evan, drew, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2688
Summary:
- Also refactors the code a bit for testability and maintainability
- Fixes#1515
Test Plan: - Unit tests
Reviewers: evan, drew, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2651
Summary:
When we delete drafts, they can sometimes come back because we receive deltas about them,
find that they're not in the cache, and re-save them.
This diff fixes that by permanently incrementing the optimistic change count, which was also do
to prevent deltas from changing threads while we're in the middle of a request that will change
them further. (This may not actually be necessary anymore, because we'd ignore the delta anyway
due to it's out-of-date version?)
Test Plan: Run a couple new tests
Reviewers: drew, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2665
Summary:
By default, the messages in a thread are now filtered to exclude
ones moved to trash or spam. You can choose to view those messages by clicking
the new bar in the message list.
When you view your spam or trash, we only show the messages on those threads
that have been marked as spam/trash.
Test Plan: Run a couple new tests
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2662
Summary: Just new specs. Tested by manually breaking lots of things in SendDraft
Test Plan: Run new tests
Reviewers: juan, drew, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2649
Summary: fix(account): allow users to reconnect accounts if auth has failed
Test Plan: manual
Reviewers: bengotow, juan
Differential Revision: https://phab.nylas.com/D2663
Fix broken links in link tracking and read receipts
Fix bug in email frame where it wouldn't adjust the height even when
content changed
MessageItem bodies automatically clear the MessageBodyProcessor cache when
the message contents (including metadata) change.
Remove unused Account stuff from nylas-observables
Plugins appIds properly read if there's an environment set
Summary:
This diff does two things:
- It adds a new SwipeContainer that makes it easy to implement swipe gestures. This is built into listTabular, so you can create a list and define onSwipeLeft/Right to enable gestures.
- It adds support for basic add/remove animations to the thread list. This works by adding a CSS transition to `top` and also leaving removed rows around for a specified time. (these times need to match.) Pretty much just cloned the core idea from TimeoutTransitionGroup.
Test Plan: No tests yet
Reviewers: evan, juan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2581
Summary:
- Adds a class ModelWithMetadata which models can now extend from
- Instances of this class can query metadata for a plugin via
`obj.metadataForPluginId(pluginId)`
- To observe changes on metadata it is sufficient to observe database changes on
the model. e.g.:
`DatabaseStore.findAll(Thread,
[Thread.attributes.pluginMetadata.contains(pluginId)])`
- To set metadata a new action has been created: Actions.setMetadata
- Adds a helper observable in nylas-observables to query for models with
metadata
- Merges CreateModelTask and UpdateModelTask into SyncbackModelTask
- Update SendDraftTask ans SynbackDraftTask to handle metadata changes
Test Plan: - Unit tests
Reviewers: drew, evan, bengotow
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2575
- When accounts changed and the saved perspective could reference
accounts that no longer exist and cause all sorts of errors. This is
fixed.
- Add specs
- Fixes some sentry errors
This method is called for every contact on a thread in the thread list, so I figured we should see if one version was faster. I ran this test code:
```
d = Date.now(); for(var ii = 0; ii < 10000; ii ++){ $n.AccountStore.accountForEmail("ben.gotow@gmail.com") }; console.log(Date.now() - d);
```
The other approach which calls meUsingAlias takes `3784ms`, and this version which uses the alias contacts cached in aliases() only takes `264ms`. Confirmed that the tests still pass.
- Fixes a bug where reply_to_message_id = "" when we receive drafts from the sever.
- In general behavior should be consistent with API. Since they allow null we should too.
Summary:
This diff adds an "OutboxStore" which reflects the TaskQueue and
adds a progress bar / cancel button to drafts which are currently sending.
- Sending state is different from things like Send later because drafts
which are sending shouldn't be editable. You should have to stop them
from sending before editing. I think we can implement "Send Later"
indicators, etc. with a simple InjectedComponentSet on the draft list
rows, but the OutboxStore is woven into the DraftList query subscription
so every draft has a `uploadTaskId`.
- The TaskQueue now saves periodically (every one second) when there are
"Processing" tasks. This is not really necessary, but makes it super
easy for tasks to expose "progress", because they're essentially
serialized and propagated to all windows every one second with the
current progress value. Kind of questionable, but super convenient.
- I also cleaned up ListTabular and MultiselectList a bit because they
applied the className prop to an inner element and not the top one.
- If a DestroyDraft task is created for a draft without a server id, it
ends with Task.Status.Continue and not Failed.
- The SendDraftTask doesn't delete uploads until the send actually goes
through, in case the app crashes and it forgets the file IDs it created.
Test Plan: Tests coming soon
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2524
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
Summary:
Now all plugins get passed a `cloudState` object to their `activate`
method.
The `cloudState` object is an instance of `CloudState` and acts like a
key-value store backed by the yet-to-be-implemented Metadata service.
It has a `get`, `getAll`, and `observe` method. The `observe` method
returns a new `Rx.Observable` for the given key.
It has a `set`, and `unset` method that doesn't actually mutate state, but
rather dispatches new `Task`s to Create, Update, and Delete `Metadata`
objects.
The whole object is backed by `Metadata` objects. Since these are standard
Database Objects that will appear on the delta sync streaming API, any
updates from the server will automatically propagate down to listening
views via the `Rx.Observable`s.
Additionally, there is a new `N1-Send-Later` stub plugin that demonstrates
how to use the `cloudState`.
There are few other minor refactors included in this diff:
**Generic CUD Tasks**: There is now a generic `CreateModelTask`,
`UpdateModelTask`, and `DestroyModelTask`. These can either be used as-is
or trivially overridden to easily update simple objects. Hopefully all of
the boilerplate rollback, error handling, and undo logic won't have to be
re-duplicated on every task. There are also tests for these tasks. We use
them to perform mutating actions on `Metadata` objects.
**New `boundProps` for `InjectedComponents`**: When making the
`N1-Send_later` plugin, I realized that the injected component needed to
get the `cloudState` somehow. Traditionally components would require
Stores and load data that way, but these are setup at `require`-time. Now
that `cloudState` only is available on `activate` we needed a way to get
the data to the components. There's now the concept of `boundProps` which
will be props added to the Component when it gets injected. This required
changing the return signature of `findComponentMatching`, which got
renamed to `findComponentDataMatching`.
**Failing on Promise Rejects**: Turns out that if a Promise rejected
due to an error or `Promise.reject` we were ignoring it and letting tests
pass. Now, tests will Fail if any unhandled promise rejects. This
uncovered a variety of errors throughout the test suite that had to be
fixed. The most significant one was during the `theme-manager` tests when
all packages (and their stores with async DB requests) was loaded. Long
after the `theme-manager` specs finished, those DB requests were
(somtimes) silently failing.
**Globally stub `DatabaseStore._query`**: All tests shouldn't actually
make queries on the database. Furthremore, the `inTransaction` block
doesn't resolve at all unless `_query` is stubbed. Instead of manually
remembering to do this in every test that touches the DB, it's now mocked
in `spec_helper`. This broke a handful of tests that needed to be manually
fixed.
**ESLint Fixes**: Some minor fixes to the linter config to prevent
yelling about minor ES6 things and ensuring we have the correct parser.
Test Plan: new tests
Reviewers: drew, bengotow, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2419
Summary:
- Now behaves exactly like in Gmail:
- If viewing inbox, it will archive or trash, depending on setting
- If viewing starred, will unstar
- If viewing trash, will move to inbox
- If viewing label, will remove label (no folder support)
- No op otherwise
- Updates TaskFactory helpers and adds some helper methods
- Updates specs
Test Plan: - Manual
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2492
In general, we call the functions in AccountStore and CategoryStore / constantly / and inside of critical places like thread list render. Would be nice to create a safe and generic way of caching things and invalidating them when data changes.
- 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
Summary: Send and Archive plus a new setting.
Test Plan: new tests
Reviewers: bengotow, juan
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2446
- Account switcher can now switch between all accounts and each account
- Updates FocusedPerspectiveStore and Actions.focusDefaultMailboxPerspectiveForAccounts
to focus a perspective for accountIds instead of for a single account,
and updates methods
- Adds helpers to CategoryStore and MailboxPerspective
- Updates key commands to allow switch to unified inbox
Summary:
1. **Generic CUD Tasks**: There is now a generic `CreateModelTask`,
`UpdateModelTask`, and `DestroyModelTask`. These can either be used as-is
or trivially overridden to easily update simple objects. Hopefully all of
the boilerplate rollback, error handling, and undo logic won't have to be
re-duplicated on every task. There are also tests for these tasks. We use
them to perform mutating actions on `Metadata` objects.
1. **Failing on Promise Rejects**: Turns out that if a Promise rejected
due to an error or `Promise.reject` we were ignoring it and letting tests
pass. Now, tests will Fail if any unhandled promise rejects. This
uncovered a variety of errors throughout the test suite that had to be
fixed. The most significant one was during the `theme-manager` tests when
all packages (and their stores with async DB requests) was loaded. Long
after the `theme-manager` specs finished, those DB requests were
(somtimes) silently failing.
1. **Globally stub `DatabaseStore._query`**: All tests shouldn't actually
make queries on the database. Furthremore, the `inTransaction` block
doesn't resolve at all unless `_query` is stubbed. Instead of manually
remembering to do this in every test that touches the DB, it's now mocked
in `spec_helper`. This broke a handful of tests that needed to be manually
fixed.
1. **ESLint Fixes**: Some minor fixes to the linter config to prevent
yelling about minor ES6 things and ensuring we have the correct parser.
Test Plan: new tests
Reviewers: bengotow, juan, drew
Differential Revision: https://phab.nylas.com/D2419
Remove cloudState and N1-Send-Later