2024-04-02 01:41:51 +02:00

236 lines
9.1 KiB
TypeScript

import React, {Component} from "react";
import {
Alert,
Backdrop,
Box,
Button,
CircularProgress,
Fade,
FormControl, InputLabel, LinearProgress,
MenuItem,
Modal,
Select, SelectChangeEvent,
Stack,
TextField,
Typography
} from "@mui/material";
import WifiPasswordIcon from "@mui/icons-material/WifiPassword";
import WifiIcon from "@mui/icons-material/Wifi";
import {IPCAnswer, WiFiNetwork} from "../RawConstants";
interface WiFiState {
open: boolean,
currentSelection: string,
selectedSecured: boolean,
foundWiFis: WiFiNetwork[],
scanning: boolean,
status: status,
password: string,
}
type status = "NONE" | "SELECTION_FAILURE" | "CONNECTING" | "PASSWORD_NEEDED" | "FAILURE" | "CONNECTED" | 'SCAN_FAILURE';
export default class WiFi extends Component<{}, WiFiState> {
constructor(props: {}) {
super(props);
this.state = {
open: true,
currentSelection: "pleaseSelect",
selectedSecured: false,
foundWiFis: [],
scanning: false,
status: "NONE",
password: "",
};
}
componentDidMount() {
this.scanWifi();
}
style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '50%',
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
scanWifi = () => {
this.setState((prevState) => ({
...prevState,
//currentSelection: "pleaseSelect",
//foundWiFis: [],
scanning: true,
}));
window.api.request('WIFI_SCAN', {}).then((answer: IPCAnswer) => {
if(answer.status)
this.setState((prevState) => ({
...prevState,
foundWiFis: answer.data as WiFiNetwork[],
scanning: false
}));
else
this.setState((prevState) => ({
...prevState,
status: "SCAN_FAILURE",
scanning: false
}));
});
}
handleClose = () => {
window.app.toggleWiFiSettings(false);
}
handleConnect = () => {
if(this.state.currentSelection == "pleaseSelect")
{
return this.setState((prevState) => ({
...prevState,
status: "SELECTION_FAILURE"
}));
}
this.setState((prevState) => ({
...prevState,
status: "CONNECTING"
}));
window.api.request('WIFI_CONNECT', {data: {ssid: this.state.currentSelection, psk: this.state.password}}).then((answer: IPCAnswer) => {
this.setState((prevState) => ({
...prevState,
status: answer.status ? "CONNECTED" : "FAILURE"
}));
})
}
onChange = (event: SelectChangeEvent) => {
let isSecured = false;
for(let x of this.state.foundWiFis)
{
if(x.ssid == event.target.value)
isSecured = x.isSecured;
}
this.setState((prevState) => ({
...prevState,
currentSelection: event.target.value,
selectedSecured: isSecured,
}));
}
render() {
return <Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={this.state.open}
onClose={null}
closeAfterTransition
slots={{backdrop: Backdrop}}
slotProps={{
backdrop: {
timeout: 500,
},
}}
>
<Fade in={this.state.open}>
<Box sx={this.style}>
<Box sx={{width: '100%', mb: 2}}>
{(this.state.scanning||this.state.status == "CONNECTING") && <LinearProgress/>}
</Box>
<Typography id="transition-modal-title" variant="h6" component="h2">
WiFi Verbindungsmanager
</Typography>
<Typography id="transition-modal-description" sx={{mt: 2}}>
<Alert variant={this.state.status == "FAILURE" ? "filled" : "standard"}
severity={this.state.status.includes("FAILURE") ? "error" : (this.state.status == "CONNECTED" ? "success" : "info")}>
{this.state.status == "NONE" && "Bitte wählen Sie eins der folgenden Netzwerke aus"}
{this.state.status == "CONNECTING" && "Verbinden..." }
{this.state.status == "CONNECTED" && "Verbunden!" }
{this.state.status == "SCAN_FAILURE" && "Das Scannen ist fehlgeschlagen. - Möglicherweise fehlen Berechtigungen, um Netzwerke zu scannen, oder es befindet sich kein WLAN-Interface auf diesem Gerät." }
{this.state.status == "FAILURE" && "Verbindungsfehler!" }
{this.state.status == "SELECTION_FAILURE" && "Bitte zunächst ein Netzwerk auswählen!" }
</Alert>
<br/>
<FormControl sx={{m: 1, minWidth: '70%'}} error={this.state.status == "SELECTION_FAILURE"}>
<InputLabel id="wifi-select-label">WiFi</InputLabel>
<Select
labelId="wifi-select-label"
id="wifi-select"
value={this.state.currentSelection}
label="WiFi"
disabled={this.state.scanning}
onChange={this.onChange}
>
<MenuItem disabled={true} value="pleaseSelect">Bitte wählen...</MenuItem>
{this.state.foundWiFis.map((wifi: WiFiNetwork) => (
<MenuItem value={wifi.ssid}>{wifi.ssid} {wifi.isSecured ? <WifiPasswordIcon sx={{ml: 1}}/> :
<WifiIcon sx={{ml: 1}}/>}</MenuItem>
))};
{null}
</Select>
</FormControl>
<FormControl sx={{mt: 2, minWidth: '5%'}}>
<Button variant="contained" disabled={this.state.scanning || this.state.status == "CONNECTING"} onClick={() => this.scanWifi()}>Aktualisieren
{this.state.scanning && (
<CircularProgress
size={24}
sx={{
position: 'absolute',
top: '50%',
left: '50%',
marginTop: '-12px',
marginLeft: '-12px',
}}
/>
)}</Button>
</FormControl>
<FormControl sx={{m: 1, minWidth: '70%'}}>
<TextField id="password" value={this.state.password} onChange={evt => this.setState(prev => ({
...prev,
password: evt.target.value
}))} label="Passwort" disabled={this.state.scanning || !this.state.selectedSecured} variant="outlined" />
</FormControl>
<br/>
<br/>
<FormControl sx={{mr: 2, minWidth: '20%'}}>
<Button variant="contained" disabled={this.state.status == "CONNECTING" || this.state.scanning}
onClick={() => this.handleConnect()}>Verbinden
{this.state.status == "CONNECTING" && (
<CircularProgress
size={24}
sx={{
position: 'absolute',
top: '50%',
left: '50%',
marginTop: '-12px',
marginLeft: '-12px',
}}
/>
)}</Button>
</FormControl>
<FormControl sx={{ml: 2, minWidth: '20%'}}>
<Button variant="contained" disabled={this.state.status == "CONNECTING"}
onClick={() => this.handleClose()}
color="secondary">Schließen</Button>
</FormControl>
</Typography>
</Box>
</Fade>
</Modal>
}
}