fix(perspective): Update MailboxPerspective.canApplyToThreads

- Checks if the account ids of the threads that want to be applied are
  contained inside the perspectives account ids. E.g.:
  - I can move thread from account A to unified inbox or inbox A, but
    not to inbox B.
  - I can move threads from account A to a folder in account A but not a
    folder in account B
- Update data transferred in drag + other minor updates
This commit is contained in:
Juan Tejada 2016-01-28 13:27:23 -08:00
parent 2e0469805b
commit 8237e3742c
4 changed files with 37 additions and 19 deletions

View file

@ -4,7 +4,8 @@ _ = require 'underscore'
FocusedPerspectiveStore, FocusedPerspectiveStore,
SyncbackCategoryTask, SyncbackCategoryTask,
DestroyCategoryTask, DestroyCategoryTask,
Actions} = require 'nylas-exports' Actions,
Utils} = require 'nylas-exports'
{OutlineViewItem} = require 'nylas-component-kit' {OutlineViewItem} = require 'nylas-component-kit'
@ -65,27 +66,24 @@ class SidebarItem
selected: isItemSelected(perspective) selected: isItemSelected(perspective)
collapsed: isItemCollapsed(id) ? true collapsed: isItemCollapsed(id) ? true
counterStyle: counterStyle counterStyle: counterStyle
dataTransferType: 'nylas-thread-ids' dataTransferType: 'nylas-threads-data'
onDelete: if opts.deletable then onDeleteItem else undefined onDelete: if opts.deletable then onDeleteItem else undefined
onEdited: if opts.editable then onEditItem else undefined onEdited: if opts.editable then onEditItem else undefined
onToggleCollapsed: toggleItemCollapsed onToggleCollapsed: toggleItemCollapsed
onDrop: (item, event) -> onDrop: (item, event) ->
jsonString = event.dataTransfer.getData(item.dataTransferType) jsonString = event.dataTransfer.getData(item.dataTransferType)
ids = null data = Utils.jsonParse(jsonString)
try return unless data
ids = JSON.parse(jsonString); item.perspective.applyToThreads(data.threadIds)
catch err
console.error('OutlineViewItem onDrop: JSON parse #{err}');
return unless ids
item.perspective.applyToThreads(ids)
shouldAcceptDrop: (item, event) -> shouldAcceptDrop: (item, event) ->
target = item.perspective target = item.perspective
current = FocusedPerspectiveStore.current() current = FocusedPerspectiveStore.current()
jsonString = event.dataTransfer.getData(item.dataTransferType)
data = Utils.jsonParse(jsonString)
return false unless data
return false unless target return false unless target
return false if target.isEqual(current) return false if target.isEqual(current)
return false unless _.isEqual(target.accountIds, current.accountIds) return false unless target.canApplyToThreads(data.accountIds)
return false unless target.canApplyToThreads()
return item.dataTransferType in event.dataTransfer.types return item.dataTransferType in event.dataTransfer.types

View file

@ -106,17 +106,26 @@ class ThreadList extends React.Component
event.preventDefault() event.preventDefault()
return return
if itemThreadId in ThreadListStore.dataSource().selection.ids() dataSource = ThreadListStore.dataSource()
dragThreadIds = ThreadListStore.dataSource().selection.ids() if itemThreadId in dataSource.selection.ids()
dragThreadIds = dataSource.selection.ids()
else else
dragThreadIds = [itemThreadId] dragThreadIds = [itemThreadId]
dragAccountIds = dragThreadIds.map (threadId) -> dataSource.getById(threadId).accountId
dragAccountIds = _.uniq(dragAccountIds)
dragData = {
accountIds: dragAccountIds,
threadIds: dragThreadIds
}
event.dataTransfer.effectAllowed = "move" event.dataTransfer.effectAllowed = "move"
event.dataTransfer.dragEffect = "move" event.dataTransfer.dragEffect = "move"
canvas = CanvasUtils.canvasWithThreadDragImage(dragThreadIds.length) canvas = CanvasUtils.canvasWithThreadDragImage(dragThreadIds.length)
event.dataTransfer.setDragImage(canvas, 10, 10) event.dataTransfer.setDragImage(canvas, 10, 10)
event.dataTransfer.setData('nylas-thread-ids', JSON.stringify(dragThreadIds)) event.dataTransfer.setData('nylas-threads-data', JSON.stringify(dragData))
return return
_onDragEnd: (event) => _onDragEnd: (event) =>

View file

@ -496,3 +496,13 @@ Utils =
fn.executing = true fn.executing = true
fn.apply(@, [fnFinished, fnReinvoked, arguments...]) fn.apply(@, [fnFinished, fnReinvoked, arguments...])
fnRun fnRun
# Parse json without throwing an error. Logs a sensible message to indicate
# the error occurred while parsing
jsonParse: (jsonString) =>
data = null
try
data = JSON.parse(jsonString)
catch err
console.error("JSON parse error: #{err}")
return data

View file

@ -73,8 +73,9 @@ class MailboxPerspective
threadUnreadCount: => threadUnreadCount: =>
0 0
canApplyToThreads: => canApplyToThreads: (targetAccountIds) =>
throw new Error("canApplyToThreads: Not implemented in base class.") targetIdsInCurrent = _.difference(targetAccountIds, @accountIds).length is 0
return targetIdsInCurrent
applyToThreads: (threadsOrIds) => applyToThreads: (threadsOrIds) =>
throw new Error("applyToThreads: Not implemented in base class.") throw new Error("applyToThreads: Not implemented in base class.")
@ -149,7 +150,7 @@ class StarredMailboxPerspective extends MailboxPerspective
return new MutableQuerySubscription(query, {asResultSet: true}) return new MutableQuerySubscription(query, {asResultSet: true})
canApplyToThreads: => canApplyToThreads: =>
true super
applyToThreads: (threadsOrIds) => applyToThreads: (threadsOrIds) =>
ChangeStarredTask = require './flux/tasks/change-starred-task' ChangeStarredTask = require './flux/tasks/change-starred-task'
@ -224,7 +225,7 @@ class CategoryMailboxPerspective extends MailboxPerspective
@_categories[0].name is 'inbox' @_categories[0].name is 'inbox'
canApplyToThreads: => canApplyToThreads: =>
not _.any @_categories, (c) -> c.isLockedCategory() super and not _.any @_categories, (c) -> c.isLockedCategory()
canArchiveThreads: => canArchiveThreads: =>
for cat in @_categories for cat in @_categories