Typescript (About app for Windows) (#611)

* Typescript - Complete about app screen for Windows

* Typescript - Fix unit test for about app component

* Typescript - Add safety checks for window validation
This commit is contained in:
Kiran Niranjan 2019-03-25 13:17:08 +05:30 committed by Kiran Niranjan
parent f565f394b4
commit 82b57abaa7
4 changed files with 110 additions and 78 deletions

View File

@ -6,7 +6,7 @@ exports[`about app should render correctly 1`] = `
> >
<img <img
className="AboutApp-logo" className="AboutApp-logo"
src="../assets/symphony-logo.png" src="../renderer/assets/symphony-logo.png"
/> />
<span <span
className="AboutApp-name" className="AboutApp-name"

View File

@ -1,4 +1,4 @@
import { app, dialog, Menu, session, shell } from 'electron'; import { app, dialog, Menu, MenuItemConstructorOptions, session, shell } from 'electron';
import { isMac, isWindowsOS } from '../common/env'; import { isMac, isWindowsOS } from '../common/env';
import { i18n, LocaleType } from '../common/i18n'; import { i18n, LocaleType } from '../common/i18n';
@ -7,7 +7,7 @@ import { autoLaunchInstance as autoLaunch } from './auto-launch-controller';
import { config, IConfig } from './config-handler'; import { config, IConfig } from './config-handler';
import { exportCrashDumps, exportLogs } from './reports-handler'; import { exportCrashDumps, exportLogs } from './reports-handler';
import { updateAlwaysOnTop } from './window-actions'; import { updateAlwaysOnTop } from './window-actions';
import { windowHandler } from './window-handler'; import { ICustomBrowserWindow, windowHandler } from './window-handler';
export const menuSections = { export const menuSections = {
about: 'about', about: 'about',
@ -204,81 +204,93 @@ export class AppMenu {
* Builds menu items for window section * Builds menu items for window section
*/ */
private buildWindowMenu(): Electron.MenuItemConstructorOptions { private buildWindowMenu(): Electron.MenuItemConstructorOptions {
const submenu: MenuItemConstructorOptions[] = [
this.assignRoleOrLabel('minimize', i18n.t('Minimize')()),
this.assignRoleOrLabel('close', i18n.t('Close')()),
this.buildSeparator(),
{
checked: launchOnStartup,
click: async (item) => {
if (item.checked) {
await autoLaunch.enableAutoLaunch();
} else {
await autoLaunch.disableAutoLaunch();
}
launchOnStartup = item.checked;
await config.updateUserConfig({ launchOnStartup });
},
label: i18n.t('Auto Launch On Startup')(),
type: 'checkbox',
},
{
checked: isAlwaysOnTop,
click: async (item) => {
isAlwaysOnTop = item.checked;
updateAlwaysOnTop(item.checked, true);
await config.updateUserConfig({ alwaysOnTop: item.checked });
},
label: i18n.t('Always on Top')(),
type: 'checkbox',
},
{
checked: minimizeOnClose,
click: async (item) => {
minimizeOnClose = item.checked;
await config.updateUserConfig({ minimizeOnClose });
},
label: i18n.t('Minimize on Close')(),
type: 'checkbox',
},
{
checked: bringToFront,
click: async (item) => {
bringToFront = item.checked;
await config.updateUserConfig({ bringToFront });
},
label: isWindowsOS
? i18n.t('Flash Notification in Taskbar')()
: i18n.t('Bring to Front on Notifications')(),
type: 'checkbox',
},
this.buildSeparator(),
{
checked: memoryRefresh,
click: async (item) => {
memoryRefresh = item.checked;
await config.updateUserConfig({ memoryRefresh });
},
label: i18n.t('Refresh app when idle')(),
type: 'checkbox',
},
{
click: (_item, focusedWindow) => {
if (focusedWindow && !focusedWindow.isDestroyed()) {
const defaultSession = session.defaultSession;
if (defaultSession) {
defaultSession.clearCache(() => {
focusedWindow.reload();
});
}
}
},
label: i18n.t('Clear cache and Reload')(),
},
];
if (isWindowsOS) {
submenu.push({
label: i18n.t('About Symphony')(),
click(_menuItem, focusedWindow) {
const windowName = focusedWindow ? (focusedWindow as ICustomBrowserWindow).winName : '';
windowHandler.createAboutAppWindow(windowName);
},
});
}
return { return {
label: i18n.t('Window')(), label: i18n.t('Window')(),
role: 'window', role: 'window',
submenu: [ submenu,
this.assignRoleOrLabel('minimize', i18n.t('Minimize')()),
this.assignRoleOrLabel('close', i18n.t('Close')()),
this.buildSeparator(),
{
checked: launchOnStartup,
click: async (item) => {
if (item.checked) {
await autoLaunch.enableAutoLaunch();
} else {
await autoLaunch.disableAutoLaunch();
}
launchOnStartup = item.checked;
await config.updateUserConfig({ launchOnStartup });
},
label: i18n.t('Auto Launch On Startup')(),
type: 'checkbox',
},
{
checked: isAlwaysOnTop,
click: async (item) => {
isAlwaysOnTop = item.checked;
updateAlwaysOnTop(item.checked, true);
await config.updateUserConfig({ alwaysOnTop: item.checked });
},
label: i18n.t('Always on Top')(),
type: 'checkbox',
},
{
checked: minimizeOnClose,
click: async (item) => {
minimizeOnClose = item.checked;
await config.updateUserConfig({ minimizeOnClose });
},
label: i18n.t('Minimize on Close')(),
type: 'checkbox',
},
{
checked: bringToFront,
click: async (item) => {
bringToFront = item.checked;
await config.updateUserConfig({ bringToFront });
},
label: isWindowsOS
? i18n.t('Flash Notification in Taskbar')()
: i18n.t('Bring to Front on Notifications')(),
type: 'checkbox',
},
this.buildSeparator(),
{
checked: memoryRefresh,
click: async (item) => {
memoryRefresh = item.checked;
await config.updateUserConfig({ memoryRefresh });
},
label: i18n.t('Refresh app when idle')(),
type: 'checkbox',
},
{
click: (_item, focusedWindow) => {
if (focusedWindow && !focusedWindow.isDestroyed()) {
const defaultSession = session.defaultSession;
if (defaultSession) {
defaultSession.clearCache(() => {
focusedWindow.reload();
});
}
}
},
label: i18n.t('Clear cache and Reload')(),
},
],
}; };
} }

View File

@ -363,8 +363,28 @@ export class WindowHandler {
/** /**
* Creates a about app window * Creates a about app window
*/ */
public createAboutAppWindow(): void { public createAboutAppWindow(windowName: string): void {
this.aboutAppWindow = createComponentWindow('about-app');
// This prevents creating multiple instances of the
// about window
if (this.aboutAppWindow && windowExists(this.aboutAppWindow)) {
if (this.aboutAppWindow.isMinimized()) {
this.aboutAppWindow.restore();
}
this.aboutAppWindow.focus();
return;
}
const allWindows = BrowserWindow.getAllWindows();
const selectedParentWindow = allWindows.find((window) => {
return (window as ICustomBrowserWindow).winName === windowName;
});
this.aboutAppWindow = createComponentWindow(
'about-app',
selectedParentWindow ? { parent: selectedParentWindow } : {},
);
this.aboutAppWindow.setVisibleOnAllWorkspaces(true);
this.aboutAppWindow.webContents.once('did-finish-load', () => { this.aboutAppWindow.webContents.once('did-finish-load', () => {
if (!this.aboutAppWindow || !windowExists(this.aboutAppWindow)) { if (!this.aboutAppWindow || !windowExists(this.aboutAppWindow)) {
return; return;

View File

@ -35,7 +35,7 @@ export default class AboutApp extends React.Component<{}, IState> {
const copyright = `Copyright \xA9 ${new Date().getFullYear()} ${appName}`; const copyright = `Copyright \xA9 ${new Date().getFullYear()} ${appName}`;
return ( return (
<div className='AboutApp'> <div className='AboutApp'>
<img className='AboutApp-logo' src='../assets/symphony-logo.png'/> <img className='AboutApp-logo' src='../renderer/assets/symphony-logo.png'/>
<span className='AboutApp-name'>{appName}</span> <span className='AboutApp-name'>{appName}</span>
<span className='AboutApp-versionText'>{versionString}</span> <span className='AboutApp-versionText'>{versionString}</span>
<span className='AboutApp-copyrightText'>{copyright}</span> <span className='AboutApp-copyrightText'>{copyright}</span>