diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a2d98f11..907730cc9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ Web UI version numbers should always match the corresponding version of LBRY App
## [Unreleased]
### Added
+ * Save app state when closing to tray ([#968](https://github.com/lbryio/lbry-app/issues/968))
* Added ability to export wallet transactions to JSON and CSV format ([#976](https://github.com/lbryio/lbry-app/pull/976))
*
@@ -16,7 +17,9 @@ Web UI version numbers should always match the corresponding version of LBRY App
*
### Fixed
- *
+ * Fixed sort by date of published content ([#986](https://github.com/lbryio/lbry-app/issues/986))
+ * Fix night mode start time, set to 9PM (#1050)
+ * Fix night mode start time, set to 9PM ([#1050](https://github.com/lbryio/lbry-app/issues/1050))
*
### Deprecated
diff --git a/src/main/Tray.js b/src/main/Tray.js
deleted file mode 100644
index 6937dda42..000000000
--- a/src/main/Tray.js
+++ /dev/null
@@ -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);
- }
-}
diff --git a/src/main/createTray.js b/src/main/createTray.js
new file mode 100644
index 000000000..c8ed9ba95
--- /dev/null
+++ b/src/main/createTray.js
@@ -0,0 +1,41 @@
+import { app, Menu, Tray } 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 Tray(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;
+};
diff --git a/src/main/createWindow.js b/src/main/createWindow.js
index 6809761f3..8521b3207 100644
--- a/src/main/createWindow.js
+++ b/src/main/createWindow.js
@@ -2,7 +2,7 @@ import { app, BrowserWindow, dialog } from 'electron';
import setupBarMenu from './menu/setupBarMenu';
import setupContextMenu from './menu/setupContextMenu';
-export default deepLinkingURIArg => {
+export default appState => {
let windowConfiguration = {
backgroundColor: '#155B4A',
minWidth: 800,
@@ -35,11 +35,7 @@ export default deepLinkingURIArg => {
let deepLinkingURI;
// Protocol handler for win32
- if (
- !deepLinkingURIArg &&
- process.platform === 'win32' &&
- String(process.argv[1]).startsWith('lbry')
- ) {
+ if (process.platform === 'win32' && String(process.argv[1]).startsWith('lbry')) {
// Keep only command line / deep linked arguments
// Windows normalizes URIs when they're passed in from other apps. On Windows, this tries to
// 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
// an anchor and converts it to lbry://channel/#claimid. We remove the slash here as well.
deepLinkingURI = process.argv[1].replace(/\/$/, '').replace('/#', '#');
- } else {
- deepLinkingURI = deepLinkingURIArg;
}
setupBarMenu();
setupContextMenu(window);
- window.on('closed', () => {
- window = null;
+ window.on('close', event => {
+ if (!appState.isQuitting) {
+ event.preventDefault();
+ window.hide();
+ }
});
window.on('focus', () => {
diff --git a/src/main/index.js b/src/main/index.js
index 6aeebe453..c63de5e1c 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -8,7 +8,7 @@ import https from 'https';
import { shell, app, ipcMain, dialog } from 'electron';
import { autoUpdater } from 'electron-updater';
import Daemon from './Daemon';
-import Tray from './Tray';
+import createTray from './createTray';
import createWindow from './createWindow';
autoUpdater.autoDownload = true;
@@ -32,11 +32,7 @@ let rendererWindow;
let tray;
let daemon;
-let isQuitting;
-
-const updateRendererWindow = window => {
- rendererWindow = window;
-};
+const appState = {};
const installExtensions = async () => {
// eslint-disable-next-line import/no-extraneous-dependencies,global-require
@@ -64,7 +60,7 @@ app.on('ready', async () => {
daemon = new Daemon();
daemon.on('exit', () => {
daemon = null;
- if (!isQuitting) {
+ if (!appState.isQuitting) {
dialog.showErrorBox(
'Daemon has Exited',
'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') {
await installExtensions();
}
- rendererWindow = createWindow();
- tray = new Tray(rendererWindow, updateRendererWindow);
- tray.create();
+ rendererWindow = createWindow(appState);
+ tray = createTray(rendererWindow);
});
app.on('activate', () => {
- // On macOS it's common to re-create a window in the app when the
- // dock icon is clicked and there are no other windows open.
- if (!rendererWindow) rendererWindow = createWindow();
+ rendererWindow.show();
});
app.on('will-quit', event => {
@@ -117,7 +110,7 @@ app.on('will-quit', event => {
return;
}
- isQuitting = true;
+ appState.isQuitting = true;
if (daemon) daemon.quit();
});
@@ -126,18 +119,13 @@ app.on('will-finish-launching', () => {
// Protocol handler for macOS
app.on('open-url', (event, URL) => {
event.preventDefault();
- if (rendererWindow && !rendererWindow.isDestroyed()) {
- rendererWindow.webContents.send('open-uri-requested', URL);
- rendererWindow.show();
- rendererWindow.focus();
- } else {
- rendererWindow = createWindow(URL);
- }
+ rendererWindow.webContents.send('open-uri-requested', URL);
+ rendererWindow.show();
});
});
-app.on('window-all-closed', () => {
- // Subscribe to event so the app doesn't quit when closing the window.
+app.on('before-quit', () => {
+ appState.isQuitting = true;
});
ipcMain.on('upgrade', (event, installerPath) => {
@@ -224,7 +212,7 @@ ipcMain.on('set-auth-token', (event, token) => {
process.on('uncaughtException', error => {
dialog.showErrorBox('Error Encountered', `Caught error: ${error}`);
- isQuitting = true;
+ appState.isQuitting = true;
if (daemon) daemon.quit();
app.exit(1);
});
@@ -240,14 +228,8 @@ const isSecondInstance = app.makeSingleInstance(argv => {
URI = argv[1].replace(/\/$/, '').replace('/#', '#');
}
- if (rendererWindow && !rendererWindow.isDestroyed()) {
- rendererWindow.webContents.send('open-uri-requested', URI);
-
- rendererWindow.show();
- rendererWindow.focus();
- } else {
- rendererWindow = createWindow(URI);
- }
+ rendererWindow.webContents.send('open-uri-requested', URI);
+ rendererWindow.show();
});
if (isSecondInstance) {
diff --git a/src/renderer/component/fileList/view.jsx b/src/renderer/component/fileList/view.jsx
index 8dcccadc3..afb446323 100644
--- a/src/renderer/component/fileList/view.jsx
+++ b/src/renderer/component/fileList/view.jsx
@@ -9,12 +9,33 @@ class FileList extends React.PureComponent {
super(props);
this.state = {
- sortBy: 'date',
+ sortBy: 'dateNew',
};
this._sortFunctions = {
- date(fileInfos) {
- return fileInfos.slice().reverse();
+ dateNew(fileInfos) {
+ return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
+ const height1 = fileInfo1.height
+ const height2 = fileInfo2.height
+ if (height1 > height2) {
+ return -1;
+ } else if (height1 < height2) {
+ return 1;
+ }
+ return 0;
+ });
+ },
+ dateOld(fileInfos) {
+ return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
+ const height1 = fileInfo1.height
+ const height2 = fileInfo2.height
+ if (height1 < height2) {
+ return -1;
+ } else if (height1 > height2) {
+ return 1;
+ }
+ return 0;
+ });
},
title(fileInfos) {
return fileInfos.slice().sort((fileInfo1, fileInfo2) => {
@@ -95,7 +116,8 @@ class FileList extends React.PureComponent {
{__('Sort by')}{' '}