mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-01-28 02:49:30 +08:00
fix(tray): Use total count, not unread count, for tray icon
This commit is contained in:
parent
4ddbf1faae
commit
510e417cb3
9 changed files with 127 additions and 100 deletions
|
@ -1406,7 +1406,7 @@
|
||||||
4208627: node_modules/request/lib/cookies.js
|
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
|
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
|
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
|
6165032: src/flux/stores/file-download-store.js
|
||||||
6196816: node_modules/request-progress/package.json
|
6196816: node_modules/request-progress/package.json
|
||||||
6202896: node_modules/request-progress/index.js
|
6202896: node_modules/request-progress/index.js
|
||||||
|
@ -1828,7 +1828,7 @@
|
||||||
6063542: src/flux/stores/file-upload-store.js
|
6063542: src/flux/stores/file-upload-store.js
|
||||||
1676695: node_modules/mkdirp/package.json
|
1676695: node_modules/mkdirp/package.json
|
||||||
1678098: node_modules/mkdirp/index.js
|
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
|
6165032: src/flux/stores/file-download-store.js
|
||||||
6196816: node_modules/request-progress/package.json
|
6196816: node_modules/request-progress/package.json
|
||||||
6202896: node_modules/request-progress/index.js
|
6202896: node_modules/request-progress/index.js
|
||||||
|
@ -3709,7 +3709,7 @@
|
||||||
6063542: src/flux/stores/file-upload-store.js
|
6063542: src/flux/stores/file-upload-store.js
|
||||||
1676695: node_modules/mkdirp/package.json
|
1676695: node_modules/mkdirp/package.json
|
||||||
1678098: node_modules/mkdirp/index.js
|
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
|
6165032: src/flux/stores/file-download-store.js
|
||||||
6196816: node_modules/request-progress/package.json
|
6196816: node_modules/request-progress/package.json
|
||||||
6202896: node_modules/request-progress/index.js
|
6202896: node_modules/request-progress/index.js
|
||||||
|
@ -5201,7 +5201,7 @@
|
||||||
6063542: src/flux/stores/file-upload-store.js
|
6063542: src/flux/stores/file-upload-store.js
|
||||||
1676695: node_modules/mkdirp/package.json
|
1676695: node_modules/mkdirp/package.json
|
||||||
1678098: node_modules/mkdirp/index.js
|
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
|
6165032: src/flux/stores/file-download-store.js
|
||||||
6196816: node_modules/request-progress/package.json
|
6196816: node_modules/request-progress/package.json
|
||||||
6202896: node_modules/request-progress/index.js
|
6202896: node_modules/request-progress/index.js
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {ipcRenderer} from 'electron';
|
import {ipcRenderer} from 'electron';
|
||||||
import {UnreadBadgeStore} from 'nylas-exports';
|
import {BadgeStore} from 'nylas-exports';
|
||||||
|
|
||||||
// Must be absolute real system path
|
// Must be absolute real system path
|
||||||
// https://github.com/atom/electron/issues/1299
|
// https://github.com/atom/electron/issues/1299
|
||||||
|
@ -23,9 +23,8 @@ class SystemTrayIconStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this._updateIcon()
|
this._updateIcon();
|
||||||
this._unsubscribers.push(UnreadBadgeStore.listen(this._updateIcon));
|
this._unsubscribers.push(BadgeStore.listen(this._updateIcon));
|
||||||
|
|
||||||
|
|
||||||
window.addEventListener('browser-window-blur', this._onWindowBlur);
|
window.addEventListener('browser-window-blur', this._onWindowBlur);
|
||||||
window.addEventListener('browser-window-focus', this._onWindowFocus);
|
window.addEventListener('browser-window-focus', this._onWindowFocus);
|
||||||
|
@ -33,8 +32,8 @@ class SystemTrayIconStore {
|
||||||
this._unsubscribers.push(() => window.removeEventListener('browser-window-focus', this._onWindowFocus))
|
this._unsubscribers.push(() => window.removeEventListener('browser-window-focus', this._onWindowFocus))
|
||||||
}
|
}
|
||||||
|
|
||||||
_getIconImageData(unreadCount, isWindowBlurred) {
|
_getIconImageData(isInboxZero, isWindowBlurred) {
|
||||||
if (unreadCount === 0) {
|
if (isInboxZero) {
|
||||||
return {iconPath: INBOX_ZERO_ICON, isTemplateImg: true};
|
return {iconPath: INBOX_ZERO_ICON, isTemplateImg: true};
|
||||||
}
|
}
|
||||||
return isWindowBlurred ?
|
return isWindowBlurred ?
|
||||||
|
@ -55,9 +54,10 @@ class SystemTrayIconStore {
|
||||||
};
|
};
|
||||||
|
|
||||||
_updateIcon = () => {
|
_updateIcon = () => {
|
||||||
const count = UnreadBadgeStore.count()
|
const unread = BadgeStore.unread();
|
||||||
const unreadString = (+count).toLocaleString();
|
const unreadString = (+unread).toLocaleString();
|
||||||
const {iconPath, isTemplateImg} = this._getIconImageData(count, this._windowBlurred);
|
const isInboxZero = (BadgeStore.total() === 0);
|
||||||
|
const {iconPath, isTemplateImg} = this._getIconImageData(isInboxZero, this._windowBlurred);
|
||||||
ipcRenderer.send('update-system-tray', iconPath, unreadString, isTemplateImg);
|
ipcRenderer.send('update-system-tray', iconPath, unreadString, isTemplateImg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {ipcRenderer} from 'electron';
|
import {ipcRenderer} from 'electron';
|
||||||
import {UnreadBadgeStore} from 'nylas-exports';
|
import {BadgeStore} from 'nylas-exports';
|
||||||
import SystemTrayIconStore from '../lib/system-tray-icon-store';
|
import SystemTrayIconStore from '../lib/system-tray-icon-store';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -21,26 +21,26 @@ describe('SystemTrayIconStore', ()=> {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('_getIconImageData', ()=> {
|
describe('_getIconImageData', ()=> {
|
||||||
it('shows inbox zero icon when unread count is 0 and window is focused', ()=> {
|
it('shows inbox zero icon when isInboxZero and window is focused', ()=> {
|
||||||
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(0, false)
|
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(true, false)
|
||||||
expect(iconPath).toBe(INBOX_ZERO_ICON)
|
expect(iconPath).toBe(INBOX_ZERO_ICON)
|
||||||
expect(isTemplateImg).toBe(true)
|
expect(isTemplateImg).toBe(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows inbox zero icon when unread count is 0 and window is blurred', ()=> {
|
it('shows inbox zero icon when isInboxZero and window is blurred', ()=> {
|
||||||
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(0, true)
|
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(true, true)
|
||||||
expect(iconPath).toBe(INBOX_ZERO_ICON)
|
expect(iconPath).toBe(INBOX_ZERO_ICON)
|
||||||
expect(isTemplateImg).toBe(true)
|
expect(isTemplateImg).toBe(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows inbox full icon when unread count > 0 and window is focused', ()=> {
|
it('shows inbox full icon when not isInboxZero and window is focused', ()=> {
|
||||||
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(1, false)
|
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(false, false)
|
||||||
expect(iconPath).toBe(INBOX_UNREAD_ICON)
|
expect(iconPath).toBe(INBOX_UNREAD_ICON)
|
||||||
expect(isTemplateImg).toBe(true)
|
expect(isTemplateImg).toBe(true)
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows inbox full /alt/ icon when unread count > 0 and window is blurred', ()=> {
|
it('shows inbox full /alt/ icon when not isInboxZero and window is blurred', ()=> {
|
||||||
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(1, true)
|
const {iconPath, isTemplateImg} = this.iconStore._getIconImageData(false, true)
|
||||||
expect(iconPath).toBe(INBOX_UNREAD_ALT_ICON)
|
expect(iconPath).toBe(INBOX_UNREAD_ALT_ICON)
|
||||||
expect(isTemplateImg).toBe(false)
|
expect(isTemplateImg).toBe(false)
|
||||||
});
|
});
|
||||||
|
@ -48,30 +48,30 @@ describe('SystemTrayIconStore', ()=> {
|
||||||
|
|
||||||
describe('updating the icon based on focus and blur', ()=> {
|
describe('updating the icon based on focus and blur', ()=> {
|
||||||
it('always shows inbox full icon when the window gets focused', ()=> {
|
it('always shows inbox full icon when the window gets focused', ()=> {
|
||||||
spyOn(UnreadBadgeStore, 'count').andReturn(1)
|
spyOn(BadgeStore, 'total').andReturn(1)
|
||||||
this.iconStore._onWindowFocus()
|
this.iconStore._onWindowFocus()
|
||||||
const {iconPath} = getCallData()
|
const {iconPath} = getCallData()
|
||||||
expect(iconPath).toBe(INBOX_UNREAD_ICON)
|
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._windowBlurred = false
|
||||||
this.iconStore._onWindowBlur()
|
this.iconStore._onWindowBlur()
|
||||||
expect(ipcRenderer.send).not.toHaveBeenCalled()
|
expect(ipcRenderer.send).not.toHaveBeenCalled()
|
||||||
|
|
||||||
// UnreadBadgeStore triggers a change
|
// BadgeStore triggers a change
|
||||||
spyOn(UnreadBadgeStore, 'count').andReturn(1)
|
spyOn(BadgeStore, 'total').andReturn(1)
|
||||||
this.iconStore._updateIcon()
|
this.iconStore._updateIcon()
|
||||||
|
|
||||||
const {iconPath} = getCallData()
|
const {iconPath} = getCallData()
|
||||||
expect(iconPath).toBe(INBOX_UNREAD_ALT_ICON)
|
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
|
this.iconStore._windowBlurred = false
|
||||||
|
|
||||||
// UnreadBadgeStore triggers a change
|
// BadgeStore triggers a change
|
||||||
spyOn(UnreadBadgeStore, 'count').andReturn(1)
|
spyOn(BadgeStore, 'total').andReturn(1)
|
||||||
this.iconStore._updateIcon()
|
this.iconStore._updateIcon()
|
||||||
|
|
||||||
const {iconPath} = getCallData()
|
const {iconPath} = getCallData()
|
||||||
|
|
19
spec/stores/badge-store-spec.coffee
Normal file
19
spec/stores/badge-store-spec.coffee
Normal file
|
@ -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+")
|
|
@ -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+")
|
|
|
@ -219,7 +219,8 @@ describe "ChangeMailTask", ->
|
||||||
describe "if _performRequests rejects with a permanent network error", ->
|
describe "if _performRequests rejects with a permanent network error", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@task = new ChangeMailTask()
|
@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())
|
spyOn(@task, 'performLocal').andReturn(Promise.resolve())
|
||||||
|
|
||||||
it "should set isReverting and call performLocal", ->
|
it "should set isReverting and call performLocal", ->
|
||||||
|
@ -231,7 +232,7 @@ describe "ChangeMailTask", ->
|
||||||
it "should resolve with Task.Status.Failed after reverting", ->
|
it "should resolve with Task.Status.Failed after reverting", ->
|
||||||
waitsForPromise =>
|
waitsForPromise =>
|
||||||
@task.performRemote().then (result) =>
|
@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", ->
|
describe "if _performRequests rejects with a temporary network error", ->
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
|
|
75
src/flux/stores/badge-store.es6
Normal file
75
src/flux/stores/badge-store.es6
Normal file
|
@ -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()
|
|
@ -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()
|
|
|
@ -128,7 +128,7 @@ class NylasExports
|
||||||
@require "FileUploadStore", 'flux/stores/file-upload-store'
|
@require "FileUploadStore", 'flux/stores/file-upload-store'
|
||||||
@require "MailRulesStore", 'flux/stores/mail-rules-store'
|
@require "MailRulesStore", 'flux/stores/mail-rules-store'
|
||||||
@require "ThreadCountsStore", 'flux/stores/thread-counts-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 "FileDownloadStore", 'flux/stores/file-download-store'
|
||||||
@require "FocusedContentStore", 'flux/stores/focused-content-store'
|
@require "FocusedContentStore", 'flux/stores/focused-content-store'
|
||||||
@require "FocusedPerspectiveStore", 'flux/stores/focused-perspective-store'
|
@require "FocusedPerspectiveStore", 'flux/stores/focused-perspective-store'
|
||||||
|
|
Loading…
Reference in a new issue