diff --git a/src/main/index.ts b/src/main/index.ts index a4e38cdb0c..0c5558ec33 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -18,7 +18,6 @@ import { userStore } from "../common/user-store"; import { workspaceStore } from "../common/workspace-store"; import { tracker } from "../common/tracker"; import logger from "./logger" -import { initMenu } from "./menu"; let windowManager: WindowManager; let clusterManager: ClusterManager; @@ -31,7 +30,6 @@ if (app.commandLine.getSwitchValue("proxy-server") !== "") { async function main() { await shellSync(); - initMenu(); const workingDir = path.join(app.getPath("appData"), appName); app.setName(appName); diff --git a/src/main/menu.ts b/src/main/menu.ts index 09cf33b20f..c634631925 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,35 +1,36 @@ -import { app, BrowserWindow, dialog, ipcMain, Menu, MenuItem, MenuItemConstructorOptions, shell, webContents } from "electron" -import { autorun, observable } from "mobx"; -import { broadcastIpc } from "../common/ipc"; +import { app, BrowserWindow, dialog, Menu, MenuItem, MenuItemConstructorOptions, shell } from "electron" +import { autorun } from "mobx"; +import { WindowManager } from "./window-manager"; import { appName, isMac, issuesTrackerUrl, isWindows, slackUrl } from "../common/vars"; -import { ClusterId, clusterStore } from "../common/cluster-store"; import { addClusterURL } from "../renderer/components/+add-cluster/add-cluster.route"; import { preferencesURL } from "../renderer/components/+preferences/preferences.route"; import { whatsNewURL } from "../renderer/components/+whats-new/whats-new.route"; import { clusterSettingsURL } from "../renderer/components/+cluster-settings/cluster-settings.route"; import logger from "./logger"; -const activeClusterView = observable.box(); - -export function initMenu() { - autorun(buildMenu); - ipcMain.on("menu:refresh", (evt, activeClusterId: ClusterId) => { - activeClusterView.set(activeClusterId); +export function initMenu(windowManager: WindowManager) { + autorun(() => buildMenu(windowManager), { + delay: 100 }); } -export function buildMenu() { - function macOnly(menuItems: MenuItemConstructorOptions[]): MenuItemConstructorOptions[] { +export function buildMenu(windowManager: WindowManager) { + function macOnly(menuItems: MenuItemConstructorOptions[]) { if (!isMac) return []; return menuItems; } + function activeClusterOnly(menuItems: MenuItemConstructorOptions[]) { + if (!windowManager.activeClusterId) return []; + return menuItems; + } + function navigate(url: string, toClusterView = false) { logger.info(`[MENU]: navigating to ${url}`); - const clusterId = activeClusterView.get(); - broadcastIpc({ - channel: "menu:navigate" + (toClusterView ? `:${clusterId}` : ""), - args: [url], + windowManager.navigate({ + channel: "menu:navigate", + url: url, + clusterId: toClusterView ? windowManager.activeClusterId : null, }) } @@ -42,12 +43,14 @@ export function buildMenu() { navigate(addClusterURL()) } }, - ...(activeClusterView.get() ? [{ - label: 'Cluster Settings', - click() { - navigate(clusterSettingsURL(), true) + ...activeClusterOnly([ + { + label: 'Cluster Settings', + click() { + navigate(clusterSettingsURL(), true) + } } - }] : []), + ]), { type: 'separator' }, { label: 'Preferences', @@ -90,24 +93,33 @@ export function buildMenu() { label: 'Back', accelerator: 'CmdOrCtrl+[', click() { - webContents.getFocusedWebContents()?.goBack(); // fixme: works until second cluster selected + windowManager.getActiveClusterView()?.goBack(); } }, { label: 'Forward', accelerator: 'CmdOrCtrl+]', click() { - webContents.getFocusedWebContents()?.goForward(); + windowManager.getActiveClusterView()?.goForward(); } }, { label: 'Reload', accelerator: 'CmdOrCtrl+R', click() { - webContents.getFocusedWebContents()?.reload(); + windowManager.getActiveClusterView()?.reload(); } }, { role: 'toggleDevTools' }, + ...activeClusterOnly([ + { + accelerator: "CmdOrCtrl+Shift+I", + label: "Toggle Dashboard DevTools", + click() { + windowManager.getActiveClusterView()?.toggleDevTools(); + } + } + ]), { type: 'separator' }, { role: 'resetZoom' }, { role: 'zoomIn' }, diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 512a36bc74..af1437c38d 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -1,11 +1,16 @@ -import { BrowserWindow, shell } from "electron" +import type { ClusterId } from "../common/cluster-store"; +import { BrowserWindow, ipcMain, shell, WebContents, webContents } from "electron" import windowStateKeeper from "electron-window-state" +import { observable } from "mobx"; +import { initMenu } from "./menu"; export class WindowManager { protected mainView: BrowserWindow; protected splashWindow: BrowserWindow; protected windowState: windowStateKeeper.State; + @observable activeClusterId: ClusterId; + constructor(protected proxyPort: number) { // Manage main window size and position with state persistence this.windowState = windowStateKeeper({ @@ -35,8 +40,32 @@ export class WindowManager { shell.openExternal(url); }); + // track visible cluster from ui + ipcMain.on("cluster-view:change", (event, clusterId: ClusterId) => { + this.activeClusterId = clusterId; + }); + // load & show app this.showMain(); + initMenu(this); + } + + navigate({ url, channel, clusterId }: { url: string, channel: string, clusterId?: ClusterId }) { + if (clusterId) { + this.getClusterView(clusterId)?.send(channel, url); + } else { + this.mainView.webContents.send(channel, url); + } + } + + getActiveClusterView() { + return this.getClusterView(this.activeClusterId) + } + + getClusterView(clusterId: ClusterId): WebContents { + return webContents.getAllWebContents().find(view => { + return new URL(view.getURL()).host.split(".")[0] === clusterId; + }) } async showMain() { diff --git a/src/renderer/components/cluster-manager/cluster-view.route.ts b/src/renderer/components/cluster-manager/cluster-view.route.ts index 3078db4f94..f186ad23ce 100644 --- a/src/renderer/components/cluster-manager/cluster-view.route.ts +++ b/src/renderer/components/cluster-manager/cluster-view.route.ts @@ -33,7 +33,7 @@ if (ipcRenderer) { const isMainView = !getHostedClusterId(); if (isMainView) { reaction(() => getMatchedClusterId(), clusterId => { - ipcRenderer.send("menu:refresh", clusterId); + ipcRenderer.send("cluster-view:change", clusterId); }, { fireImmediately: true }) diff --git a/src/renderer/navigation.ts b/src/renderer/navigation.ts index eb46fe728c..a2b0bce889 100644 --- a/src/renderer/navigation.ts +++ b/src/renderer/navigation.ts @@ -4,16 +4,13 @@ import { ipcRenderer } from "electron"; import { compile } from "path-to-regexp" import { createBrowserHistory, createMemoryHistory, Location, LocationDescriptor } from "history"; import { createObservableHistory } from "mobx-observable-history"; -import { getHostedClusterId } from "../common/cluster-store"; export const history = typeof window !== "undefined" ? createBrowserHistory() : createMemoryHistory(); export const navigation = createObservableHistory(history); // handle navigation from global menu if (ipcRenderer) { - const clusterId = getHostedClusterId(); - const channel = "menu:navigate" + (clusterId ? `:${clusterId}` : ""); - ipcRenderer.on(channel, (event, path: string) => { + ipcRenderer.on("menu:navigate", (event, path: string) => { navigate(path); }) }