From ef503a1e29a540c7318efb5f2018efbf00706198 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Thu, 19 Oct 2017 11:15:25 +0200 Subject: Add option to disable system tray icon --- .../settings/settings/EditSettingsForm.js | 1 + src/config.js | 10 ++++ src/containers/settings/EditSettingsScreen.js | 23 ++++++-- src/electron/Settings.js | 14 ++++- src/electron/ipc-api/appIndicator.js | 45 +++++---------- src/i18n/locales/en-US.json | 1 + src/index.js | 25 ++++++--- src/lib/Tray.js | 64 ++++++++++++++++++++++ 8 files changed, 136 insertions(+), 47 deletions(-) create mode 100644 src/lib/Tray.js diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js index 02736dbb9..5675fecf4 100644 --- a/src/components/settings/settings/EditSettingsForm.js +++ b/src/components/settings/settings/EditSettingsForm.js @@ -115,6 +115,7 @@ export default class EditSettingsForm extends Component {

{intl.formatMessage(messages.headlineGeneral)}

+ {process.platform === 'win32' && ( )} diff --git a/src/config.js b/src/config.js index acbf57f3c..0a4856ece 100644 --- a/src/config.js +++ b/src/config.js @@ -3,3 +3,13 @@ export const LOCAL_API = 'http://localhost:3000'; export const DEV_API = 'https://dev.franzinfra.com'; export const LIVE_API = 'https://api.franzinfra.com'; export const GA_ID = 'UA-74126766-6'; + +export const DEFAULT_APP_SETTINGS = { + autoLaunchOnStart: true, + autoLaunchInBackground: false, + runInBackground: false, + enableSystemTray: true, + minimizeToSystemTray: false, + locale: 'en-us', // TODO: Replace with proper solution once translations are in + beta: false, +}; diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js index 0e17cafce..6dc2175e1 100644 --- a/src/containers/settings/EditSettingsScreen.js +++ b/src/containers/settings/EditSettingsScreen.js @@ -9,6 +9,7 @@ import UserStore from '../../stores/UserStore'; import Form from '../../lib/Form'; import languages from '../../i18n/languages'; import { gaPage } from '../../lib/analytics'; +import { DEFAULT_APP_SETTINGS } from '../../config'; import EditSettingsForm from '../../components/settings/settings/EditSettingsForm'; @@ -26,6 +27,10 @@ const messages = defineMessages({ id: 'settings.app.form.runInBackground', defaultMessage: '!!!Keep Franz in background when closing the window', }, + enableSystemTray: { + id: 'settings.app.form.enableSystemTray', + defaultMessage: '!!!Show Franz in system tray', + }, minimizeToSystemTray: { id: 'settings.app.form.minimizeToSystemTray', defaultMessage: '!!!Minimize Franz to system tray', @@ -61,6 +66,7 @@ export default class EditSettingsScreen extends Component { settings.update({ settings: { runInBackground: settingsData.runInBackground, + enableSystemTray: settingsData.enableSystemTray, minimizeToSystemTray: settingsData.minimizeToSystemTray, locale: settingsData.locale, beta: settingsData.beta, @@ -91,33 +97,38 @@ export default class EditSettingsScreen extends Component { autoLaunchOnStart: { label: intl.formatMessage(messages.autoLaunchOnStart), value: app.autoLaunchOnStart, - default: true, + default: DEFAULT_APP_SETTINGS.autoLaunchOnStart, }, autoLaunchInBackground: { label: intl.formatMessage(messages.autoLaunchInBackground), value: app.launchInBackground, - default: false, + default: DEFAULT_APP_SETTINGS.autoLaunchInBackground, }, runInBackground: { label: intl.formatMessage(messages.runInBackground), value: settings.all.runInBackground, - default: true, + default: DEFAULT_APP_SETTINGS.runInBackground, + }, + enableSystemTray: { + label: intl.formatMessage(messages.enableSystemTray), + value: settings.all.enableSystemTray, + default: DEFAULT_APP_SETTINGS.enableSystemTray, }, minimizeToSystemTray: { label: intl.formatMessage(messages.minimizeToSystemTray), value: settings.all.minimizeToSystemTray, - default: false, + default: DEFAULT_APP_SETTINGS.minimizeToSystemTray, }, locale: { label: intl.formatMessage(messages.language), value: app.locale, options, - default: 'en-US', + default: DEFAULT_APP_SETTINGS.locale, }, beta: { label: intl.formatMessage(messages.beta), value: user.data.beta, - default: false, + default: DEFAULT_APP_SETTINGS.beta, }, }, }; diff --git a/src/electron/Settings.js b/src/electron/Settings.js index 049a08296..824b4c20c 100644 --- a/src/electron/Settings.js +++ b/src/electron/Settings.js @@ -1,5 +1,17 @@ +import { observable } from 'mobx'; + +import { DEFAULT_APP_SETTINGS } from '../config'; + export default class Settings { - store = {}; + @observable store = { + autoLaunchOnStart: DEFAULT_APP_SETTINGS.autoLaunchOnStart, + autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground, + runInBackground: DEFAULT_APP_SETTINGS.runInBackground, + enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray, + minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray, + locale: DEFAULT_APP_SETTINGS.locale, + beta: DEFAULT_APP_SETTINGS.beta, + }; set(settings) { this.store = Object.assign(this.store, settings); diff --git a/src/electron/ipc-api/appIndicator.js b/src/electron/ipc-api/appIndicator.js index 576234d25..d31819068 100644 --- a/src/electron/ipc-api/appIndicator.js +++ b/src/electron/ipc-api/appIndicator.js @@ -1,12 +1,11 @@ -import { app, ipcMain, Tray, Menu } from 'electron'; +import { app, ipcMain } from 'electron'; import path from 'path'; +import { autorun } from 'mobx'; -const INDICATOR_TRAY_PLAIN = 'tray'; -const INDICATOR_TRAY_UNREAD = 'tray-unread'; const INDICATOR_TASKBAR = 'taskbar'; - const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; -let trayIcon; + +let isTrayIconEnabled; function getAsset(type, asset) { return path.join( @@ -15,26 +14,14 @@ function getAsset(type, asset) { } export default (params) => { - trayIcon = new Tray(getAsset('tray', INDICATOR_TRAY_PLAIN)); - const trayMenuTemplate = [ - { - label: 'Show Franz', - click() { - params.mainWindow.show(); - }, - }, { - label: 'Quit Franz', - click() { - app.quit(); - }, - }, - ]; - - const trayMenu = Menu.buildFromTemplate(trayMenuTemplate); - trayIcon.setContextMenu(trayMenu); + autorun(() => { + isTrayIconEnabled = params.settings.get('enableSystemTray'); - trayIcon.on('click', () => { - params.mainWindow.show(); + if (!isTrayIconEnabled) { + params.trayIcon.hide(); + } else if (isTrayIconEnabled) { + params.trayIcon.show(); + } }); ipcMain.on('updateAppIndicator', (event, args) => { @@ -68,13 +55,7 @@ export default (params) => { } } - // Update system tray - trayIcon.setImage(getAsset('tray', args.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); - - if (process.platform === 'darwin') { - trayIcon.setPressedImage( - getAsset('tray', `${args.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`), - ); - } + // Update Tray + params.trayIcon.setIndicator(args.indicator); }); }; diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 194b8047c..b9ed51b83 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -126,6 +126,7 @@ "settings.app.updateStatusUpToDate": "You are using the latest version of Franz", "settings.app.form.autoLaunchOnStart": "Launch Franz on start", "settings.app.form.autoLaunchInBackground": "Open in background", + "settings.app.form.enableSystemTray": "Show Franz in system tray", "settings.app.form.minimizeToSystemTray": "Minimize Franz to system tray", "settings.app.form.runInBackground": "Keep Franz in background when closing the window", "settings.app.form.language": "Language", diff --git a/src/index.js b/src/index.js index 3244c44ad..6f45d95b8 100644 --- a/src/index.js +++ b/src/index.js @@ -2,16 +2,18 @@ import { app, BrowserWindow, shell } from 'electron'; import fs from 'fs-extra'; import path from 'path'; -// eslint-disable-next-line +/* eslint-disable */ if (require('electron-squirrel-startup')) app.quit(); -import windowStateKeeper from 'electron-window-state'; // eslint-disable-line +import windowStateKeeper from 'electron-window-state'; -import { isDevMode, isWindows } from './environment'; // eslint-disable-line -import ipcApi from './electron/ipc-api'; // eslint-disable-line -import Settings from './electron/Settings'; // eslint-disable-line -import { appId } from './package.json'; // eslint-disable-line -import './electron/exception'; // eslint-disable-line +import { isDevMode, isWindows } from './environment'; +import ipcApi from './electron/ipc-api'; +import Tray from './lib/Tray'; +import Settings from './electron/Settings'; +import { appId } from './package.json'; +import './electron/exception'; +/* eslint-enable */ // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -47,8 +49,11 @@ const createWindow = async () => { autoHideMenuBar: true, }); + // Initialize System Tray + const trayIcon = new Tray(mainWindow); + // Initialize ipcApi - ipcApi({ mainWindow, settings }); + ipcApi({ mainWindow, settings, trayIcon }); // Manage Window State mainWindowState.manage(mainWindow); @@ -102,6 +107,10 @@ const createWindow = async () => { if (app.wasMaximized) { mainWindow.maximize(); } + + if (!settings.get('enableSystemTray')) { + trayIcon.hide(); + } }); mainWindow.on('show', () => { diff --git a/src/lib/Tray.js b/src/lib/Tray.js new file mode 100644 index 000000000..631342b24 --- /dev/null +++ b/src/lib/Tray.js @@ -0,0 +1,64 @@ +import { app, Tray, Menu } from 'electron'; +import path from 'path'; + +const FILE_EXTENSION = process.platform === 'win32' ? 'ico' : 'png'; +const INDICATOR_TRAY_PLAIN = 'tray'; +const INDICATOR_TRAY_UNREAD = 'tray-unread'; + +function getAsset(type, asset) { + return path.join( + __dirname, '..', 'assets', 'images', type, process.platform, `${asset}.${FILE_EXTENSION}`, + ); +} + +export default class TrayIcon { + mainWindow = null; + trayIcon = null; + + constructor(mainWindow) { + this.mainWindow = mainWindow; + } + + show() { + this.trayIcon = new Tray(getAsset('tray', INDICATOR_TRAY_PLAIN)); + const trayMenuTemplate = [ + { + label: 'Show Franz', + click() { + this.mainWindow.show(); + }, + }, { + label: 'Quit Franz', + click() { + app.quit(); + }, + }, + ]; + + const trayMenu = Menu.buildFromTemplate(trayMenuTemplate); + this.trayIcon.setContextMenu(trayMenu); + + this.trayIcon.on('click', () => { + this.mainWindow.show(); + }); + } + + hide() { + if (this.trayIcon) { + this.trayIcon.destroy(); + this.trayIcon = null; + } + } + + setIndicator(indicator) { + if (!this.trayIcon) return; + + this.trayIcon.setImage(getAsset('tray', indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); + + if (process.platform === 'darwin') { + this.trayIcon.setPressedImage( + getAsset('tray', `${indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`), + ); + } + } +} -- cgit v1.2.3-70-g09d2