Merge branch 'master' of github.com:nylas/N1

This commit is contained in:
dillon 2015-10-02 15:38:57 -07:00
commit 66c3b0c4e6
13 changed files with 33 additions and 28 deletions

View file

@ -5,17 +5,15 @@ Section: Guides
Order: 7 Order: 7
--- ---
# Writing specs
Nylas uses [Jasmine](http://jasmine.github.io/1.3/introduction.html) as its spec framework. As a package developer, you can write specs using Jasmine 1.3 and get some quick wins. Jasmine specs can be run in N1 directly from the Developer menu, and the test environment provides you with helpful stubs. You can also require your own test framework, or use Jasmine for integration tests and your own framework for your existing business logic. Nylas uses [Jasmine](http://jasmine.github.io/1.3/introduction.html) as its spec framework. As a package developer, you can write specs using Jasmine 1.3 and get some quick wins. Jasmine specs can be run in N1 directly from the Developer menu, and the test environment provides you with helpful stubs. You can also require your own test framework, or use Jasmine for integration tests and your own framework for your existing business logic.
This documentation describes using [Jasmine 1.3](http://jasmine.github.io/1.3/introduction.html) to write specs for a Nylas package. This documentation describes using [Jasmine 1.3](http://jasmine.github.io/1.3/introduction.html) to write specs for a Nylas package.
#### Running Specs ### Running Specs
You can run your package specs from `Developer > Run Package Specs...`. Once you've opened the spec window, you can see output and re-run your specs by clicking `Reload Specs`. You can run your package specs from `Developer > Run Package Specs...`. Once you've opened the spec window, you can see output and re-run your specs by clicking `Reload Specs`.
#### Writing Specs ### Writing Specs
To create specs, place `js`, `coffee`, or `cjsx` files in the `spec` directory of your package. Spec files must end with the `-spec` suffix. To create specs, place `js`, `coffee`, or `cjsx` files in the `spec` directory of your package. Spec files must end with the `-spec` suffix.

View file

@ -322,7 +322,8 @@ class CategoryPicker extends React.Component
_isUserFacing: (allInInbox, category) => _isUserFacing: (allInInbox, category) =>
hiddenCategories = [] hiddenCategories = []
currentCategoryId = FocusedMailViewStore.mailView().categoryId() currentCategoryId = FocusedMailViewStore.mailView()?.categoryId()
if @_account?.usesLabels() if @_account?.usesLabels()
hiddenCategories = ["all", "spam", "trash", "drafts", "sent"] hiddenCategories = ["all", "spam", "trash", "drafts", "sent"]
if allInInbox if allInInbox

View file

@ -90,7 +90,7 @@ class ActivitySidebar extends React.Component
<RetinaImg name="sending-spinner.gif" width={18} mode={RetinaImg.Mode.ContentPreserve} /> <RetinaImg name="sending-spinner.gif" width={18} mode={RetinaImg.Mode.ContentPreserve} />
</div> </div>
<div className="inner"> <div className="inner">
Syncing mail data&hellip; Syncing your mailbox&hellip;
</div> </div>
</div> </div>

View file

@ -55,7 +55,7 @@ class InitialSyncActivity extends React.Component
else else
<div className={classSet} key="initial-sync" onClick={=> @setState expandedSync: !@state.expandedSync}> <div className={classSet} key="initial-sync" onClick={=> @setState expandedSync: !@state.expandedSync}>
{@_renderProgressBar(totalProgress)} {@_renderProgressBar(totalProgress)}
<div className="inner">Syncing mail data&hellip;</div> <div className="inner">Syncing your mailbox&hellip;</div>
{@_expandedSyncState()} {@_expandedSyncState()}
</div> </div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -30,7 +30,7 @@ class AccountChoosePage extends React.Component
<RetinaImg name="onboarding-close.png" mode={RetinaImg.Mode.ContentPreserve}/> <RetinaImg name="onboarding-close.png" mode={RetinaImg.Mode.ContentPreserve}/>
</div> </div>
<RetinaImg url="nylas://onboarding/assets/nylas-pictograph@2x.png" mode={RetinaImg.Mode.ContentIsMask} style={zoom: 0.29} className="logo"/> <RetinaImg url="nylas://onboarding/assets/nylas-pictographB@2x.png" mode={RetinaImg.Mode.ContentPreserve} style={zoom: 0.29, opacity: 0.55} className="logo"/>
<div className="caption" style={marginTop: 15, marginBottom:20}>Select your email provider</div> <div className="caption" style={marginTop: 15, marginBottom:20}>Select your email provider</div>

View file

@ -79,11 +79,16 @@ class AccountSettingsPage extends React.Component
_onSettingsChanged: (event) => _onSettingsChanged: (event) =>
field = event.target.dataset.field field = event.target.dataset.field
format = event.target.dataset.format
int_formatter = (a) ->
i = parseInt(a)
if isNaN(i) then "" else i
formatter = if format is 'integer' then int_formatter else (a) -> a
settings = @state.settings settings = @state.settings
if event.target.type is 'checkbox' if event.target.type is 'checkbox'
settings[field] = event.target.checked settings[field] = event.target.checked
else else
settings[field] = event.target.value settings[field] = formatter(event.target.value)
@setState({settings}) @setState({settings})
_onValueChanged: (event) => _onValueChanged: (event) =>
@ -94,7 +99,11 @@ class AccountSettingsPage extends React.Component
_onFieldKeyPress: (event) => _onFieldKeyPress: (event) =>
if event.key in ['Enter', 'Return'] if event.key in ['Enter', 'Return']
@_onSubmit() pages = @state.provider.pages || []
if pages.length > @state.pageNumber+1
@_onNextButton()
else
@_onSubmit()
_renderTitle: => _renderTitle: =>
if @state.provider.name is 'gmail' if @state.provider.name is 'gmail'
@ -129,6 +138,7 @@ class AccountSettingsPage extends React.Component
onChange={@_onValueChanged} onChange={@_onValueChanged}
onKeyPress={@_onFieldKeyPress} onKeyPress={@_onFieldKeyPress}
data-field={field.name} data-field={field.name}
data-format={field.format} ? ""
className={errclass} className={errclass}
placeholder={field.placeholder} /> placeholder={field.placeholder} />
</label> </label>
@ -144,6 +154,7 @@ class AccountSettingsPage extends React.Component
onChange={@_onSettingsChanged} onChange={@_onSettingsChanged}
onKeyPress={@_onFieldKeyPress} onKeyPress={@_onFieldKeyPress}
data-field={field.name} data-field={field.name}
data-format={field.format} ? ""
className={field.className ? ""} /> className={field.className ? ""} />
{field.label} {field.label}
</label> </label>
@ -159,6 +170,7 @@ class AccountSettingsPage extends React.Component
onChange={@_onSettingsChanged} onChange={@_onSettingsChanged}
onKeyPress={@_onFieldKeyPress} onKeyPress={@_onFieldKeyPress}
data-field={field.name} data-field={field.name}
data-format={field.format} ? ""
className={errclass+(field.className ? "")} className={errclass+(field.className ? "")}
placeholder={field.placeholder} /> placeholder={field.placeholder} />
</label> </label>

View file

@ -125,6 +125,7 @@ Providers = [
label: 'Port (optional)' label: 'Port (optional)'
className: 'half' className: 'half'
default: 993 default: 993
format: 'integer'
page: 1 page: 1
}, { }, {
name: 'imap_ssl_enabled' name: 'imap_ssl_enabled'
@ -157,6 +158,7 @@ Providers = [
placeholder: '587' placeholder: '587'
label: 'Port (optional)' label: 'Port (optional)'
className: 'half' className: 'half'
format: 'integer'
default: 587 default: 587
page: 2 page: 2
}, { }, {

View file

@ -4,11 +4,10 @@ NylasStore = require 'nylas-store'
class NylasApiEnvironmentStore extends NylasStore class NylasApiEnvironmentStore extends NylasStore
constructor: -> constructor: ->
@listenTo Actions.changeAPIEnvironment, @_setEnvironment @listenTo Actions.changeAPIEnvironment, @_setEnvironment
@_setEnvironment('production') unless atom.config.get('env')
defaultEnv = if atom.inDevMode() then 'staging' else 'staging' getEnvironment: ->
@_setEnvironment(defaultEnv) unless atom.config.get('env') atom.config.get('env')
getEnvironment: -> atom.config.get('env')
_setEnvironment: (env) -> _setEnvironment: (env) ->
throw new Error("Environment #{env} is not allowed") unless env in ['development', 'experimental', 'staging', 'production'] throw new Error("Environment #{env} is not allowed") unless env in ['development', 'experimental', 'staging', 'production']

View file

@ -45,7 +45,7 @@ class WelcomePage extends React.Component
_renderStep0: -> _renderStep0: ->
<div className={@_stepClass(0)} key="step-0"> <div className={@_stepClass(0)} key="step-0">
<RetinaImg className="logo" style={zoom: 0.20, marginTop: 60} url="nylas://onboarding/assets/nylas-pictograph@2x.png" mode={RetinaImg.Mode.ContentIsMask} /> <RetinaImg className="logo" style={zoom: 0.20, marginTop: 60, opacity: 0.7} url="nylas://onboarding/assets/nylas-pictographB@2x.png" mode={RetinaImg.Mode.ContentPreserve}/>
<p className="hero-text" style={marginTop: 30, fontSize: 44}>Say hello to N1.</p> <p className="hero-text" style={marginTop: 30, fontSize: 44}>Say hello to N1.</p>
<p className="sub-text" style={marginTop: 0, fontSize: 24}>The next-generation email platform.</p> <p className="sub-text" style={marginTop: 0, fontSize: 24}>The next-generation email platform.</p>
<div style={fontSize:17, marginTop: 45}>Built with ❤︎ by Nylas</div> <div style={fontSize:17, marginTop: 45}>Built with ❤︎ by Nylas</div>
@ -65,7 +65,7 @@ class WelcomePage extends React.Component
<RetinaImg className="wrench" mode={RetinaImg.Mode.ContentPreserve} <RetinaImg className="wrench" mode={RetinaImg.Mode.ContentPreserve}
url="nylas://onboarding/assets/wrench@2x.png" /> url="nylas://onboarding/assets/wrench@2x.png" />
<p className="sub-text">N1 is built with modern web technologies and easy to extend with JavaScript.</p> <p className="sub-text">N1 is built with modern web technologies and is easy to extend with JavaScript.</p>
{@_renderNavBubble(1)} {@_renderNavBubble(1)}
</div> </div>

View file

@ -15,18 +15,18 @@ describe "NylasApiEnvironmentStore", ->
spyOn(atom, "inDevMode").andReturn true spyOn(atom, "inDevMode").andReturn true
spyOn(atom.config, "get").andReturn undefined spyOn(atom.config, "get").andReturn undefined
store = new storeConstructor() store = new storeConstructor()
expect(atom.config.set).toHaveBeenCalledWith("env", "staging") expect(atom.config.set).toHaveBeenCalledWith("env", "production")
it "initializes with the correct default in production", -> it "initializes with the correct default in production", ->
spyOn(atom, "inDevMode").andReturn false spyOn(atom, "inDevMode").andReturn false
spyOn(atom.config, "get").andReturn undefined spyOn(atom.config, "get").andReturn undefined
store = new storeConstructor() store = new storeConstructor()
expect(atom.config.set).toHaveBeenCalledWith("env", "staging") expect(atom.config.set).toHaveBeenCalledWith("env", "production")
describe "when setting the environment", -> describe "when setting the environment", ->
it "sets from the desired action", -> it "sets from the desired action", ->
Actions.changeAPIEnvironment("production") Actions.changeAPIEnvironment("staging")
expect(atom.config.set).toHaveBeenCalledWith("env", "production") expect(atom.config.set).toHaveBeenCalledWith("env", "staging")
it "throws if the env is invalid", -> it "throws if the env is invalid", ->
expect( -> Actions.changeAPIEnvironment("bad")).toThrow() expect( -> Actions.changeAPIEnvironment("bad")).toThrow()

View file

@ -312,9 +312,6 @@
.page.account-choose { .page.account-choose {
width: 388px; width: 388px;
height: 615px; height: 615px;
img.logo.content-mask {
background-color: rgba(255,255,255,0.4);
}
.caption { .caption {
font-size: 17px; font-size: 17px;
@ -539,9 +536,6 @@
line-height: 41px; line-height: 41px;
} }
img.logo.content-mask {
background-color: rgba(255,255,255,0.4);
}
img.icons.content-mask { img.icons.content-mask {
background-color: rgba(255,255,255,0.7); background-color: rgba(255,255,255,0.7);
} }
@ -647,7 +641,7 @@
p { p {
margin-top: 1em; margin-top: 1em;
color: rgba(255,255,255,0.7); color: rgba(255,255,255,0.9);
font-size: 17px; font-size: 17px;
line-height: 24px; line-height: 24px;
} }

View file

@ -18,7 +18,6 @@ class EdgehillAPI
_onConfigChanged: => _onConfigChanged: =>
env = atom.config.get('env') env = atom.config.get('env')
if env is 'development' if env is 'development'
# @APIRoot = "http://localhost:5009"
@APIRoot = "https://edgehill-dev.nylas.com" @APIRoot = "https://edgehill-dev.nylas.com"
else if env is 'experimental' else if env is 'experimental'
@APIRoot = "https://edgehill-experimental.nylas.com" @APIRoot = "https://edgehill-experimental.nylas.com"