+
-
+ {@_renderImportanceOptionElement()}
+
+
Delay for marking messages as read:
+
{subject(thread.subject)}
{thread.snippet}
diff --git a/internal_packages/thread-list/stylesheets/thread-list.less b/internal_packages/thread-list/stylesheets/thread-list.less
index 7d1fab204..9aff6b80a 100644
--- a/internal_packages/thread-list/stylesheets/thread-list.less
+++ b/internal_packages/thread-list/stylesheets/thread-list.less
@@ -22,7 +22,7 @@
color: @text-color-inverse-subtle;
}
- .thread-icon, .draft-icon {
+ .thread-icon, .draft-icon, .mail-important-icon {
-webkit-filter: brightness(600%) grayscale(100%);
}
@@ -58,6 +58,16 @@
border-bottom: 1px solid fade(@list-border, 60%);
}
+ .mail-important-icon {
+ margin-top:1px;
+ margin-left:6px;
+ padding: 12px;
+ vertical-align: initial;
+ &:not(.active) {
+ visibility: hidden;
+ }
+ }
+
.message-count {
color: @text-color-inverse;
background: @background-tertiary;
@@ -157,6 +167,7 @@
width:15px;
height:15px;
background-size: 15px;
+ display:inline-block;
background-repeat: no-repeat;
background-position:center;
padding:12px;
@@ -261,10 +272,18 @@
// stars
-.thread-list .thread-icon-star:hover {
+.thread-list .thread-icon-star:hover,
+.thread-list .list-item:hover .thread-icon-none:hover {
background-image:url(../static/images/thread-list/icon-star-action-hover-@2x.png);
background-size: 16px;
}
+.thread-list .list-item:hover .thread-icon-none {
+ background-image:url(../static/images/thread-list/icon-star-hover-@2x.png);
+ background-size: 16px;
+}
+.thread-list .list-item:hover .mail-important-icon {
+ visibility: inherit;
+}
.thread-list .thread-icon-star-on-hover:hover {
background-image:url(../static/images/thread-list/icon-star-hover-@2x.png);
background-size: 16px;
@@ -280,6 +299,15 @@
.thread-icon {
margin-right:6px;
}
+
+ .mail-important-icon {
+ margin-top:1px;
+ margin-left:1px;
+ float:left;
+ padding: 12px;
+ vertical-align: initial;
+ }
+
.subject {
font-size: @font-size-base;
overflow: hidden;
diff --git a/src/components/mail-important-icon.cjsx b/src/components/mail-important-icon.cjsx
new file mode 100644
index 000000000..14116a3d5
--- /dev/null
+++ b/src/components/mail-important-icon.cjsx
@@ -0,0 +1,55 @@
+_ = require 'underscore'
+React = require 'react'
+{Actions,
+ Utils,
+ Thread,
+ ChangeLabelsTask,
+ CategoryStore,
+ AccountStore} = require 'nylas-exports'
+
+class MailImportantIcon extends React.Component
+ @displayName: 'MailImportantIcon'
+ @propTypes:
+ thread: React.PropTypes.object
+
+ constructor: (@props) ->
+ @state = @getStateFromStores()
+
+ getStateFromStores: =>
+ showing: AccountStore.current().usesImportantFlag() and atom.config.get('core.showImportant')
+
+ componentDidMount: =>
+ @subscription = atom.config.observe 'core.showImportant', =>
+ @setState(@getStateFromStores())
+
+ componentWillUnmount: =>
+ @subscription?.dispose()
+
+ shouldComponentUpdate: (nextProps, nextState) =>
+ return false if nextProps.thread is @props.thread and @state.showing is nextState.showing
+ true
+
+ render: =>
+ return false unless @state.showing
+
+ importantId = CategoryStore.getStandardCategory('important').id
+ isImportant = _.findWhere(@props.thread.labels, {id: importantId})?
+
+ activeClassname = if isImportant then "active" else ""
+
+
+ _onToggleImportant: (event) =>
+ importantLabel = CategoryStore.getStandardCategory('important')
+ isImportant = _.findWhere(@props.thread.labels, {id: importantLabel.id})?
+
+ if isImportant
+ task = new ChangeLabelsTask(thread: @props.thread, labelsToRemove: [importantLabel], labelsToAdd: [])
+ else
+ task = new ChangeLabelsTask(thread: @props.thread, labelsToAdd: [importantLabel], labelsToRemove: [])
+
+ Actions.queueTask(task)
+
+ # Don't trigger the thread row click
+ event.stopPropagation()
+
+module.exports = MailImportantIcon
diff --git a/src/config-schema.coffee b/src/config-schema.coffee
index 9db26d4b6..54a3f11ad 100644
--- a/src/config-schema.coffee
+++ b/src/config-schema.coffee
@@ -10,6 +10,9 @@ module.exports =
showUnreadBadge:
type: 'boolean'
default: true
+ showImportant:
+ type: 'boolean'
+ default: true
disabledPackages:
type: 'array'
default: []
diff --git a/src/flux/models/account.coffee b/src/flux/models/account.coffee
index bf64d81f7..38fac5651 100644
--- a/src/flux/models/account.coffee
+++ b/src/flux/models/account.coffee
@@ -66,4 +66,7 @@ class Account extends Model
return 'Gmail'
return @provider
+ usesImportantFlag: ->
+ @provider is 'gmail'
+
module.exports = Account
diff --git a/src/flux/stores/category-store.coffee b/src/flux/stores/category-store.coffee
index d340ee4fe..a719a8a7a 100644
--- a/src/flux/stores/category-store.coffee
+++ b/src/flux/stores/category-store.coffee
@@ -9,8 +9,14 @@ AccountStore = require './account-store'
class CategoryStore extends NylasStore
constructor: ->
@_categoryCache = {}
+ @_standardCategories = []
+ @_userCategories = []
+ @_hiddenCategories = []
+
@listenTo DatabaseStore, @_onDBChanged
@listenTo AccountStore, @_refreshCacheFromDB
+ atom.config.observe 'core.showImportant', => @_refreshCacheFromDB()
+
@_refreshCacheFromDB()
# We look for a few standard categories and display them in the Mailboxes
@@ -37,6 +43,7 @@ class CategoryStore extends NylasStore
"all"
"archive"
"starred"
+ "important"
]
AllMailName: "all"
@@ -69,7 +76,6 @@ class CategoryStore extends NylasStore
#
getCategories: -> _.values @_categoryCache
-
# Public: Returns the Folder or Label object for a standard category name.
# ('inbox', 'drafts', etc.) It's possible for this to return `null`.
# For example, Gmail likely doesn't have an `archive` label.
@@ -82,25 +88,20 @@ class CategoryStore extends NylasStore
# Public: Returns all of the standard categories for the current account.
#
getStandardCategories: ->
- # Single pass to create lookup table, single pass to get ordered array
- byStandardName = {}
- for key, val of @_categoryCache
- byStandardName[val.name] = val
- _.compact @StandardCategoryNames.map (name) =>
- byStandardName[name]
+ @_standardCategories
getUnhiddenStandardCategories: ->
@getStandardCategories().filter (c) ->
not _.contains @HiddenCategoryNames, c.name
+ getHiddenCategories: ->
+ @_hiddenCategories
+
# Public: Returns all of the categories that are not part of the standard
# category set.
#
getUserCategories: ->
- userCategories = _.reject _.values(@_categoryCache), (cat) =>
- cat.name in @StandardCategoryNames or cat.name in @HiddenCategoryNames
- userCategories = _.sortBy(userCategories, 'displayName')
- return _.compact(userCategories)
+ @_userCategories
_onDBChanged: (change) ->
categoryClass = @categoryClass()
@@ -117,6 +118,29 @@ class CategoryStore extends NylasStore
DatabaseStore.findAll(categoryClass).where(categoryClass.attributes.accountId.equal(account.id)).then (categories=[]) =>
@_categoryCache = {}
@_categoryCache[category.id] = category for category in categories
+
+ # Compute user categories
+ userCategories = _.reject _.values(@_categoryCache), (cat) =>
+ cat.name in @StandardCategoryNames or cat.name in @HiddenCategoryNames
+ userCategories = _.sortBy(userCategories, 'displayName')
+ @_userCategories = _.compact(userCategories)
+
+ # Compute hidden categories
+ @_hiddenCategories = _.filter _.values(@_categoryCache), (cat) =>
+ cat.name in @HiddenCategoryNames
+
+ # Compute standard categories
+ # Single pass to create lookup table, single pass to get ordered array
+ byStandardName = {}
+ for key, val of @_categoryCache
+ byStandardName[val.name] = val
+
+ if not atom.config.get('core.showImportant')
+ delete byStandardName['important']
+
+ @_standardCategories = _.compact @StandardCategoryNames.map (name) =>
+ byStandardName[name]
+
@trigger()
module.exports = new CategoryStore()
diff --git a/static/components/extra.less b/static/components/extra.less
index 5d246d92a..bccb78c54 100644
--- a/static/components/extra.less
+++ b/static/components/extra.less
@@ -61,3 +61,23 @@
opacity: 1;
}
}
+
+
+.mail-important-icon {
+ width:16px;
+ height:16px;
+ vertical-align: middle;
+ display:inline-block;
+ background-repeat: no-repeat;
+ background-position:center;
+ background-image:url(../static/images/important/Icon-Important-Hover@2x.png);
+ background-size: 16px;
+}
+.mail-important-icon.active {
+ background-image:url(../static/images/important/Icon-Important-Active@2x.png);
+ background-size: 16px;
+}
+.mail-important-icon:hover {
+ background-image:url(../static/images/important/Icon-Important-HoverActive@2x.png);
+ background-size: 16px;
+}
diff --git a/static/images/important/Icon-Important-Active@2x.png b/static/images/important/Icon-Important-Active@2x.png
new file mode 100644
index 000000000..fd85eddcc
Binary files /dev/null and b/static/images/important/Icon-Important-Active@2x.png differ
diff --git a/static/images/important/Icon-Important-Hover@2x.png b/static/images/important/Icon-Important-Hover@2x.png
new file mode 100644
index 000000000..b9a3b4414
Binary files /dev/null and b/static/images/important/Icon-Important-Hover@2x.png differ
diff --git a/static/images/important/Icon-Important-HoverActive@2x.png b/static/images/important/Icon-Important-HoverActive@2x.png
new file mode 100644
index 000000000..22b696334
Binary files /dev/null and b/static/images/important/Icon-Important-HoverActive@2x.png differ