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
Summary:
You can now break up blockquotes (as in quoted text areas) by pressing
"delete" at the start of a line. This allows you to reply inline.
Test Plan: new tests
Reviewers: bengotow, juan
Reviewed By: bengotow, juan
Differential Revision: https://phab.nylas.com/D2421
- Removes use of observables from category store and keeps a big cache
of categories per account
- Upates Category Observables with new helper observables
- Updates CategoryPicker and AccountSidebarStore to use observables
- Misc fixes
commit 7a67c1fd349c575a91b162024cc03050e86574c9
Author: Ben Gotow <bengotow@gmail.com>
Date: Fri Jan 8 11:14:07 2016 -0800
WIP
commit 891f23487827a447ec95406ef26f1473a0c07de6
Author: Ben Gotow <bengotow@gmail.com>
Date: Wed Jan 6 15:25:09 2016 -0800
WIP
commit 3c323cd4beb2df2fae2439a556d3129404d942cc
Author: Ben Gotow <bengotow@gmail.com>
Date: Mon Jan 4 17:46:11 2016 -0800
WIP
commit ec7090ea9e1969fea2ea583f80a9a2ac41e6c8b0
Author: Ben Gotow <bengotow@gmail.com>
Date: Mon Jan 4 17:22:07 2016 -0800
Remove unused LRUCache
commit e10c3919559d3c364cb7bb94d19094a2444c10f3
Author: Ben Gotow <bengotow@gmail.com>
Date: Mon Jan 4 16:21:37 2016 -0800
rm(database-view): Performance refactor of thread-list
Summary:
This diff removes the old DatabaseView class, which included lots of gross optimizations that have since been duplicated in QuerySubscription and makes the thread list use the QuerySubscription class.
This diff also substantially replaces the QuerySubscription class. The new implementation actually makes more queries but is less gross and more straightforward. It leverages a couple findings from database profiling:
- Because of the sqlite page cache, asking for ids you've previously asked for is very fast.
+ Don't bother sorting in memory to avoid a query, just ask for ids again and fill in any missing objects.
- Loading and inflating models is 4x+ slower than just grabbing ids
I've also added more convenience classes around database queries:
- QueryRange: Represents {offset, limit}, and can do boolean intersections
- QueryResultSet: Better than passing an array of 50 items when you really mean items 150-200. Also tries hard to be immutable.
This diff doesn't fully remove the concept of a "ModelView" because it's used /everywhere/ in the multiselect list source. There's a small shim that we can remove when we refactor that code. Ideally, I think we should rename ModelView to "MultiselectListDataSource" to follow iOS conventions (eg UITableViewDataSource). RIP 80char lines?
Test Plan: They've gone to hell. WIP.
Reviewers: evan, juan
Differential Revision: https://phab.nylas.com/D2408
commit 32607eee8aafb7fa98b866347bdd2c0b963a602c
Author: Ben Gotow <bengotow@gmail.com>
Date: Mon Jan 4 09:56:34 2016 -0800
WIP
commit 5ab5fe74e94db6904bd77d224720ad9fc69fe6a7
Author: Ben Gotow <bengotow@gmail.com>
Date: Wed Dec 30 22:56:46 2015 -0800
redo scrollbars to not require counts
commit 361bb192d072dc8a69fd3ef143cad7bed214ebdc
Author: Ben Gotow <bengotow@gmail.com>
Date: Wed Dec 30 17:50:57 2015 -0800
wip
commit 079394de1cc3344fb6568efe00a52d7fc97fbd27
Author: Ben Gotow <bengotow@gmail.com>
Date: Wed Dec 30 13:49:11 2015 -0800
wip
commit 65142be03c27c653fe1147fdde6c2f9b046ade22
Author: Ben Gotow <bengotow@gmail.com>
Date: Wed Dec 30 01:23:20 2015 -0800
wip
commit 5d412ec276be1104175ad0f43c9d54e1cea857bf
Author: Ben Gotow <bengotow@gmail.com>
Date: Tue Dec 29 22:49:58 2015 -0800
Refactor start
commit d2b6eea884fcd2bd81ebe3985f2b2636a510c493
Author: Ben Gotow <bengotow@gmail.com>
Date: Tue Dec 29 18:51:53 2015 -0800
RIP DatabaseView
Summary:
- WIP: Need to fix tests and some errors!
- Refactors Category class to hold information about its type
- Refactors CategoryStore to rely on observables instead of local caches
- Adds and updates Observables and helpers
- Refactors ContactStore to hold entire cache of contacts instead of per
current account
- Same for ContactRankingStore and other stores
- Refactors method names for AccountStore + some helpers
- Updates MailViewFilter to hold an account
- Adds basic Unified filter
- Replaces AccountStore.current calls with either:
- The account of the currently focused MailViewFilter
- The account associated with a thread, message, file, etc...
- A parameter to be passed in
- Arbitrarily, the first account in the AccountsStore
Test Plan: - Unit tests
Reviewers: evan, bengotow
Differential Revision: https://phab.nylas.com/D2423
Summary:
- Rewrites composer extension adpater to support all versions of the
ComposerExtension API we've ever declared. This will allow old plugins (or
plugins that haven't been reinstalled after update) to keep functioning
without breaking N1
- Adds specs
Test Plan: - Unit tests
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2399
Summary:
- Fixes bug with Composer focus caused by injected component. The composer body
was being focused, but the cursor remained at the beginning of the content
instead of at the end. This was caused because the focus method was being
called before the content had actually been rendered to the dom.
- Adds a callback to check when injected comp was actually rendered, and uses
that to focus the body at the correct time.
- Updates specs
- Updates behavior of focusing composer body when selecting threads in split
mode -- resolves #T3444
- It will focus the body when a thread is selcted via a click
- It wont focus the body when a thread is selected via arrow keys
- It will focus the body when a new inline reply is created
- Updates specs
Test Plan: - Unit tests
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2393
Summary:
Originally, this was going to be a totally independent package, but
I wasn't able to isolate the functionality and get it tied in to
the delta-stream consumption. Here's how it currently works:
- The preferences package has a new tab which allows you to edit
mail filters. Filters are saved in a new core store, and a new
stock component (ScenarioEditor) renders the editor. The editor
takes a set of templates that define a value space, and outputs
a valid set of values.
- A new MailFilterProcessor takes messages and creates tasks to
apply the actions from the MailFiltersStore.
- The worker-sync package now uses the MailFilterProcessor to
apply filters /before/ it calls didPassivelyReceiveNewModels,
so filtrs are applied before any notifications are created.
- A new task, ReprocessMailFiltersTask allows you to run filters
on all of your existing mail. It leverages the existing TaskQueue
architecture to: a) resume where it left off if you quit midway,
b) be queryable (for status) from all windows and c) cancelable.
The TaskQueue is a bit strange because it runs performLocal and
performRemote very differently, and I had to use `performRemote`.
(todo refactor soon.)
This diff also changes the EditableList a bit to behave like a
controlled component and render focused / unfocused states.
Test Plan: Run tests, only for actual filter processing atm.
Reviewers: juan, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2379
Summary:
This provides a new API for `ContenteditableExtension`s. Instead of
manually manipulating the raw DOM and `Selection` objects, there's a new
`Editor` interface that encapsulates it and provides helper methods.
You can now do:
editor.select(someNode).createLink("foo").collapseToEnd()
Now raw methods like `execCommand` ONLY show up in the `Editor` interface
as well as most of the raw `Selection` APIs.
There are also more integration tests :)
Another major goal was cleaning up the contenteditable file itself. To
that end:
1. The DOMNormalizer got pulled out into its own extension
1. The TabManager is now its own extension
1. Url wrangling got moved into the FloatingToolbar control
1. There is now the concept of a `ContenteditableService`, which are
tightly-couple blocks of code separated out into logical units. These are
dependent on the core state, innerState, and props and are not full
extensions.
1. `MouseService` now handles all the click event logic
1. `ClipboardService` was modified to the new service architecture
Test Plan: script/grunt run-integration-tests
Reviewers: drew, juan, bengotow
Reviewed By: juan, bengotow
Differential Revision: https://phab.nylas.com/D2367
Summary:
This is a WIP for the new send draft logic.
I'll add tests then update the diff
Test Plan: todo
Reviewers: bengotow, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2341
Summary:
- The main purpose of this is to be able to properly register the editor for the markdown plugin (and any other plugins to come)
- Refactors ComposerView and Contenteditable ->
- Replaces Contenteditable with an InjectedComponent for a new region role:
"Composer:Editor"
- Creates a new component called ComposerEditor, which is the one that is
being registered by default as "Composer:Editor"
- I used this class to try to standardize the props that should be
passed to any would be editor Component:
- Renamed a bunch of the props which (I think) had a bit of
confusing names
- Added a bunch of docs for these in the source file, although
I feel like those docs should live elsewhere, like in the
ComponentRegion docs.
- In the process, I ended up pulling some stuff out of ComposerView and
some stuff out of the Contenteditable, namely:
- The scrolling logic to ensure that the composer is visible while
typing was moved outside of the Contenteditable -- this feels more
like the ComposerEditor's responsibility, especially since the
Contenteditable is meant to be used in other contexts as well.
- The ComposerExtensions state; it feels less awkward for me if this
is inside the ComposerEditor because 1) ComposerView does less
things, 2) these are actually just being passed to the
Contenteditable, 3) I feel like other plugins shouldn't need to
mess around with ComposerExtensions, so we shouldn't pass them to the
editor. If you register an editor different from our default one,
any other ComposerExtension callbacks will be disabled, which
I feel is expected behavior.
- I think there is still some more refactoring to be done, and I left some TODOS
here and there, but I think this diff is already big enough and its a minimal
set of changes to get the markdown editor working in a not so duck
tapish way.
- New props for InjectedComponent:
- `requiredMethods`: allows you to define a collection of methods that
should be implemented by any Component that registers for your
desired region.
- It will throw an error if these are not implemented
- It will automatically pass calls made on the InjectedComponent to these methods
down to the instance of the actual registered component
- Would love some comments on this approach and impl
- `fallback`: allows you to define a default component to use if none were
registered through the ComponentRegistry
- Misc:
- Added a new test case for the QuotedHTMLTransformer
- Tests:
- They were minimally updated so that they don't break, but a big TODO
is to properly refactor them. I plan to do that in an upcoming
diff.
Test Plan: - Unit tests
Reviewers: bengotow, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2372