mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
1 parent
f88aa2f22e
commit
eee7febfc3
10 files changed
+272
-57
No files matched your search
@@ -2,18 +2,18 @@ import { autoUpdater } from "electron-updater"
|
||||
import logger from "./logger"
|
||||
|
||||
export default class AppUpdater {
|
||||
static defaultUpdateIntervalMs = 1000 * 60 * 60 * 24 // once a day
|
||||
|
||||
protected updateInterval: number = (1000 * 60 * 60 * 24) // once a day
|
||||
static checkForUpdates() {
|
||||
return autoUpdater.checkForUpdatesAndNotify()
|
||||
}
|
||||
|
||||
constructor() {
|
||||
constructor(protected updateInterval = AppUpdater.defaultUpdateIntervalMs) {
|
||||
autoUpdater.logger = logger
|
||||
}
|
||||
|
||||
public start() {
|
||||
setInterval(() => {
|
||||
autoUpdater.checkForUpdatesAndNotify()
|
||||
}, this.updateInterval)
|
||||
|
||||
return autoUpdater.checkForUpdatesAndNotify()
|
||||
setInterval(AppUpdater.checkForUpdates, this.updateInterval)
|
||||
return AppUpdater.checkForUpdates();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import { shellSync } from "./shell-sync"
|
||||
import { getFreePort } from "./port"
|
||||
import { mangleProxyEnv } from "./proxy-env"
|
||||
import { registerFileProtocol } from "../common/register-protocol";
|
||||
import { setupTrayIcon } from "./tray";
|
||||
import { clusterStore } from "../common/cluster-store"
|
||||
import { userStore } from "../common/user-store";
|
||||
import { workspaceStore } from "../common/workspace-store";
|
||||
@@ -77,7 +76,6 @@ async function main() {
|
||||
|
||||
// create window manager and open app
|
||||
windowManager = new WindowManager(proxyPort);
|
||||
trayIcon = await setupTrayIcon();
|
||||
}
|
||||
|
||||
app.on("ready", main);
|
||||
|
||||
+18
-21
@@ -14,6 +14,22 @@ export function initMenu(windowManager: WindowManager) {
|
||||
});
|
||||
}
|
||||
|
||||
export function showAbout(browserWindow: BrowserWindow) {
|
||||
const appInfo = [
|
||||
`${appName}: ${app.getVersion()}`,
|
||||
`Electron: ${process.versions.electron}`,
|
||||
`Chrome: ${process.versions.chrome}`,
|
||||
`Copyright 2020 Mirantis, Inc.`,
|
||||
]
|
||||
dialog.showMessageBoxSync(browserWindow, {
|
||||
title: `${isWindows ? " ".repeat(2) : ""}${appName}`,
|
||||
type: "info",
|
||||
buttons: ["Close"],
|
||||
message: `Lens`,
|
||||
detail: appInfo.join("\r\n")
|
||||
})
|
||||
}
|
||||
|
||||
export function buildMenu(windowManager: WindowManager) {
|
||||
function ignoreOnMac(menuItems: MenuItemConstructorOptions[]) {
|
||||
if (isMac) return [];
|
||||
@@ -31,26 +47,7 @@ export function buildMenu(windowManager: WindowManager) {
|
||||
|
||||
function navigate(url: string) {
|
||||
logger.info(`[MENU]: navigating to ${url}`);
|
||||
windowManager.navigate({
|
||||
channel: "menu:navigate",
|
||||
url: url,
|
||||
})
|
||||
}
|
||||
|
||||
function showAbout(browserWindow: BrowserWindow) {
|
||||
const appInfo = [
|
||||
`${appName}: ${app.getVersion()}`,
|
||||
`Electron: ${process.versions.electron}`,
|
||||
`Chrome: ${process.versions.chrome}`,
|
||||
`Copyright 2020 Mirantis, Inc.`,
|
||||
]
|
||||
dialog.showMessageBoxSync(browserWindow, {
|
||||
title: `${isWindows ? " ".repeat(2) : ""}${appName}`,
|
||||
type: "info",
|
||||
buttons: ["Close"],
|
||||
message: `Lens`,
|
||||
detail: appInfo.join("\r\n")
|
||||
})
|
||||
windowManager.navigate(url);
|
||||
}
|
||||
|
||||
const mt: MenuItemConstructorOptions[] = [];
|
||||
@@ -162,7 +159,7 @@ export function buildMenu(windowManager: WindowManager) {
|
||||
label: 'Reload',
|
||||
accelerator: 'CmdOrCtrl+R',
|
||||
click() {
|
||||
windowManager.reload({ channel: "menu:reload" });
|
||||
windowManager.reload();
|
||||
}
|
||||
},
|
||||
{ role: 'toggleDevTools' },
|
||||
|
||||
+48
-11
@@ -1,23 +1,60 @@
|
||||
import path from "path"
|
||||
import { app, Menu, nativeImage, Tray } from "electron"
|
||||
import { isDevelopment } from "../common/vars";
|
||||
import sharp from "sharp";
|
||||
import packageInfo from "../../package.json"
|
||||
import { app, dialog, Menu, nativeImage, Tray } from "electron"
|
||||
import { isDevelopment, isMac } from "../common/vars";
|
||||
import { WindowManager } from "./window-manager";
|
||||
import { showAbout } from "./menu";
|
||||
import AppUpdater from "./app-updater";
|
||||
import { preferencesURL } from "../renderer/components/+preferences/preferences.route";
|
||||
|
||||
export async function setupTrayIcon() {
|
||||
export const trayIcon = isDevelopment
|
||||
? path.resolve(__static, "../src/renderer/components/icon/logo-lens.svg")
|
||||
: path.resolve(__static, "logo.svg") // electron-builder's extraResources
|
||||
|
||||
export async function setupTrayIcon(windowManager: WindowManager) {
|
||||
await app.whenReady();
|
||||
|
||||
const iconPath = path.resolve(__static, isDevelopment ? "../build" : "", "icon.png");
|
||||
const iconSize = isMac ? 16 : 32; // todo: verify on windows/linux
|
||||
const pngIcon = await sharp(trayIcon).png().toBuffer();
|
||||
const icon = nativeImage.createFromBuffer(pngIcon).resize({
|
||||
width: iconSize,
|
||||
height: iconSize
|
||||
});
|
||||
|
||||
// todo: https://www.electronjs.org/docs/api/native-image#high-resolution-image
|
||||
const icon = nativeImage.createFromPath(iconPath).resize({ width: 16, height: 16 });
|
||||
|
||||
const appTray = new Tray(icon);
|
||||
const appTray = new Tray(icon)
|
||||
appTray.setToolTip(packageInfo.description)
|
||||
appTray.setIgnoreDoubleClickEvents(true)
|
||||
appTray.setIgnoreDoubleClickEvents(true);
|
||||
|
||||
// note: browserWindow not available within menuItem.click() as argument[1] when app is not focused / hidden
|
||||
const trayMenu = Menu.buildFromTemplate([
|
||||
{ label: 'Item1', type: 'radio' },
|
||||
{ label: 'Item2', type: 'radio' }
|
||||
{
|
||||
label: "About Lens",
|
||||
click() {
|
||||
windowManager.bringToTop();
|
||||
showAbout(windowManager.mainView);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Preferences",
|
||||
click() {
|
||||
windowManager.bringToTop();
|
||||
windowManager.navigate(preferencesURL());
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Check for updates",
|
||||
async click() {
|
||||
const result = await AppUpdater.checkForUpdates();
|
||||
if (!result) {
|
||||
windowManager.bringToTop();
|
||||
dialog.showMessageBoxSync({
|
||||
message: "No updates available",
|
||||
type: "info",
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
appTray.setContextMenu(trayMenu);
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import type { ClusterId } from "../common/cluster-store";
|
||||
import { clusterStore } from "../common/cluster-store";
|
||||
import { BrowserWindow, dialog, ipcMain, shell, webContents } from "electron"
|
||||
import { BrowserWindow, dialog, ipcMain, shell, Tray, webContents } from "electron"
|
||||
import windowStateKeeper from "electron-window-state"
|
||||
import { observable } from "mobx";
|
||||
import { initMenu } from "./menu";
|
||||
import { setupTrayIcon } from "./tray";
|
||||
|
||||
export class WindowManager {
|
||||
protected mainView: BrowserWindow;
|
||||
public mainView: BrowserWindow;
|
||||
protected splashWindow: BrowserWindow;
|
||||
protected windowState: windowStateKeeper.State;
|
||||
protected trayIcon: Tray;
|
||||
|
||||
@observable activeClusterId: ClusterId;
|
||||
|
||||
@@ -48,21 +50,38 @@ export class WindowManager {
|
||||
|
||||
// load & show app
|
||||
this.showMain();
|
||||
initMenu(this);
|
||||
this.initMenus();
|
||||
}
|
||||
|
||||
navigate({ url, channel, frameId }: { url: string, channel: string, frameId?: number }) {
|
||||
async initMenus() {
|
||||
initMenu(this);
|
||||
this.trayIcon = await setupTrayIcon(this);
|
||||
}
|
||||
|
||||
bringToTop() {
|
||||
this.mainView.show();
|
||||
}
|
||||
|
||||
sendToView({ channel, frameId, data = [] }: { channel: string, frameId?: number, data?: any[] }) {
|
||||
if (frameId) {
|
||||
this.mainView.webContents.sendToFrame(frameId, channel, url);
|
||||
this.mainView.webContents.sendToFrame(frameId, channel, ...data);
|
||||
} else {
|
||||
this.mainView.webContents.send(channel, url);
|
||||
this.mainView.webContents.send(channel, ...data);
|
||||
}
|
||||
}
|
||||
|
||||
reload({ channel }: { channel: string }) {
|
||||
navigate(url: string, frameId?: number) {
|
||||
this.sendToView({
|
||||
channel: "menu:navigate",
|
||||
frameId: frameId,
|
||||
data: [url],
|
||||
})
|
||||
}
|
||||
|
||||
reload() {
|
||||
const frameId = clusterStore.getById(this.activeClusterId)?.frameId;
|
||||
if (frameId) {
|
||||
this.mainView.webContents.sendToFrame(frameId, channel);
|
||||
this.sendToView({ channel: "menu:reload", frameId });
|
||||
} else {
|
||||
webContents.getFocusedWebContents()?.reload();
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
@@ -79,7 +79,7 @@ export class Sidebar extends React.Component<Props> {
|
||||
<div className={cssNames("Sidebar flex column", className, { pinned: isPinned })}>
|
||||
<div className="header flex align-center">
|
||||
<NavLink exact to="/" className="box grow">
|
||||
<Icon svg="logo-full" className="logo-icon" />
|
||||
<Icon svg="logo-lens" className="logo-icon" />
|
||||
<div className="logo-text">Lens</div>
|
||||
</NavLink>
|
||||
<Icon
|
||||
|
||||
Reference in new issue
Block a user