Summary:
- `from` participants now have their own line
- `to` participants in collapsed mode merge `to`, `cc`, `bcc` as in
gmail, and start in separate line from `from`
- number of `to` participants in collapsed mode is limited, and also overflows
with an ellipsis with css in case its too long
- /some/ cleanup
- Unsuccessfully tried to update the css for the message item header to convert to a flexbox. Wrapping the `from` address when the text is too long is still a TODO
- Fixes#1113
Test Plan: - Manual
Reviewers: bengotow, evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2507
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
Summary:
This implements EditableList re-ordering via a new prop callback.
You can drag and drop items in the mail rules list and the accounts list.
Note that you can't drag between lists - right now this is just to enable
re-ordering.
Test Plan: No new specs yet
Reviewers: evan, juan
Reviewed By: juan
Differential Revision: https://phab.nylas.com/D2495
- This fixes unresponsive draft items in the draft list, i.e. draft
windows would not reopen after opening them the first time.
- The `beforeunload` handler will no longer hide a window before its
actually closed. To reduce visible latency when closing, we moved
saving window state to the `unload` event handler.
- Before unload was hiding the window before actually closing it. A
hidden window causes chromium to throttle its renderer process for
performance, even though `pageVisibility` was set to true (see
https://github.com/atom/electron/issues/3225 for more detils).
NylasEnv.finishUnload is used in this context: When a `beforeunload`
callback prevents the window from closing, it can close it at some point
in the future using finishUnload. NylasEnv.finishUnload uses _.defer to make
sure we don't call `close` inside the `beforeunload` call stack so the
window doesn't go crazy.
However, since _.defer was being called in the renderer process of a
hidden window, the deferred callback execution could end up delayed by
a second or more, which effectively delayed closing the window by a
second.
If we tried to reopen a window with the same window props, e.g. a
draft window, before it was actually closed, the app would go crazy
and wouldn't open it.
So now we just don't hide windows on beforeunload