const _ = require('underscore'); const MailspringStore = require('mailspring-store').default; const { Actions, AccountStore, ThreadCountsStore, WorkspaceStore, OutboxStore, FocusedPerspectiveStore, CategoryStore, } = require('mailspring-exports'); const SidebarSection = require('./sidebar-section'); const SidebarActions = require('./sidebar-actions'); const AccountCommands = require('./account-commands'); const Sections = { Standard: 'Standard', User: 'User', }; class SidebarStore extends MailspringStore { constructor() { super(); if (AppEnv.savedState.sidebarKeysCollapsed == null) { AppEnv.savedState.sidebarKeysCollapsed = {}; } this._sections = {}; this._sections[Sections.Standard] = {}; this._sections[Sections.User] = []; this._registerCommands(); this._registerMenuItems(); this._registerListeners(); this._updateSections(); } accounts() { return AccountStore.accounts(); } sidebarAccountIds() { return FocusedPerspectiveStore.sidebarAccountIds(); } standardSection() { return this._sections[Sections.Standard]; } userSections() { return this._sections[Sections.User]; } _registerListeners() { this.listenTo(Actions.setCollapsedSidebarItem, this._onSetCollapsedByName); this.listenTo(SidebarActions.setKeyCollapsed, this._onSetCollapsedByKey); this.listenTo(AccountStore, this._onAccountsChanged); this.listenTo(FocusedPerspectiveStore, this._onFocusedPerspectiveChanged); this.listenTo(WorkspaceStore, this._updateSections); this.listenTo(OutboxStore, this._updateSections); this.listenTo(ThreadCountsStore, this._updateSections); this.listenTo(CategoryStore, this._updateSections); this.configSubscription = AppEnv.config.onDidChange( 'core.workspace.showUnreadForAllCategories', this._updateSections ); } _onSetCollapsedByKey = (itemKey, collapsed) => { const currentValue = AppEnv.savedState.sidebarKeysCollapsed[itemKey]; if (currentValue !== collapsed) { AppEnv.savedState.sidebarKeysCollapsed[itemKey] = collapsed; this._updateSections(); } }; _onSetCollapsedByName = (itemName, collapsed) => { let item = _.findWhere(this.standardSection().items, { name: itemName }); if (!item) { for (let section of this.userSections()) { item = _.findWhere(section.items, { name: itemName }); if (item) { break; } } } if (!item) { return; } this._onSetCollapsedByKey(item.id, collapsed); }; _registerCommands = accounts => { if (accounts == null) { accounts = AccountStore.accounts(); } AccountCommands.registerCommands(accounts); }; _registerMenuItems = accounts => { if (accounts == null) { accounts = AccountStore.accounts(); } AccountCommands.registerMenuItems(accounts, FocusedPerspectiveStore.sidebarAccountIds()); }; // TODO Refactor this // Listen to changes on the account store only for when the account label // or order changes. When accounts or added or removed, those changes will // come in through the FocusedPerspectiveStore _onAccountsChanged = () => { this._updateSections(); }; // TODO Refactor this // The FocusedPerspectiveStore tells this store the accounts that should be // displayed in the sidebar (i.e. unified inbox vs single account) and will // trigger whenever an account is added or removed, as well as when a // perspective is focused. // However, when udpating the SidebarSections, we also depend on the actual // accounts in the AccountStore. The problem is that the FocusedPerspectiveStore // triggers before the AccountStore is actually updated, so we need to wait for // the AccountStore to get updated (via `defer`) before updateing our sidebar // sections _onFocusedPerspectiveChanged = () => { _.defer(() => { this._registerCommands(); this._registerMenuItems(); this._updateSections(); }); }; _updateSections = () => { const accounts = FocusedPerspectiveStore.sidebarAccountIds() .map(id => AccountStore.accountForId(id)) .filter(a => !!a); if (accounts.length === 0) { return; } const multiAccount = accounts.length > 1; this._sections[Sections.Standard] = SidebarSection.standardSectionForAccounts(accounts); this._sections[Sections.User] = accounts.map(function(acc) { const opts = {}; if (multiAccount) { opts.title = acc.label; opts.collapsible = true; } return SidebarSection.forUserCategories(acc, opts); }); this.trigger(); }; } module.exports = new SidebarStore();