diff --git a/src/components/cards/wificard/WiFiCard.tsx b/src/components/cards/wificard/WiFiCard.tsx index 0a62d75..487073a 100644 --- a/src/components/cards/wificard/WiFiCard.tsx +++ b/src/components/cards/wificard/WiFiCard.tsx @@ -1,16 +1,77 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import Card from "../card"; import Button from "../../button"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faWifi } from "@fortawesome/free-solid-svg-icons"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; +import { Stats } from "../../../services/controllerservice/commands/GetStatsCommand"; type WiFiCardProps = { disabled?: boolean; + stats?: Stats; onClick: () => void; }; -export const WiFiCard = ({ onClick, disabled = false }: WiFiCardProps) => { +async function fetchWithTimeout( + resource, + options: RequestInit = {}, + timeout = 8000 +) { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeout); + + const response = await fetch(resource, { + ...options, + signal: controller.signal + }); + clearTimeout(id); + + return response; +} + +const WebUiLink = ({ stats }: { stats: Stats }) => { + return ( + <> +
+ + http://{stats.ip}/ + + + ); +}; + +export const WiFiCard = ({ + onClick, + disabled = false, + stats +}: WiFiCardProps) => { + const [accessWebUI, setAccessWebUI] = useState(false); + + useEffect(() => { + if (!stats) { + return; + } + + const timer = setInterval(() => { + const url = "http://" + stats.ip + "/"; + fetchWithTimeout( + url, + { + mode: "no-cors" + }, + 2000 + ) + .then(() => setAccessWebUI(true)) + .catch(() => setAccessWebUI(false)); + }, 5000); + + return () => { + if (!timer) return; + + clearInterval(timer); + }; + }, [stats]); + return ( {
- <>Manage the controller WiFi settings + <> + {stats?.connectedTo === undefined && + stats?.apSSID === undefined && ( + <>Manage the controller WiFi settings + )} + + <> + {stats?.apSSID !== undefined && + stats?.connectedTo === undefined && ( + <> + Access point{" "} + + {stats?.apSSID} {stats.signal} + + {accessWebUI && } + + )} + + <> + {stats?.connectedTo !== undefined && ( + <> + Connected to{" "} + + {stats?.connectedTo} ({stats?.signal}) + + {accessWebUI && } + + )} +
); }; diff --git a/src/components/fields/SelectField.tsx b/src/components/fields/SelectField.tsx index 3810c6f..f53b869 100644 --- a/src/components/fields/SelectField.tsx +++ b/src/components/fields/SelectField.tsx @@ -14,6 +14,7 @@ type SelectFieldProps = { placeholder?: string; helpText?: string; groupedControls?: ReactElement; + disabled?: boolean; }; const SelectField = ({ @@ -23,7 +24,8 @@ const SelectField = ({ options = [], placeholder = "", helpText, - groupedControls + groupedControls, + disabled }: SelectFieldProps) => { return ( @@ -33,6 +35,7 @@ const SelectField = ({ setValue(event.target.value)} value={value} diff --git a/src/components/fields/TextField.tsx b/src/components/fields/TextField.tsx index 56bb96c..7000df7 100644 --- a/src/components/fields/TextField.tsx +++ b/src/components/fields/TextField.tsx @@ -13,6 +13,7 @@ type TextFieldProps = { groupedControls?: ReactElement; type?: string; validationMessage?: string; + disabled?: boolean; }; const TextField = ({ @@ -25,7 +26,8 @@ const TextField = ({ helpText, groupedControls, type, - validationMessage + validationMessage, + disabled }: TextFieldProps) => { return ( @@ -35,6 +37,7 @@ const TextField = ({ { usePageView("Home"); const navigate = useNavigate(); + const [isLoading, setIsLoading] = useState(false); const controllerService = useContext(ControllerServiceContext); const [stats, setStats] = useState(); useEffect(() => { if (!controllerService) return; - controllerService.getStats().then(setStats); + setIsLoading(true); + sleep(1000) + .then(() => controllerService.send(new GetStatsCommand(), 5000)) + .then((command) => setStats(command.getStats())) + .finally(() => setIsLoading(false)); }, [controllerService]); + if (isLoading) { + return ( + <> + FluidNC Web Installer +

+ Loading configuration +

+ + ); + } + return ( <> FluidNC Web Installer @@ -49,7 +70,10 @@ const SelectMode = () => { )} {stats?.version && ( - navigate(Page.WIFI)} /> + navigate(Page.WIFI)} + stats={stats} + /> )} diff --git a/src/pages/terminal/Terminal.tsx b/src/pages/terminal/Terminal.tsx index 23ac785..e723074 100644 --- a/src/pages/terminal/Terminal.tsx +++ b/src/pages/terminal/Terminal.tsx @@ -57,10 +57,7 @@ const handleTerminalInput = (data: ArrayBuffer, terminal: XTerminal) => { / { setHostname("" + value)} @@ -240,6 +241,7 @@ const WiFiSettings = () => { { { refreshAccessPoints()} > - + @@ -351,6 +356,7 @@ const WiFiSettings = () => { setStationPassword("" + value)} @@ -364,6 +370,7 @@ const WiFiSettings = () => { { { <> setStationIP("" + value)} /> @@ -413,6 +423,7 @@ const WiFiSettings = () => { /> @@ -429,6 +440,7 @@ const WiFiSettings = () => {

Access point settings

setApSSID("" + value)} @@ -436,6 +448,7 @@ const WiFiSettings = () => { setApPassword("" + value)} @@ -449,6 +462,7 @@ const WiFiSettings = () => { setApCountry("" + value)} @@ -502,12 +516,14 @@ const WiFiSettings = () => { /> setApChannel("" + value)} /> setApIP("" + value)} diff --git a/src/services/controllerservice/commands/GetStatsCommand.ts b/src/services/controllerservice/commands/GetStatsCommand.ts index 53cb50d..3dbdb6f 100644 --- a/src/services/controllerservice/commands/GetStatsCommand.ts +++ b/src/services/controllerservice/commands/GetStatsCommand.ts @@ -12,7 +12,6 @@ export type Stats = { signal?: string; apSSID?: string; wifiMode?: string; - wifiSignal?: string; flashSize?: string; cpuTemperature?: string; currentWifiMode?: string; @@ -36,7 +35,6 @@ export class GetStatsCommand extends Command { channel: this.getParam("Channel: "), signal: this.getParam("Signal: "), wifiMode: this.getParam("Current WiFi Mode: "), - wifiSignal: this.getParam("Signal: "), flashSize: this.getParam("Flash Size: "), cpuTemperature: this.getParam("CPU Temperature: "), currentWifiMode: this.getParam("Current WiFi Mode: "),