Mailspring/internal_packages/thread-list/lib/thread-list-store.coffee
Juan Tejada e83bf2bbec feat(selection): Add new display for selection count + update toolbar
Summary:
- New behavior is that the in split mode, you will perform actions on
  the selection via the MessageListToolbar (the toolbar positioned above
  the message list)
- Refactored and moved around a bunch of code to achieve this:
  - Mostly renaming stuff and moving stuff around and removing some
    duplication
  - Update naming of toolbar role to a single role, and update relevant code
  - Converted and refactored a bunch of code into ES6, specifically to reuse the code for the ThreadActionsToolbar at the 2 locations
  - Deprecated MultiselectActionBar in favor of MultiselectToolbar
  - Deprecated old roles
- Punted the animation for the stackable cards in the selection display for now.
- #370

Test Plan: - Manual and unit tests

Reviewers: evan, drew, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2756
2016-03-21 12:20:11 -07:00

96 lines
3 KiB
CoffeeScript

_ = require 'underscore'
NylasStore = require 'nylas-store'
{Rx,
Thread,
Message,
Actions,
DatabaseStore,
WorkspaceStore,
FocusedContentStore,
TaskQueueStatusStore,
FocusedPerspectiveStore} = require 'nylas-exports'
{ListTabular} = require 'nylas-component-kit'
ThreadListDataSource = require './thread-list-data-source'
class ThreadListStore extends NylasStore
constructor: ->
@listenTo FocusedPerspectiveStore, @_onPerspectiveChanged
@createListDataSource()
dataSource: =>
@_dataSource
createListDataSource: =>
@_dataSourceUnlisten?()
@_dataSource = null
threadsSubscription = FocusedPerspectiveStore.current().threads()
if threadsSubscription
@_dataSource = new ThreadListDataSource(threadsSubscription)
@_dataSourceUnlisten = @_dataSource.listen(@_onDataChanged, @)
# Set up a one-time listener to focus an item in the new view
if WorkspaceStore.layoutMode() is 'split'
unlisten = @_dataSource.listen =>
if @_dataSource.loaded()
Actions.setFocus(collection: 'thread', item: @_dataSource.get(0))
unlisten()
else
@_dataSource = new ListTabular.DataSource.Empty()
@trigger(@)
Actions.setFocus(collection: 'thread', item: null)
selectionObservable: =>
return Rx.Observable.fromListSelection(@)
# Inbound Events
_onPerspectiveChanged: =>
@createListDataSource()
_onDataChanged: ({previous, next} = {}) =>
# This code keeps the focus and keyboard cursor in sync with the thread list.
# When the thread list changes, it looks to see if the focused thread is gone,
# or no longer matches the query criteria and advances the focus to the next
# thread.
# This means that removing a thread from view in any way causes selection
# to advance to the adjacent thread. Nice and declarative.
if previous and next
focused = FocusedContentStore.focused('thread')
keyboard = FocusedContentStore.keyboardCursor('thread')
viewModeAutofocuses = WorkspaceStore.layoutMode() is 'split' or WorkspaceStore.topSheet().root is true
matchers = next.query()?.matchers()
focusedIndex = if focused then previous.offsetOfId(focused.id) else -1
keyboardIndex = if keyboard then previous.offsetOfId(keyboard.id) else -1
nextItemFromIndex = (i) =>
if i > 0 and (next.modelAtOffset(i - 1)?.unread or i >= next.count())
nextIndex = i - 1
else
nextIndex = i
# May return null if no thread is loaded at the next index
next.modelAtOffset(nextIndex)
notInSet = (model) ->
if matchers
return model.matches(matchers) is false
else
return next.offsetOfId(model.id) is -1
if viewModeAutofocuses and focused and notInSet(focused)
Actions.setFocus(collection: 'thread', item: nextItemFromIndex(focusedIndex))
if keyboard and notInSet(keyboard)
Actions.setCursorPosition(collection: 'thread', item: nextItemFromIndex(keyboardIndex))
@trigger(@)
module.exports = new ThreadListStore()