From 510e417cb3b7dc6c2abc7fe48d723ea65ff0a445 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Mon, 21 Mar 2016 17:36:18 -0700 Subject: [PATCH] fix(tray): Use total count, not unread count, for tray icon --- build/resources/asar-ordering-hint.txt | 8 +- .../lib/system-tray-icon-store.es6 | 18 ++--- .../spec/system-tray-icon-store-spec.es6 | 32 ++++---- spec/stores/badge-store-spec.coffee | 19 +++++ spec/stores/unread-badge-store-spec.coffee | 19 ----- spec/tasks/change-mail-task-spec.coffee | 5 +- src/flux/stores/badge-store.es6 | 75 +++++++++++++++++++ src/flux/stores/unread-badge-store.coffee | 49 ------------ src/global/nylas-exports.coffee | 2 +- 9 files changed, 127 insertions(+), 100 deletions(-) create mode 100644 spec/stores/badge-store-spec.coffee delete mode 100644 spec/stores/unread-badge-store-spec.coffee create mode 100644 src/flux/stores/badge-store.es6 delete mode 100644 src/flux/stores/unread-badge-store.coffee diff --git a/build/resources/asar-ordering-hint.txt b/build/resources/asar-ordering-hint.txt index bad405f37..1ed24ed06 100644 --- a/build/resources/asar-ordering-hint.txt +++ b/build/resources/asar-ordering-hint.txt @@ -1406,7 +1406,7 @@ 4208627: node_modules/request/lib/cookies.js 4209596: node_modules/less-cache/node_modules/less/node_modules/request/node_modules/tough-cookie/lib/cookie.js 4247150: node_modules/less-cache/node_modules/less/node_modules/request/node_modules/tough-cookie/lib/pubsuffix.js -6156359: src/flux/stores/unread-badge-store.js +6156359: src/flux/stores/badge-store.js 6165032: src/flux/stores/file-download-store.js 6196816: node_modules/request-progress/package.json 6202896: node_modules/request-progress/index.js @@ -1828,7 +1828,7 @@ 6063542: src/flux/stores/file-upload-store.js 1676695: node_modules/mkdirp/package.json 1678098: node_modules/mkdirp/index.js -6156359: src/flux/stores/unread-badge-store.js +6156359: src/flux/stores/badge-store.js 6165032: src/flux/stores/file-download-store.js 6196816: node_modules/request-progress/package.json 6202896: node_modules/request-progress/index.js @@ -3709,7 +3709,7 @@ 6063542: src/flux/stores/file-upload-store.js 1676695: node_modules/mkdirp/package.json 1678098: node_modules/mkdirp/index.js -6156359: src/flux/stores/unread-badge-store.js +6156359: src/flux/stores/badge-store.js 6165032: src/flux/stores/file-download-store.js 6196816: node_modules/request-progress/package.json 6202896: node_modules/request-progress/index.js @@ -5201,7 +5201,7 @@ 6063542: src/flux/stores/file-upload-store.js 1676695: node_modules/mkdirp/package.json 1678098: node_modules/mkdirp/index.js -6156359: src/flux/stores/unread-badge-store.js +6156359: src/flux/stores/badge-store.js 6165032: src/flux/stores/file-download-store.js 6196816: node_modules/request-progress/package.json 6202896: node_modules/request-progress/index.js diff --git a/internal_packages/system-tray/lib/system-tray-icon-store.es6 b/internal_packages/system-tray/lib/system-tray-icon-store.es6 index b830165f7..e8d2d24f4 100644 --- a/internal_packages/system-tray/lib/system-tray-icon-store.es6 +++ b/internal_packages/system-tray/lib/system-tray-icon-store.es6 @@ -1,6 +1,6 @@ import path from 'path'; import {ipcRenderer} from 'electron'; -import {UnreadBadgeStore} from 'nylas-exports'; +import {BadgeStore} from 'nylas-exports'; // Must be absolute real system path // https://github.com/atom/electron/issues/1299 @@ -23,9 +23,8 @@ class SystemTrayIconStore { } activate() { - this._updateIcon() - this._unsubscribers.push(UnreadBadgeStore.listen(this._updateIcon)); - + this._updateIcon(); + this._unsubscribers.push(BadgeStore.listen(this._updateIcon)); window.addEventListener('browser-window-blur', this._onWindowBlur); window.addEventListener('browser-window-focus', this._onWindowFocus); @@ -33,8 +32,8 @@ class SystemTrayIconStore { this._unsubscribers.push(() => window.removeEventListener('browser-window-focus', this._onWindowFocus)) } - _getIconImageData(unreadCount, isWindowBlurred) { - if (unreadCount === 0) { + _getIconImageData(isInboxZero, isWindowBlurred) { + if (isInboxZero) { return {iconPath: INBOX_ZERO_ICON, isTemplateImg: true}; } return isWindowBlurred ? @@ -55,9 +54,10 @@ class SystemTrayIconStore { }; _updateIcon = () => { - const count = UnreadBadgeStore.count() - const unreadString = (+count).toLocaleString(); - const {iconPath, isTemplateImg} = this._getIconImageData(count, this._windowBlurred); + const unread = BadgeStore.unread(); + const unreadString = (+unread).toLocaleString(); + const isInboxZero = (BadgeStore.total() === 0); + const {iconPath, isTemplateImg} = this._getIconImageData(isInboxZero, this._windowBlurred); ipcRenderer.send('update-system-tray', iconPath, unreadString, isTemplateImg); }; diff --git a/internal_packages/system-tray/spec/system-tray-icon-store-spec.es6 b/internal_packages/system-tray/spec/system-tray-icon-store-spec.es6 index 262cf6cc4..84322412f 100644 --- a/internal_packages/system-tray/spec/system-tray-icon-store-spec.es6 +++ b/internal_packages/system-tray/spec/system-tray-icon-store-spec.es6 @@ -1,5 +1,5 @@ import {ipcRenderer} from 'electron'; -import {UnreadBadgeStore} from 'nylas-exports'; +import {BadgeStore} from 'nylas-exports'; import SystemTrayIconStore from '../lib/system-tray-icon-store'; const { @@ -21,26 +21,26 @@ describe('SystemTrayIconStore', ()=> { } describe('_getIconImageData', ()=> { - it('shows inbox zero icon when unread count is 0 and window is focused', ()=> { - const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(0, false) + it('shows inbox zero icon when isInboxZero and window is focused', ()=> { + const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(true, false) expect(iconPath).toBe(INBOX_ZERO_ICON) expect(isTemplateImg).toBe(true) }); - it('shows inbox zero icon when unread count is 0 and window is blurred', ()=> { - const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(0, true) + it('shows inbox zero icon when isInboxZero and window is blurred', ()=> { + const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(true, true) expect(iconPath).toBe(INBOX_ZERO_ICON) expect(isTemplateImg).toBe(true) }); - it('shows inbox full icon when unread count > 0 and window is focused', ()=> { - const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(1, false) + it('shows inbox full icon when not isInboxZero and window is focused', ()=> { + const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(false, false) expect(iconPath).toBe(INBOX_UNREAD_ICON) expect(isTemplateImg).toBe(true) }); - it('shows inbox full /alt/ icon when unread count > 0 and window is blurred', ()=> { - const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(1, true) + it('shows inbox full /alt/ icon when not isInboxZero and window is blurred', ()=> { + const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(false, true) expect(iconPath).toBe(INBOX_UNREAD_ALT_ICON) expect(isTemplateImg).toBe(false) }); @@ -48,30 +48,30 @@ describe('SystemTrayIconStore', ()=> { describe('updating the icon based on focus and blur', ()=> { it('always shows inbox full icon when the window gets focused', ()=> { - spyOn(UnreadBadgeStore, 'count').andReturn(1) + spyOn(BadgeStore, 'total').andReturn(1) this.iconStore._onWindowFocus() const {iconPath} = getCallData() expect(iconPath).toBe(INBOX_UNREAD_ICON) }); - it('shows inbox full /alt/ icon ONLY when window is currently blurred and unread count changes', ()=> { + it('shows inbox full /alt/ icon ONLY when window is currently blurred and total count changes', ()=> { this.iconStore._windowBlurred = false this.iconStore._onWindowBlur() expect(ipcRenderer.send).not.toHaveBeenCalled() - // UnreadBadgeStore triggers a change - spyOn(UnreadBadgeStore, 'count').andReturn(1) + // BadgeStore triggers a change + spyOn(BadgeStore, 'total').andReturn(1) this.iconStore._updateIcon() const {iconPath} = getCallData() expect(iconPath).toBe(INBOX_UNREAD_ALT_ICON) }); - it('does not show inbox full /alt/ icon when window is currently focused and unread count changes', ()=> { + it('does not show inbox full /alt/ icon when window is currently focused and total count changes', ()=> { this.iconStore._windowBlurred = false - // UnreadBadgeStore triggers a change - spyOn(UnreadBadgeStore, 'count').andReturn(1) + // BadgeStore triggers a change + spyOn(BadgeStore, 'total').andReturn(1) this.iconStore._updateIcon() const {iconPath} = getCallData() diff --git a/spec/stores/badge-store-spec.coffee b/spec/stores/badge-store-spec.coffee new file mode 100644 index 000000000..4a1a3bac9 --- /dev/null +++ b/spec/stores/badge-store-spec.coffee @@ -0,0 +1,19 @@ +Label = require '../../src/flux/models/label' +BadgeStore = require '../../src/flux/stores/badge-store' + +describe "BadgeStore", -> + describe "_setBadgeForCount", -> + it "should set the badge correctly", -> + spyOn(BadgeStore, '_setBadge') + BadgeStore._unread = 0 + BadgeStore._setBadgeForCount() + expect(BadgeStore._setBadge).toHaveBeenCalledWith("") + BadgeStore._unread = 1 + BadgeStore._setBadgeForCount() + expect(BadgeStore._setBadge).toHaveBeenCalledWith("1") + BadgeStore._unread = 100 + BadgeStore._setBadgeForCount() + expect(BadgeStore._setBadge).toHaveBeenCalledWith("100") + BadgeStore._unread = 1000 + BadgeStore._setBadgeForCount() + expect(BadgeStore._setBadge).toHaveBeenCalledWith("999+") diff --git a/spec/stores/unread-badge-store-spec.coffee b/spec/stores/unread-badge-store-spec.coffee deleted file mode 100644 index cd8b385d5..000000000 --- a/spec/stores/unread-badge-store-spec.coffee +++ /dev/null @@ -1,19 +0,0 @@ -Label = require '../../src/flux/models/label' -UnreadBadgeStore = require '../../src/flux/stores/unread-badge-store' - -describe "UnreadBadgeStore", -> - describe "_setBadgeForCount", -> - it "should set the badge correctly", -> - spyOn(UnreadBadgeStore, '_setBadge') - UnreadBadgeStore._count = 0 - UnreadBadgeStore._setBadgeForCount() - expect(UnreadBadgeStore._setBadge).toHaveBeenCalledWith("") - UnreadBadgeStore._count = 1 - UnreadBadgeStore._setBadgeForCount() - expect(UnreadBadgeStore._setBadge).toHaveBeenCalledWith("1") - UnreadBadgeStore._count = 100 - UnreadBadgeStore._setBadgeForCount() - expect(UnreadBadgeStore._setBadge).toHaveBeenCalledWith("100") - UnreadBadgeStore._count = 1000 - UnreadBadgeStore._setBadgeForCount() - expect(UnreadBadgeStore._setBadge).toHaveBeenCalledWith("999+") diff --git a/spec/tasks/change-mail-task-spec.coffee b/spec/tasks/change-mail-task-spec.coffee index 753930950..37d7a5de1 100644 --- a/spec/tasks/change-mail-task-spec.coffee +++ b/spec/tasks/change-mail-task-spec.coffee @@ -219,7 +219,8 @@ describe "ChangeMailTask", -> describe "if _performRequests rejects with a permanent network error", -> beforeEach -> @task = new ChangeMailTask() - spyOn(@task, '_performRequests').andReturn(Promise.reject(new APIError(statusCode: 400))) + @error = new APIError(statusCode: 400) + spyOn(@task, '_performRequests').andReturn(Promise.reject(@error)) spyOn(@task, 'performLocal').andReturn(Promise.resolve()) it "should set isReverting and call performLocal", -> @@ -231,7 +232,7 @@ describe "ChangeMailTask", -> it "should resolve with Task.Status.Failed after reverting", -> waitsForPromise => @task.performRemote().then (result) => - expect(result).toBe(Task.Status.Failed) + expect(result).toEqual([Task.Status.Failed, @error]) describe "if _performRequests rejects with a temporary network error", -> beforeEach -> diff --git a/src/flux/stores/badge-store.es6 b/src/flux/stores/badge-store.es6 new file mode 100644 index 000000000..62fd58733 --- /dev/null +++ b/src/flux/stores/badge-store.es6 @@ -0,0 +1,75 @@ +import NylasStore from 'nylas-store'; +import FocusedPerspectiveStore from './focused-perspective-store'; +import ThreadCountsStore from './thread-counts-store'; +import CategoryStore from './category-store'; + +class BadgeStore extends NylasStore { + + constructor() { + super(); + + this.listenTo(FocusedPerspectiveStore, this._updateCounts); + this.listenTo(ThreadCountsStore, this._updateCounts); + + NylasEnv.config.onDidChange('core.notifications.unreadBadge', ({newValue}) => { + if (newValue === true) { + this._setBadgeForCount() + } else { + this._setBadge(""); + } + }); + + this._updateCounts(); + } + + // Public: Returns the number of unread threads in the user's mailbox + unread() { + return this._unread; + } + + total() { + return this._total; + } + + _updateCounts = () => { + let unread = 0; + let total = 0; + + const accountIds = FocusedPerspectiveStore.current().accountIds; + for (const cat of CategoryStore.getStandardCategories(accountIds, 'inbox')) { + unread += ThreadCountsStore.unreadCountForCategoryId(cat.id) + total += ThreadCountsStore.totalCountForCategoryId(cat.id) + } + + if ((this._unread === unread) && (this._total === total)) { + return; + } + this._unread = unread; + this._total = total; + this._setBadgeForCount(); + this.trigger(); + } + + _setBadgeForCount = () => { + if (!NylasEnv.config.get('core.notifications.unreadBadge')) { + return; + } + if (!NylasEnv.isMainWindow() && !NylasEnv.inSpecMode()) { + return; + } + + if (this._unread > 999) { + this._setBadge("999+"); + } else if (this._unread > 0) { + this._setBadge(`${this._unread}`); + } else { + this._setBadge(""); + } + } + + _setBadge = (val) => { + require('electron').ipcRenderer.send('set-badge-value', val); + } +} + +module.exports = new BadgeStore() diff --git a/src/flux/stores/unread-badge-store.coffee b/src/flux/stores/unread-badge-store.coffee deleted file mode 100644 index 6b9eb1f25..000000000 --- a/src/flux/stores/unread-badge-store.coffee +++ /dev/null @@ -1,49 +0,0 @@ -Reflux = require 'reflux' -_ = require 'underscore' -NylasStore = require 'nylas-store' -FocusedPerspectiveStore = require './focused-perspective-store' -ThreadCountsStore = require './thread-counts-store' - -class UnreadBadgeStore extends NylasStore - - constructor: -> - @_count = FocusedPerspectiveStore.current().unreadCount() - - @listenTo FocusedPerspectiveStore, @_updateCount - @listenTo ThreadCountsStore, @_updateCount - NylasEnv.config.onDidChange 'core.notifications.unreadBadge', ({newValue}) => - if newValue is true - @_setBadgeForCount() - else - @_setBadge("") - - @_updateCount() - - # Public: Returns the number of unread threads in the user's mailbox - count: -> - @_count - - _updateCount: => - current = FocusedPerspectiveStore.current() - if current.isInbox() - count = current.unreadCount() - return if @_count is count - @_count = count - @_setBadgeForCount() - @trigger() - - _setBadgeForCount: => - return unless NylasEnv.config.get('core.notifications.unreadBadge') - return unless NylasEnv.isMainWindow() or NylasEnv.inSpecMode() - - if @_count > 999 - @_setBadge("999+") - else if @_count > 0 - @_setBadge("#{@_count}") - else - @_setBadge("") - - _setBadge: (val) => - require('electron').ipcRenderer.send('set-badge-value', val) - -module.exports = new UnreadBadgeStore() diff --git a/src/global/nylas-exports.coffee b/src/global/nylas-exports.coffee index af6293bc2..c086e5adf 100644 --- a/src/global/nylas-exports.coffee +++ b/src/global/nylas-exports.coffee @@ -128,7 +128,7 @@ class NylasExports @require "FileUploadStore", 'flux/stores/file-upload-store' @require "MailRulesStore", 'flux/stores/mail-rules-store' @require "ThreadCountsStore", 'flux/stores/thread-counts-store' - @require "UnreadBadgeStore", 'flux/stores/unread-badge-store' + @require "BadgeStore", 'flux/stores/badge-store' @require "FileDownloadStore", 'flux/stores/file-download-store' @require "FocusedContentStore", 'flux/stores/focused-content-store' @require "FocusedPerspectiveStore", 'flux/stores/focused-perspective-store'