Save app state when closing to tray

This commit is contained in:
Igor Gassmann 2018-02-23 18:20:12 -05:00
parent fcc26a1930
commit 47e0f7c992
5 changed files with 67 additions and 110 deletions

View file

@ -1,10 +1,10 @@
{ {
"appId": "io.lbry.LBRY", "appId": "io.lbry.LBRY",
"publish": { // "publish": {
"provider": "s3", // "provider": "s3",
"bucket": "releases.lbry.io", // "bucket": "releases.lbry.io",
"path": "app/latest" // "path": "app/latest"
}, // },
"mac": { "mac": {
"category": "public.app-category.entertainment" "category": "public.app-category.entertainment"
}, },

View file

@ -1,63 +0,0 @@
import { app, Menu, Tray as ElectronTray } from 'electron';
import path from 'path';
import createWindow from './createWindow';
export default class Tray {
window;
updateAttachedWindow;
tray;
constructor(window, updateAttachedWindow) {
this.window = window;
this.updateAttachedWindow = updateAttachedWindow;
}
create() {
let iconPath;
switch (process.platform) {
case 'darwin': {
iconPath = path.join(__static, '/img/tray/mac/trayTemplate.png');
break;
}
case 'win32': {
iconPath = path.join(__static, '/img/tray/windows/tray.ico');
break;
}
default: {
iconPath = path.join(__static, '/img/tray/default/tray.png');
}
}
this.tray = new ElectronTray(iconPath);
this.tray.on('double-click', () => {
if (!this.window || this.window.isDestroyed()) {
this.window = createWindow();
this.updateAttachedWindow(this.window);
} else {
this.window.show();
this.window.focus();
}
});
this.tray.setToolTip('LBRY App');
const template = [
{
label: `Open ${app.getName()}`,
click: () => {
if (!this.window || this.window.isDestroyed()) {
this.window = createWindow();
this.updateAttachedWindow(this.window);
} else {
this.window.show();
this.window.focus();
}
},
},
{ role: 'quit' },
];
const contextMenu = Menu.buildFromTemplate(template);
this.tray.setContextMenu(contextMenu);
}
}

41
src/main/createTray.js Normal file
View file

@ -0,0 +1,41 @@
import { app, Menu, Tray as ElectronTray } from 'electron';
import path from 'path';
export default window => {
let iconPath;
switch (process.platform) {
case 'darwin': {
iconPath = path.join(__static, '/img/tray/mac/trayTemplate.png');
break;
}
case 'win32': {
iconPath = path.join(__static, '/img/tray/windows/tray.ico');
break;
}
default: {
iconPath = path.join(__static, '/img/tray/default/tray.png');
}
}
const tray = new ElectronTray(iconPath);
tray.on('double-click', () => {
window.show();
});
tray.setToolTip('LBRY App');
const template = [
{
label: `Open ${app.getName()}`,
click: () => {
window.show();
},
},
{ role: 'quit' },
];
const contextMenu = Menu.buildFromTemplate(template);
tray.setContextMenu(contextMenu);
return tray;
};

View file

@ -2,7 +2,7 @@ import { app, BrowserWindow, dialog } from 'electron';
import setupBarMenu from './menu/setupBarMenu'; import setupBarMenu from './menu/setupBarMenu';
import setupContextMenu from './menu/setupContextMenu'; import setupContextMenu from './menu/setupContextMenu';
export default deepLinkingURIArg => { export default appState => {
let windowConfiguration = { let windowConfiguration = {
backgroundColor: '#155B4A', backgroundColor: '#155B4A',
minWidth: 800, minWidth: 800,
@ -35,11 +35,7 @@ export default deepLinkingURIArg => {
let deepLinkingURI; let deepLinkingURI;
// Protocol handler for win32 // Protocol handler for win32
if ( if (process.platform === 'win32' && String(process.argv[1]).startsWith('lbry')) {
!deepLinkingURIArg &&
process.platform === 'win32' &&
String(process.argv[1]).startsWith('lbry')
) {
// Keep only command line / deep linked arguments // Keep only command line / deep linked arguments
// Windows normalizes URIs when they're passed in from other apps. On Windows, this tries to // Windows normalizes URIs when they're passed in from other apps. On Windows, this tries to
// restore the original URI that was typed. // restore the original URI that was typed.
@ -48,15 +44,16 @@ export default deepLinkingURIArg => {
// - In a URI with a claim ID, like lbry://channel#claimid, Windows interprets the hash mark as // - In a URI with a claim ID, like lbry://channel#claimid, Windows interprets the hash mark as
// an anchor and converts it to lbry://channel/#claimid. We remove the slash here as well. // an anchor and converts it to lbry://channel/#claimid. We remove the slash here as well.
deepLinkingURI = process.argv[1].replace(/\/$/, '').replace('/#', '#'); deepLinkingURI = process.argv[1].replace(/\/$/, '').replace('/#', '#');
} else {
deepLinkingURI = deepLinkingURIArg;
} }
setupBarMenu(); setupBarMenu();
setupContextMenu(window); setupContextMenu(window);
window.on('closed', () => { window.on('close', event => {
window = null; if (!appState.isQuitting) {
event.preventDefault();
window.hide();
}
}); });
window.on('focus', () => { window.on('focus', () => {

View file

@ -8,7 +8,7 @@ import https from 'https';
import { shell, app, ipcMain, dialog } from 'electron'; import { shell, app, ipcMain, dialog } from 'electron';
import { autoUpdater } from 'electron-updater'; import { autoUpdater } from 'electron-updater';
import Daemon from './Daemon'; import Daemon from './Daemon';
import Tray from './Tray'; import createTray from './createTray';
import createWindow from './createWindow'; import createWindow from './createWindow';
autoUpdater.autoDownload = true; autoUpdater.autoDownload = true;
@ -32,11 +32,7 @@ let rendererWindow;
let tray; let tray;
let daemon; let daemon;
let isQuitting; const appState = {};
const updateRendererWindow = window => {
rendererWindow = window;
};
const installExtensions = async () => { const installExtensions = async () => {
// eslint-disable-next-line import/no-extraneous-dependencies,global-require // eslint-disable-next-line import/no-extraneous-dependencies,global-require
@ -64,7 +60,7 @@ app.on('ready', async () => {
daemon = new Daemon(); daemon = new Daemon();
daemon.on('exit', () => { daemon.on('exit', () => {
daemon = null; daemon = null;
if (!isQuitting) { if (!appState.isQuitting) {
dialog.showErrorBox( dialog.showErrorBox(
'Daemon has Exited', 'Daemon has Exited',
'The daemon may have encountered an unexpected error, or another daemon instance is already running.' 'The daemon may have encountered an unexpected error, or another daemon instance is already running.'
@ -77,15 +73,12 @@ app.on('ready', async () => {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
await installExtensions(); await installExtensions();
} }
rendererWindow = createWindow(); rendererWindow = createWindow(appState);
tray = new Tray(rendererWindow, updateRendererWindow); tray = createTray(rendererWindow);
tray.create();
}); });
app.on('activate', () => { app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the rendererWindow.show();
// dock icon is clicked and there are no other windows open.
if (!rendererWindow) rendererWindow = createWindow();
}); });
app.on('will-quit', event => { app.on('will-quit', event => {
@ -117,7 +110,7 @@ app.on('will-quit', event => {
return; return;
} }
isQuitting = true; appState.isQuitting = true;
if (daemon) daemon.quit(); if (daemon) daemon.quit();
}); });
@ -126,18 +119,13 @@ app.on('will-finish-launching', () => {
// Protocol handler for macOS // Protocol handler for macOS
app.on('open-url', (event, URL) => { app.on('open-url', (event, URL) => {
event.preventDefault(); event.preventDefault();
if (rendererWindow && !rendererWindow.isDestroyed()) {
rendererWindow.webContents.send('open-uri-requested', URL); rendererWindow.webContents.send('open-uri-requested', URL);
rendererWindow.show(); rendererWindow.show();
rendererWindow.focus();
} else {
rendererWindow = createWindow(URL);
}
}); });
}); });
app.on('window-all-closed', () => { app.on('before-quit', () => {
// Subscribe to event so the app doesn't quit when closing the window. appState.isQuitting = true;
}); });
ipcMain.on('upgrade', (event, installerPath) => { ipcMain.on('upgrade', (event, installerPath) => {
@ -224,7 +212,7 @@ ipcMain.on('set-auth-token', (event, token) => {
process.on('uncaughtException', error => { process.on('uncaughtException', error => {
dialog.showErrorBox('Error Encountered', `Caught error: ${error}`); dialog.showErrorBox('Error Encountered', `Caught error: ${error}`);
isQuitting = true; appState.isQuitting = true;
if (daemon) daemon.quit(); if (daemon) daemon.quit();
app.exit(1); app.exit(1);
}); });
@ -240,14 +228,8 @@ const isSecondInstance = app.makeSingleInstance(argv => {
URI = argv[1].replace(/\/$/, '').replace('/#', '#'); URI = argv[1].replace(/\/$/, '').replace('/#', '#');
} }
if (rendererWindow && !rendererWindow.isDestroyed()) {
rendererWindow.webContents.send('open-uri-requested', URI); rendererWindow.webContents.send('open-uri-requested', URI);
rendererWindow.show(); rendererWindow.show();
rendererWindow.focus();
} else {
rendererWindow = createWindow(URI);
}
}); });
if (isSecondInstance) { if (isSecondInstance) {