mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-09-21 15:56:10 +08:00
fix(sidebar): Handle edge cases for sidebar shortcuts
Summary: - Update menus and shortcuts correclt when accounts change or focused accounts change - Move menu logic into SidebarCommands to remove duplicated logic - Make `Window` menu also contain checkboxes Test Plan: - Manual Reviewers: evan, bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D2534
This commit is contained in:
parent
57e7df8356
commit
199150188d
|
@ -0,0 +1,87 @@
|
|||
_ = require 'underscore'
|
||||
{AccountStore, MenuHelpers} = require 'nylas-exports'
|
||||
SidebarActions = require './sidebar-actions'
|
||||
|
||||
|
||||
class AccountCommands
|
||||
|
||||
@_focusAccounts: (accounts) ->
|
||||
SidebarActions.focusAccounts(accounts)
|
||||
NylasEnv.show() unless NylasEnv.isVisible()
|
||||
|
||||
@_isSelected: (account, focusedAccounts) =>
|
||||
if focusedAccounts.length > 1
|
||||
return account instanceof Array
|
||||
else
|
||||
return account?.id is focusedAccounts[0].id
|
||||
|
||||
@registerCommands: (accounts) ->
|
||||
@_commandsDisposable?.dispose()
|
||||
commands = {}
|
||||
|
||||
allKey = "application:select-account-0"
|
||||
commands[allKey] = @_focusAccounts.bind(@, accounts)
|
||||
|
||||
[1..8].forEach (index) =>
|
||||
account = accounts[index - 1]
|
||||
return unless account
|
||||
key = "application:select-account-#{index}"
|
||||
commands[key] = @_focusAccounts.bind(@, [account])
|
||||
|
||||
@_commandsDisposable = NylasEnv.commands.add('body', commands)
|
||||
|
||||
@registerMenuItems: (accounts, focusedAccounts) ->
|
||||
windowMenu = _.find NylasEnv.menu.template, ({label}) ->
|
||||
MenuHelpers.normalizeLabel(label) is 'Window'
|
||||
return unless windowMenu
|
||||
|
||||
submenu = _.reject windowMenu.submenu, (item) -> item.account
|
||||
return unless submenu
|
||||
|
||||
idx = _.findIndex submenu, ({type}) -> type is 'separator'
|
||||
return unless idx > 0
|
||||
|
||||
template = @menuTemplate(accounts, focusedAccounts)
|
||||
submenu.splice(idx + 1, 0, template...)
|
||||
windowMenu.submenu = submenu
|
||||
NylasEnv.menu.update()
|
||||
|
||||
@menuItem: (account, idx, {isSelected, clickHandlers} = {}) =>
|
||||
item = {
|
||||
label: account.label ? "All Accounts",
|
||||
command: "application:select-account-#{idx}",
|
||||
account: true
|
||||
}
|
||||
if isSelected
|
||||
item.type = 'checkbox'
|
||||
item.checked = true
|
||||
if clickHandlers
|
||||
accounts = if account instanceof Array then account else [account]
|
||||
item.click = @_focusAccounts.bind(@, accounts)
|
||||
item.accelerator = "CmdOrCtrl+#{idx + 1}"
|
||||
return item
|
||||
|
||||
@menuTemplate: (accounts, focusedAccounts, {clickHandlers} = {}) =>
|
||||
template = []
|
||||
multiAccount = accounts.length > 1
|
||||
|
||||
if multiAccount
|
||||
isSelected = @_isSelected(accounts, focusedAccounts)
|
||||
template = [
|
||||
@menuItem(accounts, 0, {isSelected, clickHandlers})
|
||||
]
|
||||
|
||||
template = template.concat accounts.map((account, idx) =>
|
||||
# If there's only one account, it should be mapped to Cmd+1, not Cmd+2
|
||||
accIdx = if multiAccount then idx + 1 else idx
|
||||
isSelected = @_isSelected(account, focusedAccounts)
|
||||
return @menuItem(account, accIdx, {isSelected, clickHandlers})
|
||||
)
|
||||
return template
|
||||
|
||||
@register: (accounts, focusedAccounts) ->
|
||||
@registerCommands(accounts)
|
||||
@registerMenuItems(accounts, focusedAccounts)
|
||||
|
||||
|
||||
module.exports = AccountCommands
|
|
@ -1,15 +1,9 @@
|
|||
React = require 'react'
|
||||
crypto = require 'crypto'
|
||||
classNames = require 'classnames'
|
||||
{Actions} = require 'nylas-exports'
|
||||
{RetinaImg} = require 'nylas-component-kit'
|
||||
SidebarActions = require '../sidebar-actions'
|
||||
AccountCommands = require '../account-commands'
|
||||
|
||||
|
||||
ItemTypes = {
|
||||
"Unified"
|
||||
}
|
||||
|
||||
class AccountSwitcher extends React.Component
|
||||
@displayName: 'AccountSwitcher'
|
||||
|
||||
|
@ -17,71 +11,21 @@ class AccountSwitcher extends React.Component
|
|||
accounts: React.PropTypes.array.isRequired
|
||||
focusedAccounts: React.PropTypes.array.isRequired
|
||||
|
||||
# Helpers
|
||||
|
||||
_makeAccountItem: (account) =>
|
||||
{id, label, emailAddress, provider} = account
|
||||
email = emailAddress
|
||||
iconName = provider
|
||||
accounts = [account]
|
||||
return {id, label, email, iconName, accounts}
|
||||
|
||||
_makeUnifiedItem: =>
|
||||
id = ItemTypes.Unified
|
||||
label = "All Accounts"
|
||||
email = ""
|
||||
iconName = 'unified'
|
||||
accounts = @props.accounts
|
||||
return {id, label, email, iconName, accounts}
|
||||
|
||||
|
||||
_selectedItem: =>
|
||||
if @props.focusedAccounts.length > 1
|
||||
@_makeUnifiedItem()
|
||||
else
|
||||
@_makeAccountItem(@props.focusedAccounts[0])
|
||||
|
||||
_toggleDropdown: =>
|
||||
@setState showing: !@state.showing
|
||||
|
||||
_makeMenuItem: (item, idx) =>
|
||||
menuItem = {
|
||||
label: item.label,
|
||||
click: @_onSwitchAccount.bind(@, item)
|
||||
accelerator: "CmdOrCtrl+#{idx}"
|
||||
}
|
||||
|
||||
if @_selectedItem().id is item.id
|
||||
menuItem.type = 'checkbox'
|
||||
menuItem.checked = true
|
||||
|
||||
return menuItem
|
||||
|
||||
_makeMenuTemplate: =>
|
||||
template = []
|
||||
items = @props.accounts.map(@_makeAccountItem)
|
||||
|
||||
if @props.accounts.length > 1
|
||||
unifiedItem = @_makeUnifiedItem()
|
||||
template = [
|
||||
@_makeMenuItem(unifiedItem, 1)
|
||||
{type: 'separator'}
|
||||
]
|
||||
|
||||
items.forEach (item, idx) => template.push(@_makeMenuItem(item, idx + 2))
|
||||
|
||||
template = AccountCommands.menuTemplate(
|
||||
@props.accounts,
|
||||
@props.focusedAccounts,
|
||||
clickHandlers: true
|
||||
)
|
||||
template = template.concat [
|
||||
{type: 'separator'}
|
||||
{label: 'Manage Accounts...', click: @_onManageAccounts}
|
||||
]
|
||||
return template
|
||||
|
||||
|
||||
# Handlers
|
||||
|
||||
_onSwitchAccount: (item) =>
|
||||
SidebarActions.focusAccounts(item.accounts)
|
||||
|
||||
_onManageAccounts: =>
|
||||
Actions.switchPreferencesTab('Accounts')
|
||||
Actions.openPreferences()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
React = require "react"
|
||||
AccountSidebar = require "./components/account-sidebar"
|
||||
SidebarCommands = require "./sidebar-commands"
|
||||
{ComponentRegistry, WorkspaceStore} = require "nylas-exports"
|
||||
|
||||
module.exports =
|
||||
|
@ -9,7 +8,6 @@ module.exports =
|
|||
activate: (@state) ->
|
||||
ComponentRegistry.register AccountSidebar,
|
||||
location: WorkspaceStore.Location.RootSidebar
|
||||
SidebarCommands.register()
|
||||
|
||||
deactivate: (@state) ->
|
||||
ComponentRegistry.unregister(AccountSidebar)
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
_ = require 'underscore'
|
||||
{AccountStore, MenuHelpers} = require 'nylas-exports'
|
||||
SidebarActions = require './sidebar-actions'
|
||||
|
||||
|
||||
class SidebarCommands
|
||||
|
||||
@_focusAccounts: (accounts) ->
|
||||
SidebarActions.focusAccounts(accounts)
|
||||
NylasEnv.show() unless NylasEnv.isVisible()
|
||||
|
||||
@_registerCommands: ->
|
||||
commands = {}
|
||||
|
||||
allKey = "application:select-account-0"
|
||||
commands[allKey] = @_focusAccounts.bind(@, AccountStore.accounts())
|
||||
|
||||
[1..8].forEach (index) =>
|
||||
account = AccountStore.accounts()[index - 1]
|
||||
return unless account
|
||||
key = "application:select-account-#{index}"
|
||||
commands[key] = @_focusAccounts.bind(@, [account])
|
||||
|
||||
NylasEnv.commands.add('body', commands)
|
||||
|
||||
@_registerMenuItems: ->
|
||||
windowMenu = _.find NylasEnv.menu.template, ({label}) ->
|
||||
MenuHelpers.normalizeLabel(label) is 'Window'
|
||||
return unless windowMenu
|
||||
|
||||
submenu = _.reject windowMenu.submenu, (item) -> item.account
|
||||
return unless submenu
|
||||
|
||||
idx = _.findIndex submenu, ({type}) -> type is 'separator'
|
||||
return unless idx > 0
|
||||
|
||||
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, menuItems...)
|
||||
windowMenu.submenu = submenu
|
||||
NylasEnv.menu.update()
|
||||
|
||||
@register: ->
|
||||
@_registerCommands()
|
||||
@_registerMenuItems()
|
||||
|
||||
|
||||
module.exports = SidebarCommands
|
|
@ -10,6 +10,7 @@ _ = require 'underscore'
|
|||
|
||||
SidebarSection = require './sidebar-section'
|
||||
SidebarActions = require './sidebar-actions'
|
||||
AccountCommands = require './account-commands'
|
||||
|
||||
Sections = {
|
||||
"Standard",
|
||||
|
@ -23,6 +24,8 @@ class SidebarStore extends NylasStore
|
|||
@_sections[Sections.Standard] = {}
|
||||
@_sections[Sections.User] = []
|
||||
@_focusedAccounts = @accounts()
|
||||
@_registerCommands()
|
||||
@_registerMenuItems()
|
||||
@_registerListeners()
|
||||
@_updateSections()
|
||||
|
||||
|
@ -57,13 +60,23 @@ class SidebarStore extends NylasStore
|
|||
)
|
||||
return
|
||||
|
||||
_registerCommands: (accounts = AccountStore.accounts()) =>
|
||||
AccountCommands.registerCommands(accounts)
|
||||
|
||||
_registerMenuItems: (accounts = AccountStore.accounts()) =>
|
||||
AccountCommands.registerMenuItems(accounts, @_focusedAccounts)
|
||||
|
||||
_onAccountsFocused: (accounts) =>
|
||||
Actions.focusDefaultMailboxPerspectiveForAccounts(accounts)
|
||||
@_focusedAccounts = accounts
|
||||
@_registerMenuItems()
|
||||
@_updateSections()
|
||||
|
||||
_onAccountsChanged: =>
|
||||
@_focusedAccounts = AccountStore.accounts()
|
||||
accounts = AccountStore.accounts()
|
||||
@_focusedAccounts = accounts
|
||||
@_registerCommands()
|
||||
@_registerMenuItems()
|
||||
@_updateSections()
|
||||
|
||||
_onFocusedPerspectiveChanged: =>
|
||||
|
@ -72,6 +85,7 @@ class SidebarStore extends NylasStore
|
|||
newIdsNotInCurrent = _.difference(newIds, currentIds).length > 0
|
||||
if newIdsNotInCurrent
|
||||
@_focusedAccounts = newIds.map (id) -> AccountStore.accountForId(id)
|
||||
@_registerMenuItems()
|
||||
@_updateSections()
|
||||
|
||||
_updateSections: =>
|
||||
|
|
Loading…
Reference in a new issue