diff --git a/app/internal_packages/preferences/lib/tabs/preferences-appearance.tsx b/app/internal_packages/preferences/lib/tabs/preferences-appearance.tsx index 231a1b33f..ce425121a 100644 --- a/app/internal_packages/preferences/lib/tabs/preferences-appearance.tsx +++ b/app/internal_packages/preferences/lib/tabs/preferences-appearance.tsx @@ -170,8 +170,6 @@ class AppearanceModeSwitch extends React.Component< } } -const { INBOX_ZERO_ICON, INBOX_FULL_ICON, INBOX_FULL_NEW_ICON, INBOX_FULL_UNREAD_ICON } = SystemTrayIconStore; - class TrayIconStylePicker extends React.Component<{ config: ConfigLike }> { kp = 'core.workspace.trayIconStyle'; @@ -180,11 +178,12 @@ class TrayIconStylePicker extends React.Component<{ config: ConfigLike }> { }; render() { + let systemTrayIconScore = new SystemTrayIconStore(); const val = this.props.config.get(this.kp) || 'blue'; const options = [ - ['blue', localized('Blue icon for new and unread messages'), localized('(The same blue tray icon is used whether you have new or old unread messages.)'), INBOX_FULL_UNREAD_ICON], - ['red', localized('Red icon for new and blue icon for unread messages'), localized('(A red tray icon is displayed for new messages and a blue icon for older unread messages.)'), INBOX_FULL_NEW_ICON], + ['blue', localized('Blue icon for new and unread messages'), localized('(The same blue tray icon is used whether you have new or old unread messages.)'), systemTrayIconScore.inboxFullUnreadIcon()], + ['red', localized('Red icon for new and blue icon for unread messages'), localized('(A red tray icon is displayed for new messages and a blue icon for older unread messages.)'), systemTrayIconScore.inboxFullNewIcon()], ]; return ( diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark.png new file mode 100644 index 000000000..b1c114e6d Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark@2x.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark@2x.png new file mode 100644 index 000000000..ace4696d8 Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-NewItems-dark@2x.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark.png new file mode 100644 index 000000000..6c50bf660 Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark@2x.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark@2x.png new file mode 100644 index 000000000..d0285af50 Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-UnreadItems-dark@2x.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark.png new file mode 100644 index 000000000..6704183ba Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark@2x.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark@2x.png new file mode 100644 index 000000000..c15829c53 Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Full-dark@2x.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark.png new file mode 100644 index 000000000..dc1c80363 Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark.png differ diff --git a/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark@2x.png b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark@2x.png new file mode 100644 index 000000000..7af1c7d3c Binary files /dev/null and b/app/internal_packages/system-tray/assets/win32/MenuItem-Inbox-Zero-dark@2x.png differ diff --git a/app/internal_packages/system-tray/lib/system-tray-icon-store.ts b/app/internal_packages/system-tray/lib/system-tray-icon-store.ts index 4c820a1ff..7237817ec 100644 --- a/app/internal_packages/system-tray/lib/system-tray-icon-store.ts +++ b/app/internal_packages/system-tray/lib/system-tray-icon-store.ts @@ -5,22 +5,7 @@ import { BadgeStore } from 'mailspring-exports'; // Must be absolute real system path // https://github.com/atom/electron/issues/1299 const { platform } = process; -const INBOX_ZERO_ICON = path.join(__dirname, '..', 'assets', platform, 'MenuItem-Inbox-Zero.png'); -const INBOX_FULL_ICON = path.join(__dirname, '..', 'assets', platform, 'MenuItem-Inbox-Full.png'); -const INBOX_FULL_NEW_ICON = path.join( - __dirname, - '..', - 'assets', - platform, - 'MenuItem-Inbox-Full-NewItems.png' -); -const INBOX_FULL_UNREAD_ICON = path.join( - __dirname, - '..', - 'assets', - platform, - 'MenuItem-Inbox-Full-UnreadItems.png' -); +const { nativeTheme } = require("@electron/remote"); /* Current / Intended Behavior: @@ -38,13 +23,6 @@ Current / Intended Behavior: it will switch to blue.) */ class SystemTrayIconStore { - static INBOX_ZERO_ICON = INBOX_ZERO_ICON; - - static INBOX_FULL_ICON = INBOX_FULL_ICON; - - static INBOX_FULL_NEW_ICON = INBOX_FULL_NEW_ICON; - - static INBOX_FULL_UNREAD_ICON = INBOX_FULL_UNREAD_ICON; _windowBackgrounded = false; _unsubscribers: (() => void)[]; @@ -66,6 +44,11 @@ class SystemTrayIconStore { window.removeEventListener('browser-window-hide', this._onWindowBackgrounded); window.removeEventListener('browser-window-blur', this._onWindowBackgrounded); }); + + // If the theme changes from bright to dark mode or vice versa, we need to update the tray icon + nativeTheme.on('updated', () => { + this._updateIcon(); + }) } deactivate() { @@ -84,6 +67,44 @@ class SystemTrayIconStore { this._updateIcon(); }; + // This implementation is windows only. + // On Mac the icon color is automatically inverted + // Linux ships with the icons used for a dark tray only + _dark = () => { + if (nativeTheme.shouldUseDarkColors && process.platform === 'win32') { + return "-dark"; + } + return ""; + } + + inboxZeroIcon = () => { + return path.join(__dirname, '..', 'assets', platform, `MenuItem-Inbox-Zero${this._dark()}.png`); + } + + inboxFullIcon = () => { + return path.join(__dirname, '..', 'assets', platform, `MenuItem-Inbox-Full${this._dark()}.png`); + } + + inboxFullNewIcon = () => { + return path.join( + __dirname, + '..', + 'assets', + platform, + `MenuItem-Inbox-Full-NewItems${this._dark()}.png` + ); + } + + inboxFullUnreadIcon = () => { + return path.join( + __dirname, + '..', + 'assets', + platform, + `MenuItem-Inbox-Full-UnreadItems${this._dark()}.png` + ); + } + _updateIcon = () => { const unread = BadgeStore.unread(); const unreadString = (+unread).toLocaleString(); @@ -91,17 +112,17 @@ class SystemTrayIconStore { const newMessagesIconStyle = AppEnv.config.get('core.workspace.trayIconStyle') || 'blue'; - let icon = { path: INBOX_FULL_ICON, isTemplateImg: true }; + let icon = { path: this.inboxFullIcon(), isTemplateImg: true }; if (isInboxZero) { - icon = { path: INBOX_ZERO_ICON, isTemplateImg: true }; + icon = { path: this.inboxZeroIcon(), isTemplateImg: true }; } else if (unread !== 0) { if (newMessagesIconStyle === 'blue') { - icon = { path: INBOX_FULL_UNREAD_ICON, isTemplateImg: false }; + icon = { path: this.inboxFullUnreadIcon(), isTemplateImg: false }; } else { if (this._windowBackgrounded) { - icon = { path: INBOX_FULL_NEW_ICON, isTemplateImg: false }; + icon = { path: this.inboxFullNewIcon(), isTemplateImg: false }; } else { - icon = { path: INBOX_FULL_UNREAD_ICON, isTemplateImg: false }; + icon = { path: this.inboxFullUnreadIcon(), isTemplateImg: false }; } } } diff --git a/app/internal_packages/system-tray/specs/system-tray-icon-store-spec.ts b/app/internal_packages/system-tray/specs/system-tray-icon-store-spec.ts index d5c27afe0..485d48508 100644 --- a/app/internal_packages/system-tray/specs/system-tray-icon-store-spec.ts +++ b/app/internal_packages/system-tray/specs/system-tray-icon-store-spec.ts @@ -2,8 +2,6 @@ import { ipcRenderer } from 'electron'; import { BadgeStore } from 'mailspring-exports'; import SystemTrayIconStore from '../lib/system-tray-icon-store'; -const { INBOX_ZERO_ICON, INBOX_FULL_ICON, INBOX_FULL_NEW_ICON, INBOX_FULL_UNREAD_ICON } = SystemTrayIconStore; - describe('SystemTrayIconStore', function systemTrayIconStore() { beforeEach(() => { spyOn(ipcRenderer, 'send'); @@ -20,7 +18,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { spyOn(BadgeStore, 'unread').andReturn(0); spyOn(BadgeStore, 'total').andReturn(0); this.iconStore._updateIcon(); - expect(getCallData()).toEqual({ path: INBOX_ZERO_ICON, isTemplateImg: true }); + expect(getCallData()).toEqual({ path: this.iconStore.inboxZeroIcon(), isTemplateImg: true }); }); it('shows inbox zero icon when isInboxZero and window is blurred', () => { @@ -28,7 +26,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { spyOn(BadgeStore, 'unread').andReturn(0); spyOn(BadgeStore, 'total').andReturn(0); this.iconStore._updateIcon(); - expect(getCallData()).toEqual({ path: INBOX_ZERO_ICON, isTemplateImg: true }); + expect(getCallData()).toEqual({ path: this.iconStore.inboxZeroIcon(), isTemplateImg: true }); }); it('shows inbox full icon when not isInboxZero and window is focused', () => { @@ -36,7 +34,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { spyOn(BadgeStore, 'unread').andReturn(102); spyOn(BadgeStore, 'total').andReturn(123123); this.iconStore._updateIcon(); - expect(getCallData()).toEqual({ path: INBOX_FULL_ICON, isTemplateImg: true }); + expect(getCallData()).toEqual({ path: this.iconStore.inboxFullIcon(), isTemplateImg: true }); }); it('shows inbox full /alt/ icon when not isInboxZero and window is blurred', () => { @@ -44,7 +42,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { spyOn(BadgeStore, 'unread').andReturn(102); spyOn(BadgeStore, 'total').andReturn(123123); this.iconStore._updateIcon(); - expect(getCallData()).toEqual({ path: INBOX_FULL_UNREAD_ICON, isTemplateImg: false }); + expect(getCallData()).toEqual({ path: this.iconStore.inboxFullUnreadIcon(), isTemplateImg: false }); }); }); @@ -53,7 +51,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { spyOn(BadgeStore, 'total').andReturn(1); this.iconStore._onWindowFocus(); const { path } = getCallData(); - expect(path).toBe(INBOX_FULL_ICON); + expect(path).toBe(this.iconStore.inboxFullIcon()); }); it('shows inbox full /alt/ icon ONLY when window is currently blurred and total count changes', () => { @@ -66,7 +64,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { this.iconStore._updateIcon(); const { path } = getCallData(); - expect(path).toBe(INBOX_FULL_UNREAD_ICON); + expect(path).toBe(this.iconStore.inboxFullUnreadIcon()); }); it('does not show inbox full /alt/ icon when window is currently focused and total count changes', () => { @@ -77,7 +75,7 @@ describe('SystemTrayIconStore', function systemTrayIconStore() { this.iconStore._updateIcon(); const { path } = getCallData(); - expect(path).toBe(INBOX_FULL_ICON); + expect(path).toBe(this.iconStore.inboxFullIcon()); }); }); });