import AppsIcon from '@mui/icons-material/Apps'; import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; import DevicesIcon from '@mui/icons-material/Devices'; import FolderIcon from '@mui/icons-material/Folder'; import MemoryIcon from '@mui/icons-material/Memory'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import RefreshIcon from '@mui/icons-material/Refresh'; import SdCardAlertIcon from '@mui/icons-material/SdCardAlert'; import SdStorageIcon from '@mui/icons-material/SdStorage'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; import ShowChartIcon from '@mui/icons-material/ShowChart'; import TimerIcon from '@mui/icons-material/Timer'; import { Avatar, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider, List, ListItem, ListItemAvatar, ListItemText, Link, Typography } from '@mui/material'; import axios from 'axios'; import { useContext, useState, useEffect } from 'react'; import { toast } from 'react-toastify'; import RestartMonitor from './RestartMonitor'; import type { FC } from 'react'; import type { SystemStatus, Version } from 'types'; import * as SystemApi from 'api/system'; import { ButtonRow, FormLoader, SectionContent, MessageBox } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import { extractErrorMessage, useRest } from 'utils'; export const VERSIONCHECK_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/latest'; export const VERSIONCHECK_DEV_ENDPOINT = 'https://api.github.com/repos/emsesp/EMS-ESP32/releases/tags/latest'; export const uploadURL = window.location.origin + '/system/upload'; function formatNumber(num: number) { return new Intl.NumberFormat().format(num); } const SystemStatusForm: FC = () => { const { LL } = useI18nContext(); const [restarting, setRestarting] = useState(); // TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus); const { loadData, data, errorMessage } = useRest({ read: SystemApi.readSystemStatus }); const { me } = useContext(AuthenticatedContext); const [confirmRestart, setConfirmRestart] = useState(false); const [confirmFactoryReset, setConfirmFactoryReset] = useState(false); const [processing, setProcessing] = useState(false); const [showingVersion, setShowingVersion] = useState(false); const [latestVersion, setLatestVersion] = useState(); const [latestDevVersion, setLatestDevVersion] = useState(); useEffect(() => { void axios.get(VERSIONCHECK_ENDPOINT).then((response) => { setLatestVersion({ version: response.data.name, url: response.data.assets[1].browser_download_url, changelog: response.data.assets[0].browser_download_url }); }); void axios.get(VERSIONCHECK_DEV_ENDPOINT).then((response) => { setLatestDevVersion({ version: response.data.name.split(/\s+/).splice(-1), url: response.data.assets[1].browser_download_url, changelog: response.data.assets[0].browser_download_url }); }); }, []); const restart = async () => { setProcessing(true); try { const response = await SystemApi.restart(); if (response.status === 200) { setRestarting(true); } } catch (error) { toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); } finally { setConfirmRestart(false); setProcessing(false); } }; const partition = async () => { setProcessing(true); try { await SystemApi.partition(); setRestarting(true); } catch (error) { toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); } finally { setConfirmRestart(false); setProcessing(false); } }; const renderRestartDialog = () => ( setConfirmRestart(false)}> {LL.RESTART()} {LL.RESTART_CONFIRM()} {data?.has_loader && ( )} ); const renderVersionDialog = () => ( setShowingVersion(false)}> {LL.VERSION_CHECK(1)} {latestVersion && ( {LL.THE_LATEST()} {LL.OFFICIAL()} {LL.RELEASE_IS()} {latestVersion.version}  ( {LL.RELEASE_NOTES()} ) ( {LL.DOWNLOAD(1)} ) )} {latestDevVersion && ( {LL.THE_LATEST()} {LL.DEVELOPMENT()} {LL.RELEASE_IS()}  {latestDevVersion.version}  ( {LL.RELEASE_NOTES()} ) ( {LL.DOWNLOAD(1)} ) )} {LL.USE()}  {LL.UPLOAD()}  {LL.SYSTEM_APPLY_FIRMWARE()} ); const factoryReset = async () => { setProcessing(true); try { await SystemApi.factoryReset(); setRestarting(true); } catch (error) { toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); } finally { setConfirmFactoryReset(false); setProcessing(false); } }; const renderFactoryResetDialog = () => ( setConfirmFactoryReset(false)}> {LL.FACTORY_RESET()} {LL.SYSTEM_FACTORY_TEXT_DIALOG()} ); const content = () => { if (!data) { return ; } return ( <> {latestVersion && ( )} {data.psram_size !== undefined && data.free_psram !== undefined && ( <> )} {me.admin && ( )} {renderVersionDialog()} {renderRestartDialog()} {renderFactoryResetDialog()} ); }; return ( {restarting ? : content()} ); }; export default SystemStatusForm;