mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-14 13:44:41 +08:00
a716726c46
Summary: Give DatabaseStore trigger payload a 'type' so that you can handle the deletion of objects (clear focus if the object is focused, know to remove it from database view) Fix specs and add one for new DatabaseView => unpersist handler Test Plan: Run new test case Reviewers: evan Reviewed By: evan Differential Revision: https://phab.nylas.com/D1639
187 lines
5.4 KiB
CoffeeScript
187 lines
5.4 KiB
CoffeeScript
Reflux = require 'reflux'
|
|
_ = require 'underscore'
|
|
|
|
{DatabaseStore,
|
|
DatabaseView,
|
|
SearchView,
|
|
NamespaceStore,
|
|
WorkspaceStore,
|
|
AddRemoveTagsTask,
|
|
FocusedTagStore,
|
|
FocusedContentStore,
|
|
Actions,
|
|
Utils,
|
|
Thread,
|
|
Message} = require 'nylas-exports'
|
|
|
|
# Public: A mutable text container with undo/redo support and the ability to
|
|
# annotate logical regions in the text.
|
|
#
|
|
module.exports =
|
|
ThreadListStore = Reflux.createStore
|
|
init: ->
|
|
@_resetInstanceVars()
|
|
@_afterViewUpdate = []
|
|
|
|
@listenTo Actions.searchQueryCommitted, @_onSearchCommitted
|
|
@listenTo Actions.selectLayoutMode, @_autofocusForLayoutMode
|
|
|
|
@listenTo Actions.archiveAndPrevious, @_onArchiveAndPrev
|
|
@listenTo Actions.archiveAndNext, @_onArchiveAndNext
|
|
@listenTo Actions.archiveSelection, @_onArchiveSelection
|
|
@listenTo Actions.archive, @_onArchive
|
|
|
|
@listenTo Actions.toggleStarSelection, @_onToggleStarSelection
|
|
|
|
@listenTo DatabaseStore, @_onDataChanged
|
|
@listenTo FocusedTagStore, @_onTagChanged
|
|
@listenTo NamespaceStore, @_onNamespaceChanged
|
|
|
|
@createView()
|
|
|
|
_resetInstanceVars: ->
|
|
@_lastQuery = null
|
|
@_searchQuery = null
|
|
|
|
view: ->
|
|
@_view
|
|
|
|
setView: (view) ->
|
|
@_viewUnlisten() if @_viewUnlisten
|
|
@_view = view
|
|
|
|
@_viewUnlisten = view.listen ->
|
|
@trigger(@)
|
|
fn() for fn in @_afterViewUpdate
|
|
@_afterViewUpdate = []
|
|
@_autofocusForLayoutMode()
|
|
,@
|
|
|
|
@trigger(@)
|
|
|
|
createView: ->
|
|
tagId = FocusedTagStore.tagId()
|
|
namespaceId = NamespaceStore.current()?.id
|
|
|
|
if @_searchQuery
|
|
@setView(new SearchView(@_searchQuery, namespaceId))
|
|
|
|
else if namespaceId and tagId
|
|
matchers = []
|
|
matchers.push Thread.attributes.namespaceId.equal(namespaceId)
|
|
matchers.push Thread.attributes.tags.contains(tagId) if tagId isnt "*"
|
|
@setView new DatabaseView Thread, {matchers}, (item) ->
|
|
DatabaseStore.findAll(Message, {threadId: item.id})
|
|
|
|
Actions.setFocus(collection: 'thread', item: null)
|
|
|
|
# Inbound Events
|
|
|
|
_onTagChanged: -> @createView()
|
|
_onNamespaceChanged: ->
|
|
namespaceId = NamespaceStore.current()?.id
|
|
namespaceMatcher = (m) ->
|
|
m.attribute() is Thread.attributes.namespaceId and m.value() is namespaceId
|
|
|
|
return if @view and _.find(@view.matchers, namespaceMatcher)
|
|
@createView()
|
|
|
|
_onSearchCommitted: (query) ->
|
|
return if @_searchQuery is query
|
|
@_searchQuery = query
|
|
@createView()
|
|
|
|
_onDataChanged: (change) ->
|
|
if change.objectClass is Thread.name
|
|
@_view.invalidate({change: change, shallow: true})
|
|
|
|
if change.objectClass is Message.name
|
|
threadIds = _.uniq _.map change.objects, (m) -> m.threadId
|
|
@_view.invalidateMetadataFor(threadIds)
|
|
|
|
_onToggleStarSelection: ->
|
|
selected = @_view.selection.items()
|
|
focusedId = FocusedContentStore.focusedId('thread')
|
|
keyboardId = FocusedContentStore.keyboardCursorId('thread')
|
|
|
|
oneAlreadyStarred = false
|
|
for thread in selected
|
|
if thread.hasTagId('starred')
|
|
oneAlreadyStarred = true
|
|
|
|
for thread in selected
|
|
if oneAlreadyStarred
|
|
task = new AddRemoveTagsTask(thread, [], ['starred'])
|
|
else
|
|
task = new AddRemoveTagsTask(thread, ['starred'], [])
|
|
Actions.queueTask(task)
|
|
|
|
_onArchive: ->
|
|
@_archiveAndShiftBy('auto')
|
|
|
|
_onArchiveSelection: ->
|
|
selected = @_view.selection.items()
|
|
focusedId = FocusedContentStore.focusedId('thread')
|
|
keyboardId = FocusedContentStore.keyboardCursorId('thread')
|
|
|
|
for thread in selected
|
|
task = new AddRemoveTagsTask(thread, ['archive'], ['inbox'])
|
|
Actions.queueTask(task)
|
|
if thread.id is focusedId
|
|
Actions.setFocus(collection: 'thread', item: null)
|
|
if thread.id is keyboardId
|
|
Actions.setCursorPosition(collection: 'thread', item: null)
|
|
|
|
@_view.selection.clear()
|
|
|
|
_onArchiveAndPrev: ->
|
|
@_archiveAndShiftBy(-1)
|
|
|
|
_onArchiveAndNext: ->
|
|
@_archiveAndShiftBy(1)
|
|
|
|
_archiveAndShiftBy: (offset) ->
|
|
layoutMode = WorkspaceStore.layoutMode()
|
|
focused = FocusedContentStore.focused('thread')
|
|
explicitOffset = if offset is "auto" then false else true
|
|
|
|
return unless focused
|
|
|
|
# Determine the current index
|
|
index = @_view.indexOfId(focused.id)
|
|
return if index is -1
|
|
|
|
# Determine the next index we want to move to
|
|
if offset is 'auto'
|
|
if @_view.get(index - 1)?.isUnread()
|
|
offset = -1
|
|
else
|
|
offset = 1
|
|
|
|
index = Math.min(Math.max(index + offset, 0), @_view.count() - 1)
|
|
nextKeyboard = nextFocus = @_view.get(index)
|
|
|
|
# Archive the current thread
|
|
task = new AddRemoveTagsTask(focused, ['archive'], ['inbox'])
|
|
Actions.queueTask(task)
|
|
|
|
# Remove the current thread from selection
|
|
@_view.selection.remove(focused)
|
|
|
|
# If the user is in list mode and archived without specifically saying
|
|
# "archive and next" or "archive and prev", return to the thread list
|
|
# instead of focusing on the next message.
|
|
if layoutMode is 'list' and not explicitOffset
|
|
nextFocus = null
|
|
|
|
@_afterViewUpdate.push ->
|
|
Actions.setFocus(collection: 'thread', item: nextFocus)
|
|
Actions.setCursorPosition(collection: 'thread', item: nextKeyboard)
|
|
|
|
_autofocusForLayoutMode: ->
|
|
layoutMode = WorkspaceStore.layoutMode()
|
|
focused = FocusedContentStore.focused('thread')
|
|
if layoutMode is 'split' and not focused and @_view.selection.count() is 0
|
|
item = @_view.get(0)
|
|
_.defer =>
|
|
Actions.setFocus({collection: 'thread', item: item})
|