2016-01-19 15:18:19 +08:00
|
|
|
_ = require 'underscore'
|
2016-02-05 06:48:15 +08:00
|
|
|
_str = require 'underscore.string'
|
2016-01-19 15:18:19 +08:00
|
|
|
{WorkspaceStore,
|
|
|
|
MailboxPerspective,
|
|
|
|
FocusedPerspectiveStore,
|
2016-01-28 15:16:17 +08:00
|
|
|
SyncbackCategoryTask,
|
2016-01-19 15:18:19 +08:00
|
|
|
DestroyCategoryTask,
|
2016-02-25 02:50:21 +08:00
|
|
|
CategoryStore,
|
2016-01-29 05:27:23 +08:00
|
|
|
Actions,
|
2016-06-16 07:46:34 +08:00
|
|
|
Utils,
|
|
|
|
RegExpUtils} = require 'nylas-exports'
|
2016-01-19 15:18:19 +08:00
|
|
|
{OutlineViewItem} = require 'nylas-component-kit'
|
|
|
|
|
2016-02-06 10:36:48 +08:00
|
|
|
SidebarActions = require './sidebar-actions'
|
2016-01-19 15:18:19 +08:00
|
|
|
|
|
|
|
idForCategories = (categories) ->
|
2016-01-26 10:42:56 +08:00
|
|
|
_.pluck(categories, 'id').join('-')
|
2016-01-19 15:18:19 +08:00
|
|
|
|
|
|
|
countForItem = (perspective) ->
|
|
|
|
unreadCountEnabled = NylasEnv.config.get('core.workspace.showUnreadForAllCategories')
|
|
|
|
if perspective.isInbox() or unreadCountEnabled
|
2016-02-05 06:14:24 +08:00
|
|
|
return perspective.unreadCount()
|
2016-01-19 15:18:19 +08:00
|
|
|
return 0
|
|
|
|
|
|
|
|
isItemSelected = (perspective) ->
|
2016-01-26 08:36:56 +08:00
|
|
|
(WorkspaceStore.rootSheet() in [WorkspaceStore.Sheet.Threads, WorkspaceStore.Sheet.Drafts] and
|
2016-01-19 15:18:19 +08:00
|
|
|
FocusedPerspectiveStore.current().isEqual(perspective))
|
|
|
|
|
|
|
|
isItemCollapsed = (id) ->
|
2016-02-06 10:36:48 +08:00
|
|
|
if NylasEnv.savedState.sidebarKeysCollapsed[id] isnt undefined
|
|
|
|
NylasEnv.savedState.sidebarKeysCollapsed[id]
|
|
|
|
else
|
|
|
|
true
|
2016-01-19 15:18:19 +08:00
|
|
|
|
2016-01-20 02:50:33 +08:00
|
|
|
toggleItemCollapsed = (item) ->
|
|
|
|
return unless item.children.length > 0
|
2016-02-06 10:36:48 +08:00
|
|
|
SidebarActions.setKeyCollapsed(item.id, not isItemCollapsed(item.id))
|
2016-01-20 02:50:33 +08:00
|
|
|
|
2016-01-28 15:16:17 +08:00
|
|
|
onDeleteItem = (item) ->
|
|
|
|
# TODO Delete multiple categories at once
|
|
|
|
return if item.deleted is true
|
|
|
|
category = item.perspective.category()
|
|
|
|
return unless category
|
|
|
|
|
|
|
|
Actions.queueTask(new DestroyCategoryTask({category}))
|
|
|
|
|
|
|
|
onEditItem = (item, value) ->
|
2016-01-28 16:02:55 +08:00
|
|
|
return unless value
|
2016-01-28 15:16:17 +08:00
|
|
|
return if item.deleted is true
|
|
|
|
category = item.perspective.category()
|
|
|
|
return unless category
|
2016-06-16 07:46:34 +08:00
|
|
|
re = RegExpUtils.subcategorySplitRegex()
|
|
|
|
match = re.exec(category.displayName)
|
|
|
|
lastMatch = match
|
|
|
|
while match
|
|
|
|
lastMatch = match
|
|
|
|
match = re.exec(category.displayName)
|
|
|
|
if lastMatch
|
|
|
|
newDisplayName = category.displayName.slice(0, lastMatch.index + 1) + value
|
|
|
|
else
|
|
|
|
newDisplayName = value
|
|
|
|
if newDisplayName is category.displayName
|
|
|
|
return
|
|
|
|
Actions.queueTask(new SyncbackCategoryTask({category, displayName: newDisplayName}))
|
2016-01-28 15:16:17 +08:00
|
|
|
|
2016-01-19 15:18:19 +08:00
|
|
|
|
|
|
|
class SidebarItem
|
|
|
|
|
2016-01-26 08:36:56 +08:00
|
|
|
@forPerspective: (id, perspective, opts = {}) ->
|
2016-01-19 15:18:19 +08:00
|
|
|
counterStyle = OutlineViewItem.CounterStyles.Alt if perspective.isInbox()
|
|
|
|
|
2016-01-26 08:36:56 +08:00
|
|
|
return _.extend({
|
2016-01-19 15:18:19 +08:00
|
|
|
id: id
|
2016-01-26 08:36:56 +08:00
|
|
|
name: perspective.name
|
2016-02-05 06:48:15 +08:00
|
|
|
contextMenuLabel: perspective.name
|
2016-01-19 15:18:19 +08:00
|
|
|
count: countForItem(perspective)
|
|
|
|
iconName: perspective.iconName
|
2016-01-26 08:36:56 +08:00
|
|
|
children: []
|
2016-01-19 15:18:19 +08:00
|
|
|
perspective: perspective
|
|
|
|
selected: isItemSelected(perspective)
|
2016-01-21 11:22:33 +08:00
|
|
|
collapsed: isItemCollapsed(id) ? true
|
2016-01-19 15:18:19 +08:00
|
|
|
counterStyle: counterStyle
|
2016-01-28 15:16:17 +08:00
|
|
|
onDelete: if opts.deletable then onDeleteItem else undefined
|
|
|
|
onEdited: if opts.editable then onEditItem else undefined
|
2016-01-29 08:18:43 +08:00
|
|
|
onCollapseToggled: toggleItemCollapsed
|
2016-09-21 06:48:15 +08:00
|
|
|
|
2016-01-28 03:45:02 +08:00
|
|
|
onDrop: (item, event) ->
|
2016-09-21 06:48:15 +08:00
|
|
|
jsonString = event.dataTransfer.getData('nylas-threads-data')
|
|
|
|
jsonData = null
|
|
|
|
try
|
|
|
|
jsonData = JSON.parse(jsonString)
|
|
|
|
catch err
|
|
|
|
console.error("JSON parse error: #{err}")
|
|
|
|
return unless jsonData
|
|
|
|
item.perspective.receiveThreads(jsonData.threadIds)
|
|
|
|
|
2016-01-19 15:18:19 +08:00
|
|
|
shouldAcceptDrop: (item, event) ->
|
2016-01-28 03:45:02 +08:00
|
|
|
target = item.perspective
|
|
|
|
current = FocusedPerspectiveStore.current()
|
2016-09-21 06:48:15 +08:00
|
|
|
return false unless event.dataTransfer.types.includes('nylas-threads-data')
|
2016-01-28 03:45:02 +08:00
|
|
|
return false if target.isEqual(current)
|
2016-09-21 06:48:15 +08:00
|
|
|
|
|
|
|
# We can't inspect the drag payload until drop, so we use a dataTransfer
|
|
|
|
# type to encode the account IDs of threads currently being dragged.
|
|
|
|
accountsType = event.dataTransfer.types.find((t) => t.startsWith('nylas-accounts='))
|
|
|
|
accountIds = (accountsType || "").replace('nylas-accounts=', '').split(',')
|
|
|
|
return target.canReceiveThreadsFromAccountIds(accountIds)
|
|
|
|
|
2016-01-19 15:18:19 +08:00
|
|
|
onSelect: (item) ->
|
|
|
|
Actions.focusMailboxPerspective(item.perspective)
|
2016-01-26 08:36:56 +08:00
|
|
|
}, opts)
|
2016-01-19 15:18:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
@forCategories: (categories = [], opts = {}) ->
|
|
|
|
id = idForCategories(categories)
|
2016-02-05 06:48:15 +08:00
|
|
|
contextMenuLabel = _str.capitalize(categories[0]?.displayType())
|
2016-01-19 15:18:19 +08:00
|
|
|
perspective = MailboxPerspective.forCategories(categories)
|
2016-02-05 06:48:15 +08:00
|
|
|
|
2016-01-29 08:20:46 +08:00
|
|
|
opts.deletable ?= true
|
|
|
|
opts.editable ?= true
|
2016-02-05 06:48:15 +08:00
|
|
|
opts.contextMenuLabel = contextMenuLabel
|
2016-01-19 15:18:19 +08:00
|
|
|
@forPerspective(id, perspective, opts)
|
|
|
|
|
2016-02-25 02:50:21 +08:00
|
|
|
@forSnoozed: (accountIds, opts = {}) ->
|
|
|
|
# TODO This constant should be available elsewhere
|
2016-05-04 09:08:24 +08:00
|
|
|
constants = require('../../thread-snooze/lib/snooze-constants')
|
|
|
|
displayName = constants.SNOOZE_CATEGORY_NAME
|
2016-02-25 02:50:21 +08:00
|
|
|
id = displayName
|
|
|
|
id += "-#{opts.name}" if opts.name
|
|
|
|
opts.name = "Snoozed" unless opts.name
|
|
|
|
opts.iconName= 'snooze.png'
|
2016-02-25 03:43:51 +08:00
|
|
|
|
2016-02-25 02:50:21 +08:00
|
|
|
categories = accountIds.map (accId) =>
|
2016-02-25 08:51:19 +08:00
|
|
|
_.findWhere CategoryStore.categories(accId), {displayName}
|
2016-02-25 03:43:51 +08:00
|
|
|
categories = _.compact(categories)
|
2016-02-25 02:50:21 +08:00
|
|
|
|
|
|
|
perspective = MailboxPerspective.forCategories(categories)
|
2016-02-25 03:43:51 +08:00
|
|
|
perspective.name = id unless perspective.name
|
2016-02-25 02:50:21 +08:00
|
|
|
@forPerspective(id, perspective, opts)
|
|
|
|
|
2016-01-19 15:18:19 +08:00
|
|
|
@forStarred: (accountIds, opts = {}) ->
|
|
|
|
perspective = MailboxPerspective.forStarred(accountIds)
|
|
|
|
id = 'Starred'
|
|
|
|
id += "-#{opts.name}" if opts.name
|
|
|
|
@forPerspective(id, perspective, opts)
|
|
|
|
|
2016-04-20 02:32:33 +08:00
|
|
|
@forUnread: (accountIds, opts = {}) ->
|
|
|
|
categories = accountIds.map (accId) =>
|
|
|
|
CategoryStore.getStandardCategory(accId, 'inbox')
|
2016-05-04 02:30:41 +08:00
|
|
|
|
|
|
|
# NOTE: It's possible for an account to not yet have an `inbox`
|
|
|
|
# category. Since the `SidebarStore` triggers on `AccountStore`
|
|
|
|
# changes, it'll trigger the exact moment an account is added to the
|
|
|
|
# config. However, the API has not yet come back with the list of
|
|
|
|
# `categories` for that account.
|
|
|
|
categories = _.compact(categories)
|
|
|
|
|
2016-04-20 02:32:33 +08:00
|
|
|
perspective = MailboxPerspective.forUnread(categories)
|
|
|
|
id = 'Unread'
|
|
|
|
id += "-#{opts.name}" if opts.name
|
|
|
|
@forPerspective(id, perspective, opts)
|
|
|
|
|
2016-01-26 08:36:56 +08:00
|
|
|
@forDrafts: (accountIds, opts = {}) ->
|
|
|
|
perspective = MailboxPerspective.forDrafts(accountIds)
|
|
|
|
id = "Drafts-#{opts.name}"
|
|
|
|
@forPerspective(id, perspective, opts)
|
2016-01-19 15:18:19 +08:00
|
|
|
|
|
|
|
module.exports = SidebarItem
|