Mailspring/internal_packages/account-sidebar/lib/account-sidebar-store.coffee
Ben Gotow d15b5080fb fix(stores): FocusedThreadStore, FocusedTagStore, speed improvements
Summary:
ThreadStore is now in the thread-list package.

Account sidebar no longer has random stuff dealing with search, no longer maintains selection apart from FocusedTagStore

Thread nav buttons are in the thread package

Account sidebar pulls selection from FocusedTagStore, no longer fires an Action to select Inbox, which was weird

Thread store is in thread-list package. No longer has any selection concept -> moved to FocusedThreadStore. Also looks at database changes to do "shallow" updates when only threads and not messages have changed, or when only messages of a few...

...threads have changed.

WorkspaceStore now handles both pushing AND popping the thread sheet. So all sheet behavior is here.

ThreadStore => FocusedThreadStore, selectThreadId => selectThread

Include all models in inbox-exports

It actually takes a long time to call Promise.reject because Bluebird generates stack traces. Resolve with false instead (100msec faster!)

Cache the model class map. All the requires take ~20msec per call to this method

ThreadList looks at FocusedThreadStore for selection

FocusedThreadStore, FocusedTagStore

Updated specs

Test Plan: Run tests

Reviewers: evan

Reviewed By: evan

Differential Revision: https://review.inboxapp.com/D1384
2015-03-31 17:19:17 -07:00

122 lines
3.5 KiB
CoffeeScript

Reflux = require 'reflux'
_ = require 'underscore-plus'
{DatabaseStore,
NamespaceStore,
Actions,
Tag,
Message,
FocusedTagStore,
Thread} = require 'inbox-exports'
AccountSidebarStore = Reflux.createStore
init: ->
@_setStoreDefaults()
@_registerListeners()
@_populate()
# Keep a cache of unread counts since requesting the number from the
# server is a fairly expensive operation.
@_unreadCountCache = {}
@localDraftsTag = new Tag({id: "drafts", name: "Local Drafts"})
########### PUBLIC #####################################################
sections: ->
@_sections
########### PRIVATE ####################################################
_setStoreDefaults: ->
@_sections = []
_registerListeners: ->
@listenTo DatabaseStore, @_onDataChanged
@listenTo NamespaceStore, @_onNamespaceChanged
_populate: ->
namespace = NamespaceStore.current()
return unless namespace
DatabaseStore.findAll(Tag, namespaceId: namespace.id).then (tags) =>
# Collect the built-in tags we want to display, and the user tags
# (which can be identified by having non-hardcoded IDs)
# We ignore the server drafts so we can use our own localDrafts
tags = _.reject tags, (tag) -> tag.id is "drafts"
tags.push(@localDraftsTag)
mainTagIDs = ['inbox', 'drafts', 'sent', 'archive']
mainTags = _.filter tags, (tag) -> _.contains(mainTagIDs, tag.id)
userTags = _.filter tags, (tag) -> tag.name != tag.id
# Sort the main tags so they always appear in a standard order
mainTags = _.sortBy mainTags, (tag) -> mainTagIDs.indexOf(tag.id)
mainTags.push new Tag(name: 'All Mail', id: '*')
lastSections = @_sections
@_sections = [
{ label: 'Mailboxes', tags: mainTags }
]
if _.isEqual(@_sections, lastSections) is false
@_populateUnreadCounts()
@trigger(@)
_populateUnreadCounts: ->
namespace = NamespaceStore.current()
return unless namespace
@_sections.forEach (section) =>
section.tags.forEach (tag) =>
if tag.id is "drafts"
@_populateDraftsCount(tag)
else if tag.id in ['drafts', 'sent', 'archive', 'trash', '*']
return
else
# Make a web request for unread count
atom.inbox.makeRequest
method: 'GET'
path: "/n/#{namespace.id}/tags/#{tag.id}"
returnsModel: true
_populateDraftsCount: ->
namespace = NamespaceStore.current()
return unless namespace
DatabaseStore.count(Message, draft: true).then (count) =>
@localDraftsTag.unreadCount = count
@trigger(@)
# Unfortunately, the joins necessary to compute unread counts are expensive.
# Rather than update unread counts every time threads change in the database,
# we debounce aggressively and update only after changes have stopped.
# Remove this when JOIN query speed is fixed!
_populateUnreadCountsDebounced: _.debounce ->
@_populateUnreadCounts()
, 1000
_refetchFromAPI: ->
namespace = NamespaceStore.current()
return unless namespace
# Trigger a request to the API
atom.inbox.getCollection(namespace.id, 'tags')
# Inbound Events
_onNamespaceChanged: ->
@_refetchFromAPI()
@_populate()
_onDataChanged: (change) ->
if change.objectClass == Tag.name
@_populate()
if change.objectClass == Thread.name
@_populateUnreadCountsDebounced()
if change.objectClass == Message.name
@_populateDraftsCount()
module.exports = AccountSidebarStore