import { useState } from 'react'; import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import DownloadIcon from '@mui/icons-material/GetApp'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import WarningIcon from '@mui/icons-material/Warning'; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Link, Typography } from '@mui/material'; import Grid from '@mui/material/Grid2'; import * as SystemApi from 'api/system'; import { API, callAction } from 'api/app'; import { getDevVersion, getStableVersion } from 'api/system'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova/client'; import type { APIcall } from 'app/main/types'; import RestartMonitor from 'app/status/RestartMonitor'; import { FormLoader, SectionContent, SingleUpload, useLayoutTitle } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; import { saveFile } from 'utils'; const DownloadUpload = () => { const { LL } = useI18nContext(); const [restarting, setRestarting] = useState(false); const [openDialog, setOpenDialog] = useState(false); const [useDev, setUseDev] = useState(false); const [upgradeAvailable, setUpgradeAvailable] = useState(false); const { send: sendCheckUpgrade } = useRequest( (version: string) => callAction({ action: 'checkUpgrade', param: version }), { immediate: false } ).onSuccess((event) => { setUpgradeAvailable((event.data as { upgradeable: boolean }).upgradeable); }); const { send: sendExportData } = useRequest( (type: string) => callAction({ action: 'export', param: type }), { immediate: false } ) .onSuccess((event) => { saveFile(event.data, event.args[0], '.json'); toast.info(LL.DOWNLOAD_SUCCESSFUL()); }) .onError((error) => { toast.error(error.message); }); const { send: sendAPI } = useRequest((data: APIcall) => API(data), { immediate: false }); const { data, send: loadData, error } = useRequest(SystemApi.readSystemStatus); const { send: sendUploadURL } = useRequest( (url: string) => callAction({ action: 'uploadURL', param: url }), { immediate: false } ); const doRestart = async () => { setRestarting(true); await sendAPI({ device: 'system', cmd: 'restart', id: 0 }).catch( (error: Error) => { toast.error(error.message); } ); }; // called immediately to get the latest version, on page load const { data: latestVersion } = useRequest(getStableVersion, { // uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin // immediate: false, // initialData: '3.6.5' }); // called immediately to get the latest version, on page load, then check for upgrade const { data: latestDevVersion } = useRequest(getDevVersion, { // uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin // immediate: false, // initialData: '3.7.0-dev.32' }).onSuccess((event) => { void sendCheckUpgrade(event.data); }); const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/'; const STABLE_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/main/CHANGELOG.md'; const DEV_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/latest/'; const DEV_RELNOTES_URL = 'https://github.com/emsesp/EMS-ESP32/blob/dev/CHANGELOG_LATEST.md'; const getBinURL = (useDevVersion: boolean) => { if (!latestVersion || !latestDevVersion) { return ''; } const filename = 'EMS-ESP-' + (useDevVersion ? latestDevVersion : latestVersion).replaceAll('.', '_') + '-' + getPlatform() + '.bin'; return useDevVersion ? DEV_URL + filename : STABLE_URL + 'v' + latestVersion + '/' + filename; }; const getPlatform = () => { return ( [data.esp_platform, data.flash_chip_size >= 16384 ? '16MB' : '4MB'].join('-') + (data.psram ? '+' : '') ); }; const installFirmwareURL = async (url: string) => { await sendUploadURL(url).catch((error: Error) => { toast.error(error.message); }); setRestarting(true); }; useLayoutTitle(LL.DOWNLOAD_UPLOAD()); const internet_live = latestDevVersion !== undefined && latestVersion !== undefined; const renderUploadDialog = () => { if (!internet_live) { return null; } return ( setOpenDialog(false)} > {LL.INSTALL('') + ' ' + (useDev ? LL.DEVELOPMENT() : LL.STABLE()) + ' Firmware'} {LL.INSTALL_VERSION(useDev ? latestDevVersion : latestVersion)} {LL.RELEASE_NOTES()}  |  {LL.DOWNLOAD(1)} ); }; // useDevVersion = true to force using the dev version const showFirmwareDialog = (useDevVersion: boolean) => { if (useDevVersion || data.emsesp_version.includes('dev')) { setUseDev(true); } setOpenDialog(true); }; const content = () => { if (!data) { return ; } const isDev = data.emsesp_version.includes('dev'); return ( <> {LL.DOWNLOAD(0)} {LL.DOWNLOAD_SETTINGS_TEXT()}. {LL.UPLOAD()} {LL.UPLOAD_TEXT()}. {LL.EMS_ESP_VER()} {LL.VERSION() + ':'} {data.emsesp_version} {data.build_flags && (   ({data.build_flags}) )} Platform: {getPlatform()} Release: {isDev ? LL.DEVELOPMENT() : LL.STABLE()} {!isDev && ( )}    {upgradeAvailable ? LL.UPGRADE_AVAILABLE() : LL.LATEST_VERSION()} {upgradeAvailable && internet_live && (data.psram ? ( ) : ( <>    {LL.DOWNLOAD(1)} v {isDev ? latestDevVersion : latestVersion} ))} {renderUploadDialog()} ); }; return ( {restarting ? : content()} ); }; export default DownloadUpload;