diff --git a/exports/nylas-exports.coffee b/exports/nylas-exports.coffee index 102a5dbd9..4d063b8be 100644 --- a/exports/nylas-exports.coffee +++ b/exports/nylas-exports.coffee @@ -48,6 +48,7 @@ Exports = # Stores DraftStore: require '../src/flux/stores/draft-store' + DraftCountStore: require '../src/flux/stores/draft-count-store' DraftStoreExtension: require '../src/flux/stores/draft-store-extension' MessageStore: require '../src/flux/stores/message-store' ContactStore: require '../src/flux/stores/contact-store' @@ -60,6 +61,7 @@ Exports = FileUploadStore: require '../src/flux/stores/file-upload-store' FileDownloadStore: require '../src/flux/stores/file-download-store' FocusedContactsStore: require '../src/flux/stores/focused-contacts-store' + UnreadCountStore: require '../src/flux/stores/unread-count-store' # Errors APIError: APIError diff --git a/internal_packages/account-sidebar/lib/account-sidebar-store.coffee b/internal_packages/account-sidebar/lib/account-sidebar-store.coffee index 8abba01c9..6f10b56bf 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar-store.coffee +++ b/internal_packages/account-sidebar/lib/account-sidebar-store.coffee @@ -3,6 +3,8 @@ _ = require 'underscore' {DatabaseStore, NamespaceStore, WorkspaceStore, + UnreadCountStore, + DraftCountStore, Actions, Tag, Message, @@ -12,13 +14,11 @@ _ = require 'underscore' AccountSidebarStore = Reflux.createStore init: -> - @_inboxCount = null @_tags = [] @_setStoreDefaults() @_registerListeners() @_populate() - @_populateInboxCount() ########### PUBLIC ##################################################### @@ -40,6 +40,8 @@ AccountSidebarStore = Reflux.createStore @listenTo DatabaseStore, @_onDataChanged @listenTo NamespaceStore, @_onNamespaceChanged @listenTo WorkspaceStore, @_onWorkspaceChanged + @listenTo UnreadCountStore, @_onCountChanged + @listenTo DraftCountStore, @_onCountChanged @listenTo FocusedTagStore, @_onFocusChange _populate: -> @@ -50,19 +52,6 @@ AccountSidebarStore = Reflux.createStore @_tags = tags @_build() - _populateInboxCount: -> - namespace = NamespaceStore.current() - return unless namespace - - DatabaseStore.count(Thread, [ - Thread.attributes.namespaceId.equal(namespace.id), - Thread.attributes.unread.equal(true), - Thread.attributes.tags.contains('inbox') - ]).then (count) => - if count isnt @_inboxCount - @_inboxCount = count - @_build() - _build: -> tags = @_tags @@ -75,6 +64,10 @@ AccountSidebarStore = Reflux.createStore # We ignore the trash tag because you can't trash anything tags = _.reject tags, (tag) -> tag.id is "trash" + # Clone the tag objects so that components holding on to tags + # don't have identical object references with new data. + tags = _.map tags, (tag) -> new Tag(tag) + mainTagIDs = ['inbox', 'starred', 'drafts', 'sent', 'archive'] mainTags = _.filter tags, (tag) -> _.contains(mainTagIDs, tag.id) userTags = _.reject tags, (tag) -> _.contains(mainTagIDs, tag.id) @@ -83,8 +76,9 @@ AccountSidebarStore = Reflux.createStore mainTags = _.sortBy mainTags, (tag) -> mainTagIDs.indexOf(tag.id) mainTags.push new Tag(name: 'All Mail', id: '*') + # Add the counts inboxTag = _.find tags, (tag) -> tag.id is 'inbox' - inboxTag?.unreadCount = @_inboxCount + inboxTag?.unreadCount = UnreadCountStore.count() # Sort user tags by name userTags = _.sortBy(userTags, 'name') @@ -114,23 +108,19 @@ AccountSidebarStore = Reflux.createStore _onNamespaceChanged: -> @_refetchFromAPI() - @_populateInboxCount() @_populate() _onWorkspaceChanged: -> @_populate() + _onCountChanged: -> + @_build() + _onFocusChange: -> @trigger(@) _onDataChanged: (change) -> - @populateInboxCountDebounced ?= _.debounce => - @_populateInboxCount() - , 5000 - if change.objectClass is Tag.name @_populate() - if change.objectClass is Thread.name - @populateInboxCountDebounced() module.exports = AccountSidebarStore diff --git a/internal_packages/account-sidebar/lib/account-sidebar.cjsx b/internal_packages/account-sidebar/lib/account-sidebar.cjsx index 7581db6fb..0b115ed00 100644 --- a/internal_packages/account-sidebar/lib/account-sidebar.cjsx +++ b/internal_packages/account-sidebar/lib/account-sidebar.cjsx @@ -41,14 +41,14 @@ class AccountSidebar extends React.Component _itemComponents: (section) => - if section.type is 'tag' - itemClass = SidebarTagItem - else if section.type is 'sheet' - itemClass = SidebarSheetItem - else - throw new Error("Unsure how to render item type #{section.type}") - section.items?.map (item) => + if section.type is 'tag' + itemClass = SidebarTagItem + else if section.type is 'sheet' + itemClass = item.sidebarComponent ? SidebarSheetItem + else + throw new Error("Unsure how to render item type #{section.type}") + selected = @props.thread? and @props.thread.isStarred() diff --git a/internal_packages/thread-list/lib/draft-list-sidebar-item.cjsx b/internal_packages/thread-list/lib/draft-list-sidebar-item.cjsx new file mode 100644 index 000000000..1dcc424e5 --- /dev/null +++ b/internal_packages/thread-list/lib/draft-list-sidebar-item.cjsx @@ -0,0 +1,44 @@ +React = require 'react' +_ = require 'underscore' +classNames = require 'classnames' +{Actions, Utils, WorkspaceStore, DraftCountStore} = require 'nylas-exports' +{RetinaImg} = require 'nylas-component-kit' + +class DraftListSidebarItem extends React.Component + @displayName: 'DraftListSidebarItem' + + constructor: (@props) -> + @state = @getStateFromStores() + + componentDidMount: => + @unsubscribe = DraftCountStore.listen(@_onCountChanged) + + componentWillUnmount: => + @unsubscribe() + + getStateFromStores: => + count: DraftCountStore.count() + + _onCountChanged: => + @setState(@getStateFromStores()) + + render: => + classSet = classNames + 'item': true + 'selected': @props.select + + unread = [] + if @state.count > 0 + unread =
{@state.count}
+ +
+ + {@props.item.name} + {unread} +
+ + _onClick: (event) => + event.preventDefault() + Actions.selectRootSheet(@props.item) + +module.exports = DraftListSidebarItem diff --git a/internal_packages/thread-list/lib/main.cjsx b/internal_packages/thread-list/lib/main.cjsx index 230c5678b..473b1dfcf 100644 --- a/internal_packages/thread-list/lib/main.cjsx +++ b/internal_packages/thread-list/lib/main.cjsx @@ -6,11 +6,15 @@ React = require "react" ThreadSelectionBar = require './thread-selection-bar' ThreadList = require './thread-list' +DraftListSidebarItem = require './draft-list-sidebar-item' DraftSelectionBar = require './draft-selection-bar' DraftList = require './draft-list' module.exports = activate: (@state={}) -> + WorkspaceStore.defineSheet 'Drafts', {root: true, name: 'Local Drafts', sidebarComponent: DraftListSidebarItem}, + list: ['RootSidebar', 'DraftList'] + ComponentRegistry.register ThreadList, location: WorkspaceStore.Location.ThreadList diff --git a/internal_packages/unread-badge/lib/main.coffee b/internal_packages/unread-badge/lib/main.coffee deleted file mode 100644 index 438cae565..000000000 --- a/internal_packages/unread-badge/lib/main.coffee +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = - - activate: -> - @store = require "./unread-badge-store" - - deactivate: -> - - serialize: -> diff --git a/internal_packages/unread-badge/package.json b/internal_packages/unread-badge/package.json deleted file mode 100755 index dc30b8278..000000000 --- a/internal_packages/unread-badge/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "unread-badge", - "version": "0.1.0", - "main": "./lib/main", - "description": "Updates the Mac's app icon to display unread count", - "license": "Proprietary", - "private": true, - "engines": { - "atom": "*" - }, - "dependencies": { - } -} diff --git a/src/flux/stores/draft-count-store.coffee b/src/flux/stores/draft-count-store.coffee new file mode 100644 index 000000000..868694242 --- /dev/null +++ b/src/flux/stores/draft-count-store.coffee @@ -0,0 +1,44 @@ +Reflux = require 'reflux' +_ = require 'underscore' +NamespaceStore = require './namespace-store' +DatabaseStore = require './database-store' +DraftStore = require './draft-store' +Actions = require '../actions' +Message = require '../models/message' + +### +Public: The DraftCountStore exposes a simple API for getting the number of +drafts in the user's account. If you plugin needs the number of drafts, +it's more efficient to observe the DraftCountStore than retrieve the value +yourself from the database. +### +DraftCountStore = Reflux.createStore + init: -> + @listenTo NamespaceStore, @_onNamespaceChanged + @listenTo DraftStore, @_onDraftChanged + @_count = null + _.defer => @_fetchCount() + + # Public: Returns the number of drafts in the user's mailbox + count: -> + @_count + + _onNamespaceChanged: -> + @_onDraftChanged() + + _onDraftChanged: -> + @_fetchCountDebounced ?= _.debounce(@_fetchCount, 250) + @_fetchCountDebounced() + + _fetchCount: -> + namespace = NamespaceStore.current() + return unless namespace + + DatabaseStore.count(Message, [ + Message.attributes.draft.equal(true) + ]).then (count) => + return if @_count is count + @_count = count + @trigger() + +module.exports = DraftCountStore diff --git a/internal_packages/unread-badge/lib/unread-badge-store.coffee b/src/flux/stores/unread-count-store.coffee similarity index 55% rename from internal_packages/unread-badge/lib/unread-badge-store.coffee rename to src/flux/stores/unread-count-store.coffee index 1b5c0a3a6..cdb22c8e5 100644 --- a/internal_packages/unread-badge/lib/unread-badge-store.coffee +++ b/src/flux/stores/unread-count-store.coffee @@ -1,17 +1,29 @@ Reflux = require 'reflux' _ = require 'underscore' -{DatabaseStore, NamespaceStore, Actions, Thread} = require 'nylas-exports' remote = require 'remote' app = remote.require 'app' +NamespaceStore = require './namespace-store' +DatabaseStore = require './database-store' +Actions = require '../actions' +Thread = require '../models/thread' -AppUnreadCount = null - -module.exports = -AppUnreadBadgeStore = Reflux.createStore +### +Public: The UnreadCountStore exposes a simple API for getting the number of +unread threads in the user's inbox. If you plugin needs the current unread count, +it's more efficient to observe the UnreadCountStore than retrieve the value +yourself from the database. +### +UnreadCountStore = Reflux.createStore init: -> @listenTo NamespaceStore, @_onNamespaceChanged @listenTo DatabaseStore, @_onDataChanged - @_fetchCount() + + @_count = null + _.defer => @_fetchCount() + + # Public: Returns the number of unread threads in the user's mailbox + count: -> + @_count _onNamespaceChanged: -> @_onDataChanged() @@ -31,9 +43,9 @@ AppUnreadBadgeStore = Reflux.createStore Thread.attributes.namespaceId.equal(namespace.id), Thread.attributes.unread.equal(true), Thread.attributes.tags.contains('inbox') - ]).then (count) -> - return if AppUnreadCount is count - AppUnreadCount = count + ]).then (count) => + return if @_count is count + @_count = count if count > 999 app.dock?.setBadge?("999+") @@ -41,3 +53,7 @@ AppUnreadBadgeStore = Reflux.createStore app.dock?.setBadge?("#{count}") else app.dock?.setBadge?("") + + @trigger() + +module.exports = UnreadCountStore diff --git a/src/flux/stores/workspace-store.coffee b/src/flux/stores/workspace-store.coffee index 2d5e4710b..a1c8ba2dc 100644 --- a/src/flux/stores/workspace-store.coffee +++ b/src/flux/stores/workspace-store.coffee @@ -48,11 +48,8 @@ class WorkspaceStore @defineSheet 'Threads', {root: true}, list: ['RootSidebar', 'ThreadList'] split: ['RootSidebar', 'ThreadList', 'MessageList', 'MessageListSidebar'] - @defineSheet 'Drafts', {root: true, name: 'Local Drafts'}, - list: ['RootSidebar', 'DraftList'] @defineSheet 'Thread', {}, list: ['MessageList', 'MessageListSidebar'] - @_onSelectRootSheet(Sheet.Threads) else @defineSheet 'Global' @@ -146,6 +143,7 @@ class WorkspaceStore icon: options.icon name: options.name root: options.root + sidebarComponent: options.sidebarComponent Toolbar: Left: {id: "Sheet:#{id}:Toolbar:Left"}