Skip to content

Commit

Permalink
Merge pull request #1241 from responsively-org/about-window-revamp
Browse files Browse the repository at this point in the history
Revamped the about window and added info about app update status
  • Loading branch information
manojVivek authored Jun 7, 2024
2 parents 1bf5835 + 895ff0a commit 98c456d
Show file tree
Hide file tree
Showing 11 changed files with 369 additions and 133 deletions.
3 changes: 2 additions & 1 deletion desktop-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@
"electron-debug": "^3.2.0",
"electron-log": "^4.4.8",
"electron-store": "^8.0.2",
"electron-updater": "^6.1.1",
"electron-updater": "^6.1.8",
"emitter": "^0.0.5",
"javascript-time-ago": "^2.5.10",
"mousetrap": "^1.6.5",
"os": "^0.1.2",
"postcss": "^8.4.31",
Expand Down
1 change: 1 addition & 0 deletions desktop-app/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const IPC_MAIN_CHANNELS = {
OPEN_URL: 'open-url',
START_WATCHING_FILE: 'start-watching-file',
STOP_WATCHER: 'stop-watcher',
OPEN_ABOUT_DIALOG: 'open-about-dialog',
} as const;

export type Channels = typeof IPC_MAIN_CHANNELS[keyof typeof IPC_MAIN_CHANNELS];
Expand Down
71 changes: 71 additions & 0 deletions desktop-app/src/main/app-updater.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { autoUpdater } from 'electron-updater';

export interface AppUpdaterStatus {
status: string;
version?: string;
lastChecked?: number;
progress?: number;
size?: number;
error?: Error;
}

export class AppUpdater {
status: string = 'IDLE';

version?: string;

lastChecked?: number;

progress?: number;

size?: number;

error?: Error;

constructor() {
autoUpdater.logger = console;
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('checking-for-update', () => {
this.status = 'CHECKING';
this.lastChecked = Date.now();
});
autoUpdater.on('update-available', (info) => {
this.status = 'AVAILABLE';
this.version = info.version;
this.lastChecked = Date.now();
});
autoUpdater.on('update-not-available', (info) => {

Check warning on line 37 in desktop-app/src/main/app-updater.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest)

'info' is defined but never used
this.status = 'UP_TO_DATE';
this.lastChecked = Date.now();
});
autoUpdater.on('error', (err) => {
this.status = 'ERROR';
this.error = err;
this.lastChecked = Date.now();
});
autoUpdater.on('download-progress', (progressObj) => {
const logMessage = `Download speed: ${progressObj.bytesPerSecond} - Downloaded ${progressObj.percent}% (${progressObj.transferred}/${progressObj.total})`;
// eslint-disable-next-line no-console
console.log(logMessage);
this.status = `DOWNLOADING - ${progressObj.percent}%`;
this.progress = progressObj.percent;
this.size = progressObj.total;
this.lastChecked = Date.now();
});
autoUpdater.on('update-downloaded', (info) => {

Check warning on line 55 in desktop-app/src/main/app-updater.ts

View workflow job for this annotation

GitHub Actions / test (macos-latest)

'info' is defined but never used
this.status = 'DOWNLOADED (Restart to apply update)';
this.lastChecked = Date.now();
});
}

getStatus(): AppUpdaterStatus {
return {
status: this.status,
version: this.version,
lastChecked: this.lastChecked,
progress: this.progress,
size: this.size,
error: this.error,
};
}
}
23 changes: 5 additions & 18 deletions desktop-app/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
*/
import path from 'path';
import { app, BrowserWindow, shell, screen, ipcMain } from 'electron';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import {
setupTitlebar,
attachTitlebarToWindow,
} from 'custom-electron-titlebar/main';
import { setupTitlebar } from 'custom-electron-titlebar/main';
import cli from './cli';
import { PROTOCOL } from '../common/constants';
import MenuBuilder from './menu';
Expand All @@ -36,6 +31,7 @@ import { WebPermissionHandlers } from './web-permissions';
import { initHttpBasicAuthHandlers } from './http-basic-auth';
import { initAppMetaHandlers } from './app-meta';
import { openUrl } from './protocol-handler';
import { AppUpdater } from './app-updater';

let windowShownOnOpen = false;

Expand All @@ -53,14 +49,6 @@ let urlToOpen: string | undefined = cli.input[0]?.includes('electronmon')
? undefined
: cli.input[0];

export default class AppUpdater {
constructor() {
log.transports.file.level = 'info';
autoUpdater.logger = log;
autoUpdater.checkForUpdatesAndNotify();
}
}

let mainWindow: BrowserWindow | null = null;

initAppMetaHandlers();
Expand Down Expand Up @@ -217,7 +205,9 @@ const createWindow = async () => {
mainWindow = null;
});

const menuBuilder = new MenuBuilder(mainWindow);
const appUpdater = new AppUpdater();

const menuBuilder = new MenuBuilder(mainWindow, appUpdater);
menuBuilder.buildMenu();

// Open urls in the user's browser
Expand All @@ -239,9 +229,6 @@ const createWindow = async () => {
ipcMain.on('stop-watcher', async () => {
await stopWatchFiles();
});
// Remove this if your app does not use auto updates
// eslint-disable-next-line
new AppUpdater();
};

app.on('open-url', async (event, url) => {
Expand Down
159 changes: 68 additions & 91 deletions desktop-app/src/main/menu/help.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,83 @@
import {
BrowserWindow,
clipboard,
dialog,
MenuItemConstructorOptions,
ipcMain,
shell,
} from 'electron';
import path from 'path';

import { getEnvironmentInfo, getPackageJson } from '../util';
import { EnvironmentInfo, getEnvironmentInfo } from '../util';
import { IPC_MAIN_CHANNELS } from '../../common/constants';
import { AppUpdater, AppUpdaterStatus } from '../app-updater';

const aboutOnClick = () => {
const iconPath = path.join(__dirname, '../resources/icons/64x64.png');
const title = 'Responsively';
const { description } = getPackageJson();
const {
appVersion,
electronVersion,
chromeVersion,
nodeVersion,
v8Version,
osInfo,
} = getEnvironmentInfo();
export interface AboutDialogArgs {
environmentInfo: EnvironmentInfo;
updaterStatus: AppUpdaterStatus;
}

const usefulInfo = `Version: ${appVersion}\nElectron: ${electronVersion}\nChrome: ${chromeVersion}\nNode.js: ${nodeVersion}\nV8: ${v8Version}\nOS: ${osInfo}`;
const detail = description ? `${description}\n\n${usefulInfo}` : usefulInfo;
let buttons = ['OK', 'Copy'];
let cancelId = 0;
let defaultId = 1;
if (process.platform === 'linux') {
buttons = ['Copy', 'OK'];
cancelId = 1;
defaultId = 0;
}
dialog
.showMessageBox(BrowserWindow.getAllWindows()[0], {
type: 'none',
buttons,
title,
message: title,
detail,
noLink: true,
icon: iconPath,
cancelId,
defaultId,
})
.then(({ response }) => {
if (response === defaultId) {
clipboard.writeText(usefulInfo, 'clipboard');
}
return null;
})
.catch((err) => {
console.error('Error opening about', err);
});
};
export const subMenuHelp = (
mainWindow: BrowserWindow,
appUpdater: AppUpdater
): MenuItemConstructorOptions => {
const environmentInfo = getEnvironmentInfo();
ipcMain.handle('get-about-info', async (_): Promise<AboutDialogArgs> => {
return {
environmentInfo,
updaterStatus: appUpdater.getStatus(),
};
});

export const subMenuHelp: MenuItemConstructorOptions = {
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://responsively.app');
return {
label: 'Help',
submenu: [
{
label: 'Learn More',
click() {
shell.openExternal('https://responsively.app');
},
},
{
label: 'Open Source',
click() {
shell.openExternal(
'https://github.com/responsively-org/responsively-app'
);
},
},
{
label: 'Join Discord',
click() {
shell.openExternal('https://responsively.app/join-discord/');
},
},
},
{
label: 'Open Source',
click() {
shell.openExternal(
'https://github.com/responsively-org/responsively-app'
);
{
label: 'Search Issues',
click() {
shell.openExternal(
'https://github.com/responsively-org/responsively-app/issues'
);
},
},
},
{
label: 'Join Discord',
click() {
shell.openExternal('https://responsively.app/join-discord/');
{
label: 'Sponsor Responsively',
click() {
shell.openExternal(
'https://responsively.app/sponsor?utm_source=app&utm_medium=menu&utm_campaign=sponsor'
);
},
},
},
{
label: 'Search Issues',
click() {
shell.openExternal(
'https://github.com/responsively-org/responsively-app/issues'
);
{
type: 'separator',
},
},
{
label: 'Sponsor Responsively',
click() {
shell.openExternal(
'https://responsively.app/sponsor?utm_source=app&utm_medium=menu&utm_campaign=sponsor'
);
{
label: 'About',
accelerator: 'F1',
click: () => {
mainWindow.webContents.send(IPC_MAIN_CHANNELS.OPEN_ABOUT_DIALOG, {
environmentInfo,
updaterStatus: appUpdater.getStatus(),
});
},
},
},
{
type: 'separator',
},
{
label: 'About',
accelerator: 'F1',
click: aboutOnClick,
},
],
],
};
};
10 changes: 7 additions & 3 deletions desktop-app/src/main/menu/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { app, Menu, BrowserWindow, MenuItemConstructorOptions } from 'electron';
import { subMenuHelp } from './help';
import { getViewMenu } from './view';
import { AppUpdater } from '../app-updater';

interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
selector?: string;
Expand All @@ -14,8 +15,11 @@ export interface ReloadArgs {
export default class MenuBuilder {
mainWindow: BrowserWindow;

constructor(mainWindow: BrowserWindow) {
appUpdater: AppUpdater;

constructor(mainWindow: BrowserWindow, appUpdater: AppUpdater) {
this.mainWindow = mainWindow;
this.appUpdater = appUpdater;
}

buildMenu(): Menu {
Expand Down Expand Up @@ -118,7 +122,7 @@ export default class MenuBuilder {
subMenuEdit,
getViewMenu(this.mainWindow),
subMenuWindow,
subMenuHelp,
subMenuHelp(this.mainWindow, this.appUpdater),
];
}

Expand All @@ -141,7 +145,7 @@ export default class MenuBuilder {
],
},
getViewMenu(this.mainWindow),
subMenuHelp,
subMenuHelp(this.mainWindow, this.appUpdater),
];
}
}
6 changes: 5 additions & 1 deletion desktop-app/src/main/native-functions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ipcMain, nativeTheme, webContents } from 'electron';
import { clipboard, ipcMain, nativeTheme, webContents } from 'electron';

export interface DisableDefaultWindowOpenHandlerArgs {
webContentsId: number;
Expand Down Expand Up @@ -38,4 +38,8 @@ export const initNativeFunctionHandlers = () => {
return { done: true };
}
);

ipcMain.handle('copy-to-clipboard', async (_, arg: string): Promise<void> => {
clipboard.writeText(arg);
});
};
11 changes: 10 additions & 1 deletion desktop-app/src/main/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@ export const getPackageJson = () => {
return {};
};

export const getEnvironmentInfo = () => {
export interface EnvironmentInfo {
appVersion: string;
electronVersion: string;
chromeVersion: string;
nodeVersion: string;
v8Version: string;
osInfo: string;
}

export const getEnvironmentInfo = (): EnvironmentInfo => {
const pkg = getPackageJson();
const appVersion = pkg.version || 'Unknown';
const electronVersion = process.versions.electron || 'Unknown';
Expand Down
Loading

0 comments on commit 98c456d

Please sign in to comment.