diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx
index 932a6fb2d..44269447d 100644
--- a/src/renderer/App.tsx
+++ b/src/renderer/App.tsx
@@ -10,7 +10,6 @@ import { initialize as initializeIpcListeners } from './ipc';
import NodeScreen from './NodeScreen';
import DataRefresher from './DataRefresher';
import electron from './electronGlobal';
-import Sidebar from './Presentational/Sidebar/Sidebar';
import { SidebarWrapper } from './Presentational/SidebarWrapper/SidebarWrapper';
import NNSplash from './Presentational/NNSplashScreen/NNSplashScreen';
import { dragWindowContainer } from './app.css';
@@ -81,15 +80,7 @@ const MainScreen = () => {
flex: 1,
}}
>
-
- {(sUserNodes) => (
-
- )}
-
+
diff --git a/src/renderer/Generics/redesign/Banner/Banner.tsx b/src/renderer/Generics/redesign/Banner/Banner.tsx
index 67f6512b2..a117313e6 100644
--- a/src/renderer/Generics/redesign/Banner/Banner.tsx
+++ b/src/renderer/Generics/redesign/Banner/Banner.tsx
@@ -12,21 +12,31 @@ export interface BannerProps {
/**
* Is it offline?
*/
- offline: boolean;
+ offline?: boolean;
/**
* Is update available?
*/
- updateAvailable: boolean;
+ updateAvailable?: boolean;
+ /**
+ * Is docker not running?
+ */
+ dockerStopped?: boolean;
+ onClick?: () => void;
}
/**
* Primary UI component for user interaction
*/
-export const Banner = ({ offline, updateAvailable }: BannerProps) => {
+export const Banner = ({
+ offline,
+ updateAvailable,
+ dockerStopped,
+ onClick,
+}: BannerProps) => {
let iconId: IconId = 'blank';
let title = '';
let description = '';
- let onClick = () => {};
+ let internalOnClick = () => {};
if (offline) {
iconId = 'boltstrike';
title = 'Currently offline';
@@ -35,16 +45,30 @@ export const Banner = ({ offline, updateAvailable }: BannerProps) => {
iconId = 'download1';
title = 'Update available';
description = 'New version ready to install';
- onClick = () => {
+ internalOnClick = () => {
console.log('update nice node!');
};
+ } else if (dockerStopped) {
+ iconId = 'play';
+ title = 'Docker is not running';
+ description = 'Click to start Docker';
+ internalOnClick = () => {
+ console.log('Start Docker!');
+ };
}
+ const onClickBanner = () => {
+ internalOnClick();
+ if (onClick) {
+ onClick();
+ }
+ };
+
return (
diff --git a/src/renderer/Presentational/DockerInstallation/StartDockerBanner.tsx b/src/renderer/Presentational/DockerInstallation/StartDockerBanner.tsx
new file mode 100644
index 000000000..5de3b1173
--- /dev/null
+++ b/src/renderer/Presentational/DockerInstallation/StartDockerBanner.tsx
@@ -0,0 +1,36 @@
+import electron from '../../electronGlobal';
+import { Banner } from '../../Generics/redesign/Banner/Banner';
+import { useGetIsDockerRunningQuery } from '../../state/settingsService';
+
+export const DockerStoppedBanner = () => {
+ const qIsDockerRunning = useGetIsDockerRunningQuery(null, {
+ pollingInterval: 15000,
+ });
+
+ const onClickStartDocker = async () => {
+ await electron.startDocker();
+ // todo: verify it is started and changed banner for 5 secs?
+ qIsDockerRunning.refetch();
+ // console.log('installDocker finished. Install result: ', installResult);
+ };
+
+ return (
+
+ //
+ //
+ //
+ //
+ //
{title}
+ //
{description}
+ //
+ //
+ //
+ );
+};
diff --git a/src/renderer/Presentational/Sidebar/Sidebar.tsx b/src/renderer/Presentational/Sidebar/Sidebar.tsx
index 073056e17..8af0e5e7b 100644
--- a/src/renderer/Presentational/Sidebar/Sidebar.tsx
+++ b/src/renderer/Presentational/Sidebar/Sidebar.tsx
@@ -15,6 +15,7 @@ import { IconId } from '../../assets/images/icons';
import { Modal } from '../../Generics/redesign/Modal/Modal';
import AddNodeStepper from '../AddNodeStepper/AddNodeStepper';
import PreferencesWrapper from '../PreferencesModal/PreferencesWrapper';
+import { DockerStoppedBanner } from '../DockerInstallation/StartDockerBanner';
export interface SidebarProps {
/**
@@ -25,7 +26,11 @@ export interface SidebarProps {
* Nice Node update available?
*/
updateAvailable: boolean;
- sUserNodes: UserNodes;
+ /**
+ * Is docker not running?
+ */
+ dockerStopped: boolean;
+ sUserNodes?: UserNodes;
}
const itemListData: { iconId: IconId; label: string; count?: number }[] = [
@@ -62,7 +67,12 @@ const NODE_SIDEBAR_STATUS_MAP: Record
= {
unknown: 'error',
};
-const Sidebar = ({ sUserNodes, updateAvailable, offline }: SidebarProps) => {
+const Sidebar = ({
+ sUserNodes,
+ updateAvailable,
+ offline,
+ dockerStopped,
+}: SidebarProps) => {
const dispatch = useAppDispatch();
const [sIsModalOpenAddNode, setIsModalOpenAddNode] = useState();
const [sIsModalOpenSettings, setIsModalOpenSettings] =
@@ -115,6 +125,7 @@ const Sidebar = ({ sUserNodes, updateAvailable, offline }: SidebarProps) => {
return (
+ {dockerStopped &&
}
{renderBanners()}
diff --git a/src/renderer/Presentational/SidebarWrapper/SidebarWrapper.tsx b/src/renderer/Presentational/SidebarWrapper/SidebarWrapper.tsx
index 0266d021a..5f73654af 100644
--- a/src/renderer/Presentational/SidebarWrapper/SidebarWrapper.tsx
+++ b/src/renderer/Presentational/SidebarWrapper/SidebarWrapper.tsx
@@ -1,23 +1,31 @@
-import React, { ReactElement, useEffect } from 'react';
+import { ReactElement, useEffect } from 'react';
import { useAppDispatch, useAppSelector } from '../../state/hooks';
import {
selectSelectedNodeId,
selectUserNodes,
updateSelectedNodeId,
} from '../../state/node';
+import { useGetIsDockerRunningQuery } from '../../state/settingsService';
+import Sidebar from '../Sidebar/Sidebar';
export interface SidebarWrapperProps {
children: ReactElement;
}
-export const SidebarWrapper = ({
- children,
-}: {
- children: (sUserNodes: any) => React.ReactNode;
-}) => {
+export const SidebarWrapper = () => {
const sSelectedNodeId = useAppSelector(selectSelectedNodeId);
const sUserNodes = useAppSelector(selectUserNodes);
const dispatch = useAppDispatch();
+ // todo: implement a back-off polling strategy which can be "reset"
+ const qIsDockerRunning = useGetIsDockerRunningQuery(null, {
+ pollingInterval: 15000,
+ });
+ // default to docker is running while data is being fetched, so
+ // the user isn't falsely warned
+ let isDockerRunning = true;
+ if (qIsDockerRunning && !qIsDockerRunning.fetching) {
+ isDockerRunning = qIsDockerRunning.data;
+ }
// Default selected node to be the first node
useEffect(() => {
@@ -31,5 +39,12 @@ export const SidebarWrapper = ({
}
}, [sSelectedNodeId, sUserNodes, dispatch]);
- return <>{children(sUserNodes)}>;
+ return (
+
+ );
};