mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
refactoring
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
4a06f65cb8
commit
507e2dcfee
@ -40,6 +40,7 @@ export interface ClusterPreferences {
|
||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
@observable activeCluster: ClusterId;
|
||||
@observable clusters = observable.map<ClusterId, Cluster>();
|
||||
@observable removedClusters = observable.map<ClusterId, Cluster>();
|
||||
|
||||
private constructor() {
|
||||
super({
|
||||
@ -86,12 +87,32 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
|
||||
@action
|
||||
protected fromStore({ activeCluster, clusters = [] }: ClusterStoreModel = {}) {
|
||||
const clustersMap = new Map<ClusterId, Cluster>();
|
||||
const currentClusters = this.clusters.toJS();
|
||||
const newClusters = new Map<ClusterId, Cluster>();
|
||||
const removedClusters = new Map<ClusterId, Cluster>();
|
||||
|
||||
// update new clusters
|
||||
clusters.forEach(clusterModel => {
|
||||
clustersMap.set(clusterModel.id, new Cluster(clusterModel));
|
||||
let cluster = currentClusters.get(clusterModel.id);
|
||||
if (cluster) {
|
||||
Object.assign(cluster, clusterModel);
|
||||
cluster.mergeModel(clusterModel);
|
||||
} else {
|
||||
cluster = new Cluster(clusterModel);
|
||||
}
|
||||
newClusters.set(clusterModel.id, cluster);
|
||||
});
|
||||
this.activeCluster = clustersMap.has(activeCluster) ? activeCluster : null;
|
||||
this.clusters.replace(clustersMap);
|
||||
|
||||
// update removed clusters
|
||||
currentClusters.forEach(cluster => {
|
||||
if (!newClusters.has(cluster.id)) {
|
||||
removedClusters.set(cluster.id, cluster);
|
||||
}
|
||||
});
|
||||
|
||||
this.activeCluster = newClusters.has(activeCluster) ? activeCluster : null;
|
||||
this.clusters.replace(newClusters);
|
||||
this.removedClusters.replace(removedClusters);
|
||||
}
|
||||
|
||||
toJSON(): ClusterStoreModel {
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import { autorun } from "mobx";
|
||||
import { apiPrefix, appProto } from "../common/vars";
|
||||
import { app } from "electron"
|
||||
import { reaction } from "mobx";
|
||||
import path from "path"
|
||||
import http from "http"
|
||||
import { copyFile, ensureDir } from "fs-extra"
|
||||
import filenamify from "filenamify"
|
||||
import { validateConfig } from "./k8s";
|
||||
import { Cluster } from "./cluster"
|
||||
import { apiPrefix, appProto } from "../common/vars";
|
||||
import { ClusterId, ClusterModel, clusterStore } from "../common/cluster-store"
|
||||
import logger from "./logger"
|
||||
import { onMessages } from "../common/ipc-helpers";
|
||||
import { ClusterIpcMessage } from "../common/ipc-messages";
|
||||
import { FeatureInstallRequest } from "./feature";
|
||||
import { tracker } from "../common/tracker";
|
||||
import { validateConfig } from "./k8s";
|
||||
import { Cluster } from "./cluster"
|
||||
import { FeatureInstallRequest } from "./feature";
|
||||
import logger from "./logger"
|
||||
|
||||
export interface ClusterIconUpload {
|
||||
clusterId: string;
|
||||
@ -26,16 +26,19 @@ export class ClusterManager {
|
||||
}
|
||||
|
||||
constructor(protected port: number) {
|
||||
autorun(() => {
|
||||
// fixme: detect and stop removed clusters from config file ?
|
||||
clusterStore.clusters.forEach((cluster: Cluster) => {
|
||||
reaction(() => clusterStore.clusters.toJS(), clusters => {
|
||||
clusters.forEach(cluster => {
|
||||
if (!cluster.initialized) {
|
||||
cluster.init(this.port);
|
||||
cluster.refreshCluster();
|
||||
cluster.init(this.port).then(() => cluster.refreshCluster());
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
reaction(() => clusterStore.removedClusters.toJS(), removedClusters => {
|
||||
if (removedClusters.size > 0) {
|
||||
removedClusters.forEach(cluster => cluster.stopServer());
|
||||
clusterStore.removedClusters.clear();
|
||||
}
|
||||
});
|
||||
ClusterManager.ipcListen(this);
|
||||
}
|
||||
|
||||
|
||||
@ -56,6 +56,10 @@ export class Cluster implements ClusterModel {
|
||||
@observable features: FeatureStatusMap = {};
|
||||
|
||||
constructor(model: ClusterModel) {
|
||||
this.mergeModel(model);
|
||||
}
|
||||
|
||||
mergeModel(model: ClusterModel) {
|
||||
Object.assign(this, model)
|
||||
}
|
||||
|
||||
|
||||
@ -25,12 +25,6 @@ let windowManager: WindowManager = null;
|
||||
let clusterManager: ClusterManager = null;
|
||||
let proxyServer: proxy.LensProxy = null;
|
||||
|
||||
const vmURL = formatUrl({
|
||||
pathname: path.join(__dirname, `${appName}.html`),
|
||||
protocol: "file",
|
||||
slashes: true,
|
||||
})
|
||||
|
||||
mangleProxyEnv()
|
||||
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
||||
process.env.HTTPS_PROXY = app.commandLine.getSwitchValue("proxy-server")
|
||||
@ -82,8 +76,13 @@ async function main() {
|
||||
}
|
||||
|
||||
// manage lens windows
|
||||
windowManager = new WindowManager({showSplash: true});
|
||||
windowManager.showMain(vmURL)
|
||||
const vmURL = formatUrl({
|
||||
pathname: path.join(__dirname, `${appName}.html`),
|
||||
protocol: "file",
|
||||
slashes: true,
|
||||
})
|
||||
windowManager = new WindowManager();
|
||||
windowManager.loadURL(vmURL)
|
||||
}
|
||||
|
||||
app.on("ready", main)
|
||||
@ -96,15 +95,8 @@ app.on('window-all-closed', function () {
|
||||
windowManager = null
|
||||
if (clusterManager) clusterManager.stop()
|
||||
}
|
||||
})
|
||||
// app.on("activate", () => {
|
||||
// if (!windowManager) {
|
||||
// logger.debug("activate main window")
|
||||
// windowManager = new WindowManager({ showSplash: false })
|
||||
// windowManager.showMain(vmURL)
|
||||
// }
|
||||
// })
|
||||
app.on("will-quit", async (event) => {
|
||||
});
|
||||
app.on("will-quit", async event => {
|
||||
event.preventDefault(); // To allow mixpanel sending to be executed
|
||||
if (clusterManager) clusterManager.stop()
|
||||
if (proxyServer) proxyServer.close()
|
||||
|
||||
@ -1,36 +1,30 @@
|
||||
import { BrowserWindow, shell } from "electron"
|
||||
import { BrowserView, BrowserWindow, shell } from "electron"
|
||||
import { reaction } from "mobx";
|
||||
import windowStateKeeper from "electron-window-state"
|
||||
import type { ClusterId } from "../common/cluster-store";
|
||||
import { clusterStore } from "../common/cluster-store";
|
||||
import { tracker } from "../common/tracker";
|
||||
|
||||
export class WindowManager {
|
||||
public mainWindow: BrowserWindow = null;
|
||||
public splashWindow: BrowserWindow = null;
|
||||
protected windowState: windowStateKeeper.State;
|
||||
export interface WindowManagerParams {
|
||||
showSplash?: boolean;
|
||||
}
|
||||
|
||||
constructor({ showSplash = true } = {}) {
|
||||
// Manage main window size&position with persistence
|
||||
export class WindowManager {
|
||||
protected mainWindow: BrowserWindow;
|
||||
protected splashWindow?: BrowserWindow;
|
||||
protected windowState: windowStateKeeper.State;
|
||||
protected views = new Map<ClusterId, BrowserView>();
|
||||
protected disposers: Function[] = [];
|
||||
|
||||
constructor(protected params: WindowManagerParams = {}) {
|
||||
this.params = { showSplash: true, ...params };
|
||||
|
||||
// Manage main window size and position with state persistence
|
||||
this.windowState = windowStateKeeper({
|
||||
defaultHeight: 900,
|
||||
defaultWidth: 1440,
|
||||
});
|
||||
|
||||
this.splashWindow = new BrowserWindow({
|
||||
width: 500,
|
||||
height: 300,
|
||||
backgroundColor: "#1e2124",
|
||||
center: true,
|
||||
frame: false,
|
||||
resizable: false,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
if (showSplash) {
|
||||
this.splashWindow.loadURL("static://splash.html")
|
||||
this.splashWindow.show()
|
||||
}
|
||||
|
||||
this.mainWindow = new BrowserWindow({
|
||||
show: false,
|
||||
x: this.windowState.x,
|
||||
@ -41,45 +35,92 @@ export class WindowManager {
|
||||
titleBarStyle: "hidden",
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webviewTag: true
|
||||
},
|
||||
});
|
||||
|
||||
// Splash-screen window with loading indicator
|
||||
this.splashWindow = new BrowserWindow({
|
||||
width: 500,
|
||||
height: 300,
|
||||
backgroundColor: "#1e2124",
|
||||
center: true,
|
||||
frame: false,
|
||||
resizable: false,
|
||||
show: false,
|
||||
});
|
||||
this.splashWindow.loadURL("static://splash.html")
|
||||
|
||||
// Hook window state manager into window lifecycle
|
||||
this.windowState.manage(this.mainWindow);
|
||||
|
||||
// handle close event
|
||||
this.mainWindow.on("close", () => {
|
||||
this.mainWindow = null;
|
||||
// Disallow closing main window
|
||||
this.mainWindow.on("close", (evt) => {
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
// open external links in default browser (target=_blank, window.open)
|
||||
// Open external links in default browser (target=_blank, window.open)
|
||||
this.mainWindow.webContents.on("new-window", (event, url) => {
|
||||
event.preventDefault();
|
||||
shell.openExternal(url);
|
||||
});
|
||||
|
||||
// handle external links
|
||||
this.mainWindow.webContents.on("will-navigate", (event, link) => {
|
||||
if (link.startsWith("http://localhost")) {
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
shell.openExternal(link);
|
||||
})
|
||||
|
||||
// Track main window focus
|
||||
this.mainWindow.on("focus", () => {
|
||||
tracker.event("app", "focus")
|
||||
})
|
||||
});
|
||||
|
||||
// Clean up views for removed clusters
|
||||
this.disposers.push(
|
||||
reaction(() => clusterStore.removedClusters.toJS(), removedClusters => {
|
||||
removedClusters.forEach(cluster => {
|
||||
const lensView = this.getView(cluster.id);
|
||||
if (lensView) {
|
||||
lensView.destroy();
|
||||
this.views.delete(cluster.id);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public showMain(url: string) {
|
||||
this.mainWindow.loadURL(url).then(() => {
|
||||
this.splashWindow.hide()
|
||||
this.splashWindow.loadURL("data:text/html;charset=utf-8,").then(() => {
|
||||
this.splashWindow.close()
|
||||
this.mainWindow.show()
|
||||
setView(clusterId: ClusterId) {
|
||||
const view = this.getView(clusterId)
|
||||
this.mainWindow.setBrowserView(view);
|
||||
}
|
||||
|
||||
getView(clusterId: ClusterId): BrowserView {
|
||||
let view = this.views.get(clusterId);
|
||||
if (!view) {
|
||||
view = new BrowserView({
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
})
|
||||
})
|
||||
// view.setBackgroundColor("#878686");
|
||||
// view.setAutoResize({ horizontal: true, vertical: true });
|
||||
// view.webContents.loadURL("data:text/html;charset=utf-8,<b>TEST</b>")
|
||||
this.views.set(clusterId, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
async loadURL(url: string) {
|
||||
if (this.params.showSplash) {
|
||||
this.splashWindow.show();
|
||||
}
|
||||
await this.mainWindow.loadURL(url);
|
||||
this.mainWindow.show();
|
||||
this.splashWindow.hide();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.disposers.forEach(dispose => dispose());
|
||||
this.disposers.length = 0;
|
||||
this.views.forEach(view => view.destroy());
|
||||
this.views.clear();
|
||||
this.mainWindow.destroy();
|
||||
this.splashWindow.destroy();
|
||||
this.mainWindow = null;
|
||||
this.splashWindow = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
.Workspaces {
|
||||
height: 100%;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas: "draggable draggable" "menu lens-view" "bottom-bar bottom-bar";
|
||||
grid-template-rows: 20px 1fr min-content;
|
||||
grid-template-columns: min-content 1fr;
|
||||
height: 100%;
|
||||
|
||||
> .draggable-top {
|
||||
@include set-draggable;
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import "./workspaces.scss"
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Trans } from "@lingui/macro";
|
||||
@ -8,7 +9,6 @@ import { Icon } from "../icon";
|
||||
import { ClustersMenu } from "./clusters-menu";
|
||||
import { Menu, MenuItem } from "../menu";
|
||||
import { prevDefault } from "../../utils";
|
||||
import { observable } from "mobx";
|
||||
|
||||
// todo: support `workspaceId` in URL
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user