describe "when focus() is called", ->
describe "if a field name is provided", ->
it "should focus that field", ->
- useDraft.call(@)
+ useDraft.call(@, cc: [u2])
makeComposer.call(@)
spyOn(@composer.refs['textFieldCc'], 'focus')
@composer.focus('textFieldCc')
diff --git a/internal_packages/composer/stylesheets/composer.less b/internal_packages/composer/stylesheets/composer.less
index 25ae2924c..475729dd4 100644
--- a/internal_packages/composer/stylesheets/composer.less
+++ b/internal_packages/composer/stylesheets/composer.less
@@ -28,15 +28,15 @@
width: 100%;
background: transparent;
border-bottom: 0;
- max-width: @compose-width;
- margin: 0 auto;
.composer-action-bar-content {
display:flex;
+ margin: 0 auto;
flex-direction:row;
- margin-left: -@spacing-standard / 2;
- margin-right: -@spacing-standard / 2;
- padding: @spacing-standard @spacing-double;
+ max-width: @compose-width;
+ padding-left: @spacing-standard + @spacing-standard / 2;
+ padding-right: @spacing-standard + @spacing-standard / 2;
+ padding-top: @spacing-standard;
padding-bottom: @spacing-standard*1.1;
> * {
@@ -109,7 +109,7 @@
margin: 0 @spacing-standard;
border-bottom: 1px solid @border-color-divider;
flex-shrink:0;
-
+
.subject-label {
color: @text-color-very-subtle;
float: left;
diff --git a/internal_packages/message-list/lib/message-timestamp.cjsx b/internal_packages/message-list/lib/message-timestamp.cjsx
index f1655a4e3..1f0975506 100644
--- a/internal_packages/message-list/lib/message-timestamp.cjsx
+++ b/internal_packages/message-list/lib/message-timestamp.cjsx
@@ -23,7 +23,7 @@ class MessageTimestamp extends React.Component
_timeFormat: =>
if @props.isDetailed
- return "DD / MM / YYYY h:mm a z"
+ return "MMMM D, YYYY [at] h:mm A"
else
today = moment(@_today())
dayOfEra = today.dayOfYear() + today.year() * 365
diff --git a/internal_packages/message-list/spec/message-timestamp-spec.cjsx b/internal_packages/message-list/spec/message-timestamp-spec.cjsx
index c0f1947e2..322921fc8 100644
--- a/internal_packages/message-list/spec/message-timestamp-spec.cjsx
+++ b/internal_packages/message-list/spec/message-timestamp-spec.cjsx
@@ -38,4 +38,4 @@ describe "MessageTimestamp", ->
)
spyOn(itemDetailed, "_today").andCallFake -> testDate()
- expect(itemDetailed._timeFormat()).toBe "DD / MM / YYYY h:mm a z"
+ expect(itemDetailed._timeFormat()).toBe "MMMM D, YYYY [at] h:mm A"
diff --git a/internal_packages/message-templates/lib/template-picker.cjsx b/internal_packages/message-templates/lib/template-picker.cjsx
index 4907cb9b4..80b02c53a 100644
--- a/internal_packages/message-templates/lib/template-picker.cjsx
+++ b/internal_packages/message-templates/lib/template-picker.cjsx
@@ -37,7 +37,7 @@ class TemplatePicker extends React.Component
]
footerComponents = [
- Save as Template...
+ Save Draft as Template...
Open Templates Folder...
]
diff --git a/internal_packages/message-templates/lib/template-store.coffee b/internal_packages/message-templates/lib/template-store.coffee
index 06b671ad4..886abd9e7 100644
--- a/internal_packages/message-templates/lib/template-store.coffee
+++ b/internal_packages/message-templates/lib/template-store.coffee
@@ -1,6 +1,7 @@
Reflux = require 'reflux'
_ = require 'underscore'
{DatabaseStore, DraftStore, Actions, Message} = require 'nylas-exports'
+shell = require 'shell'
path = require 'path'
fs = require 'fs-plus'
@@ -59,21 +60,32 @@ TemplateStore = Reflux.createStore
draft = session.draft()
name ?= draft.subject
contents ?= draft.body
+ if not name or name.length is 0
+ return @_displayError("Give your draft a subject to name your template.")
+ if not contents or contents.length is 0
+ return @_displayError("To create a template you need to fill the body of the current draft.")
@_writeTemplate(name, contents)
+
else
+ if not name or name.length is 0
+ return @_displayError("You must provide a name for your template.")
+ if not contents or contents.length is 0
+ return @_displayError("You must provide contents for your template.")
@_writeTemplate(name, contents)
_onShowTemplates: ->
- # show in finder how?
- shell = require 'shell'
shell.showItemInFolder(@_items[0]?.path || @_templatesDir)
+ _displayError: (message) ->
+ dialog = require('remote').require('dialog')
+ dialog.showErrorBox('Template Creation Error', message)
+
_writeTemplate: (name, contents) ->
- throw new Error("You must provide a template name") unless name
- throw new Error("You must provide template contents") unless contents
filename = "#{name}.html"
templatePath = path.join(@_templatesDir, filename)
fs.writeFile templatePath, contents, (err) =>
+ @_displayError(err) if err
+ shell.showItemInFolder(templatePath)
@_items.push
id: filename,
name: name,
diff --git a/internal_packages/message-templates/spec/template-store-spec.coffee b/internal_packages/message-templates/spec/template-store-spec.coffee
index 344111e69..f35a75ed3 100644
--- a/internal_packages/message-templates/spec/template-store-spec.coffee
+++ b/internal_packages/message-templates/spec/template-store-spec.coffee
@@ -18,6 +18,9 @@ stubTemplates = [
describe "TemplateStore", ->
beforeEach ->
spyOn(fs, 'mkdir')
+ spyOn(shell, 'showItemInFolder').andCallFake ->
+ spyOn(fs, 'writeFile').andCallFake (path, contents, callback) ->
+ callback(null)
spyOn(fs, 'readFile').andCallFake (path, callback) ->
filename = path.split('/').pop()
callback(null, stubTemplateFiles[filename])
@@ -71,9 +74,15 @@ describe "TemplateStore", ->
describe "onCreateTemplate", ->
beforeEach ->
- spyOn(fs, 'readdir').andCallFake (path, callback) -> callback(null, [])
- spyOn(fs, 'writeFile').andCallFake (path, contents, callback) -> callback(null)
TemplateStore.init()
+ spyOn(DraftStore, 'sessionForLocalId').andCallFake (draftLocalId) ->
+ if draftLocalId is 'localid-nosubject'
+ d = new Message(subject: '', body: 'Body
')
+ else
+ d = new Message(subject: 'Subject', body: 'Body
')
+ session =
+ draft: -> d
+ Promise.resolve(session)
it "should create a template with the given name and contents", ->
TemplateStore._onCreateTemplate({name: '123', contents: 'bla'})
@@ -82,11 +91,15 @@ describe "TemplateStore", ->
expect(item.name).toBe "123"
expect(item.path.split("/").pop()).toBe "123.html"
- it "should throw an exception if no name is provided", ->
- expect( -> TemplateStore._onCreateTemplate({contents: 'bla'})).toThrow()
+ it "should display an error if no name is provided", ->
+ spyOn(TemplateStore, '_displayError')
+ TemplateStore._onCreateTemplate({contents: 'bla'})
+ expect(TemplateStore._displayError).toHaveBeenCalled()
- it "should throw an exception if no content is provided", ->
- expect( -> TemplateStore._onCreateTemplate({name: 'bla'})).toThrow()
+ it "should display an error if no content is provided", ->
+ spyOn(TemplateStore, '_displayError')
+ TemplateStore._onCreateTemplate({name: 'bla'})
+ expect(TemplateStore._displayError).toHaveBeenCalled()
it "should save the template file to the templates folder", ->
TemplateStore._onCreateTemplate({name: '123', contents: 'bla'})
@@ -95,17 +108,30 @@ describe "TemplateStore", ->
expect(fs.writeFile.mostRecentCall.args[0]).toEqual(path)
expect(fs.writeFile.mostRecentCall.args[1]).toEqual('bla')
+ it "should open the template so you can see it", ->
+ TemplateStore._onCreateTemplate({name: '123', contents: 'bla'})
+ path = "#{stubTemplatesDir}/123.html"
+ expect(shell.showItemInFolder).toHaveBeenCalled()
+
describe "when given a draft id", ->
it "should create a template from the name and contents of the given draft", ->
- draft = new Message
- subject: 'Subject'
- body: 'Body
'
- spyOn(DatabaseStore, 'findByLocalId').andReturn(Promise.resolve(draft))
- TemplateStore._onCreateTemplate({draftLocalId: 'localid-b'})
- expect(TemplateStore.items()).toEqual([])
+ runs ->
+ TemplateStore._onCreateTemplate({draftLocalId: 'localid-b'})
+ waitsFor ->
+ fs.writeFile.callCount > 0
+ runs ->
+ expect(TemplateStore.items().length).toEqual(1)
+
+ it "should display an error if the draft has no subject", ->
+ spyOn(TemplateStore, '_displayError')
+ runs ->
+ TemplateStore._onCreateTemplate({draftLocalId: 'localid-nosubject'})
+ waitsFor ->
+ TemplateStore._displayError.callCount > 0
+ runs ->
+ expect(TemplateStore._displayError).toHaveBeenCalled()
describe "onShowTemplates", ->
it "should open the templates folder in the Finder", ->
- spyOn(shell, 'showItemInFolder')
TemplateStore._onShowTemplates()
expect(shell.showItemInFolder).toHaveBeenCalled()
diff --git a/internal_packages/unread-badge/lib/unread-badge-store.coffee b/internal_packages/unread-badge/lib/unread-badge-store.coffee
index 60ee23253..1b5c0a3a6 100644
--- a/internal_packages/unread-badge/lib/unread-badge-store.coffee
+++ b/internal_packages/unread-badge/lib/unread-badge-store.coffee
@@ -36,7 +36,7 @@ AppUnreadBadgeStore = Reflux.createStore
AppUnreadCount = count
if count > 999
- app.dock?.setBadge?("\u221E")
+ app.dock?.setBadge?("999+")
else if count > 0
app.dock?.setBadge?("#{count}")
else