import React from 'react'; import { AppBar, Button, Checkbox, CircularProgress, ClickAwayListener, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, FormControl, FormControlLabel, FormGroup, Grid, InputAdornment, List, ListItem, ListItemText, Paper, Tab, Tabs, TextField, Typography, } from '@material-ui/core'; import {fade, makeStyles} from '@material-ui/core/styles'; import SearchIcon from '@material-ui/icons/Search'; import CloudDownloadIcon from '@material-ui/icons/CloudDownload'; import WarningIcon from '@material-ui/icons/Warning'; import BuildIcon from '@material-ui/icons/Build'; import './home.scss'; import {withTranslation} from 'react-i18next'; import FuzzySet from 'fuzzyset.js'; const useStylesSearch = makeStyles(theme => ({ root: { borderColor: '#e2e2e1', overflow: 'hidden', margin: 0, borderRadius: 4, transition: theme.transitions.create(['border-color', 'box-shadow']), '&:hover': { borderColor: fade(theme.palette.primary.main, 0.25), }, '&$focused': { backgroundColor: '#fff', boxShadow: `${fade(theme.palette.primary.main, 0.25)} 0 0 0 2px`, borderColor: theme.palette.primary.main, }, }, focused: {}, })); function SearchTextField(props) { const classes = useStylesSearch(); return ( {props.labeltext} } InputProps={ { classes, endAdornment: ( ), } } {...props} /> ); } function TabContainer({children, dir}) { return ( {children} ); } function AlertDialog({open, handleClose, text, title, t}) { return ( handleClose(-1)} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > {t(title)} {t(text)} ); } class Home extends React.Component { deviceNames = []; deviceNamesID = {}; state = { showDeviceData: false, device: {}, deviceLoaded: false, devices: [], devicesLoaded: false, searchResults: [], showSearch: false, selectedSearchIndex: 0, query: '', downloading: false, packages: {}, release_version_number: '', }; fuzzySet; basicInterface = 0; confirmingBuild = false; packages = [ 'opkg', 'ip6tables', 'odhcp6c', 'base-files', 'mtd', 'fstools', 'kmod-leds-gpio', 'busybox', 'wpad-mini', 'kmod-gpio-button-hotplug', 'kmod-mt76', 'logd', 'swconfig', 'dnsmasq', 'dropbear', 'ppp', 'netifd', 'ppp-mod-pppoe', 'uci', 'libc', 'uclient-fetch', 'kmod-ipt-offload', 'libgcc', 'odhcpd-ipv6only', 'iptables', 'firewall', 'luci']; getDevicesData = () => fetch( 'https://chef.libremesh.org/download/json/devices.json') .then(res => res.json()); getDeviceData = (device_id) => fetch( 'https://chef.libremesh.org/download/json/' + device_id + '.json') .then(res => res.json()); componentDidMount() { this.getDevicesData().then(data => { Object.keys(data['devices']).forEach((device_id) => { const device_name = data['devices'][device_id]; this.deviceNames.push(device_name); this.deviceNamesID[device_name] = device_id; }); this.fuzzySet = FuzzySet(this.deviceNames); this.setState({ devices: data['devices'], devicesLoaded: true, release_version_number: data['version_number'], }); }); let packages = {}; this.packages.forEach((package_name) => { packages[package_name] = true; }); this.setState({ packages, }); } selectDevice = (device_name) => { if (device_name != null) { const device_id = this.deviceNamesID[device_name]; this.setState({ showDeviceData: true, showSearch: false, query: device_name, deviceLoaded: false, }); this.getDeviceData(device_id).then(data => { this.setState({ device: data, deviceLoaded: true, }); }); } }; search = (event) => { const query = event.target.value; this.setState({ query, searchResults: [], showSearch: false, }); const deviceNames = this.fuzzySet.get(query, undefined, 0); let searchResults = []; if (deviceNames != null) { for (let i = 0; i < deviceNames.length && i < 6; i++) { searchResults.push(deviceNames[i][1]); } } this.setState({ searchResults, showSearch: query.length > 0, }); }; hideSearchResults = () => { this.setState({ showSearch: false, }); }; changeInterface = (e, val) => { this.basicInterface = val; }; packageSettingChange = (event, package_name) => { let packages = this.state.packages; packages[package_name] = event.target.checked; this.setState({ packages, }); }; downloadingImageIndicatorShow = (i) => { this.setState({ downloading: true, }); setTimeout(() => { this.setState({ downloading: false, }); }, 1000); }; closeConfirmBuildDialog = (v) => { this.confirmingBuild = false; console.log(v); }; openConfirmBuildDialog = () => { this.confirmingBuild = true; }; render() { const warning432 = this.state.showDeviceData && parseInt( (this.state.device['image_size'] || '').slice(0, -1)) <= 4000 && ( {this.props.t( 'Devices with ≤4MB flash and/or ≤32MB ram will work but they will be very limited (usually they can\'t install or run additional packages) because they have low RAM and flash space. Consider this when choosing a device to buy, or when deciding to flash OpenWrt on your device because it is listed as supported.')} ); const notLoaded = ( ); const onLoad = ( <> {this.props.t('Download OpenWrt firmware for your device!')} {this.props.t( 'Please use the input below to download firmware for your device!')}
{ this.state.showSearch && ( { this.state.searchResults.map((res, index) => { return ( this.selectDevice(res)} > {res}
}/> ); }) } ) } { (this.state.searchResults.length === 0 && this.state.showSearch) && ( ) }
{ this.state.showDeviceData && !this.state.deviceLoaded && ( <>
{notLoaded} ) } { this.state.showDeviceData && this.state.deviceLoaded && ( <> {warning432}
{this.props.t( 'Name')}: {this.state.device['title']}({this.state.device['target']}/{this.state.device['subtarget']}) {this.props.t( 'Release Version')}: {this.state.release_version_number} { this.basicInterface === 0 ? ( { this.state.device.images.map((image, i) => { return ( ); }) }   { this.state.downloading && ( ) } ) : ( { this.packages.map((package_name, i) => { return ( this.packageSettingChange( event, package_name)} value={this.state.packages[package_name]} checked={this.state.packages[package_name]} /> } label={package_name} /> ); }) }
) } ) } ); return ( {this.state.devicesLoaded ? onLoad : notLoaded} ); } } export default withTranslation()(Home);