Summary:
WIP. I added a collection index to make displaying the threads of a
currently selected participant on the sidebar easy and fast.
The problem is that the `participants` of a thread, while a collection of
`Contact` objects, have no "ids" for those contact objects.
One idea was to create the join table but access contacts by email instead
of id. This required a minor change to the way the data is entered in the
join table.
This means the sidebar can now simply do:
`DatabaseStore.findAll(Thread).where(Thread.attributes.participants.contains('foo@bar.com'))`
While I didn't for this initial test, we could also/instead create the
`Message-Contact` join table. The trick about a Message-Contact table is
that I believe we'd have to create additional columns further specifying
which field we're interested in.
The following two queries:
`DatabaseStore.findAll(Message).where(Message.attributes.to.contains('foo@bar.com'))`
`DatabaseStore.findAll(Message).where(Message.attributes.from.contains('foo@bar.com'))`
would require additional columns in the `Message-Contact` join table
because currently the only columns are `id` and `value`.
In the case of the sidebar use case, I think the Thread participants is
what you want to see anyway.
Unfortunately an email-centric scheme can't distinguish between
`noreply@phab.com <Evan>` and `noreply@phab.com <Juan>`. I actually think
this may be a good thing since I think most people think in terms of email
address as the unique key anyway and for the use case of showing related
emails in the sidebar I'd rather overshow than undershow.
This solution seems to be working pretty well in initial testing, but I
want to see if you guys can think of anything this may subtly screw up
down the line, or if you can think of a simpler way to do this.
Test Plan: todo
Reviewers: juan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2687
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: Themes can now be uninstalled by clicking a button in the theme picker, instead of going to `~/.nylas/packages` to delete the directory.
Test Plan: Tested locally.
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2700
Summary:
Changes the delta code to handle new deltas on the Account object,
which are triggered by changes in sync state indicating various backend
issues. Saves the sync state in a new field on the Account object, which
is persisited in `config.cson`.
Includes several UI changes to display more information when an account has
backend sync issues. Adds better messages and new actions the user can take
based on the type of sync issue.
Additionally, fixes bug in action bridge that was preventing multi-arg global
actions from working.
Test Plan:
Manual, by testing different sync state values and triggering deltas from the
backend
Reviewers: juan, evan, bengotow
Reviewed By: evan, bengotow
Subscribers: khamidou
Differential Revision: https://phab.nylas.com/D2696
Summary:
Add specs to test the components of open tracking and link
tracking. Notably does not test the overall functionality, which
still needs specs.
Test Plan: adds specs
Reviewers: juan, evan, bengotow
Reviewed By: evan, bengotow
Differential Revision: https://phab.nylas.com/D2667
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: Adds a new visual theme picker to the menu that allows users to select different themes based on color palettes and then change their themes live.
Test Plan: Test included.
Reviewers: evan, bengotow
Reviewed By: evan, bengotow
Differential Revision: https://phab.nylas.com/D2669
As of now, link-tracking creates link tracking for every <a> tag, no matter the href attribute. This commit only creates link tracking for valid URLs.
The reason I wrote a new regex instead of rewriting linkTagRegex is that this regex is used by message-list.
https://regex101.com/r/jD5zC7/3 vs https://regex101.com/r/cK0zD8/2Resolves: #1525
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:
This fixes a serious issue where drafts could appear to be sending if
they were located in the same index of the message list as a draft which was
previously sending.
Under the hood this was due to two bad programming choices:
1) State based on props in MessageContainer requires correct implementation of
componentWillReceiveProps. This is definitely an anti-pattern.
2) Using item index rather than clientId as the key for items in the MessageList
caused containers to be given a different message prop when one was inserted,
rather than just shifting the existing ones down and inserting a new one.
Test Plan: Not sure how to test this really...
Reviewers: drew, juan
Differential Revision: https://phab.nylas.com/D2673
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: fix(account): allow users to reconnect accounts if auth has failed
Test Plan: manual
Reviewers: bengotow, juan
Differential Revision: https://phab.nylas.com/D2663
Summary:
Previously we were storing sync cursors in config.cson. They were by
far the most frequently updated piece of data in config. To make things worse,
all the writing was happening in the worker window - the main window was just
seeing the changes on disk and reloading.
I believe there's an edge case which causes the main window to read the config
file when it's mid-write and empty. This causes the accounts array to become
empty in the AccountStore and lots of downstream issues. It's also then possible
for the main window to write a config change of it's own and empty the file
permanently.
Test Plan: A few new tests to make sure this is backwards compatible.
Reviewers: juan, evan
Reviewed By: juan, evan
Differential Revision: https://phab.nylas.com/D2642
Summary:
Now that IMAP auth without SSL is enabled,
those checkboxes that weren't doing anything can come
back.
Test Plan:
This change isn't fully tested and should be thoroughly
inspected (on staging?) before rollout. The N1 end works and sends
parameters correctly, but a 401 prevented local testing of the
interface between N1 auth and sync-engine auth.
Reviewers: bengotow, drew
Reviewed By: drew
Subscribers: kav-ya
Maniphest Tasks: T6666
Differential Revision: https://phab.nylas.com/D2632
- Adds a new InjectedComponentSet for the role 'ThreadList:Label'.
- Adds a new label to the thread list indicating the snooze date if the
thread has been snoozed
- Coerces MailLabel to achieve this. This is a temporary hack, we should
design a better view to display snooze date information
- Rather than have a `showing` prop on the fixed popover, I just remove it and put a span in it's place when it's gone. This means we always get componentDidMount when the popover appears and simplifies when to focus it's content.
- The fixed popover implements esc and blur behaviors itself
- The fixed popover uses the background-secondary color and works in dark mode
- The snooze items have hover and active states
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: The floating toolbar now takes an optional boolean to decide whether it shows the pointer.
Test Plan: Tested locally.
Reviewers: evan
Reviewed By: evan
Differential Revision: https://phab.nylas.com/D2628
Summary: Adjust sizing, padding, etc., to fit better with overall app design.
Test Plan: Tested locally.
Differential Revision: https://phab.nylas.com/D2627
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
Summary:
- Fixes#1223
- Still uses a package in the renderer process to listen to changes in
the unread count and have access to the canvas api.
- Renderer process will write icon to disk and inform main process that
it should update the icon
Test Plan: - Manual
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2613
Summary:
- Add FixedPopover, an absolutely positioned popover component to use for swipe snoozing:
- This component needs to be finished, as its current behavior is primarily for the snooze plugin
- Updates popover.cjsx to properly render pointer for thesnooze popover for the `down` direction
- Adds new design assets
- Adds date input to snooze popover
Test Plan: - TODO
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2624
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.
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 right click menu to the thread list
Moving to folders and labels #TODO
Test Plan: TODO
Reviewers: bengotow, juan
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2609
Summary:
Adds two (very similar) plugins - Open Tracking and Link Tracking.
Both can be enabled via a button in the composer. Open tracking
inserts a tracking pixel right before send, and link tracking replaces
all links with tracked redirects. Both plugins use the new Metadata
service to store their open/click counts, and have backend servers to
respectively serve the pixel image or handle the redirects. Requests
also trigger a metadata update to increment the open/click counters.
Test Plan: Manual for now
Reviewers: evan, bengotow, drew
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2583
Summary:
Some of our users who reauth are getting weird errors from Google — it seems that in some cases Google OAuth doesn’t pass us a `refresh_token`, even though we ask for one by passing `approval_prompt=force` (I’ve landed a commit to log more details about this in edgehill-server —- 6e984ffa26 — but this won’t fix the problem).
Apparently, Google recently « soft-deprecated » `approval_prompt` in favor of a new parameter called `prompt`, which does mostly the same thing (https://developers.google.com/identity/protocols/OAuth2WebServer#formingtheurl)
This diff replaces `approval_prompt` by `prompt`.
Test Plan: Tested by authing a Gmail account and checking that it worked.
Reviewers: bengotow
Reviewed By: bengotow
Subscribers: emfree
Differential Revision: https://phab.nylas.com/D2557
Summary:
- Add initial version of snooze and send later plugins
- Tests are missing since this will probably heavily change before we are done with them
Test Plan: - TODO
Reviewers: drew, bengotow, evan
Reviewed By: bengotow, evan
Differential Revision: https://phab.nylas.com/D2578
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
- This fixes#1354 and #1235
- This issue was caused because the account details preferences
component was keeping as state all of the account object fields. `setState` works
like `extend`, so when the account changed, state was set to the new set of account fields,
but the old values were only removed if they were overriden, and remained the
same if the field did not exist in the new state object.
Specifically, when a new account was added, setState was called with
`{..., defaultAlias: undefined}` which did /not/ remove the the defaultAlias
from the previous state.
- Switched to managing state with a top level key `account`
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
Summary:
Adds tests to the emoji picker.
The emoji picker should also now be able to add emojis consecutively (without spaces).
Finally, the toolbar positioning bug (emoji picker appearing in front of typed text, the toolbar manager appearing in the upper left corner when empty lines are selected) should be fixed so that the toolbar appears directly above/below the selection area.
Test Plan: Tests included in diff.
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2551
Summary:
- Update menus and shortcuts correclt when accounts change or focused
accounts change
- Move menu logic into SidebarCommands to remove duplicated logic
- Make `Window` menu also contain checkboxes
Test Plan: - Manual
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2534
Summary:
- Removes account switcher almost entirely
- Update context menu to edit and delete sidebar items
- Gross hardcoded position and size for the switcher icon -- will likely update with later redesign
Test Plan: - Visual
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2527
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 error message from D2515 is being upgraded to also disable the
continue button so that a user is unable to sync an @gmail.com account
using the IMAP flow.
Test Plan: Tested locally.
Reviewers: bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2516
Summary: Removes the MessageListNotificationBar editable component in favor of the existing MessageListHeaders
Test Plan: Manually built N1 and verified the MessageListNotificationBar no longer appears as editable component.
Reviewers: bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2523
Summary: Corrected the linting errors and changed some of the logic around tracking typed text and triggering properly.
Test Plan: Tested locally.
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2522
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.
Summary:
Users have been configuring their Gmail accounts using the IMAP
authentication method, which causes problems. Attempting to do so will
now create an error message.
Test Plan: Tested locally.
Reviewers: bengotow
Reviewed By: bengotow
Subscribers: mg, emfree
Maniphest Tasks: T6621
Differential Revision: https://phab.nylas.com/D2515
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:
Emojis can now be added in the composer window with colons and the emoji names (referenced by the same names used on Slack/GitHub/etc.).
When using the correct syntax, if there are emojis that match the text typed, they appear in a dropdown floating toolbar.
Selection works with either mouse clicks or arrow keys (plus `Enter`).
Currently, the toolbar won't trigger if the colon is adjacent to a non-whitespace character.
Test Plan: TODO: Will write tests soon!
Reviewers: evan, bengotow
Reviewed By: bengotow
Differential Revision: https://phab.nylas.com/D2505
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