mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Tray icon (#1005)
* Tray icon #833 -- part 1 Signed-off-by: Roman <ixrock@gmail.com> * Tray icon #833 -- part 2 Signed-off-by: Roman <ixrock@gmail.com> * Tray icon #833 -- part 3 Signed-off-by: Roman <ixrock@gmail.com> * Tray icon #833 -- part 4 Signed-off-by: Roman <ixrock@gmail.com> * fix: lint / linux build failed Signed-off-by: Roman <ixrock@gmail.com> * allow to disable tray from preferences Signed-off-by: Roman <ixrock@gmail.com> * allow to tweak svg-icon before applying as tray-icon Signed-off-by: Roman <ixrock@gmail.com> * add checkbox indication, setActive workspace on cluster select Signed-off-by: Roman <ixrock@gmail.com> * fix build version (cannon find module 'react') Signed-off-by: Roman <ixrock@gmail.com> * - switching dark/light icon depending on os-x theme settings - optimization: don't re-create tray icon on menu udpates (avoid blinking) Signed-off-by: Roman <ixrock@gmail.com> * fix: refresh icon after turning on/off + switching dark-mode Signed-off-by: Roman <ixrock@gmail.com> * allow to close main window and re-open from dock or tray icon Signed-off-by: Roman <ixrock@gmail.com> * small fix Signed-off-by: Roman <ixrock@gmail.com> * fix: ensure main-window from global menu Signed-off-by: Roman <ixrock@gmail.com> * chore Signed-off-by: Roman <ixrock@gmail.com> * fix: hide traffic-light buttons for tray window Signed-off-by: Roman <ixrock@gmail.com> * removed redundant tray window Signed-off-by: Roman <ixrock@gmail.com> * removed delay from base-store Signed-off-by: Roman <ixrock@gmail.com> * adding cluster fix (reverted changes from master) Signed-off-by: Roman <ixrock@gmail.com> * - hide icon in dock when main-window closed (mac-os only) - added preferences checkbox to open app at system start-up Signed-off-by: Roman <ixrock@gmail.com> * handle quit app action from tray menu Signed-off-by: Roman <ixrock@gmail.com> * moved generating tray icons to build step Signed-off-by: Roman <ixrock@gmail.com> * Fix integration tests (#1080) * Fix integration tests Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com> * Update integration/helpers/utils.ts Co-authored-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com> Co-authored-by: Sebastian Malton <sebastian@malton.name> * fix-build: invisible app icon when there are more files within "build/icons/*.png" Signed-off-by: Roman <ixrock@gmail.com> * chore Signed-off-by: Roman <ixrock@gmail.com> * yarn i18n.extract Signed-off-by: Roman <ixrock@gmail.com> * clean-up Signed-off-by: Roman <ixrock@gmail.com> * navigation refactoring, move out `buildUrl` to common/utils so `react` and `react-router` not required as package.json dependecies in runtime (main) Signed-off-by: Roman <ixrock@gmail.com> * Ignore namespace query param on integration tests (#1109) Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com> * merge-conflicts fixes Signed-off-by: Roman <ixrock@gmail.com> * support page fixes Signed-off-by: Roman <ixrock@gmail.com> * make eslint happy again Signed-off-by: Roman <ixrock@gmail.com> Co-authored-by: Lauri Nevala <lauri.nevala@gmail.com> Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
74 files changed
+939
-417
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import "./cluster-manager.scss"
|
||||
|
||||
import React from "react";
|
||||
import { Redirect, Route, Switch } from "react-router";
|
||||
import { comparer, reaction } from "mobx";
|
||||
@@ -11,14 +12,17 @@ import { Workspaces, workspacesRoute } from "../+workspaces";
|
||||
import { AddCluster, addClusterRoute } from "../+add-cluster";
|
||||
import { ClusterView } from "./cluster-view";
|
||||
import { ClusterSettings, clusterSettingsRoute } from "../+cluster-settings";
|
||||
import { clusterViewRoute, clusterViewURL, getMatchedCluster, getMatchedClusterId } from "./cluster-view.route";
|
||||
import { clusterViewRoute, clusterViewURL } from "./cluster-view.route";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views";
|
||||
import { globalPageRegistry } from "../../../extensions/registries/page-registry";
|
||||
import { getMatchedClusterId } from "../../navigation";
|
||||
|
||||
@observer
|
||||
export class ClusterManager extends React.Component {
|
||||
componentDidMount() {
|
||||
const getMatchedCluster = () => clusterStore.getById(getMatchedClusterId());
|
||||
|
||||
disposeOnUnmount(this, [
|
||||
reaction(getMatchedClusterId, initView, {
|
||||
fireImmediately: true
|
||||
@@ -55,7 +59,7 @@ export class ClusterManager extends React.Component {
|
||||
return (
|
||||
<div className="ClusterManager">
|
||||
<main>
|
||||
<div id="lens-views" />
|
||||
<div id="lens-views"/>
|
||||
<Switch>
|
||||
<Route component={LandingPage} {...landingRoute} />
|
||||
<Route component={Preferences} {...preferencesRoute} />
|
||||
@@ -66,11 +70,11 @@ export class ClusterManager extends React.Component {
|
||||
{globalPageRegistry.getItems().map(({ path, url = String(path), components: { Page } }) => {
|
||||
return <Route key={url} path={path} component={Page}/>
|
||||
})}
|
||||
<Redirect exact to={this.startUrl} />
|
||||
<Redirect exact to={this.startUrl}/>
|
||||
</Switch>
|
||||
</main>
|
||||
<ClustersMenu />
|
||||
<BottomBar />
|
||||
<ClustersMenu/>
|
||||
<BottomBar/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { reaction } from "mobx";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { matchPath, RouteProps } from "react-router";
|
||||
import { buildURL, navigation } from "../../navigation";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
import type { RouteProps } from "react-router";
|
||||
import { buildURL } from "../../../common/utils/buildUrl";
|
||||
|
||||
export interface IClusterViewRouteParams {
|
||||
clusterId: string;
|
||||
@@ -14,33 +11,3 @@ export const clusterViewRoute: RouteProps = {
|
||||
}
|
||||
|
||||
export const clusterViewURL = buildURL<IClusterViewRouteParams>(clusterViewRoute.path)
|
||||
|
||||
export function getMatchedClusterId(): string {
|
||||
const matched = matchPath<IClusterViewRouteParams>(navigation.location.pathname, {
|
||||
exact: true,
|
||||
path: clusterViewRoute.path
|
||||
})
|
||||
if (matched) {
|
||||
return matched.params.clusterId;
|
||||
}
|
||||
}
|
||||
|
||||
export function getMatchedCluster() {
|
||||
return clusterStore.getById(getMatchedClusterId())
|
||||
}
|
||||
|
||||
if (ipcRenderer) {
|
||||
if (process.isMainFrame) {
|
||||
// Keep track of active cluster-id for handling IPC/menus/etc.
|
||||
reaction(() => getMatchedClusterId(), clusterId => {
|
||||
ipcRenderer.send("cluster-view:current-id", clusterId);
|
||||
}, {
|
||||
fireImmediately: true
|
||||
})
|
||||
}
|
||||
|
||||
// Reload dashboard
|
||||
ipcRenderer.on("menu:reload", () => {
|
||||
location.reload();
|
||||
});
|
||||
}
|
||||
@@ -1,14 +1,37 @@
|
||||
import "./cluster-view.scss"
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { getMatchedCluster } from "./cluster-view.route";
|
||||
import { reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { IClusterViewRouteParams } from "./cluster-view.route";
|
||||
import { ClusterStatus } from "./cluster-status";
|
||||
import { hasLoadedView } from "./lens-views";
|
||||
import { Cluster } from "../../../main/cluster";
|
||||
import { clusterStore } from "../../../common/cluster-store";
|
||||
|
||||
interface Props extends RouteComponentProps<IClusterViewRouteParams> {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class ClusterView extends React.Component {
|
||||
export class ClusterView extends React.Component<Props> {
|
||||
get clusterId() {
|
||||
return this.props.match.params.clusterId;
|
||||
}
|
||||
|
||||
get cluster(): Cluster {
|
||||
return clusterStore.getById(this.clusterId);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.clusterId, clusterId => clusterStore.setActive(clusterId), {
|
||||
fireImmediately: true,
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
render() {
|
||||
const cluster = getMatchedCluster();
|
||||
const { cluster } = this;
|
||||
const showStatus = cluster && (!cluster.available || !hasLoadedView(cluster.id) || !cluster.ready)
|
||||
return (
|
||||
<div className="ClusterView">
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { Cluster } from "../../../main/cluster";
|
||||
import "./clusters-menu.scss"
|
||||
|
||||
import { remote } from "electron"
|
||||
import React from "react";
|
||||
import { remote } from "electron"
|
||||
import type { Cluster } from "../../../main/cluster";
|
||||
import { DragDropContext, Draggable, DraggableProvided, Droppable, DroppableProvided, DropResult } from "react-beautiful-dnd";
|
||||
import { observer } from "mobx-react";
|
||||
import { _i18n } from "../../i18n";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
@@ -21,7 +22,6 @@ import { Tooltip } from "../tooltip";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { clusterIpc } from "../../../common/cluster-ipc";
|
||||
import { clusterViewURL } from "./cluster-view.route";
|
||||
import { DragDropContext, Draggable, DraggableProvided, Droppable, DroppableProvided, DropResult } from "react-beautiful-dnd";
|
||||
import { globalPageRegistry } from "../../../extensions/registries/page-registry";
|
||||
|
||||
interface Props {
|
||||
@@ -31,13 +31,11 @@ interface Props {
|
||||
@observer
|
||||
export class ClustersMenu extends React.Component<Props> {
|
||||
showCluster = (clusterId: ClusterId) => {
|
||||
clusterStore.setActive(clusterId);
|
||||
navigate(clusterViewURL({ params: { clusterId } }));
|
||||
}
|
||||
|
||||
addCluster = () => {
|
||||
navigate(addClusterURL());
|
||||
clusterStore.setActive(null);
|
||||
}
|
||||
|
||||
showContextMenu = (cluster: Cluster) => {
|
||||
@@ -47,7 +45,6 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
menu.append(new MenuItem({
|
||||
label: _i18n._(t`Settings`),
|
||||
click: () => {
|
||||
clusterStore.setActive(cluster.id);
|
||||
navigate(clusterSettingsURL({
|
||||
params: {
|
||||
clusterId: cluster.id
|
||||
@@ -112,21 +109,14 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
<div className="clusters flex column gaps">
|
||||
<DragDropContext onDragEnd={this.swapClusterIconOrder}>
|
||||
<Droppable droppableId="cluster-menu" type="CLUSTER">
|
||||
{(provided: DroppableProvided) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{({ innerRef, droppableProps, placeholder }: DroppableProvided) => (
|
||||
<div ref={innerRef} {...droppableProps}>
|
||||
{clusters.map((cluster, index) => {
|
||||
const isActive = cluster.id === clusterStore.activeClusterId;
|
||||
return (
|
||||
<Draggable draggableId={cluster.id} index={index} key={cluster.id}>
|
||||
{(provided: DraggableProvided) => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
{...provided.dragHandleProps}
|
||||
>
|
||||
{({ draggableProps, dragHandleProps, innerRef }: DraggableProvided) => (
|
||||
<div ref={innerRef} {...draggableProps} {...dragHandleProps}>
|
||||
<ClusterIcon
|
||||
key={cluster.id}
|
||||
showErrors={true}
|
||||
@@ -138,9 +128,9 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
</div>
|
||||
)}
|
||||
</Draggable>
|
||||
)}
|
||||
)}
|
||||
{provided.placeholder}
|
||||
)
|
||||
})}
|
||||
{placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
@@ -150,16 +140,14 @@ export class ClustersMenu extends React.Component<Props> {
|
||||
<Tooltip targetId="add-cluster-icon">
|
||||
<Trans>Add Cluster</Trans>
|
||||
</Tooltip>
|
||||
<Icon big material="add" id="add-cluster-icon" />
|
||||
<Icon big material="add" id="add-cluster-icon"/>
|
||||
{newContexts.size > 0 && (
|
||||
<Badge className="counter" label={newContexts.size} tooltip={<Trans>new</Trans>} />
|
||||
<Badge className="counter" label={newContexts.size} tooltip={<Trans>new</Trans>}/>
|
||||
)}
|
||||
</div>
|
||||
<div className="extensions">
|
||||
{globalPageRegistry.getItems().map(({ path, url = String(path), hideInMenu, components: { MenuIcon } }) => {
|
||||
if (!MenuIcon || hideInMenu) {
|
||||
return;
|
||||
}
|
||||
if (!MenuIcon || hideInMenu) return;
|
||||
return <MenuIcon key={url} onClick={() => navigate(url)}/>
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { observable, when } from "mobx";
|
||||
import { ClusterId, clusterStore, getClusterFrameUrl } from "../../../common/cluster-store";
|
||||
import { getMatchedCluster } from "./cluster-view.route"
|
||||
import { getMatchedClusterId } from "../../navigation";
|
||||
import logger from "../../../main/logger";
|
||||
|
||||
export interface LensView {
|
||||
@@ -51,7 +51,7 @@ export async function autoCleanOnRemove(clusterId: ClusterId, iframe: HTMLIFrame
|
||||
}
|
||||
|
||||
export function refreshViews() {
|
||||
const cluster = getMatchedCluster();
|
||||
const cluster = clusterStore.getById(getMatchedClusterId());
|
||||
lensViews.forEach(({ clusterId, view, isLoaded }) => {
|
||||
const isCurrent = clusterId === cluster?.id;
|
||||
const isReady = cluster?.available && cluster?.ready;
|
||||
|
||||
Reference in new issue
Block a user