Merge pull request #217 from jjavierdguezas/feature/status-bar-update-info

add App Updater status to Status bar
This commit is contained in:
Manoj Vivek 2020-06-24 06:22:04 +05:30 committed by GitHub
commit 7dfbd4fcf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 37 deletions

View file

@ -1,10 +1,9 @@
import {autoUpdater} from 'electron-updater';
import log from 'electron-log';
import {pkg} from './utils/generalUtils';
const EventEmitter = require('events').EventEmitter;
const {EventEmitter} = require('events');
const AppUpdaterState = {
const AppUpdaterStatus = {
Idle: 'idle',
Checking: 'checking',
NoUpdate: 'noUpdate',
@ -12,46 +11,52 @@ const AppUpdaterState = {
Downloaded: 'downloaded',
}
Object.freeze(AppUpdaterState);
Object.freeze(AppUpdaterStatus);
class AppUpdater extends EventEmitter {
state: AppUpdaterState;
status: string;
readyStates: AppUpdaterState[];
timerId = null;
constructor() {
super();
log.transports.file.level = 'info';
autoUpdater.logger = log;
this.state = AppUpdaterState.Idle;
this.readyStates = [AppUpdaterState.Idle, AppUpdaterState.NoUpdate, AppUpdaterState.Downloaded];
this.status = AppUpdaterStatus.Idle;
autoUpdater.on('checking-for-update', () => this.handleStatusChange(AppUpdaterState.Checking));
autoUpdater.on('update-not-available', () => this.handleStatusChange(AppUpdaterState.NoUpdate));
autoUpdater.on('download-progress', () => this.handleStatusChange(AppUpdaterState.Downloading));
autoUpdater.on('update-downloaded', () => this.handleStatusChange(AppUpdaterState.Downloaded));
autoUpdater.on('checking-for-update', () => this.handleStatusChange(AppUpdaterStatus.Checking, false));
autoUpdater.on('update-not-available', () => this.handleStatusChange(AppUpdaterStatus.NoUpdate, true));
autoUpdater.on('download-progress', () => this.handleStatusChange(AppUpdaterStatus.Downloading, false));
autoUpdater.on('update-downloaded', () => this.handleStatusChange(AppUpdaterStatus.Downloaded, true));
}
getCurrentState() {
return this.state;
}
readyToCheck() {
return this.readyStates.includes(this.state);
getCurrentStatus() {
return this.status;
}
checkForUpdatesAndNotify() {
if (this.readyToCheck())
if (this.status === AppUpdaterStatus.Idle)
return autoUpdater.checkForUpdatesAndNotify();
}
handleStatusChange(nextStatus: AppUpdaterState) {
const changed = this.state !== nextStatus;
this.state = nextStatus;
if (changed)
handleStatusChange(nextStatus: string, backToIdle: boolean) {
clearTimeout(this.timerId);
if (this.status !== nextStatus) {
this.status = nextStatus;
this.emit('status-changed', nextStatus);
if (backToIdle) {
this.timerId = setTimeout(() => {
if (this.status !== AppUpdaterStatus.Idle) {
this.status = AppUpdaterStatus.Idle;
this.emit('status-changed', AppUpdaterStatus.Idle);
}
}, 2000);
}
}
}
}
}
const appUpdaterInstance = new AppUpdater();
export { AppUpdaterState, appUpdaterInstance as appUpdater };
export { AppUpdaterStatus, appUpdaterInstance as appUpdater };

View file

@ -1,7 +1,7 @@
import React from 'react';
import React, {useState, useEffect} from 'react';
import cx from 'classnames';
import {shell, ipcRenderer} from 'electron';
import PropTypes from 'prop-types';
import {shell} from 'electron';
import styles from './styles.module.css';
import Github from '../icons/Github';
@ -12,6 +12,48 @@ const Spacer = ({width = 10}) => (
<div className={styles.link} style={{width}} />
);
const AppUpdaterStatusInfoSection = () => {
const [status, setAppUpdaterStatus] = useState('idle');
useEffect(() => {
const handler = (event, args) => {
setAppUpdaterStatus(args.nextStatus);
};
ipcRenderer.on('updater-status-changed', handler);
return () => {
ipcRenderer.removeListener('updater-status-changed', handler);
};
}, []);
let label = '';
switch(status) {
case 'checking':
label = 'Update Info: Checking for Updates...';
break;
case 'noUpdate':
label = 'Update Info: No Updates';
break;
case 'downloading':
label = 'Update Info: Downloading Update...';
break;
case 'downloaded':
label = 'Update Info: Update Downloaded';
break;
default:
label = null;
break;
}
if (label == null) return null;
return (
<div className={styles.section}>
<div>
<span className={cx('appUpdaterStatusInfo', styles.linkText)}>
{label}
</span>
</div>
</div>
)
}
const StatusBar = ({visible}) => {
if (!visible) {
return null;
@ -62,6 +104,7 @@ const StatusBar = ({visible}) => {
</span>
</div>
</div>
<AppUpdaterStatusInfoSection />
<div className={styles.section}>
<div
className={styles.link}

View file

@ -297,7 +297,7 @@ const createWindow = async () => {
appUpdater.on('status-changed', nextStatus => {
menuBuilder.buildMenu(true);
// update status bar info
mainWindow.webContents.send('updater-status-changed', {nextStatus});
});
// Remove this if your app does not use auto updates
appUpdater.checkForUpdatesAndNotify();

View file

@ -14,7 +14,7 @@ import {
getAllShortcuts,
registerShortcut,
} from './shortcut-manager/main-shortcut-manager';
import {appUpdater, AppUpdaterState} from './app-updater';
import {appUpdater, AppUpdaterStatus} from './app-updater';
import {statusBarSettings} from './settings/statusBarSettings';
import {STATUS_BAR_VISIBILITY_CHANGE} from './constants/pubsubEvents';
@ -190,18 +190,33 @@ export default class MenuBuilder {
};
getCheckForUpdatesMenuState() {
const updaterState = appUpdater.getCurrentState();
const updaterStatus = appUpdater.getCurrentStatus();
let label = 'Check for Updates...';
let enabled = true;
if (updaterState === AppUpdaterState.Checking) {
enabled = false;
label = 'Checking for Updates...';
} else if (updaterState === AppUpdaterState.Downloading) {
enabled = false;
label = 'Downloading Update...';
switch(updaterStatus) {
case AppUpdaterStatus.Idle:
label = 'Check for Updates...';
enabled = true;
break;
case AppUpdaterStatus.Checking:
label = 'Checking for Updates...';
enabled = false;
break;
case AppUpdaterStatus.NoUpdate:
label = 'No Updates';
enabled = false;
break;
case AppUpdaterStatus.Downloading:
label = 'Downloading Update...';
enabled = false;
break;
case AppUpdaterStatus.Downloaded:
label = 'Update Downloaded';
enabled = false;
break;
}
return {label, enabled};
}