mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-11-10 00:11:34 +08:00
Add subscription tab
This commit is contained in:
parent
bd4c25405a
commit
c4f9dfb4e4
11 changed files with 229 additions and 43 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
import OnboardingActions from './onboarding-actions';
|
import OnboardingActions from './onboarding-actions';
|
||||||
import {AccountStore, Actions, NylasAPI} from 'nylas-exports';
|
import {AccountStore, Actions, IdentityStore} from 'nylas-exports';
|
||||||
import {shell, ipcRenderer} from 'electron';
|
import {shell, ipcRenderer} from 'electron';
|
||||||
import NylasStore from 'nylas-store';
|
import NylasStore from 'nylas-store';
|
||||||
import AccountTypes from './account-types';
|
import {accountTypeForProvider} from './account-types';
|
||||||
import {buildWelcomeURL} from './onboarding-helpers';
|
import {buildWelcomeURL} from './onboarding-helpers';
|
||||||
|
|
||||||
class OnboardingStore extends NylasStore {
|
class OnboardingStore extends NylasStore {
|
||||||
|
|
@ -16,23 +16,22 @@ class OnboardingStore extends NylasStore {
|
||||||
this.listenTo(OnboardingActions.setAccountInfo, this._onSetAccountInfo);
|
this.listenTo(OnboardingActions.setAccountInfo, this._onSetAccountInfo);
|
||||||
this.listenTo(OnboardingActions.setAccountType, this._onSetAccountType);
|
this.listenTo(OnboardingActions.setAccountType, this._onSetAccountType);
|
||||||
|
|
||||||
const {page, existingAccount} = NylasEnv.getWindowProps();
|
const {existingAccount} = NylasEnv.getWindowProps();
|
||||||
|
|
||||||
if (existingAccount) {
|
if (existingAccount) {
|
||||||
|
const accountType = accountTypeForProvider(existingAccount.provider);
|
||||||
this._pageStack = ['account-choose']
|
this._pageStack = ['account-choose']
|
||||||
this._accountInfo = {
|
this._accountInfo = {
|
||||||
name: existingAccount.name,
|
name: existingAccount.name,
|
||||||
email: existingAccount.email,
|
email: existingAccount.emailAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
const accountType = AccountTypes.accountTypeForProvider(existingAccount.provider);
|
|
||||||
this._onSetAccountType(accountType);
|
this._onSetAccountType(accountType);
|
||||||
} else {
|
} else {
|
||||||
this._pageStack = [page || 'welcome'];
|
const identity = IdentityStore.identity();
|
||||||
const N1Account = NylasAPI.N1UserAccount();
|
this._pageStack = ['welcome'];
|
||||||
if (N1Account) {
|
if (identity) {
|
||||||
this._accountInfo = {
|
this._accountInfo = {
|
||||||
name: `${N1Account.firstname || ""} ${N1Account.lastname || ""}`,
|
name: `${identity.firstname || ""} ${identity.lastname || ""}`,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this._accountInfo = {};
|
this._accountInfo = {};
|
||||||
|
|
@ -81,7 +80,7 @@ class OnboardingStore extends NylasStore {
|
||||||
_onAuthenticationJSONReceived = (json) => {
|
_onAuthenticationJSONReceived = (json) => {
|
||||||
const isFirstAccount = AccountStore.accounts().length === 0;
|
const isFirstAccount = AccountStore.accounts().length === 0;
|
||||||
|
|
||||||
NylasAPI.setN1UserAccount(json);
|
Actions.setNylasIdentity(json);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (isFirstAccount) {
|
if (isFirstAccount) {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {RetinaImg} from 'nylas-component-kit';
|
||||||
import OnboardingActions from './onboarding-actions';
|
import OnboardingActions from './onboarding-actions';
|
||||||
import networkErrors from 'chromium-net-errors';
|
import networkErrors from 'chromium-net-errors';
|
||||||
|
|
||||||
class AuthenticateLoadingCover extends React.Component {
|
class InitialLoadingCover extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
ready: React.PropTypes.bool,
|
ready: React.PropTypes.bool,
|
||||||
error: React.PropTypes.string,
|
error: React.PropTypes.string,
|
||||||
|
|
@ -40,7 +40,7 @@ class AuthenticateLoadingCover extends React.Component {
|
||||||
if (this.props.error) {
|
if (this.props.error) {
|
||||||
message = this.props.error;
|
message = this.props.error;
|
||||||
} else if (this.state.slow) {
|
} else if (this.state.slow) {
|
||||||
message = "Still trying to reach Nylas.com...";
|
message = "Still trying to reach Nylas…";
|
||||||
} else {
|
} else {
|
||||||
message = ' '
|
message = ' '
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ export default class AuthenticatePage extends React.Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const webview = ReactDOM.findDOMNode(this.refs.webview);
|
const webview = ReactDOM.findDOMNode(this.refs.webview);
|
||||||
webview.src = "https://billing-staging.nylas.com/onboarding";
|
webview.src = `${IdentityStore.URLRoot}/onboarding`;
|
||||||
webview.addEventListener('did-start-loading', this.webviewDidStartLoading);
|
webview.addEventListener('did-start-loading', this.webviewDidStartLoading);
|
||||||
webview.addEventListener('did-fail-load', this.webviewDidFailLoad);
|
webview.addEventListener('did-fail-load', this.webviewDidFailLoad);
|
||||||
webview.addEventListener('did-finish-load', this.webviewDidFinishLoad);
|
webview.addEventListener('did-finish-load', this.webviewDidFinishLoad);
|
||||||
|
|
@ -94,7 +94,7 @@ export default class AuthenticatePage extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
webviewDidStartLoading = () => {
|
webviewDidStartLoading = () => {
|
||||||
this.setState({error: null});
|
this.setState({error: null, webviewLoading: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
webviewDidFailLoad = ({errorCode, errorDescription, validatedURL}) => {
|
webviewDidFailLoad = ({errorCode, errorDescription, validatedURL}) => {
|
||||||
|
|
@ -108,7 +108,7 @@ export default class AuthenticatePage extends React.Component {
|
||||||
const e = networkErrors.createByCode(errorCode);
|
const e = networkErrors.createByCode(errorCode);
|
||||||
error = `Could not reach ${validatedURL}. ${e ? e.message : errorCode}`;
|
error = `Could not reach ${validatedURL}. ${e ? e.message : errorCode}`;
|
||||||
}
|
}
|
||||||
this.setState({ready: false, error: error});
|
this.setState({ready: false, error: error, webviewLoading: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
webviewDidFinishLoad = () => {
|
webviewDidFinishLoad = () => {
|
||||||
|
|
@ -122,7 +122,7 @@ export default class AuthenticatePage extends React.Component {
|
||||||
|
|
||||||
const webview = ReactDOM.findDOMNode(this.refs.webview);
|
const webview = ReactDOM.findDOMNode(this.refs.webview);
|
||||||
webview.executeJavaScript(js, false, (result) => {
|
webview.executeJavaScript(js, false, (result) => {
|
||||||
this.setState({ready: true});
|
this.setState({ready: true, webviewLoading: false});
|
||||||
if (result !== null) {
|
if (result !== null) {
|
||||||
OnboardingActions.authenticationJSONReceived(JSON.parse(result));
|
OnboardingActions.authenticationJSONReceived(JSON.parse(result));
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +133,14 @@ export default class AuthenticatePage extends React.Component {
|
||||||
return (
|
return (
|
||||||
<div className="page authenticate">
|
<div className="page authenticate">
|
||||||
<webview ref="webview"></webview>
|
<webview ref="webview"></webview>
|
||||||
<AuthenticateLoadingCover
|
<div className={`webview-loading-spinner loading-${this.state.webviewLoading}`}>
|
||||||
|
<RetinaImg
|
||||||
|
style={{width: 20, height: 20}}
|
||||||
|
name="inline-loading-spinner.gif"
|
||||||
|
mode={RetinaImg.Mode.ContentPreserve}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<InitialLoadingCover
|
||||||
ready={this.state.ready}
|
ready={this.state.ready}
|
||||||
error={this.state.error}
|
error={this.state.error}
|
||||||
onTryAgain={this.onTryAgain}
|
onTryAgain={this.onTryAgain}
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@
|
||||||
|
|
||||||
label[for=subscribe-check] {
|
label[for=subscribe-check] {
|
||||||
color: black;
|
color: black;
|
||||||
|
white-space: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
label.checkbox {
|
label.checkbox {
|
||||||
|
|
@ -174,7 +175,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.page.authenticate {
|
.page.authenticate {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -184,6 +184,18 @@
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.webview-loading-spinner {
|
||||||
|
position: absolute;
|
||||||
|
right: 17px;
|
||||||
|
top: 17px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 200ms ease-in-out;
|
||||||
|
transition-delay: 200ms;
|
||||||
|
&.loading-true {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.webview-cover {
|
.webview-cover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import PreferencesAccounts from './tabs/preferences-accounts';
|
||||||
import PreferencesAppearance from './tabs/preferences-appearance';
|
import PreferencesAppearance from './tabs/preferences-appearance';
|
||||||
import PreferencesKeymaps from './tabs/preferences-keymaps';
|
import PreferencesKeymaps from './tabs/preferences-keymaps';
|
||||||
import PreferencesMailRules from './tabs/preferences-mail-rules';
|
import PreferencesMailRules from './tabs/preferences-mail-rules';
|
||||||
|
import PreferencesIdentity from './tabs/preferences-identity';
|
||||||
|
|
||||||
export function activate() {
|
export function activate() {
|
||||||
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
||||||
|
|
@ -23,23 +23,29 @@ export function activate() {
|
||||||
component: PreferencesAccounts,
|
component: PreferencesAccounts,
|
||||||
order: 2,
|
order: 2,
|
||||||
}))
|
}))
|
||||||
|
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
||||||
|
tabId: 'Subscription',
|
||||||
|
displayName: 'Subscription',
|
||||||
|
component: PreferencesIdentity,
|
||||||
|
order: 3,
|
||||||
|
}))
|
||||||
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
||||||
tabId: 'Appearance',
|
tabId: 'Appearance',
|
||||||
displayName: 'Appearance',
|
displayName: 'Appearance',
|
||||||
component: PreferencesAppearance,
|
component: PreferencesAppearance,
|
||||||
order: 3,
|
order: 4,
|
||||||
}))
|
}))
|
||||||
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
||||||
tabId: 'Shortcuts',
|
tabId: 'Shortcuts',
|
||||||
displayName: 'Shortcuts',
|
displayName: 'Shortcuts',
|
||||||
component: PreferencesKeymaps,
|
component: PreferencesKeymaps,
|
||||||
order: 4,
|
order: 5,
|
||||||
}))
|
}))
|
||||||
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
PreferencesUIStore.registerPreferencesTab(new PreferencesUIStore.TabItem({
|
||||||
tabId: 'Mail Rules',
|
tabId: 'Mail Rules',
|
||||||
displayName: 'Mail Rules',
|
displayName: 'Mail Rules',
|
||||||
component: PreferencesMailRules,
|
component: PreferencesMailRules,
|
||||||
order: 5,
|
order: 6,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
WorkspaceStore.defineSheet('Preferences', {}, {
|
WorkspaceStore.defineSheet('Preferences', {}, {
|
||||||
|
|
|
||||||
105
internal_packages/preferences/lib/tabs/preferences-identity.jsx
Normal file
105
internal_packages/preferences/lib/tabs/preferences-identity.jsx
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {shell} from 'electron';
|
||||||
|
import {RetinaImg} from 'nylas-component-kit';
|
||||||
|
import {IdentityStore} from 'nylas-exports';
|
||||||
|
import request from 'request';
|
||||||
|
|
||||||
|
class OpenIdentityPageButton extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
destination: React.PropTypes.string,
|
||||||
|
label: React.PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_onClick = () => {
|
||||||
|
const identity = IdentityStore.identity();
|
||||||
|
if (!identity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.props.destination.startsWith('/')) {
|
||||||
|
throw new Error("destination must start with a leading slash.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({loading: true});
|
||||||
|
|
||||||
|
request({
|
||||||
|
method: 'POST',
|
||||||
|
url: `${IdentityStore.URLRoot}/n1/login-link`,
|
||||||
|
json: true,
|
||||||
|
body: {
|
||||||
|
destination: this.props.destination,
|
||||||
|
account_token: identity.token,
|
||||||
|
},
|
||||||
|
}, (error, response = {}, body) => {
|
||||||
|
this.setState({loading: false});
|
||||||
|
if (error || !body.startsWith('http')) {
|
||||||
|
// Single-sign on attempt failed. Rather than churn the user right here,
|
||||||
|
// at least try to open the page directly in the browser.
|
||||||
|
shell.openExternal(`${IdentityStore.URLRoot}${this.props.destination}`);
|
||||||
|
} else {
|
||||||
|
shell.openExternal(body);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.loading) {
|
||||||
|
return (
|
||||||
|
<div className="btn btn-disabled">
|
||||||
|
<RetinaImg name="sending-spinner.gif" width={15} height={15} mode={RetinaImg.Mode.ContentPreserve} />
|
||||||
|
{this.props.label}…
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="btn" onClick={this._onClick}>{this.props.label}</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PreferencesIdentity extends React.Component {
|
||||||
|
|
||||||
|
static displayName = 'PreferencesIdentity';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = this.getStateFromStores();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.unsubscribe = IdentityStore.listen(() => {
|
||||||
|
this.setState(this.getStateFromStores());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
getStateFromStores() {
|
||||||
|
return {
|
||||||
|
identity: IdentityStore.identity(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="container-identity">
|
||||||
|
<div className="identity-content">
|
||||||
|
{JSON.stringify(this.state.identity)}
|
||||||
|
<OpenIdentityPageButton label="Go to web" destination="/billing" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PreferencesIdentity;
|
||||||
|
|
@ -198,26 +198,31 @@ export default class Application extends EventEmitter {
|
||||||
} else {
|
} else {
|
||||||
this.windowManager.ensureWindow(WindowManager.ONBOARDING_WINDOW, {
|
this.windowManager.ensureWindow(WindowManager.ONBOARDING_WINDOW, {
|
||||||
title: "Welcome to N1",
|
title: "Welcome to N1",
|
||||||
windowProps: {
|
|
||||||
page: "welcome",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
this.windowManager.ensureWindow(WindowManager.WORK_WINDOW);
|
this.windowManager.ensureWindow(WindowManager.WORK_WINDOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_resetConfigAndRelaunch = () => {
|
_relaunchToInitialWindows = ({resetConfig, resetDatabase} = {}) => {
|
||||||
this.setDatabasePhase('close');
|
this.setDatabasePhase('close');
|
||||||
this.windowManager.destroyAllWindows();
|
this.windowManager.destroyAllWindows();
|
||||||
this._deleteDatabase(() => {
|
|
||||||
|
let fn = (callback) => callback()
|
||||||
|
if (resetDatabase) {
|
||||||
|
fn = this._deleteDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn(() => {
|
||||||
|
if (resetConfig) {
|
||||||
this.config.set('nylas', null);
|
this.config.set('nylas', null);
|
||||||
this.config.set('edgehill', null);
|
this.config.set('edgehill', null);
|
||||||
|
}
|
||||||
this.setDatabasePhase('setup');
|
this.setDatabasePhase('setup');
|
||||||
this.openWindowsForTokenState();
|
this.openWindowsForTokenState();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_deleteDatabase(callback) {
|
_deleteDatabase = (callback) => {
|
||||||
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db'), callback);
|
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db'), callback);
|
||||||
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db-wal'));
|
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db-wal'));
|
||||||
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db-shm'));
|
this.deleteFileWithRetry(path.join(this.configDirPath, 'edgehill.db-shm'));
|
||||||
|
|
@ -293,7 +298,7 @@ export default class Application extends EventEmitter {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('application:reset-config-and-relaunch', this._resetConfigAndRelaunch);
|
this.on('application:relaunch-to-initial-windows', this._relaunchToInitialWindows);
|
||||||
|
|
||||||
this.on('application:quit', () => {
|
this.on('application:quit', () => {
|
||||||
app.quit()
|
app.quit()
|
||||||
|
|
@ -310,12 +315,10 @@ export default class Application extends EventEmitter {
|
||||||
this.on('application:add-account', ({existingAccount} = {}) => {
|
this.on('application:add-account', ({existingAccount} = {}) => {
|
||||||
this.windowManager.ensureWindow(WindowManager.ONBOARDING_WINDOW, {
|
this.windowManager.ensureWindow(WindowManager.ONBOARDING_WINDOW, {
|
||||||
title: "Add an Account",
|
title: "Add an Account",
|
||||||
windowProps: {
|
windowProps: { existingAccount },
|
||||||
page: "account-choose",
|
|
||||||
pageData: {existingAccount},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('application:new-message', () => {
|
this.on('application:new-message', () => {
|
||||||
this.windowManager.sendToWindow(WindowManager.MAIN_WINDOW, 'new-message');
|
this.windowManager.sendToWindow(WindowManager.MAIN_WINDOW, 'new-message');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,12 @@ class Actions
|
||||||
###
|
###
|
||||||
@clearDeveloperConsole: ActionScopeWindow
|
@clearDeveloperConsole: ActionScopeWindow
|
||||||
|
|
||||||
|
###
|
||||||
|
Public: Manage the Nylas identity
|
||||||
|
###
|
||||||
|
@setNylasIdentity: ActionScopeWindow
|
||||||
|
@logoutNylasIdentity: ActionScopeWindow
|
||||||
|
|
||||||
###
|
###
|
||||||
Public: Remove the selected account
|
Public: Remove the selected account
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,12 +59,6 @@ class NylasAPI
|
||||||
NylasEnv.config.onDidChange('env', @_onConfigChanged)
|
NylasEnv.config.onDidChange('env', @_onConfigChanged)
|
||||||
@_onConfigChanged()
|
@_onConfigChanged()
|
||||||
|
|
||||||
N1UserAccount: =>
|
|
||||||
NylasEnv.config.get('nylas.identity')
|
|
||||||
|
|
||||||
setN1UserAccount: (n1Account) =>
|
|
||||||
NylasEnv.config.set('nylas.identity', n1Account)
|
|
||||||
|
|
||||||
_onConfigChanged: =>
|
_onConfigChanged: =>
|
||||||
prev = {@AppID, @APIRoot, @APITokens}
|
prev = {@AppID, @APIRoot, @APITokens}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,9 @@ class AccountStore extends NylasStore
|
||||||
|
|
||||||
if remainingAccounts.length is 0
|
if remainingAccounts.length is 0
|
||||||
ipc = require('electron').ipcRenderer
|
ipc = require('electron').ipcRenderer
|
||||||
ipc.send('command', 'application:reset-config-and-relaunch')
|
ipc.send('command', 'application:relaunch-to-initial-windows', {
|
||||||
|
resetDatabase: true,
|
||||||
|
})
|
||||||
|
|
||||||
_onReorderAccount: (id, newIdx) =>
|
_onReorderAccount: (id, newIdx) =>
|
||||||
existingIdx = _.findIndex @_accounts, (a) -> a.id is id
|
existingIdx = _.findIndex @_accounts, (a) -> a.id is id
|
||||||
|
|
|
||||||
51
src/flux/stores/identity-store.es6
Normal file
51
src/flux/stores/identity-store.es6
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
import NylasStore from 'nylas-store';
|
||||||
|
import Actions from '../actions';
|
||||||
|
import keytar from 'keytar';
|
||||||
|
import {ipcRenderer} from 'electron';
|
||||||
|
|
||||||
|
const configIdentityKey = "nylas.identity";
|
||||||
|
const keytarServiceName = 'Nylas';
|
||||||
|
const keytarIdentityKey = 'Nylas Account';
|
||||||
|
|
||||||
|
class IdentityStore extends NylasStore {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.URLRoot = "https://billing-staging.nylas.com";
|
||||||
|
|
||||||
|
this.listenTo(Actions.setNylasIdentity, this._onSetNylasIdentity);
|
||||||
|
this.listenTo(Actions.logoutNylasIdentity, this._onLogoutNylasIdentity);
|
||||||
|
|
||||||
|
NylasEnv.config.onDidChange(configIdentityKey, () => {
|
||||||
|
this._loadIdentity();
|
||||||
|
this.trigger();
|
||||||
|
});
|
||||||
|
this._loadIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadIdentity() {
|
||||||
|
this._identity = NylasEnv.config.get(configIdentityKey);
|
||||||
|
if (this._identity) {
|
||||||
|
this._identity.token = keytar.getPassword(keytarServiceName, keytarIdentityKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
identity() {
|
||||||
|
return this._identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onLogoutNylasIdentity = () => {
|
||||||
|
keytar.deletePassword(keytarServiceName, keytarIdentityKey);
|
||||||
|
NylasEnv.config.unset(configIdentityKey);
|
||||||
|
ipcRenderer.send('command', 'application:relaunch-to-initial-windows');
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSetNylasIdentity = (identity) => {
|
||||||
|
keytar.replacePassword(keytarServiceName, keytarIdentityKey, identity.token);
|
||||||
|
delete identity.token;
|
||||||
|
NylasEnv.config.set(configIdentityKey, identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new IdentityStore()
|
||||||
|
|
@ -122,6 +122,7 @@ class NylasExports
|
||||||
@lazyLoadAndRegisterStore "AccountStore", 'account-store'
|
@lazyLoadAndRegisterStore "AccountStore", 'account-store'
|
||||||
@lazyLoadAndRegisterStore "MessageStore", 'message-store'
|
@lazyLoadAndRegisterStore "MessageStore", 'message-store'
|
||||||
@lazyLoadAndRegisterStore "ContactStore", 'contact-store'
|
@lazyLoadAndRegisterStore "ContactStore", 'contact-store'
|
||||||
|
@lazyLoadAndRegisterStore "IdentityStore", 'identity-store'
|
||||||
@lazyLoadAndRegisterStore "MetadataStore", 'metadata-store'
|
@lazyLoadAndRegisterStore "MetadataStore", 'metadata-store'
|
||||||
@lazyLoadAndRegisterStore "CategoryStore", 'category-store'
|
@lazyLoadAndRegisterStore "CategoryStore", 'category-store'
|
||||||
@lazyLoadAndRegisterStore "UndoRedoStore", 'undo-redo-store'
|
@lazyLoadAndRegisterStore "UndoRedoStore", 'undo-redo-store'
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue