2016-10-04 23:02:11 +08:00
|
|
|
import {shell, ipcRenderer} from 'electron';
|
2016-12-21 20:22:53 +08:00
|
|
|
import {React, Account, AccountStore, Actions} from 'nylas-exports';
|
2016-10-07 01:53:22 +08:00
|
|
|
import {Notification} from 'nylas-component-kit';
|
2016-10-04 23:02:11 +08:00
|
|
|
|
|
|
|
export default class AccountErrorNotification extends React.Component {
|
|
|
|
static displayName = 'AccountErrorNotification';
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
2017-01-20 02:52:52 +08:00
|
|
|
this._checkingTimeout = null
|
|
|
|
this.state = {
|
|
|
|
checking: false,
|
|
|
|
debugKeyPressed: false,
|
|
|
|
accounts: AccountStore.accounts(),
|
|
|
|
}
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
2017-01-20 02:52:52 +08:00
|
|
|
this.unlisten = AccountStore.listen(() => this.setState({
|
|
|
|
accounts: AccountStore.accounts(),
|
|
|
|
}));
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.unlisten();
|
|
|
|
}
|
|
|
|
|
2017-01-20 02:52:52 +08:00
|
|
|
_onContactSupport = (erroredAccount) => {
|
2017-08-17 04:20:54 +08:00
|
|
|
let url = 'https://support.getmerani.com/hc/en-us/requests/new'
|
2017-01-20 02:52:52 +08:00
|
|
|
if (erroredAccount) {
|
|
|
|
url += `?email=${encodeURIComponent(erroredAccount.emailAddress)}`
|
|
|
|
const {syncError} = erroredAccount
|
|
|
|
if (syncError != null) {
|
|
|
|
url += `&subject=${encodeURIComponent('Sync Error')}`
|
|
|
|
const description = encodeURIComponent(
|
|
|
|
`Sync Error:\n\`\`\`\n${JSON.stringify(syncError, null, 2)}\n\`\`\``
|
|
|
|
)
|
|
|
|
url += `&description=${description}`
|
|
|
|
}
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
2017-01-20 02:52:52 +08:00
|
|
|
shell.openExternal(url);
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_onReconnect = (existingAccount) => {
|
2017-02-23 05:49:17 +08:00
|
|
|
ipcRenderer.send('command', 'application:add-account', {existingAccount, source: 'Reconnect from error notification'});
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_onOpenAccountPreferences = () => {
|
|
|
|
Actions.switchPreferencesTab('Accounts');
|
|
|
|
Actions.openPreferences()
|
|
|
|
}
|
|
|
|
|
2017-01-20 02:52:52 +08:00
|
|
|
_onCheckAgain(event, account) {
|
|
|
|
clearTimeout(this._checkingTimeout)
|
|
|
|
this.setState({checking: true})
|
|
|
|
this._checkingTimeout = setTimeout(() => this.setState({checking: false}), 10000)
|
|
|
|
|
2016-12-21 20:22:53 +08:00
|
|
|
if (account) {
|
|
|
|
Actions.wakeLocalSyncWorkerForAccount(account.id)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
const erroredAccounts = this.state.accounts.filter(a => a.hasSyncStateError());
|
|
|
|
erroredAccounts.forEach(acc => Actions.wakeLocalSyncWorkerForAccount(acc.id))
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
[client-app] Correctly show auth error when we can't connect to n1cloud
Summary:
Previously, n1 cloud auth errors were stuffed into an account's
syncState. The problem with that is that the sync loop manages that
state, and as long as the sync loop is running it will set that state to
running. However, it might be the case that the sync loop is running but
we can't connect to n1Cloud, so even though we would set the `syncState`
to `n1_cloud_auth_failed`, the sync loop would just set it back to
'running', and the user wouldn't see the error notification indicating
that it can't connect to n1Cloud
This commit makes it so we keep tracj of the auth failure state for
n1Cloud in a separate field, and makes sure that the error notification
component shows that error.
Test Plan: manual
Reviewers: mark, spang, evan, halla
Reviewed By: evan, halla
Differential Revision: https://phab.nylas.com/D4172
2017-03-10 06:46:54 +08:00
|
|
|
const erroredAccounts = this.state.accounts.filter(a =>
|
|
|
|
a.hasN1CloudError() || a.hasSyncStateError()
|
|
|
|
);
|
2017-01-20 02:52:52 +08:00
|
|
|
const checkAgainLabel = this.state.checking ? 'Checking...' : 'Check Again'
|
2016-10-04 23:02:11 +08:00
|
|
|
let title;
|
|
|
|
let subtitle;
|
|
|
|
let subtitleAction;
|
|
|
|
let actions;
|
|
|
|
if (erroredAccounts.length === 0) {
|
|
|
|
return <span />
|
|
|
|
} else if (erroredAccounts.length > 1) {
|
|
|
|
title = "Several of your accounts are having issues";
|
|
|
|
actions = [{
|
2017-01-20 02:52:52 +08:00
|
|
|
label: checkAgainLabel,
|
|
|
|
fn: (e) => this._onCheckAgain(e),
|
2016-10-04 23:02:11 +08:00
|
|
|
}, {
|
|
|
|
label: "Manage",
|
|
|
|
fn: this._onOpenAccountPreferences,
|
|
|
|
}];
|
|
|
|
} else {
|
|
|
|
const erroredAccount = erroredAccounts[0];
|
[client-app] Correctly show auth error when we can't connect to n1cloud
Summary:
Previously, n1 cloud auth errors were stuffed into an account's
syncState. The problem with that is that the sync loop manages that
state, and as long as the sync loop is running it will set that state to
running. However, it might be the case that the sync loop is running but
we can't connect to n1Cloud, so even though we would set the `syncState`
to `n1_cloud_auth_failed`, the sync loop would just set it back to
'running', and the user wouldn't see the error notification indicating
that it can't connect to n1Cloud
This commit makes it so we keep tracj of the auth failure state for
n1Cloud in a separate field, and makes sure that the error notification
component shows that error.
Test Plan: manual
Reviewers: mark, spang, evan, halla
Reviewed By: evan, halla
Differential Revision: https://phab.nylas.com/D4172
2017-03-10 06:46:54 +08:00
|
|
|
if (erroredAccount.hasN1CloudError()) {
|
2017-08-17 04:20:54 +08:00
|
|
|
title = `Cannot authenticate Merani Cloud Services with ${erroredAccount.emailAddress}`;
|
[client-app] Correctly show auth error when we can't connect to n1cloud
Summary:
Previously, n1 cloud auth errors were stuffed into an account's
syncState. The problem with that is that the sync loop manages that
state, and as long as the sync loop is running it will set that state to
running. However, it might be the case that the sync loop is running but
we can't connect to n1Cloud, so even though we would set the `syncState`
to `n1_cloud_auth_failed`, the sync loop would just set it back to
'running', and the user wouldn't see the error notification indicating
that it can't connect to n1Cloud
This commit makes it so we keep tracj of the auth failure state for
n1Cloud in a separate field, and makes sure that the error notification
component shows that error.
Test Plan: manual
Reviewers: mark, spang, evan, halla
Reviewed By: evan, halla
Differential Revision: https://phab.nylas.com/D4172
2017-03-10 06:46:54 +08:00
|
|
|
actions = [{
|
|
|
|
label: checkAgainLabel,
|
|
|
|
fn: (e) => this._onCheckAgain(e, erroredAccount),
|
|
|
|
}, {
|
|
|
|
label: 'Reconnect',
|
|
|
|
fn: () => this._onReconnect(erroredAccount),
|
|
|
|
}];
|
|
|
|
} else {
|
|
|
|
switch (erroredAccount.syncState) {
|
|
|
|
case Account.SYNC_STATE_AUTH_FAILED:
|
|
|
|
title = `Cannot authenticate with ${erroredAccount.emailAddress}`;
|
|
|
|
actions = [{
|
|
|
|
label: checkAgainLabel,
|
|
|
|
fn: (e) => this._onCheckAgain(e, erroredAccount),
|
|
|
|
}, {
|
|
|
|
label: 'Reconnect',
|
|
|
|
fn: () => this._onReconnect(erroredAccount),
|
|
|
|
}];
|
|
|
|
break;
|
|
|
|
default: {
|
|
|
|
title = `Encountered an error while syncing ${erroredAccount.emailAddress}`;
|
|
|
|
let label = this.state.checking ? 'Retrying...' : 'Try Again'
|
|
|
|
if (this.state.debugKeyPressed) {
|
|
|
|
label = 'Debug'
|
|
|
|
}
|
|
|
|
actions = [{
|
|
|
|
label,
|
|
|
|
fn: (e) => this._onCheckAgain(e, erroredAccount),
|
|
|
|
props: {
|
|
|
|
onMouseEnter: (e) => this.setState({debugKeyPressed: e.metaKey}),
|
|
|
|
onMouseLeave: () => this.setState({debugKeyPressed: false}),
|
|
|
|
},
|
|
|
|
}];
|
2017-01-20 02:52:52 +08:00
|
|
|
}
|
|
|
|
}
|
2016-10-04 23:02:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Notification
|
|
|
|
priority="3"
|
|
|
|
isError
|
|
|
|
title={title}
|
|
|
|
subtitle={subtitle}
|
|
|
|
subtitleAction={subtitleAction}
|
|
|
|
actions={actions}
|
|
|
|
icon="volstead-error.png"
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|