mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-11 10:12:00 +08:00
Add account switcher back to sidebar:
- Account switcher can now switch between all accounts and each account - Updates FocusedPerspectiveStore and Actions.focusDefaultMailboxPerspectiveForAccounts to focus a perspective for accountIds instead of for a single account, and updates methods - Adds helpers to CategoryStore and MailboxPerspective - Updates key commands to allow switch to unified inbox
This commit is contained in:
parent
38590139bc
commit
b538ec050c
12 changed files with 207 additions and 178 deletions
|
@ -1,6 +1,7 @@
|
|||
_ = require 'underscore'
|
||||
React = require 'react'
|
||||
{OutlineView, ScrollRegion} = require 'nylas-component-kit'
|
||||
AccountSwitcher = require './account-switcher'
|
||||
SidebarStore = require '../sidebar-store'
|
||||
|
||||
|
||||
|
@ -26,23 +27,27 @@ class AccountSidebar extends React.Component
|
|||
@setState @_getStateFromStores()
|
||||
|
||||
_getStateFromStores: =>
|
||||
standardSection: SidebarStore.standardSection()
|
||||
accounts: SidebarStore.accounts()
|
||||
focusedAccounts: SidebarStore.focusedAccounts()
|
||||
userSections: SidebarStore.userSections()
|
||||
standardSection: SidebarStore.standardSection()
|
||||
|
||||
_renderUserSections: (sections) =>
|
||||
sections.map (section) =>
|
||||
<OutlineView key={section.title} {...section} />
|
||||
|
||||
render: =>
|
||||
standardSection = @state.standardSection
|
||||
userSections = @state.userSections
|
||||
{accounts, focusedAccounts, userSections, standardSection} = @state
|
||||
|
||||
<ScrollRegion className="account-sidebar" >
|
||||
<div className="account-sidebar-sections">
|
||||
<OutlineView {...standardSection} />
|
||||
{@_renderUserSections(userSections)}
|
||||
</div>
|
||||
</ScrollRegion>
|
||||
<div style={height: '100%'}>
|
||||
<AccountSwitcher accounts={accounts} focusedAccounts={focusedAccounts} />
|
||||
<ScrollRegion className="account-sidebar" >
|
||||
<div className="account-sidebar-sections">
|
||||
<OutlineView {...standardSection} />
|
||||
{@_renderUserSections(userSections)}
|
||||
</div>
|
||||
</ScrollRegion>
|
||||
</div>
|
||||
|
||||
|
||||
module.exports = AccountSidebar
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
React = require 'react'
|
||||
SidebarStore = require '../sidebar-store'
|
||||
{Actions, AccountStore} = require("nylas-exports")
|
||||
{Actions} = require("nylas-exports")
|
||||
{RetinaImg} = require 'nylas-component-kit'
|
||||
crypto = require 'crypto'
|
||||
classNames = require 'classnames'
|
||||
|
||||
|
||||
ItemTypes = {
|
||||
"Unified"
|
||||
}
|
||||
|
||||
class AccountSwitcher extends React.Component
|
||||
@displayName: 'AccountSwitcher'
|
||||
|
||||
|
@ -13,62 +17,69 @@ class AccountSwitcher extends React.Component
|
|||
minWidth: 165
|
||||
maxWidth: 210
|
||||
|
||||
@propTypes:
|
||||
accounts: React.PropTypes.array.isRequired
|
||||
focusedAccounts: React.PropTypes.array.isRequired
|
||||
|
||||
constructor: (@props) ->
|
||||
@state = @_getStateFromStores()
|
||||
@state.showing = false
|
||||
@state =
|
||||
showing: false
|
||||
|
||||
componentDidMount: =>
|
||||
@unsubscribers = []
|
||||
@unsubscribers.push AccountStore.listen @_onStoreChange
|
||||
# Helpers
|
||||
|
||||
componentWillUnmount: =>
|
||||
unsubscribe() for unsubscribe in @unsubscribers
|
||||
_makeItem: ({id, label, emailAddress, provider} = {}) =>
|
||||
id ?= ItemTypes.Unified
|
||||
label ?= "All Accounts"
|
||||
email = emailAddress ? ""
|
||||
iconName = provider ? 'imap'
|
||||
accounts = if id is ItemTypes.Unified
|
||||
@props.accounts
|
||||
else
|
||||
[id]
|
||||
|
||||
render: =>
|
||||
return false unless @state.account
|
||||
return {id, label, email, iconName, accounts}
|
||||
|
||||
classnames = ""
|
||||
classnames += "open" if @state.showing
|
||||
_selectedItem: =>
|
||||
if @props.focusedAccounts.length > 1
|
||||
@_makeItem()
|
||||
else
|
||||
@_makeItem(@props.focusedAccounts[0])
|
||||
|
||||
<div id="account-switcher"
|
||||
tabIndex={-1}
|
||||
onBlur={@_onBlur}
|
||||
ref="button"
|
||||
className={classnames}>
|
||||
{@_renderPrimaryItem()}
|
||||
{@_renderDropdown()}
|
||||
</div>
|
||||
_toggleDropdown: =>
|
||||
@setState showing: !@state.showing
|
||||
|
||||
_renderPrimaryItem: =>
|
||||
label = @state.account.label.trim()
|
||||
<div className="item primary-item" onClick={@_toggleDropdown}>
|
||||
{@_renderGravatarForAccount(@state.account)}
|
||||
<div style={float: 'right', marginTop: -2}>
|
||||
<RetinaImg className="toggle"
|
||||
name="account-switcher-dropdown.png"
|
||||
mode={RetinaImg.Mode.ContentDark} />
|
||||
</div>
|
||||
<div className="name" style={lineHeight: "110%"}>
|
||||
{label}
|
||||
</div>
|
||||
<div style={clear: "both"}></div>
|
||||
</div>
|
||||
|
||||
_renderAccount: (account) =>
|
||||
email = account.emailAddress.trim().toLowerCase()
|
||||
label = account.label.trim()
|
||||
# Handlers
|
||||
|
||||
_onBlur: (e) =>
|
||||
target = e.nativeEvent.relatedTarget
|
||||
if target? and React.findDOMNode(@refs.button).contains(target)
|
||||
return
|
||||
@setState(showing: false)
|
||||
|
||||
_onSwitchAccount: (item) =>
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts(item.accounts)
|
||||
@setState(showing: false)
|
||||
|
||||
_onManageAccounts: =>
|
||||
Actions.switchPreferencesTab('Accounts')
|
||||
Actions.openPreferences()
|
||||
|
||||
@setState(showing: false)
|
||||
|
||||
_renderItem: (item) =>
|
||||
classes = classNames
|
||||
"active": account is @state.account
|
||||
"active": item.id is @_selectedItem().id
|
||||
"item": true
|
||||
"secondary-item": true
|
||||
|
||||
<div className={classes} onClick={ => @_onSwitchAccount(account)} key={email}>
|
||||
{@_renderGravatarForAccount(account)}
|
||||
<div className="name" style={lineHeight: "110%"}>{label}</div>
|
||||
<div key={item.email} className={classes} onClick={@_onSwitchAccount.bind(@, item)}>
|
||||
{@_renderGravatar(item)}
|
||||
<div className="name" style={lineHeight: "110%"}>{item.label}</div>
|
||||
<div style={clear: "both"}></div>
|
||||
</div>
|
||||
|
||||
_renderNewAccountOption: =>
|
||||
_renderManageAccountsItem: =>
|
||||
<div className="item secondary-item new-account-option"
|
||||
onClick={@_onManageAccounts}
|
||||
tabIndex={999}>
|
||||
|
@ -84,51 +95,58 @@ class AccountSwitcher extends React.Component
|
|||
<div style={clear: "both"}></div>
|
||||
</div>
|
||||
|
||||
_renderDropdown: =>
|
||||
_renderDropdown: (items) =>
|
||||
<div className="dropdown">
|
||||
<div className="inner">
|
||||
{@state.accounts.map(@_renderAccount)}
|
||||
{@_renderNewAccountOption()}
|
||||
{items.map(@_renderItem)}
|
||||
{@_renderManageAccountsItem()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
_renderGravatarForAccount: (account) =>
|
||||
email = account.emailAddress.trim().toLowerCase()
|
||||
hash = crypto.createHash('md5').update(email, 'utf8').digest('hex')
|
||||
url = "url(http://www.gravatar.com/avatar/#{hash}?d=blank&s=56)"
|
||||
_renderGravatar: ({email, iconName}) =>
|
||||
if email
|
||||
hash = crypto.createHash('md5').update(email, 'utf8').digest('hex')
|
||||
url = "url(http://www.gravatar.com/avatar/#{hash}?d=blank&s=56)"
|
||||
else
|
||||
url = ''
|
||||
|
||||
<div style={float: 'left', position: "relative"}>
|
||||
<div className="gravatar" style={backgroundImage:url}></div>
|
||||
<RetinaImg name={"ic-settings-account-#{account.provider}@2x.png"}
|
||||
<RetinaImg name={"ic-settings-account-#{iconName}@2x.png"}
|
||||
style={width: 28, height: 28, marginTop: -10}
|
||||
fallback="ic-settings-account-imap.png"
|
||||
mode={RetinaImg.Mode.ContentPreserve} />
|
||||
</div>
|
||||
|
||||
_toggleDropdown: =>
|
||||
@setState showing: !@state.showing
|
||||
_renderPrimaryItem: (item) =>
|
||||
<div className="item primary-item" onClick={@_toggleDropdown}>
|
||||
{@_renderGravatar(item)}
|
||||
<div style={float: 'right', marginTop: -2}>
|
||||
<RetinaImg className="toggle"
|
||||
name="account-switcher-dropdown.png"
|
||||
mode={RetinaImg.Mode.ContentDark} />
|
||||
</div>
|
||||
<div className="name" style={lineHeight: "110%"}>
|
||||
{item.label}
|
||||
</div>
|
||||
<div style={clear: "both"}></div>
|
||||
</div>
|
||||
|
||||
_onStoreChange: =>
|
||||
@setState @_getStateFromStores()
|
||||
render: =>
|
||||
return <span /> unless @props.focusedAccounts
|
||||
classnames = ""
|
||||
classnames += "open" if @state.showing
|
||||
selected = @_selectedItem()
|
||||
items = [@_makeItem()].concat @props.accounts.map(@_makeItem)
|
||||
|
||||
_onBlur: (e) =>
|
||||
target = e.nativeEvent.relatedTarget
|
||||
if target? and React.findDOMNode(@refs.button).contains(target)
|
||||
return
|
||||
@setState(showing: false)
|
||||
<div id="account-switcher"
|
||||
tabIndex={-1}
|
||||
onBlur={@_onBlur}
|
||||
ref="button"
|
||||
className={classnames}>
|
||||
{@_renderPrimaryItem(selected)}
|
||||
{@_renderDropdown(items)}
|
||||
</div>
|
||||
|
||||
_onSwitchAccount: (account) =>
|
||||
Actions.focusDefaultMailboxPerspectiveForAccount(account.id)
|
||||
@setState(showing: false)
|
||||
|
||||
_onManageAccounts: =>
|
||||
Actions.switchPreferencesTab('Accounts')
|
||||
Actions.openPreferences()
|
||||
|
||||
@setState(showing: false)
|
||||
|
||||
_getStateFromStores: =>
|
||||
accounts: AccountStore.accounts()
|
||||
account: SidebarStore.currentAccount()
|
||||
|
||||
module.exports = AccountSwitcher
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
Reflux = require 'reflux'
|
||||
|
||||
Actions = [
|
||||
'selectAccount'
|
||||
]
|
||||
|
||||
for key in Actions
|
||||
Actions[key] = Reflux.createAction(name)
|
||||
Actions[key].sync = true
|
||||
|
||||
module.exports = Actions
|
|
@ -1,5 +1,6 @@
|
|||
_ = require 'underscore'
|
||||
{Actions,
|
||||
AccountStore,
|
||||
SyncbackCategoryTask,
|
||||
DestroyCategoryTask,
|
||||
CategoryHelpers,
|
||||
|
@ -17,13 +18,14 @@ class SidebarSection
|
|||
}
|
||||
|
||||
@standardSectionForAccount: (account) ->
|
||||
return @empty('Mailboxes') if CategoryStore.categories().length is 0
|
||||
cats = CategoryStore.standardCategories(account)
|
||||
items = _
|
||||
.reject(cats, (cat) -> cat.name is 'drafts')
|
||||
.map (cat) => SidebarItem.forCategories([cat])
|
||||
|
||||
starredItem = SidebarItem.forStarred([account.id])
|
||||
draftsItem = SidebarItem.forDrafts(accountId: account.id)
|
||||
draftsItem = SidebarItem.forDrafts({accountId: account.id})
|
||||
|
||||
# Order correctly: Inbox, Starred, rest... , Drafts
|
||||
items.splice(1, 0, starredItem)
|
||||
|
@ -39,31 +41,27 @@ class SidebarSection
|
|||
return @empty('Mailboxes') if CategoryStore.categories().length is 0
|
||||
return @standardSectionForAccount(accounts[0]) if accounts.length is 1
|
||||
|
||||
# TODO Decide standard items for the unified case
|
||||
inboxItem = SidebarItem.forCategories(
|
||||
(accounts.map (acc)-> CategoryStore.getStandardCategory(acc, 'inbox')),
|
||||
children: accounts.map (acc) ->
|
||||
cat = CategoryStore.getStandardCategory(acc, 'inbox')
|
||||
standardNames = [
|
||||
'inbox',
|
||||
'sent',
|
||||
['archive', 'all'],
|
||||
'trash'
|
||||
]
|
||||
items = []
|
||||
|
||||
for names in standardNames
|
||||
names = if Array.isArray(names) then names else [names]
|
||||
categories = CategoryStore.getStandardCategories(accounts, names...)
|
||||
continue if categories.length is 0
|
||||
|
||||
children = accounts.map (acc) ->
|
||||
cat = _.first(_.compact(
|
||||
names.map((name) -> CategoryStore.getStandardCategory(acc, name))
|
||||
))
|
||||
SidebarItem.forCategories([cat], name: acc.label)
|
||||
)
|
||||
sentItem = SidebarItem.forCategories(
|
||||
(accounts.map (acc)-> CategoryStore.getStandardCategory(acc, 'sent')),
|
||||
children: accounts.map (acc) ->
|
||||
cat = CategoryStore.getStandardCategory(acc, 'sent')
|
||||
SidebarItem.forCategories([cat], name: acc.label)
|
||||
)
|
||||
archiveItem = SidebarItem.forCategories(
|
||||
(accounts.map (acc)-> CategoryStore.getArchiveCategory(acc)),
|
||||
children: accounts.map (acc) ->
|
||||
cat = CategoryStore.getArchiveCategory(acc)
|
||||
SidebarItem.forCategories([cat], name: acc.label)
|
||||
)
|
||||
trashItem = SidebarItem.forCategories(
|
||||
(accounts.map (acc)-> CategoryStore.getTrashCategory(acc)),
|
||||
children: accounts.map (acc) ->
|
||||
cat = CategoryStore.getTrashCategory(acc)
|
||||
SidebarItem.forCategories([cat], name: acc.label)
|
||||
)
|
||||
|
||||
items.push SidebarItem.forCategories(categories, {children})
|
||||
|
||||
starredItem = SidebarItem.forStarred(_.pluck(accounts, 'id'),
|
||||
children: accounts.map (acc) -> SidebarItem.forStarred([acc.id], name: acc.label)
|
||||
)
|
||||
|
@ -72,14 +70,9 @@ class SidebarSection
|
|||
SidebarItem.forDrafts(accountId: acc.id, name: acc.label)
|
||||
)
|
||||
|
||||
items = [
|
||||
inboxItem
|
||||
starredItem
|
||||
sentItem
|
||||
archiveItem
|
||||
trashItem
|
||||
draftsItem
|
||||
]
|
||||
# Order correctly: Inbox, Starred, rest... , Drafts
|
||||
items.splice(1, 0, starredItem)
|
||||
items.push(draftsItem)
|
||||
|
||||
return {
|
||||
title: 'Mailboxes'
|
||||
|
|
|
@ -12,7 +12,6 @@ _ = require 'underscore'
|
|||
CategoryStore} = require 'nylas-exports'
|
||||
|
||||
SidebarSection = require './sidebar-section'
|
||||
SidebarActions = require './sidebar-actions'
|
||||
|
||||
Sections = {
|
||||
"Standard",
|
||||
|
@ -23,11 +22,18 @@ class SidebarStore extends NylasStore
|
|||
|
||||
constructor: ->
|
||||
@_sections = {}
|
||||
# @_account = AccountStore.accounts()[0]
|
||||
@_account = FocusedPerspectiveStore.current().account
|
||||
@_sections[Sections.Standard] = {}
|
||||
@_sections[Sections.User] = []
|
||||
@_registerListeners()
|
||||
@_updateSections()
|
||||
|
||||
accounts: ->
|
||||
AccountStore.accounts()
|
||||
|
||||
focusedAccounts: ->
|
||||
accountIds = FocusedPerspectiveStore.current().accountIds
|
||||
accountIds.map((accId) -> AccountStore.accountForId(accId))
|
||||
|
||||
standardSection: ->
|
||||
@_sections[Sections.Standard]
|
||||
|
||||
|
@ -35,7 +41,6 @@ class SidebarStore extends NylasStore
|
|||
@_sections[Sections.User]
|
||||
|
||||
_registerListeners: ->
|
||||
@listenTo SidebarActions.selectAccount, @_onAccountSelected
|
||||
@listenTo AccountStore, @_updateSections
|
||||
@listenTo WorkspaceStore, @_updateSections
|
||||
@listenTo ThreadCountsStore, @_updateSections
|
||||
|
@ -52,13 +57,9 @@ class SidebarStore extends NylasStore
|
|||
)
|
||||
return
|
||||
|
||||
_onAccountSelected: (account) =>
|
||||
if @_account isnt account
|
||||
@_account = account
|
||||
@_updateSections()
|
||||
|
||||
_updateSections: =>
|
||||
accounts = if @_account? then [@_account] else AccountStore.accounts()
|
||||
accounts = @focusedAccounts()
|
||||
|
||||
@_sections[Sections.Standard] = SidebarSection.standardSectionForAccounts(accounts)
|
||||
@_sections[Sections.User] = accounts.map (acc) ->
|
||||
SidebarSection.forUserCategories(acc)
|
||||
|
|
|
@ -50,7 +50,7 @@ class SearchSuggestionStore extends NylasStore
|
|||
Actions.focusMailboxPerspective(@_perspectiveBeforeSearch)
|
||||
@_perspectiveBeforeSearch = null
|
||||
else
|
||||
Actions.focusDefaultMailboxPerspectiveForAccount(current.accountIds[0])
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts([current.accountIds[0]])
|
||||
|
||||
@_clearResults()
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ describe "AccountStore", ->
|
|||
"auth_token": "auth-123"
|
||||
"organization_unit": "label"
|
||||
@instance = new @constructor
|
||||
spyOn(Actions, 'focusDefaultMailboxPerspectiveForAccount')
|
||||
spyOn(Actions, 'focusDefaultMailboxPerspectiveForAccounts')
|
||||
spyOn(@instance, "trigger")
|
||||
@instance.addAccountFromJSON(@json)
|
||||
|
||||
|
@ -69,7 +69,7 @@ describe "AccountStore", ->
|
|||
expect(NylasEnv.config.set.calls.length).toBe 2
|
||||
|
||||
it "selects the account", ->
|
||||
expect(Actions.focusDefaultMailboxPerspectiveForAccount).toHaveBeenCalledWith("1234")
|
||||
expect(Actions.focusDefaultMailboxPerspectiveForAccounts).toHaveBeenCalledWith(["1234"])
|
||||
|
||||
it "triggers", ->
|
||||
expect(@instance.trigger).toHaveBeenCalled()
|
||||
|
|
|
@ -227,7 +227,7 @@ class Actions
|
|||
|
||||
*Scope: Window*
|
||||
###
|
||||
@focusDefaultMailboxPerspectiveForAccount: ActionScopeWindow
|
||||
@focusDefaultMailboxPerspectiveForAccounts: ActionScopeWindow
|
||||
|
||||
###
|
||||
Public: If the message with the provided id is currently beign displayed in the
|
||||
|
|
|
@ -32,7 +32,7 @@ class AccountStore
|
|||
newAccountIds = _.keys(_.omit(updatedTokens, _.keys(@_tokens)))
|
||||
@_load()
|
||||
if newAccountIds.length > 0
|
||||
Actions.focusDefaultMailboxPerspectiveForAccount(newAccountIds[0])
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts([newAccountIds[0]])
|
||||
if NylasEnv.isComposerWindow()
|
||||
NylasEnv.config.observe saveObjectsKey, => @_load()
|
||||
|
||||
|
@ -88,7 +88,7 @@ class AccountStore
|
|||
@_save()
|
||||
|
||||
@trigger()
|
||||
Actions.focusDefaultMailboxPerspectiveForAccount(account.id)
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts([account.id])
|
||||
|
||||
# Exposed Data
|
||||
|
||||
|
@ -200,7 +200,7 @@ class AccountStore
|
|||
t.persistModels(threads)
|
||||
])
|
||||
.then =>
|
||||
Actions.focusDefaultMailboxPerspectiveForAccount(account.id)
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts([account.id])
|
||||
.then -> new Promise (resolve, reject) -> setTimeout(resolve, 1000)
|
||||
|
||||
module.exports = new AccountStore()
|
||||
|
|
|
@ -65,6 +65,16 @@ class CategoryStore extends NylasStore
|
|||
|
||||
return _.findWhere(@_standardCategories[asAccountId(accountOrId)], {name})
|
||||
|
||||
getStandardCategories: (accountsOrIds, names...) ->
|
||||
if Array.isArray(accountsOrIds)
|
||||
res = []
|
||||
for accOrId in accountsOrIds
|
||||
cats = names.map((name) => @getStandardCategory(accOrId, name))
|
||||
res = res.concat(_.compact(cats))
|
||||
res
|
||||
else
|
||||
names.map((name) => @getStandardCategory(accountsOrIds, name))
|
||||
|
||||
# Public: Returns the Folder or Label object that should be used for "Archive"
|
||||
# actions. On Gmail, this is the "all" label. On providers using folders, it
|
||||
# returns any available "Archive" folder, or null if no such folder exists.
|
||||
|
|
|
@ -16,7 +16,7 @@ class FocusedPerspectiveStore extends NylasStore
|
|||
@listenTo AccountStore, @_onAccountStoreChanged
|
||||
|
||||
@listenTo Actions.focusMailboxPerspective, @_onFocusPerspective
|
||||
@listenTo Actions.focusDefaultMailboxPerspectiveForAccount, @_onFocusAccount
|
||||
@listenTo Actions.focusDefaultMailboxPerspectiveForAccounts, @_onFocusAccounts
|
||||
|
||||
@_onCategoryStoreChanged()
|
||||
@_setupFastAccountCommands()
|
||||
|
@ -28,15 +28,16 @@ class FocusedPerspectiveStore extends NylasStore
|
|||
@_setupFastAccountMenu()
|
||||
|
||||
_onCategoryStoreChanged: ->
|
||||
if not @_current
|
||||
if @_current.isEqual(MailboxPerspective.forNothing())
|
||||
@_setPerspective(@_defaultPerspective())
|
||||
else
|
||||
account = @_current.account
|
||||
cats = @_current.categories()
|
||||
catExists = (cat) -> CategoryStore.byId(cat.accountId, cat.id)
|
||||
accountIds = @_current.accountIds
|
||||
categories = @_current.categories()
|
||||
catExists = (cat) -> CategoryStore.byId(cat.accountId, cat.id)
|
||||
categoryHasBeenDeleted = categories and not _.every(categories, catExists)
|
||||
|
||||
if cats and not _.every(cats, catExists)
|
||||
@_setPerspective(@_defaultPerspective(account))
|
||||
if categoryHasBeenDeleted
|
||||
@_setPerspective(@_defaultPerspective(accountIds))
|
||||
|
||||
_onFocusPerspective: (perspective) =>
|
||||
return if perspective.isEqual(@_current)
|
||||
|
@ -44,18 +45,13 @@ class FocusedPerspectiveStore extends NylasStore
|
|||
Actions.selectRootSheet(WorkspaceStore.Sheet.Threads)
|
||||
@_setPerspective(perspective)
|
||||
|
||||
_onFocusAccount: (accountId) =>
|
||||
account = AccountStore.accountForId(accountId) unless account instanceof Account
|
||||
return unless account
|
||||
category = CategoryStore.getStandardCategory(account, "inbox")
|
||||
return unless category
|
||||
@_setPerspective(MailboxPerspective.forCategory(category))
|
||||
_onFocusAccounts: (accountsOrIds) =>
|
||||
return unless accountsOrIds
|
||||
@_setPerspective(MailboxPerspective.forInbox(accountsOrIds))
|
||||
|
||||
_defaultPerspective: (account = AccountStore.accounts()[0]) ->
|
||||
return MailboxPerspective.forNothing() unless account
|
||||
category = CategoryStore.getStandardCategory(account, "inbox")
|
||||
return MailboxPerspective.forNothing() unless category
|
||||
return MailboxPerspective.forCategory(category)
|
||||
_defaultPerspective: (accounts = AccountStore.accounts()) ->
|
||||
return MailboxPerspective.forNothing() unless accounts.length > 0
|
||||
return MailboxPerspective.forInbox(accounts)
|
||||
|
||||
_setPerspective: (perspective) ->
|
||||
return if perspective?.isEqual(@_current)
|
||||
|
@ -64,9 +60,13 @@ class FocusedPerspectiveStore extends NylasStore
|
|||
|
||||
_setupFastAccountCommands: ->
|
||||
commands = {}
|
||||
[0..8].forEach (index) =>
|
||||
allKey = "application:select-account-0"
|
||||
commands[allKey] = => @_onFocusAccounts(AccountStore.accounts())
|
||||
[1..8].forEach (index) =>
|
||||
account = AccountStore.accounts()[index - 1]
|
||||
return unless account
|
||||
key = "application:select-account-#{index}"
|
||||
commands[key] = => @_onFocusAccount(AccountStore.accounts()[index])
|
||||
commands[key] = => @_onFocusAccounts([account])
|
||||
NylasEnv.commands.add('body', commands)
|
||||
|
||||
_setupFastAccountMenu: ->
|
||||
|
@ -77,14 +77,18 @@ class FocusedPerspectiveStore extends NylasStore
|
|||
idx = _.findIndex submenu, ({type}) -> type is 'separator'
|
||||
return unless idx > 0
|
||||
|
||||
accountMenuItems = AccountStore.accounts().map (item, idx) =>
|
||||
{
|
||||
label: item.emailAddress,
|
||||
command: "application:select-account-#{idx}",
|
||||
account: true
|
||||
}
|
||||
menuItems = [{
|
||||
label: 'All Accounts'
|
||||
command: "application:select-account-0"
|
||||
account: true
|
||||
}]
|
||||
menuItems = menuItems.concat AccountStore.accounts().map((item, idx) =>
|
||||
label: item.emailAddress,
|
||||
command: "application:select-account-#{idx + 1}",
|
||||
account: true
|
||||
)
|
||||
|
||||
submenu.splice(idx + 1, 0, accountMenuItems...)
|
||||
submenu.splice(idx + 1, 0, menuItems...)
|
||||
windowMenu.submenu = submenu
|
||||
NylasEnv.menu.update()
|
||||
|
||||
|
|
|
@ -20,21 +20,29 @@ class MailboxPerspective
|
|||
new EmptyMailboxPerspective()
|
||||
|
||||
@forCategory: (category) ->
|
||||
return @forNothing() unless category
|
||||
new CategoryMailboxPerspective([category])
|
||||
|
||||
@forCategories: (categories) ->
|
||||
return @forNothing() if categories.length is 0
|
||||
new CategoryMailboxPerspective(categories)
|
||||
|
||||
@forStarred: (accountIds) ->
|
||||
new StarredMailboxPerspective(accountIds)
|
||||
@forStandardCategories: (accountsOrIds, names...) ->
|
||||
categories = CategoryStore.getStandardCategories(accountsOrIds, names...)
|
||||
@forCategories(categories)
|
||||
|
||||
@forSearch: (accountIds, query) ->
|
||||
new SearchMailboxPerspective(accountIds, query)
|
||||
@forStarred: (accountsOrIds) ->
|
||||
new StarredMailboxPerspective(accountsOrIds)
|
||||
|
||||
@forSearch: (accountsOrIds, query) ->
|
||||
new SearchMailboxPerspective(accountsOrIds, query)
|
||||
|
||||
@forInbox: (accountsOrIds) =>
|
||||
@forStandardCategories(accountsOrIds, 'inbox')
|
||||
|
||||
@forAll: (accountsOrIds) =>
|
||||
@forStandardCategories(accountsOrIds, 'all')
|
||||
|
||||
@forAll: (accountIds) ->
|
||||
categories = accountIds.map (aid) ->
|
||||
CategoryStore.getStandardCategory(aid, "all")
|
||||
new CategoryMailboxPerspective(_.compact(categories))
|
||||
|
||||
# Instance Methods
|
||||
|
||||
|
@ -130,6 +138,7 @@ class StarredMailboxPerspective extends MailboxPerspective
|
|||
|
||||
class EmptyMailboxPerspective extends MailboxPerspective
|
||||
constructor: ->
|
||||
@accountIds = []
|
||||
|
||||
threads: =>
|
||||
query = DatabaseStore.findAll(Thread).where(accountId: -1).limit(0)
|
||||
|
|
Loading…
Reference in a new issue