Skip to content

Commit

Permalink
Checks if the WebUI can be accessed
Browse files Browse the repository at this point in the history
breiler committed May 5, 2024
1 parent 6cd350c commit 768d477
Showing 7 changed files with 145 additions and 15 deletions.
95 changes: 92 additions & 3 deletions src/components/cards/wificard/WiFiCard.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<br />
<a href={"http://" + stats.ip + "/"} target="_blank" rel="noreferrer">
http://{stats.ip}/
</a>
</>
);
};

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 (
<Card
className="select-card"
@@ -23,7 +84,35 @@ export const WiFiCard = ({ onClick, disabled = false }: WiFiCardProps) => {
<div className="select-icon">
<FontAwesomeIcon icon={faWifi as IconDefinition} size="4x" />
</div>
<>Manage the controller WiFi settings</>
<>
{stats?.connectedTo === undefined &&
stats?.apSSID === undefined && (
<>Manage the controller WiFi settings</>
)}
</>
<>
{stats?.apSSID !== undefined &&
stats?.connectedTo === undefined && (
<>
Access point{" "}
<span className="text-nowrap">
{stats?.apSSID} {stats.signal}
</span>
{accessWebUI && <WebUiLink stats={stats} />}
</>
)}
</>
<>
{stats?.connectedTo !== undefined && (
<>
Connected to{" "}
<span className="text-nowrap">
{stats?.connectedTo} ({stats?.signal})
</span>
{accessWebUI && <WebUiLink stats={stats} />}
</>
)}
</>
</Card>
);
};
5 changes: 4 additions & 1 deletion src/components/fields/SelectField.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Form.Group as={Row} className="mb-3">
@@ -33,6 +35,7 @@ const SelectField = ({
<Col sm="9">
<InputGroup>
<Form.Select
disabled={disabled}
aria-label={placeholder}
onChange={(event) => setValue(event.target.value)}
value={value}
5 changes: 4 additions & 1 deletion src/components/fields/TextField.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Form.Group as={Row} className="mb-3">
@@ -35,6 +37,7 @@ const TextField = ({
<Col>
<InputGroup hasValidation>
<Form.Control
disabled={disabled}
type={type ?? "text"}
placeholder={placeholder}
maxLength={maxLength}
30 changes: 27 additions & 3 deletions src/pages/selectmode/SelectMode.tsx
Original file line number Diff line number Diff line change
@@ -4,25 +4,46 @@ import { TerminalCard } from "../../components/cards/terminalcard/TerminalCard";
import { InstallCard } from "../../components/cards/installcard/InstallCard";
import { FileBrowserCard } from "../../components/cards/filebrowsercard/FileBrowserCard";
import { ControllerServiceContext } from "../../context/ControllerServiceContext";
import { Stats } from "../../services/controllerservice/commands/GetStatsCommand";
import {
GetStatsCommand,
Stats
} from "../../services/controllerservice/commands/GetStatsCommand";
import { useNavigate } from "react-router-dom";
import PageTitle from "../../components/pagetitle/PageTitle";
import Page from "../../model/Page";
import usePageView from "../../hooks/usePageView";
import { WiFiCard } from "../../components/cards/wificard/WiFiCard";
import { Col } from "react-bootstrap";
import { sleep } from "../../utils/utils";
import { Spinner } from "../../components";

const SelectMode = () => {
usePageView("Home");
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);
const controllerService = useContext(ControllerServiceContext);
const [stats, setStats] = useState<Stats>();

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 (
<>
<PageTitle>FluidNC Web Installer</PageTitle>
<p>
Loading configuration <Spinner />
</p>
</>
);
}

return (
<>
<PageTitle>FluidNC Web Installer</PageTitle>
@@ -49,7 +70,10 @@ const SelectMode = () => {
)}
{stats?.version && (
<Col xs={12} md={6} lg={4}>
<WiFiCard onClick={() => navigate(Page.WIFI)} />
<WiFiCard
onClick={() => navigate(Page.WIFI)}
stats={stats}
/>
</Col>
)}
</div>
5 changes: 1 addition & 4 deletions src/pages/terminal/Terminal.tsx
Original file line number Diff line number Diff line change
@@ -57,10 +57,7 @@ const handleTerminalInput = (data: ArrayBuffer, terminal: XTerminal) => {
/<Idle/g,
"<" + COLOR_GREEN + "Idle" + COLOR_GRAY
);
buffer = buffer.replace(
/error:/g,
"<" + COLOR_GREEN + "error:" + COLOR_GRAY
);
buffer = buffer.replace(/error:/g, COLOR_RED + "error:" + COLOR_GRAY);
terminal.write(buffer);
buffer = "";
timer = undefined;
18 changes: 17 additions & 1 deletion src/pages/wifisettings/WiFiSettings.tsx
Original file line number Diff line number Diff line change
@@ -233,13 +233,15 @@ const WiFiSettings = () => {

<TextField
label="Hostname"
disabled={isSaving || isLoading}
value={hostname}
placeholder="Hostname"
setValue={(value) => setHostname("" + value)}
/>

<SelectField
label="WiFi mode"
disabled={isSaving || isLoading}
options={[
{ name: "Off", value: "Off" },
{
@@ -290,6 +292,7 @@ const WiFiSettings = () => {
<Col>
<InputGroup>
<Form.Control
disabled={isSaving || isLoading}
aria-label={"SSID"}
value={stationSSID}
type="text"
@@ -300,7 +303,9 @@ const WiFiSettings = () => {
<Dropdown
onToggle={() => refreshAccessPoints()}
>
<Dropdown.Toggle>
<Dropdown.Toggle
disabled={isSaving || isLoading}
>
<FontAwesomeIcon
icon={faSearch as IconDefinition}
/>
@@ -351,6 +356,7 @@ const WiFiSettings = () => {

<TextField
label="Password"
disabled={isSaving || isLoading}
value={stationPassword}
placeholder="Password"
setValue={(value) => setStationPassword("" + value)}
@@ -364,6 +370,7 @@ const WiFiSettings = () => {

<SelectField
label="Min security"
disabled={isSaving || isLoading}
options={[
{ name: "OPEN", value: "OPEN" },
{ name: "WEP", value: "WEP" },
@@ -384,6 +391,7 @@ const WiFiSettings = () => {

<SelectField
label="IP mode"
disabled={isSaving || isLoading}
options={[
{ name: "Static", value: "Static" },
{
@@ -399,12 +407,14 @@ const WiFiSettings = () => {
<>
<TextField
label="IP"
disabled={isSaving || isLoading}
value={stationIP}
placeholder="Password"
setValue={(value) => setStationIP("" + value)}
/>
<TextField
label="Gateway"
disabled={isSaving || isLoading}
value={stationGateway}
placeholder="Gateway"
setValue={(value) =>
@@ -413,6 +423,7 @@ const WiFiSettings = () => {
/>
<TextField
label="Netmask"
disabled={isSaving || isLoading}
value={stationNetmask}
placeholder="Netmask"
setValue={(value) =>
@@ -429,13 +440,15 @@ const WiFiSettings = () => {
<h4 style={{ marginTop: "24px" }}>Access point settings</h4>
<TextField
label="SSID"
disabled={isSaving || isLoading}
value={apSSID}
placeholder="AP SSID"
setValue={(value) => setApSSID("" + value)}
/>

<TextField
label="Password"
disabled={isSaving || isLoading}
value={apPassword}
placeholder="Password"
setValue={(value) => setApPassword("" + value)}
@@ -449,6 +462,7 @@ const WiFiSettings = () => {

<SelectField
label="Country"
disabled={isSaving || isLoading}
placeholder="Country"
value={apCountry}
setValue={(value) => setApCountry("" + value)}
@@ -502,12 +516,14 @@ const WiFiSettings = () => {
/>
<TextField
label="Channel"
disabled={isSaving || isLoading}
value={apChannel}
placeholder="Channel"
setValue={(value) => setApChannel("" + value)}
/>
<TextField
label="IP"
disabled={isSaving || isLoading}
value={apIP}
placeholder="IP"
setValue={(value) => setApIP("" + value)}
2 changes: 0 additions & 2 deletions src/services/controllerservice/commands/GetStatsCommand.ts
Original file line number Diff line number Diff line change
@@ -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: "),

0 comments on commit 768d477

Please sign in to comment.