diff --git a/src/background.js b/src/background.js index 128de0a..f764c5b 100644 --- a/src/background.js +++ b/src/background.js @@ -1,8 +1,8 @@ 'use strict'; /* global __static */ -import {app, BrowserWindow, Menu, protocol} from 'electron'; -import {createProtocol, installVueDevtools} from 'vue-cli-plugin-electron-builder/lib'; +import { app, BrowserWindow, Tray, Menu, protocol } from 'electron'; +import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'; import windowRepository from './windowRepository'; const path = require('path'); @@ -18,11 +18,11 @@ const windowSettings = windowRepository(path.join(app.getPath('userData'), 'wind let win; // Standard scheme must be registered before the app is ready -protocol.registerSchemesAsPrivileged([{scheme: 'app', privileges: {secure: true}}]); +protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true }}]); function createWindow() { - windowSettings.updateWindowState({minWidth: 600}); + windowSettings.updateWindowState({ minWidth: 600 }); const windowConfig = windowSettings.getWindowState(); windowConfig.icon = path.join(__static, 'icon.png'); windowConfig.frame = false; @@ -34,6 +34,38 @@ function createWindow() { win = new BrowserWindow(windowConfig); win.userDataPath = path.join(app.getPath('userData'), 'backlog.json'); + let isQuiting; + + app.on('before-quit', function () { + isQuiting = true; + }); + + var appIcon = new Tray(path.join(__static, 'icon.png')) + + var contextMenu = Menu.buildFromTemplate([ + { + label: 'Show App', click: function () { + win.show() + } + }, + { + label: 'Quit', click: function () { + isQuiting = true + app.quit() + } + } + ]) + + appIcon.setContextMenu(contextMenu) + appIcon.setToolTip('Backlog') + appIcon.on('double-click', () => { + win.show(); + }) + + win.on('show', function () { + appIcon.setHighlightMode('always') + }) + if (process.platform === 'darwin') { Menu.setApplicationMenu(createMenuOnMac()); } else { @@ -61,7 +93,14 @@ function createWindow() { win.on('resize', () => windowSettings.updateWindowState(win.getBounds())); win.on('move', () => windowSettings.updateWindowState(win.getBounds())); - win.on('close', () => windowSettings.updateWindowState(win.getBounds())); + win.on('close', () => { + windowSettings.updateWindowState(win.getBounds()); + if (!isQuiting) { + event.preventDefault(); + window.hide(); + event.returnValue = false; + } + }); } // Quit when all windows are closed. @@ -84,7 +123,7 @@ app.on('activate', () => { // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.on('ready', async() => { +app.on('ready', async () => { if (isDevelopment && !process.env.IS_TEST) { // Install Vue Devtools try { @@ -111,25 +150,24 @@ if (isDevelopment) { } } - function createMenuOnMac() { return Menu.buildFromTemplate([ { label: app.getName(), submenu: [ - {role: 'undo'}, - {role: 'redo'}, - {type: 'separator'}, - {role: 'cut'}, - {role: 'copy'}, - {role: 'paste'}, - {role: 'pasteandmatchstyle'}, - {role: 'delete'}, - {role: 'selectall'}, - {role: 'quit'}, - {role: 'hide'}, - {role: 'hideothers'}, - {role: 'unhide'}, + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + { role: 'pasteandmatchstyle' }, + { role: 'delete' }, + { role: 'selectall' }, + { role: 'quit' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, ], }, ]); diff --git a/src/components/TopBar.vue b/src/components/TopBar.vue index 5c37398..6204e83 100644 --- a/src/components/TopBar.vue +++ b/src/components/TopBar.vue @@ -27,10 +27,18 @@ }, methods: { closeApp () { - remote.app.quit(); + if (this.$store.state.settings.minimizeToTray) { + remote.BrowserWindow.getFocusedWindow().hide(); + } else { + remote.app.quit(); + } }, minimize () { - remote.BrowserWindow.getFocusedWindow().minimize(); + if (this.$store.state.settings.minimizeToTray) { + remote.BrowserWindow.getFocusedWindow().hide(); + } else { + remote.BrowserWindow.getFocusedWindow().minimize(); + } } } }; diff --git a/src/components/modals/settings/GeneralSettings.vue b/src/components/modals/settings/GeneralSettings.vue index 43703fa..548ab01 100644 --- a/src/components/modals/settings/GeneralSettings.vue +++ b/src/components/modals/settings/GeneralSettings.vue @@ -5,6 +5,11 @@ {{$t('modals.show_creation_date_for_each_item')}} +
+ + {{$t('modals.minimize_to_tray')}} + +
@@ -30,6 +35,15 @@ this.$store.dispatch('setItemCreationDate', val); this.showSuccessNotification(); } + }, + minimizeToTray: { + get () { + return this.$store.state.settings.minimizeToTray; + }, + set (val) { + this.$store.dispatch('setMinimizeToTray', val); + this.showSuccessNotification(); + } } }, methods: { diff --git a/src/i18n/en.json b/src/i18n/en.json index 5404162..a51c403 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -115,6 +115,7 @@ "shortcut": "Shortcut", "shortcut_modified": "Shortcut modified", "show_creation_date_for_each_item": "Show creation date for each item", + "minimize_to_tray": "Minimize to Tray instead of Taskbar", "show_keymap_window": "Show keymap window", "switch_to_next_board": "Switch to the next board", "switch_to_prev_board": "Switch to the previous board", diff --git a/src/i18n/hr.json b/src/i18n/hr.json index c5cfa22..4723e92 100644 --- a/src/i18n/hr.json +++ b/src/i18n/hr.json @@ -115,6 +115,7 @@ "shortcut": "Prečac", "shortcut_modified": "Prečac je modificiran", "show_creation_date_for_each_item": "Prikaži datum stvaranja za svaku stavku", + "minimize_to_tray": "Smanjite u ladicu umjesto na programsku traku", "show_keymap_window": "Prikaži keymap prozor", "switch_to_next_board": "Prebaci na sljedeću ploču", "switch_to_prev_board": "Prebaci na prethodnu ploču", diff --git a/src/i18n/pl.json b/src/i18n/pl.json index c3117e7..b3686c6 100644 --- a/src/i18n/pl.json +++ b/src/i18n/pl.json @@ -115,6 +115,7 @@ "shortcut": "Skrót klawiszowy", "shortcut_modified": "Skrót zmodyfikowany", "show_creation_date_for_each_item": "Pokaż datę utworzenia dla każdego elementu", + "minimize_to_tray": "Smanjite u ladicu umjesto na programsku traku", "show_keymap_window": "Pokaż skróty klawiszowe", "switch_to_next_board": "Przełącz na następną tablicę", "switch_to_prev_board": "Przełącz na poprzednią tablicę", diff --git a/src/i18n/zh.json b/src/i18n/zh.json index dafa819..25fe7bc 100644 --- a/src/i18n/zh.json +++ b/src/i18n/zh.json @@ -115,6 +115,7 @@ "shortcut": "快捷方式", "shortcut_modified": "修改快捷方式", "show_creation_date_for_each_item": "显示每个项目的创建日期", + "minimize_to_tray": "最小化到托盘而不是任务栏", "show_keymap_window": "显示键盘图窗口", "switch_to_next_board": "切换到下一个页面", "switch_to_prev_board": "切换到上一块页面", diff --git a/src/repositories/settingsRepository.js b/src/repositories/settingsRepository.js index 620d3bb..fa510cb 100644 --- a/src/repositories/settingsRepository.js +++ b/src/repositories/settingsRepository.js @@ -47,6 +47,7 @@ const keyBindings = { db.defaults({ appSettings: { "itemCreationDate": true, + "minimizeToTray": false, "keyBindings": keyBindings, "prependNewItems": true, "showUpdates": true, diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 9db57cc..fdd14e5 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -3,6 +3,7 @@ import settingsRepository from './../../repositories/settingsRepository'; const state = { wasImported: true, itemCreationDate: true, + minimizeToTray: false, prependNewItems: true, stickBoardsOnTop: false, markdownMode: true, @@ -50,6 +51,9 @@ const mutations = { SET_ITEM_CREATION_DATE(state, val) { state.itemCreationDate = val; }, + SET_MINIMIZE_TO_TRAY(state, val) { + state.minimizeToTray = val; + }, SET_SHOW_UPDATES(state, val) { state.showUpdates = val; }, @@ -78,6 +82,10 @@ const actions = { commit('SET_ITEM_CREATION_DATE', itemCreationDate); settingsRepository.updateAppSettings({itemCreationDate}); }, + setMinimizeToTray({commit}, minimizeToTray) { + commit('SET_MINIMIZE_TO_TRAY', minimizeToTray); + settingsRepository.updateAppSettings({minimizeToTray}); + }, setShowUpdates({commit}, showUpdates) { commit('SET_SHOW_UPDATES', showUpdates); settingsRepository.updateAppSettings({showUpdates});