mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-10 06:34:40 +08:00
fix(counts): Centralize handling of unread count / draft count
Fixes T2155 and T1765
This commit is contained in:
parent
c6eeddd8e7
commit
4621f432b0
11 changed files with 141 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -41,14 +41,14 @@ class AccountSidebar extends React.Component
|
|||
</section>
|
||||
|
||||
_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}")
|
||||
|
||||
<itemClass
|
||||
key={item.id ? item.type}
|
||||
item={item}
|
||||
|
|
|
@ -6,7 +6,7 @@ React = require 'react'
|
|||
class StarButton extends React.Component
|
||||
@displayName: "StarButton"
|
||||
@propTypes:
|
||||
thread: React.PropTypes.object.isRequired
|
||||
thread: React.PropTypes.object
|
||||
|
||||
render: =>
|
||||
selected = @props.thread? and @props.thread.isStarred()
|
||||
|
|
|
@ -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 = <div className="unread item-count-box">{@state.count}</div>
|
||||
|
||||
<div className={classSet} onClick={@_onClick}>
|
||||
<RetinaImg name={'drafts.png'} mode={RetinaImg.Mode.ContentIsMask} />
|
||||
<span className="name"> {@props.item.name}</span>
|
||||
{unread}
|
||||
</div>
|
||||
|
||||
_onClick: (event) =>
|
||||
event.preventDefault()
|
||||
Actions.selectRootSheet(@props.item)
|
||||
|
||||
module.exports = DraftListSidebarItem
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
module.exports =
|
||||
|
||||
activate: ->
|
||||
@store = require "./unread-badge-store"
|
||||
|
||||
deactivate: ->
|
||||
|
||||
serialize: ->
|
|
@ -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": {
|
||||
}
|
||||
}
|
44
src/flux/stores/draft-count-store.coffee
Normal file
44
src/flux/stores/draft-count-store.coffee
Normal file
|
@ -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
|
|
@ -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
|
|
@ -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"}
|
||||
|
|
Loading…
Add table
Reference in a new issue