diff --git a/exports/nylas-store.coffee b/exports/nylas-store.coffee
new file mode 100644
index 000000000..59769ccac
--- /dev/null
+++ b/exports/nylas-store.coffee
@@ -0,0 +1,11 @@
+{Listener, Publisher} = require '../src/flux/modules/reflux-coffee'
+CoffeeHelpers = require '../src/flux/coffee-helpers'
+
+# A simple Flux implementation
+class NylasStore
+ @include: CoffeeHelpers.includeModule
+
+ @include Publisher
+ @include Listener
+
+module.exports = NylasStore
diff --git a/internal_packages/onboarding/lib/connect-account-page.cjsx b/internal_packages/onboarding/lib/connect-account-page.cjsx
new file mode 100644
index 000000000..9fa8dcc77
--- /dev/null
+++ b/internal_packages/onboarding/lib/connect-account-page.cjsx
@@ -0,0 +1,31 @@
+React = require 'react'
+Page = require './page'
+{RetinaImg} = require 'nylas-component-kit'
+{EdgehillAPI} = require 'nylas-exports'
+OnboardingActions = require './onboarding-actions'
+
+class ConnectAccountPage extends Page
+ @displayName: "ConnectAccountPage"
+
+ render: =>
+
+ {@_renderClose("close")}
+
+
+
+
Connect an Account
+
+
+
+
+
Link accounts from other services to supercharge your email.
+
+
+
+
+
+ _fireAuthAccount: (service) =>
+ url = EdgehillAPI.urlForConnecting(service)
+ OnboardingActions.moveToPage "add-account-auth", {url}
+
+module.exports = ConnectAccountPage
diff --git a/internal_packages/onboarding/lib/container-view.cjsx b/internal_packages/onboarding/lib/container-view.cjsx
deleted file mode 100644
index 198734a34..000000000
--- a/internal_packages/onboarding/lib/container-view.cjsx
+++ /dev/null
@@ -1,181 +0,0 @@
-React = require 'react/addons'
-ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
-OnboardingActions = require './onboarding-actions'
-OnboardingStore = require './onboarding-store'
-querystring = require 'querystring'
-{EdgehillAPI} = require 'nylas-exports'
-{RetinaImg} = require 'nylas-component-kit'
-
-class ContainerView extends React.Component
- @displayName: 'ContainerView'
- @containerRequired: false
-
- constructor: (@props) ->
- @state = @getStateFromStore()
-
- getStateFromStore: =>
- page: OnboardingStore.page()
- error: OnboardingStore.error()
- environment: OnboardingStore.environment()
- connectType: OnboardingStore.connectType()
-
- componentDidMount: =>
- @unsubscribe = OnboardingStore.listen(@_onStateChanged, @)
-
- # It's important that every React class explicitly stops listening to
- # atom events before it unmounts. Thank you event-kit
- # This can be fixed via a Reflux mixin
- componentWillUnmount: =>
- @unsubscribe() if @unsubscribe
-
- componentDidUpdate: =>
- webview = @refs['connect-iframe']
- if webview
- node = React.findDOMNode(webview)
- if node.hasListeners is undefined
- # Remove as soon as possible. Initial src is not correctly loaded
- # on webview, and this fixes it. Electron 0.26.0. (Still in 0.28.1)
- setTimeout ->
- node.src = node.src
- ,10
- node.addEventListener 'new-window', (e) ->
- require('shell').openExternal(e.url)
- node.addEventListener 'did-start-loading', (e) ->
- if node.hasMobileUserAgent is undefined
- node.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D167 Safari/9537.53")
- node.hasMobileUserAgent = true
- node.reload()
- node.addEventListener 'did-finish-load', (e) ->
- if node.getUrl().indexOf('/connect/complete') != -1
- query = node.getUrl().split('?')[1]
- query = query[0..-2] if query[query.length - 1] is '#'
- token = querystring.decode(query)
- OnboardingActions.finishedConnect(token)
- if node.getUrl().indexOf('cancelled') != -1
- OnboardingActions.moveToPreviousPage()
-
- render: =>
-
-
- {@_pageComponent()}
-
-
-
-
- _pageComponent: =>
- if @state.error
- alert = {@state.error}
- else
- alert =
-
- if @state.page is 'welcome'
-
-
-
-
-
-
Welcome to Nylas
-
-
-
-
-
-
-
- else if @state.page == 'add-account'
-
-
-
-
-
-
Connect an Account
-
-
-
-
-
-
- else if @state.page == 'add-account-auth'
-
- {
- React.createElement('webview',{
- "ref": "connect-iframe",
- "key": @state.page,
- "src": @_connectWebViewURL()
- })
- }
-
-
-
-
-
- else if @state.page == 'add-account-success'
- # http://codepen.io/stevenfabre/pen/NPWeVb
-
-
- _environmentComponent: =>
- return [] unless atom.inDevMode()
-
-
-
-
- _connectWebViewURL: =>
- EdgehillAPI.urlForConnecting(@state.connectType, @state.email)
-
- _onStateChanged: =>
- @setState(@getStateFromStore())
-
- _onValueChange: (event) =>
- changes = {}
- changes[event.target.id] = event.target.value
- @setState(changes)
-
- _fireDismiss: =>
- atom.close()
-
- _fireQuit: =>
- require('ipc').send('command', 'application:quit')
-
- _fireSetEnvironment: (event) =>
- OnboardingActions.setEnvironment(event.target.value)
-
- _fireStart: (e) =>
- OnboardingActions.startConnect('inbox')
-
- _fireAuthAccount: (service) =>
- OnboardingActions.startConnect(service)
-
- _fireMoveToPage: (page) =>
- OnboardingActions.moveToPage(page)
-
- _fireMoveToPrevPage: =>
- OnboardingActions.moveToPreviousPage()
-
-
-module.exports = ContainerView
diff --git a/internal_packages/onboarding/lib/external-auth-webview-page.cjsx b/internal_packages/onboarding/lib/external-auth-webview-page.cjsx
new file mode 100644
index 000000000..368a8b99e
--- /dev/null
+++ b/internal_packages/onboarding/lib/external-auth-webview-page.cjsx
@@ -0,0 +1,95 @@
+React = require 'react'
+Page = require './page'
+querystring = require 'querystring'
+{RetinaImg} = require 'nylas-component-kit'
+{EdgehillAPI} = require 'nylas-exports'
+OnboardingActions = require './onboarding-actions'
+
+class ExternalAuthWebviewPage extends Page
+ @displayName: "ExternalAuthWebviewPage"
+
+ render: =>
+
+ {
+ React.createElement('webview',{
+ "ref": "connect-iframe",
+ "src": @props.pageData.url
+ "style": {position: "relative", zIndex: 1}
+ })
+ }
+ {@_renderSpinner()}
+ {@_renderAction()}
+
+
+ componentDidMount: =>
+ @_listeners = {}
+ webview = @refs['connect-iframe']
+ return unless webview
+ webview = React.findDOMNode(webview)
+ @_setupWebviewListeners(webview)
+
+ componentWillUnmount: ->
+ webview = @refs['connect-iframe']
+ webview = React.findDOMNode(webview)
+ @_teardownWebviewListeners(webview)
+
+ _fireMoveToPrevPage: =>
+ OnboardingActions.moveToPreviousPage()
+
+ _teardownWebviewListeners: (webview) ->
+ for event, listener of @_listeners
+ webview.removeEventListener event, listener
+
+ _renderAction: ->
+ if @props.pageData.noPreviousPage
+ @_renderClose()
+ else
+
+
+
+
+ _setupWebviewListeners: (webview) ->
+ # Remove as soon as possible. Initial src is not correctly loaded
+ # on webview, and this fixes it. Electron 0.26.0. (Still in 0.28.1)
+ setTimeout ->
+ webview.src = webview.src
+ , 20
+
+ @_listeners =
+ "new-window": (e) ->
+ require('shell').openExternal(e.url)
+ "did-start-loading": (e) =>
+ @_setUserAgent(e, webview)
+ "did-finish-load": (e) =>
+ @_onDidFinishLoad(e, webview)
+
+ for event, listener of @_listeners
+ webview.addEventListener event, listener
+
+ _setUserAgent: (e, webview) ->
+ if webview.hasMobileUserAgent is undefined
+ webview.setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D167 Safari/9537.53")
+ webview.hasMobileUserAgent = true
+ webview.reload()
+
+ _onDidFinishLoad: (e, webview) =>
+ return unless webview
+
+ # We can't use `setState` because that'll blow away the webview :(
+ React.findDOMNode(@refs.spinner).style.visibility = "hidden"
+
+ url = webview.getUrl()
+ if url.indexOf('/connect/complete') != -1
+ query = url.split('?')[1]
+ query = query[0..-2] if query[query.length - 1] is '#'
+ token = querystring.decode(query)
+
+ EdgehillAPI.addTokens([token])
+ OnboardingActions.moveToPage('add-account-success')
+ else if url.indexOf('cancelled') != -1
+ OnboardingActions.moveToPreviousPage()
+
+
+
+module.exports = ExternalAuthWebviewPage
diff --git a/internal_packages/onboarding/lib/login-page.cjsx b/internal_packages/onboarding/lib/login-page.cjsx
new file mode 100644
index 000000000..d120c4950
--- /dev/null
+++ b/internal_packages/onboarding/lib/login-page.cjsx
@@ -0,0 +1,87 @@
+React = require 'react'
+
+{RetinaImg} = require 'nylas-component-kit'
+{EdgehillAPI} = require 'nylas-exports'
+
+Page = require './page'
+OnboardingActions = require './onboarding-actions'
+NylasApiEnvironmentStore = require './nylas-api-environment-store'
+
+class LoginPage extends Page
+ @displayName: "LoginPage"
+
+ constructor: (@props) ->
+ @state =
+ email: ""
+ environment: NylasApiEnvironmentStore.getEnvironment()
+
+ componentDidMount: ->
+ @_usub = NylasApiEnvironmentStore.listen =>
+ @setState environment: NylasApiEnvironmentStore.getEnvironment()
+
+ componentWillUnmount: ->
+ @_usub?()
+
+ render: =>
+
+ {@_renderClose("quit")}
+
+
+
+
Welcome to Nylas
+
+
+
+
+
+
+
+ _renderError: ->
+ if @state.error
+
+ {@state.error}
+
+ else
+
+ _onEmailChange: (event) =>
+ @setState email: event.target.value
+
+ _onSubmit: (e) =>
+ valid = React.findDOMNode(@refs.form).reportValidity()
+ if valid
+ url = EdgehillAPI.urlForConnecting("inbox", @state.email)
+ OnboardingActions.moveToPage("add-account-auth", {url})
+ else
+ e.preventDefault()
+
+ _environmentComponent: =>
+ return unless atom.inDevMode()
+
+
+
+
+ _onEnvChange: (event) =>
+ OnboardingActions.changeAPIEnvironment event.target.value
+
+module.exports = LoginPage
diff --git a/internal_packages/onboarding/lib/main.cjsx b/internal_packages/onboarding/lib/main.cjsx
index 89119beca..2f3c9bbe1 100644
--- a/internal_packages/onboarding/lib/main.cjsx
+++ b/internal_packages/onboarding/lib/main.cjsx
@@ -1,11 +1,14 @@
-ContainerView = require './container-view'
+PageRouter = require "./page-router"
{WorkspaceStore, ComponentRegistry} = require 'nylas-exports'
module.exports =
item: null
activate: (@state) ->
+ # This package does nothing in other windows
+ return unless atom.getWindowType() is 'onboarding'
+
WorkspaceStore.defineSheet 'Main', {root: true},
list: ['Center']
- ComponentRegistry.register ContainerView,
+ ComponentRegistry.register PageRouter,
location: WorkspaceStore.Location.Center
diff --git a/internal_packages/onboarding/lib/nylas-api-environment-store.coffee b/internal_packages/onboarding/lib/nylas-api-environment-store.coffee
new file mode 100644
index 000000000..18efc33bb
--- /dev/null
+++ b/internal_packages/onboarding/lib/nylas-api-environment-store.coffee
@@ -0,0 +1,18 @@
+Actions = require './onboarding-actions'
+NylasStore = require 'nylas-store'
+
+class NylasApiEnvironmentStore extends NylasStore
+ constructor: ->
+ @listenTo Actions.changeAPIEnvironment, @_setEnvironment
+
+ defaultEnv = if atom.inDevMode() then 'staging' else 'staging'
+ @_setEnvironment(defaultEnv) unless atom.config.get('env')
+
+ getEnvironment: -> atom.config.get('env')
+
+ _setEnvironment: (env) ->
+ throw new Error("Environment #{env} is not allowed") unless env in ['development', 'staging', 'production']
+ atom.config.set('env', env)
+ @trigger()
+
+module.exports = new NylasApiEnvironmentStore()
diff --git a/internal_packages/onboarding/lib/onboarding-actions.coffee b/internal_packages/onboarding/lib/onboarding-actions.coffee
index 51e35b01a..0075f44ef 100644
--- a/internal_packages/onboarding/lib/onboarding-actions.coffee
+++ b/internal_packages/onboarding/lib/onboarding-actions.coffee
@@ -1,13 +1,14 @@
Reflux = require 'reflux'
-actions = [
- "setEnvironment",
- "authErrorOccurred",
- "startConnect",
- "finishedConnect",
- "moveToPreviousPage",
+OnboardingActions = Reflux.createActions [
+ "changeAPIEnvironment"
+ "loadExternalAuthPage"
+
+ "moveToPreviousPage"
"moveToPage"
]
-module.exports =
-Actions = Reflux.createActions(actions)
+for key, action of OnboardingActions
+ action.sync = true
+
+module.exports = OnboardingActions
diff --git a/internal_packages/onboarding/lib/onboarding-store.coffee b/internal_packages/onboarding/lib/onboarding-store.coffee
deleted file mode 100644
index 7473cf348..000000000
--- a/internal_packages/onboarding/lib/onboarding-store.coffee
+++ /dev/null
@@ -1,64 +0,0 @@
-Reflux = require 'reflux'
-Actions = require './onboarding-actions'
-{EdgehillAPI} = require 'nylas-exports'
-ipc = require 'ipc'
-
-return unless atom.getWindowType() is "onboarding"
-
-module.exports =
-OnboardingStore = Reflux.createStore
- init: ->
- @_error = ''
- @_page = atom.getLoadSettings().page || 'welcome'
-
- @_pageStack = [@_page]
-
- # For the time being, always use staging
- defaultEnv = if atom.inDevMode() then 'staging' else 'staging'
- atom.config.set('env', defaultEnv) unless atom.config.get('env')
-
- @listenTo Actions.setEnvironment, @_onSetEnvironment
- @listenTo Actions.moveToPreviousPage, @_onMoveToPreviousPage
- @listenTo Actions.moveToPage, @_onMoveToPage
- @listenTo Actions.startConnect, @_onStartConnect
- @listenTo Actions.finishedConnect, @_onFinishedConnect
-
- page: ->
- @_page
-
- error: ->
- @_error
-
- environment: ->
- atom.config.get('env')
-
- connectType: ->
- @_connectType
-
- _onMoveToPreviousPage: ->
- current = @_pageStack.pop()
- prev = @_pageStack.pop()
- @_onMoveToPage(prev)
-
- _onMoveToPage: (page) ->
- @_error = null
- @_pageStack.push(page)
- @_page = page
- @trigger()
-
- _onStartConnect: (service) ->
- @_connectType = service
- @_onMoveToPage('add-account-auth')
-
- _onFinishedConnect: (token) ->
- EdgehillAPI.addTokens([token])
- @_onMoveToPage('add-account-success')
-
- setTimeout ->
- atom.close()
- , 2500
-
- _onSetEnvironment: (env) ->
- throw new Error("Environment #{env} is not allowed") unless env in ['development', 'staging', 'production']
- atom.config.set('env', env)
- @trigger()
diff --git a/internal_packages/onboarding/lib/page-router-store.coffee b/internal_packages/onboarding/lib/page-router-store.coffee
new file mode 100644
index 000000000..77eff3e63
--- /dev/null
+++ b/internal_packages/onboarding/lib/page-router-store.coffee
@@ -0,0 +1,41 @@
+Reflux = require 'reflux'
+OnboardingActions = require './onboarding-actions'
+NylasStore = require 'nylas-store'
+ipc = require 'ipc'
+
+return unless atom.getWindowType() is "onboarding"
+
+class PageRouterStore extends NylasStore
+ constructor: ->
+ atom.onWindowPropsReceived @_onWindowPropsChagned
+
+ @_page = atom.getWindowProps().page ? ''
+ @_pageData = atom.getWindowProps().pageData ? {}
+
+ @_pageStack = [{page: @_page, pageData: @_pageData}]
+
+ @listenTo OnboardingActions.moveToPreviousPage, @_onMoveToPreviousPage
+ @listenTo OnboardingActions.moveToPage, @_onMoveToPage
+
+ _onWindowPropsChagned: ({page, pageData}={}) =>
+ @_onMoveToPage(page, pageData)
+
+ page: -> @_page
+
+ pageData: -> @_pageData
+
+ connectType: ->
+ @_connectType
+
+ _onMoveToPreviousPage: ->
+ current = @_pageStack.pop()
+ prev = @_pageStack.pop()
+ @_onMoveToPage(prev.page, prev.pageData)
+
+ _onMoveToPage: (page, pageData={}) ->
+ @_pageStack.push({page, pageData})
+ @_page = page
+ @_pageData = pageData
+ @trigger()
+
+module.exports = new PageRouterStore()
diff --git a/internal_packages/onboarding/lib/page-router.cjsx b/internal_packages/onboarding/lib/page-router.cjsx
new file mode 100644
index 000000000..78136abc7
--- /dev/null
+++ b/internal_packages/onboarding/lib/page-router.cjsx
@@ -0,0 +1,62 @@
+React = require 'react/addons'
+OnboardingActions = require './onboarding-actions'
+ReactCSSTransitionGroup = React.addons.CSSTransitionGroup
+PageRouterStore = require './page-router-store'
+
+LoginPage = require './login-page'
+ConnectAccountPage = require './connect-account-page'
+ExternalAuthWebviewPage = require './external-auth-webview-page'
+SuccessPage = require './success-page'
+
+class PageRouter extends React.Component
+ @displayName: 'PageRouter'
+ @containerRequired: false
+
+ constructor: (@props) ->
+ @state = @_getStateFromStore()
+ window.OnboardingActions = OnboardingActions
+
+ _getStateFromStore: =>
+ page: PageRouterStore.page()
+ pageData: PageRouterStore.pageData()
+
+ componentDidMount: =>
+ @unsubscribe = PageRouterStore.listen(@_onStateChanged, @)
+
+ _onStateChanged: => @setState(@_getStateFromStore())
+
+ componentWillUnmount: => @unsubscribe?()
+
+ render: =>
+
+
+ {@_renderCurrentPage()}
+ {@_renderDragRegion()}
+
+
+
+ _renderCurrentPage: =>
+ switch @state.page
+ when "welcome"
+
+ when "add-account"
+
+ when "add-account-auth"
+
+ when "add-account-success"
+
+ else
+
+
+ _renderDragRegion: ->
+ styles =
+ top:0
+ left:40
+ right:0
+ height: 20
+ zIndex:100
+ position: 'absolute'
+ "WebkitAppRegion": "drag"
+
+
+module.exports = PageRouter
diff --git a/internal_packages/onboarding/lib/page.cjsx b/internal_packages/onboarding/lib/page.cjsx
new file mode 100644
index 000000000..e69054f07
--- /dev/null
+++ b/internal_packages/onboarding/lib/page.cjsx
@@ -0,0 +1,36 @@
+React = require 'react'
+{RetinaImg} = require 'nylas-component-kit'
+
+class Page extends React.Component
+ @displayName: "Page"
+
+ constructor: (@props) ->
+
+ _renderClose: (action="close") ->
+ if action is "close"
+ onClick = -> atom.close()
+ else if action is "quit"
+ onClick = ->
+ require('ipc').send('command', 'application:quit')
+ else onClick = ->
+
+
+
+
+
+ _renderSpinner: ->
+ styles =
+ position: "absolute"
+ zIndex: 10
+ top: "50%"
+ left: "50%"
+ width: "256px"
+ marginLeft: "-128px"
+ marginTop: "-128px"
+
+
+
+module.exports = Page
diff --git a/internal_packages/onboarding/lib/success-page.cjsx b/internal_packages/onboarding/lib/success-page.cjsx
new file mode 100644
index 000000000..c5b88fda4
--- /dev/null
+++ b/internal_packages/onboarding/lib/success-page.cjsx
@@ -0,0 +1,23 @@
+React = require 'react'
+Page = require './page'
+{RetinaImg} = require 'nylas-component-kit'
+
+class SuccessPage extends Page
+ @displayName: "SuccessPage"
+
+ componentDidMount: ->
+ setTimeout ->
+ atom.close()
+ , 2500
+
+ render: =>
+ # http://codepen.io/stevenfabre/pen/NPWeVb
+
+
+module.exports = SuccessPage
diff --git a/internal_packages/onboarding/package.json b/internal_packages/onboarding/package.json
index cbbd09686..676e88b21 100755
--- a/internal_packages/onboarding/package.json
+++ b/internal_packages/onboarding/package.json
@@ -9,5 +9,8 @@
"atom": "*"
},
"dependencies": {
+ },
+ "windowTypes": {
+ "onboarding": true
}
}
diff --git a/internal_packages/onboarding/spec/login-page-spec.cjsx b/internal_packages/onboarding/spec/login-page-spec.cjsx
new file mode 100644
index 000000000..f051cc956
--- /dev/null
+++ b/internal_packages/onboarding/spec/login-page-spec.cjsx
@@ -0,0 +1,45 @@
+_ = require "underscore"
+React = require "react/addons"
+ReactTestUtils = React.addons.TestUtils
+
+LoginPage = require '../lib/login-page'
+OnboardingActions = require '../lib/onboarding-actions'
+
+describe "LoginPage", ->
+
+ it "shows env picker in Dev Mode", ->
+ spyOn(atom, "inDevMode").andReturn true
+ @loginPage = ReactTestUtils.renderIntoDocument()
+ picker = ReactTestUtils.findRenderedDOMComponentWithClass(@loginPage, "environment-selector")
+ expect(picker).toBeDefined()
+
+ it "hides env picker in other modes", ->
+ spyOn(atom, "inDevMode").andReturn false
+ @loginPage = ReactTestUtils.renderIntoDocument()
+ expect(-> ReactTestUtils.findRenderedDOMComponentWithClass(@loginPage, "environment-selector")).toThrow()
+
+ it 'can change the environment', ->
+ spyOn(atom, "inDevMode").andReturn true
+ spyOn(OnboardingActions, "changeAPIEnvironment")
+ @loginPage = ReactTestUtils.renderIntoDocument()
+ sel = ReactTestUtils.findRenderedDOMComponentWithTag(@loginPage, "select")
+ ReactTestUtils.Simulate.change(sel, {target: {value: 'staging'}})
+ expect(OnboardingActions.changeAPIEnvironment).toHaveBeenCalledWith("staging")
+
+ describe "logging in", ->
+ beforeEach ->
+ @connectURL = "foo"
+ spyOn(OnboardingActions, "moveToPage")
+ @loginPage = ReactTestUtils.renderIntoDocument()
+
+ hasEmail = (email) ->
+ page = OnboardingActions.moveToPage.calls[0].args[0]
+ data = OnboardingActions.moveToPage.calls[0].args[1]
+ expect(page).toBe "add-account-auth"
+ expect(data.url.length).toBeGreaterThan 0
+
+ it "submits information when the form submits", ->
+ @loginPage.setState email: "test@nylas.com"
+ form = ReactTestUtils.findRenderedDOMComponentWithClass(@loginPage, 'email-form')
+ ReactTestUtils.Simulate.submit(form)
+ hasEmail("test@nylas.com")
diff --git a/internal_packages/onboarding/spec/nylas-api-environment-store-spec.coffee b/internal_packages/onboarding/spec/nylas-api-environment-store-spec.coffee
new file mode 100644
index 000000000..c6da261b6
--- /dev/null
+++ b/internal_packages/onboarding/spec/nylas-api-environment-store-spec.coffee
@@ -0,0 +1,35 @@
+Actions = require '../lib/onboarding-actions'
+NylasApiEnvironmentStore = require '../lib/nylas-api-environment-store'
+storeConstructor = NylasApiEnvironmentStore.constructor
+
+describe "NylasApiEnvironmentStore", ->
+ beforeEach ->
+ spyOn(atom.config, "set")
+
+ it "doesn't set if it alreayd exists", ->
+ spyOn(atom.config, "get").andReturn "staging"
+ store = new storeConstructor()
+ expect(atom.config.set).not.toHaveBeenCalled()
+
+ it "initializes with the correct default in dev mode", ->
+ spyOn(atom, "inDevMode").andReturn true
+ spyOn(atom.config, "get").andReturn undefined
+ store = new storeConstructor()
+ expect(atom.config.set).toHaveBeenCalledWith("env", "staging")
+
+ it "initializes with the correct default in production", ->
+ spyOn(atom, "inDevMode").andReturn false
+ spyOn(atom.config, "get").andReturn undefined
+ store = new storeConstructor()
+ expect(atom.config.set).toHaveBeenCalledWith("env", "staging")
+
+ describe "when setting the environment", ->
+ it "sets from the desired action", ->
+ Actions.changeAPIEnvironment("production")
+ expect(atom.config.set).toHaveBeenCalledWith("env", "production")
+
+ it "throws if the env is invalid", ->
+ expect( -> Actions.changeAPIEnvironment("bad")).toThrow()
+
+ it "throws if the env is blank", ->
+ expect( -> Actions.changeAPIEnvironment()).toThrow()
diff --git a/internal_packages/onboarding/stylesheets/onboarding.less b/internal_packages/onboarding/stylesheets/onboarding.less
index c7bc4f9f3..9efcbf6e9 100644
--- a/internal_packages/onboarding/stylesheets/onboarding.less
+++ b/internal_packages/onboarding/stylesheets/onboarding.less
@@ -19,7 +19,7 @@
100% { opacity: 1; border-width: 0; }
}
-.onboarding-container {
+.page-frame {
width:100%;
height:100%;
background-color: @gray-lighter;
@@ -82,6 +82,9 @@
width:100%;
height:100%;
padding-top:15%;
+ &.no-top {
+ padding-top: 0;
+ }
}
.quit {
diff --git a/src/atom.coffee b/src/atom.coffee
index d3d13bdda..647a8a1f4 100644
--- a/src/atom.coffee
+++ b/src/atom.coffee
@@ -607,16 +607,15 @@ class Atom extends Model
@commands.add 'atom-workspace',
'atom-workspace:add-account': =>
- options =
+ @newWindow
title: 'Add an Account'
- page: 'add-account'
width: 340
height: 550
toolbar: false
resizable: false
windowType: 'onboarding'
- windowPackages: ['onboarding']
- ipc.send('new-window', options)
+ windowProps:
+ page: 'add-account'
# Make sure we can't be made so small that the interface looks like crap
@getCurrentWindow().setMinimumSize(875, 500)
diff --git a/src/browser/window-manager.coffee b/src/browser/window-manager.coffee
index 5a857e226..8020e9c87 100644
--- a/src/browser/window-manager.coffee
+++ b/src/browser/window-manager.coffee
@@ -108,9 +108,9 @@ class WindowManager
height: 550
resizable: false
windowType: 'onboarding'
- windowPackages: ['onboarding']
windowProps:
- 'uniqueId': 'onboarding'
+ page: "welcome"
+ uniqueId: 'onboarding'
# Makes a new window appear of a certain `windowType`.
#
@@ -188,7 +188,7 @@ class WindowManager
# - windowPackages - A list of additional packages to load into a
# window in addition to those declared in various `package.json`s
#
- registerHotWindow: ({windowType, replenishNum, windowPackages}={}) ->
+ registerHotWindow: ({windowType, replenishNum, windowPackages, windowOptions}={}) ->
if not windowType
throw new Error("registerHotWindow: please provide a windowType")
@@ -197,6 +197,7 @@ class WindowManager
@_hotWindows[windowType].replenishNum ?= (replenishNum ? 1)
@_hotWindows[windowType].loadedWindows ?= []
@_hotWindows[windowType].windowPackages ?= (windowPackages ? [])
+ @_hotWindows[windowType].windowOptions ?= (windowOptions ? {})
@_replenishHotWindows()
@@ -248,6 +249,8 @@ class WindowManager
newColdWindow: (options={}) ->
options = _.extend(@defaultWindowOptions(), options)
win = new AtomWindow(options)
+ newLoadSettings = _.extend(win.loadSettings(), options)
+ win.setLoadSettings(newLoadSettings)
win.showWhenLoaded()
return win
@@ -262,9 +265,9 @@ class WindowManager
win = null
if not hotWindowParams?
- console.log "WindowManager: Warning! The requested windowType '#{options.windowType}'
- has not been registered. Be sure to call `registerWindowType` first
- in your packages setup."
+ console.log "WindowManager: Warning! The requested windowType
+ '#{options.windowType}' has not been registered. Be sure to call
+ `registerWindowType` first in your packages setup."
return @newColdWindow(options)
supportedHotWindowKeys = [
@@ -279,22 +282,25 @@ class WindowManager
]
unsupported = _.difference(Object.keys(options), supportedHotWindowKeys)
+
if unsupported.length > 0
- console.log "WindowManager: Nylas will open a new hot window of type #{options.windowType},
- but you are passing options that can't be applied to the preloaded window
- (#{JSON.stringify(unsupported)}). Please change the options or pass the
- `coldStart:true` option to use a new window instead of a hot window. If
- it's just data for the window, please put them in the `windowProps` param."
+ console.log "WindowManager: For the winodw of type
+ #{options.windowType}, you are passing options that can't be
+ applied to the preloaded window (#{JSON.stringify(unsupported)}).
+ Please change the options or pass the `coldStart:true` option to use
+ a new window instead of a hot window. If it's just data for the
+ window, please put them in the `windowProps` param."
if hotWindowParams.loadedWindows.length is 0
# No windows ready
+ console.log "No windows ready. Loading a new coldWindow"
options.windowPackages = hotWindowParams.windowPackages
win = @newColdWindow(options)
else
[win] = hotWindowParams.loadedWindows.splice(0,1)
+
newLoadSettings = _.extend(win.loadSettings(), options)
win.setLoadSettings(newLoadSettings)
- win.showWhenLoaded()
win.browserWindow.setTitle options.title ? ""
@@ -307,12 +313,11 @@ class WindowManager
h = options.height ? h
win.browserWindow.setSize(w,h)
- console.log JSON.stringify(options)
if options.bounds
- console.log "------------- SETTING BOUNDS"
- console.log JSON.stringify(options.bounds)
win.browserWindow.setBounds options.bounds
+ win.showWhenLoaded()
+
@_replenishHotWindows()
return win
@@ -340,7 +345,7 @@ class WindowManager
numOfType = data.replenishNum - data.loadedWindows.length
maxWin = Math.max(numOfType, maxWin)
if numOfType > 0
- options = @defaultWindowOptions()
+ options = _.extend {}, @defaultWindowOptions(), data.windowOptions
options.windowType = windowType
options.windowPackages = data.windowPackages
queues[windowType] ?= []
diff --git a/src/flux/coffee-helpers.coffee b/src/flux/coffee-helpers.coffee
index a5defd94e..54d20c874 100644
--- a/src/flux/coffee-helpers.coffee
+++ b/src/flux/coffee-helpers.coffee
@@ -1,6 +1,6 @@
_ = require 'underscore'
-module.exports =
+module.exports = CoffeeHelpers =
# This copied out CoffeeScript
includeModule: (mixin) ->
if not mixin
diff --git a/static/images/empty-state/Setup-Spinner.gif b/static/images/empty-state/Setup-Spinner.gif
new file mode 100644
index 000000000..558316475
Binary files /dev/null and b/static/images/empty-state/Setup-Spinner.gif differ