mirror of
https://git.netzspielplatz.de/docker-multiarch/openwrt-firmware-selector.git
synced 2025-11-08 20:59:29 +00:00
Change the code according to the new ASU api. (#5)
Now, upon load, the app fetched versions from the server and then the devices for that particular version. Then the user can search for their device and download an image accordingly. Signed-off-by: Sudhanshu Gautam <me@sudhanshug.com>
This commit is contained in:
parent
3d1243a946
commit
128855c278
6 changed files with 302 additions and 249 deletions
|
|
@ -34,6 +34,7 @@ function SearchTextField(props) {
|
||||||
{props.labeltext}
|
{props.labeltext}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
disabled={props.disabled}
|
||||||
InputProps={
|
InputProps={
|
||||||
{
|
{
|
||||||
classes,
|
classes,
|
||||||
|
|
@ -49,6 +50,7 @@ function SearchTextField(props) {
|
||||||
|
|
||||||
SearchTextField.propTypes = {
|
SearchTextField.propTypes = {
|
||||||
labeltext: PropTypes.string,
|
labeltext: PropTypes.string,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SearchTextField;
|
export default SearchTextField;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import SearchTextField from '../../components/device-search';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const buildStatusCheckInterval = 5000;
|
const buildStatusCheckInterval = 5000;
|
||||||
|
const confirmationPopupOnBuildResquest = false;
|
||||||
|
|
||||||
function TabContainer({children, dir}) {
|
function TabContainer({children, dir}) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -51,44 +52,19 @@ TabContainer.propTypes = {
|
||||||
dir: PropTypes.any,
|
dir: PropTypes.any,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Home extends React.Component {
|
const sleep = m => new Promise(r => setTimeout(r, m));
|
||||||
|
const asu = 'https://aparcar.stephen304.com';
|
||||||
|
const asu_download = 'https://aparcar.stephen304.com/download/json-demo/openwrt/';
|
||||||
|
|
||||||
packages = [
|
class Home extends React.Component {
|
||||||
'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'];
|
|
||||||
deviceNames = [];
|
|
||||||
deviceNamesID = {};
|
|
||||||
checkBuildStatus;
|
|
||||||
state = {
|
state = {
|
||||||
|
selection: {
|
||||||
|
version: null,
|
||||||
|
device: null,
|
||||||
|
},
|
||||||
showDeviceData: false,
|
showDeviceData: false,
|
||||||
device: {},
|
|
||||||
deviceLoaded: false,
|
deviceLoaded: false,
|
||||||
devices: [],
|
data: [],
|
||||||
devicesLoaded: false,
|
devicesLoaded: false,
|
||||||
searchResults: [],
|
searchResults: [],
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
|
|
@ -96,45 +72,44 @@ class Home extends React.Component {
|
||||||
query: '',
|
query: '',
|
||||||
downloading: false,
|
downloading: false,
|
||||||
packages: this.packages,
|
packages: this.packages,
|
||||||
distributions: {
|
|
||||||
versions: {},
|
|
||||||
},
|
|
||||||
configChanged: true,
|
configChanged: true,
|
||||||
packageName: '',
|
packageName: '',
|
||||||
release: '',
|
|
||||||
builtImages: [],
|
builtImages: [],
|
||||||
isBuilding: false,
|
isBuilding: false,
|
||||||
|
queuePosition: -1,
|
||||||
showUnexpectedErrorBar: false,
|
showUnexpectedErrorBar: false,
|
||||||
|
errorMessage: '',
|
||||||
|
fuzzySet: null,
|
||||||
|
showAdvanced: true,
|
||||||
|
basicInterface: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
fuzzySet;
|
|
||||||
basicInterface = 0;
|
basicInterface = 0;
|
||||||
confirmingBuild = false;
|
confirmingBuild = false;
|
||||||
|
|
||||||
dataService = new DataService();
|
dataService = new DataService();
|
||||||
|
|
||||||
componentDidMount() {
|
async componentDidMount() {
|
||||||
this.dataService.getDistributions.then(distros => {
|
try {
|
||||||
|
const versionsResponse = await this.dataService.getVersions();
|
||||||
|
let data = versionsResponse.data.versions;
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
const overviewResponse = await this.dataService.getOverview(data[i].path);
|
||||||
|
data[i].devices = overviewResponse.data.devices;
|
||||||
|
}
|
||||||
|
this.generateFuzzySet(data[0].devices);
|
||||||
this.setState({
|
this.setState({
|
||||||
distributions: distros['openwrt'],
|
data,
|
||||||
release: distros['openwrt']['latest'],
|
selection: {
|
||||||
|
version: 0,
|
||||||
|
},
|
||||||
|
devicesLoaded: true,
|
||||||
});
|
});
|
||||||
this.dataService.getDevicesData.then(data => {
|
} catch (err) {
|
||||||
Object.keys(data['devices']).forEach((device_name) => {
|
this.setState({
|
||||||
// const device_name = data['devices'][device_id];
|
showUnexpectedErrorBar: true,
|
||||||
// this.deviceNames.push(device_name);
|
|
||||||
// this.deviceNamesID[device_name] = device_id;
|
|
||||||
const device_id = data['devices'][device_name];
|
|
||||||
this.deviceNames.push(device_name);
|
|
||||||
this.deviceNamesID[device_name] = device_id;
|
|
||||||
});
|
|
||||||
this.fuzzySet = FuzzySet(this.deviceNames);
|
|
||||||
this.setState({
|
|
||||||
devices: data['devices'],
|
|
||||||
devicesLoaded: true,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
console.log(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closeUnexpectedErrorBar = () => {
|
closeUnexpectedErrorBar = () => {
|
||||||
|
|
@ -143,28 +118,80 @@ class Home extends React.Component {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
setRelease = (event) => {
|
generateFuzzySet = (data) => {
|
||||||
|
let deviceNames = [];
|
||||||
|
Object.keys(data).forEach((deviceName) => {
|
||||||
|
deviceNames.push(deviceName);
|
||||||
|
});
|
||||||
this.setState({
|
this.setState({
|
||||||
release: event.target.value,
|
fuzzySet: FuzzySet(deviceNames),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
selectDevice = (device_name) => {
|
setRelease = (event) => {
|
||||||
if (device_name != null) {
|
this.generateFuzzySet(this.state.data[event.target.value].devices);
|
||||||
const device_id = this.deviceNamesID[device_name];
|
this.setState({
|
||||||
|
selection: {
|
||||||
|
version: event.target.value,
|
||||||
|
},
|
||||||
|
deviceLoaded: false,
|
||||||
|
showDeviceData: false,
|
||||||
|
query: '',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
selectDevice = async (device_name) => {
|
||||||
|
const version = this.state.data[this.state.selection.version];
|
||||||
|
let selection;
|
||||||
|
try {
|
||||||
|
let deviceSubPath = version.devices[device_name];
|
||||||
|
if (deviceSubPath.indexOf('//') > 0) {
|
||||||
|
deviceSubPath = deviceSubPath.replace('//', '/generic/');
|
||||||
|
}
|
||||||
|
const devicePath = version.path + '/targets/' + deviceSubPath;
|
||||||
this.setState({
|
this.setState({
|
||||||
showDeviceData: true,
|
showDeviceData: true,
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
query: device_name,
|
query: device_name,
|
||||||
|
basicInterface: 0,
|
||||||
deviceLoaded: false,
|
deviceLoaded: false,
|
||||||
|
showAdvanced: false,
|
||||||
|
configChanged: true,
|
||||||
});
|
});
|
||||||
this.dataService.getDeviceData(device_id).then(data => {
|
let deviceResponse = await this.dataService.getDeviceData(devicePath);
|
||||||
this.setState({
|
selection = this.state.selection;
|
||||||
device: data,
|
selection.device = deviceResponse.data;
|
||||||
deviceLoaded: true,
|
if (selection.device.target[selection.device.target.length - 1] === '/') {
|
||||||
});
|
selection.device.target += 'generic';
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.setState({
|
||||||
|
showUnexpectedErrorBar: true,
|
||||||
|
});
|
||||||
|
console.log(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const noPackageFoundError = {error: 'no-packages-found'};
|
||||||
|
try {
|
||||||
|
let devicePackagesResponse = await this.dataService.getDevicePackages(version.name, selection.device.target, selection.device.id);
|
||||||
|
if (devicePackagesResponse.data.length === 0) {
|
||||||
|
throw noPackageFoundError;
|
||||||
|
}
|
||||||
|
var packages = devicePackagesResponse.data;
|
||||||
|
packages.sort();
|
||||||
|
this.setState({
|
||||||
|
packages,
|
||||||
|
showAdvanced: true,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
this.setState({
|
||||||
|
showAdvanced: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.setState({
|
||||||
|
selection,
|
||||||
|
deviceLoaded: true,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
search = (event) => {
|
search = (event) => {
|
||||||
|
|
@ -174,7 +201,7 @@ class Home extends React.Component {
|
||||||
searchResults: [],
|
searchResults: [],
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
});
|
});
|
||||||
const deviceNames = this.fuzzySet.get(query, undefined, 0);
|
const deviceNames = this.state.fuzzySet.get(query, undefined, 0);
|
||||||
let searchResults = [];
|
let searchResults = [];
|
||||||
if (deviceNames != null) {
|
if (deviceNames != null) {
|
||||||
for (let i = 0; i < deviceNames.length && i < 6; i++) {
|
for (let i = 0; i < deviceNames.length && i < 6; i++) {
|
||||||
|
|
@ -194,7 +221,9 @@ class Home extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
changeInterface = (e, val) => {
|
changeInterface = (e, val) => {
|
||||||
this.basicInterface = val;
|
this.setState({
|
||||||
|
basicInterface: val,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
downloadingImageIndicatorShow = () => {
|
downloadingImageIndicatorShow = () => {
|
||||||
|
|
@ -251,89 +280,91 @@ class Home extends React.Component {
|
||||||
|
|
||||||
displayBuiltImageData = async (buildStatusResponse) => {
|
displayBuiltImageData = async (buildStatusResponse) => {
|
||||||
let builtImages = [];
|
let builtImages = [];
|
||||||
builtImages.push({
|
buildStatusResponse.data.images.forEach((image) => {
|
||||||
url: 'https://chef.libremesh.org' +
|
builtImages.push({
|
||||||
buildStatusResponse.data.files + buildStatusResponse.data.sysupgrade,
|
url: asu +
|
||||||
type: 'sysupgrade',
|
buildStatusResponse.data.image_folder + '/' + image.name,
|
||||||
});
|
type: image.type,
|
||||||
await this.dataService.getFiles(buildStatusResponse.data.files)
|
|
||||||
.then((fileListResponse) => {
|
|
||||||
fileListResponse.forEach((file) => {
|
|
||||||
if (file.name.includes('factory')) {
|
|
||||||
const type = file.name.split('-').reverse()[0].split('.')[0];
|
|
||||||
builtImages.push({
|
|
||||||
url: 'https://chef.libremesh.org' +
|
|
||||||
buildStatusResponse.data.files + file.name,
|
|
||||||
type,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.setState({
|
|
||||||
builtImages,
|
|
||||||
configChanged: false,
|
|
||||||
isBuilding: false,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
clearTimeout(this.checkBuildStatus);
|
});
|
||||||
};
|
if (this.state.isBuilding) {
|
||||||
|
|
||||||
buildImageCheck = async (request_hash) => {
|
|
||||||
const buildStatusResponse = await this.dataService.buildStatusCheck(
|
|
||||||
request_hash);
|
|
||||||
if (buildStatusResponse.status === 202) {
|
|
||||||
this.checkBuildStatus = setTimeout(
|
|
||||||
async () => {
|
|
||||||
await this.buildImageCheck(request_hash);
|
|
||||||
}, buildStatusCheckInterval,
|
|
||||||
);
|
|
||||||
} else if (buildStatusResponse.status === 200) {
|
|
||||||
await this.displayBuiltImageData(buildStatusResponse);
|
|
||||||
} else {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
builtImages,
|
||||||
|
configChanged: false,
|
||||||
isBuilding: false,
|
isBuilding: false,
|
||||||
showUnexpectedErrorBar: true,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
buildImage = async () => {
|
buildImageCheck = async (request_hash) => {
|
||||||
this.closeConfirmBuildDialog();
|
return new Promise(async (resolve, reject) => {
|
||||||
const board = this.state.device.id;
|
try {
|
||||||
const packages = this.state.packages;
|
if (!this.state.isBuilding) {
|
||||||
const target = this.state.device['target'] + '/' + this.state.device['subtarget'];
|
return;
|
||||||
const version = this.state.release;
|
}
|
||||||
this.setState({
|
const buildStatusResponse = await this.dataService.buildStatusCheck(request_hash);
|
||||||
isBuilding: true,
|
if (buildStatusResponse.status === 202) {
|
||||||
builtImages: [],
|
if (buildStatusResponse.headers['X-Build-Queue-Position'] !== undefined) {
|
||||||
});
|
this.setState({
|
||||||
this.dataService.buildImage(board, packages, target, version).then(async res => {
|
queuePosition: buildStatusResponse.headers['X-Build-Queue-Position'],
|
||||||
if (res.status === 202 && res.data['request_hash'] !== undefined) {
|
});
|
||||||
const request_hash = res.data['request_hash'];
|
}
|
||||||
this.checkBuildStatus = setTimeout(
|
await sleep(buildStatusCheckInterval);
|
||||||
async () => {
|
await this.buildImageCheck(request_hash);
|
||||||
await this.buildImageCheck(request_hash);
|
resolve();
|
||||||
}, buildStatusCheckInterval,
|
} else if (buildStatusResponse.status === 200) {
|
||||||
);
|
await this.displayBuiltImageData(buildStatusResponse);
|
||||||
} else if (res.status === 200) {
|
resolve();
|
||||||
await this.displayBuiltImageData(res);
|
} else {
|
||||||
} else {
|
throw buildStatusResponse.data;
|
||||||
this.setState({
|
}
|
||||||
isBuilding: false,
|
} catch (err) {
|
||||||
showUnexpectedErrorBar: true,
|
reject(err);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
buildImage = async () => {
|
||||||
|
try {
|
||||||
|
this.closeConfirmBuildDialog();
|
||||||
|
const board = this.state.selection.device.id;
|
||||||
|
const packages = this.state.packages;
|
||||||
|
const target = this.state.selection.device['target'];
|
||||||
|
const version = this.state.data[this.state.selection.version].name.toLowerCase();
|
||||||
|
this.setState({
|
||||||
|
isBuilding: true,
|
||||||
|
builtImages: [],
|
||||||
|
});
|
||||||
|
let buildResponse = await this.dataService.buildImage(board, packages, target, version);
|
||||||
|
if (buildResponse.status === 202 && buildResponse.data['request_hash'] !== undefined) {
|
||||||
|
const request_hash = buildResponse.data['request_hash'];
|
||||||
|
await sleep(buildStatusCheckInterval);
|
||||||
|
await this.buildImageCheck(request_hash);
|
||||||
|
} else if (buildResponse.status === 200) {
|
||||||
|
await this.displayBuiltImageData(buildResponse);
|
||||||
|
} else {
|
||||||
|
throw buildResponse.data;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
this.setState({
|
this.setState({
|
||||||
isBuilding: false,
|
isBuilding: false,
|
||||||
showUnexpectedErrorBar: true,
|
showUnexpectedErrorBar: true,
|
||||||
});
|
});
|
||||||
});
|
console.log(err);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cancelBuild = () => {
|
||||||
|
this.setState({
|
||||||
|
isBuilding: false,
|
||||||
|
configChanged: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const warning432 = this.state.showDeviceData &&
|
const warning432 = this.state.showDeviceData && this.state.deviceLoaded &&
|
||||||
parseInt(
|
parseInt(
|
||||||
(this.state.device['image_size'] || '').slice(0, -1)) <= 4000 && (
|
(this.state.selection.device['image_size'] || '').slice(0, -1)) <= 4000 && (
|
||||||
<Paper className="warning-432" elevation={0}>
|
<Paper className="warning-432" elevation={0}>
|
||||||
<Grid
|
<Grid
|
||||||
container
|
container
|
||||||
|
|
@ -345,8 +376,7 @@ class Home extends React.Component {
|
||||||
<WarningIcon className="icon"/>
|
<WarningIcon className="icon"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs>
|
<Grid item xs>
|
||||||
{this.props.t(
|
{this.props.t('warning432')}
|
||||||
'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.')}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
@ -371,19 +401,19 @@ class Home extends React.Component {
|
||||||
{this.props.t('Version')}
|
{this.props.t('Version')}
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Select
|
<Select
|
||||||
value={this.state.release}
|
value={this.state.selection.version}
|
||||||
onChange={this.setRelease}
|
onChange={this.setRelease}
|
||||||
input={<OutlinedInput name="version"
|
disabled={this.state.isBuilding}
|
||||||
id="version-select" labelWidth={60}/>}
|
input={
|
||||||
|
<OutlinedInput name="version"id="version-select" labelWidth={60}/>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
Object.keys(this.state.distributions['versions'])
|
this.state.data.map((version, i) => (
|
||||||
.map((version) => (
|
<MenuItem value={i} key={version.name}>
|
||||||
<MenuItem value={version} key={version}>
|
<em>{version.name}</em>
|
||||||
<em>{version}</em>
|
</MenuItem>
|
||||||
</MenuItem>
|
))
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
|
@ -394,6 +424,7 @@ class Home extends React.Component {
|
||||||
value={this.state.query}
|
value={this.state.query}
|
||||||
onChange={this.search}
|
onChange={this.search}
|
||||||
onClick={this.search}
|
onClick={this.search}
|
||||||
|
disabled={this.state.isBuilding}
|
||||||
/>
|
/>
|
||||||
{
|
{
|
||||||
this.state.showSearch && this.state.searchResults.length !==
|
this.state.showSearch && this.state.searchResults.length !==
|
||||||
|
|
@ -448,56 +479,59 @@ class Home extends React.Component {
|
||||||
<>
|
<>
|
||||||
{warning432}
|
{warning432}
|
||||||
<br/>
|
<br/>
|
||||||
<Grid container className="device-info">
|
|
||||||
<Grid item xs>
|
|
||||||
<b>{this.props.t(
|
|
||||||
'Name')}: </b> {this.state.device['title']}({this.state.device['target']}/{this.state.device['subtarget']})
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs>
|
|
||||||
<b>{this.props.t(
|
|
||||||
'Release Version')}: </b> {this.state.release_version_number}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<AppBar className="interface-switch-bar" position="relative"
|
|
||||||
elevation={0}>
|
|
||||||
<Tabs value={this.basicInterface}
|
|
||||||
onChange={this.changeInterface}>
|
|
||||||
<Tab className="interface-switch"
|
|
||||||
label={this.props.t('Basic')}/>
|
|
||||||
<Tab className="interface-switch"
|
|
||||||
label={this.props.t('Advanced')}/>
|
|
||||||
</Tabs>
|
|
||||||
</AppBar>
|
|
||||||
{
|
{
|
||||||
this.basicInterface === 0 ? (
|
this.state.showAdvanced && (
|
||||||
|
<AppBar className="interface-switch-bar" position="relative" elevation={0}>
|
||||||
|
<Tabs value={this.state.basicInterface}onChange={this.changeInterface}>
|
||||||
|
<Tab className="interface-switch" label={this.props.t('Basic')} disabled={this.state.isBuilding}/>
|
||||||
|
<Tab className="interface-switch" label={this.props.t('Advanced')} disabled={this.state.isBuilding}/>
|
||||||
|
</Tabs>
|
||||||
|
</AppBar>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
this.state.basicInterface === 0 ? (
|
||||||
<TabContainer>
|
<TabContainer>
|
||||||
{
|
<Grid container className="device-info">
|
||||||
this.state.device.images.map((image, i) => {
|
<Grid item xs>
|
||||||
return (
|
{this.props.t('Model')}: <b> {this.state.selection.device['title']} </b> <br />
|
||||||
<Button
|
{this.props.t('Target')}: {this.state.selection.device['target']} <br />
|
||||||
key={i}
|
{this.props.t('Version')}: {this.state.data[this.state.selection.version].name} ({this.state.data[this.state.selection.version].revision})
|
||||||
className="download-button"
|
</Grid>
|
||||||
href={'http://downloads.openwrt.org/snapshots/targets/' +
|
<Grid item xs>
|
||||||
this.state.device.target + '/' +
|
<b>{this.props.t('Downloads')}: </b>
|
||||||
this.state.device.subtarget + '/' +
|
{
|
||||||
image.name}
|
this.state.selection.device.images.map((image) => {
|
||||||
color="primary"
|
return (
|
||||||
variant="contained"
|
<>
|
||||||
onClick={() => this.downloadingImageIndicatorShow()}
|
<br />
|
||||||
>
|
<Button
|
||||||
<CloudDownloadIcon
|
key={image.name}
|
||||||
className="download-icon"/>
|
className="download-button"
|
||||||
{image.name.split('-').reverse()[0].split('.')[0]}
|
href={asu_download +
|
||||||
</Button>
|
this.state.data[this.state.selection.version].path + '/targets/' +
|
||||||
);
|
this.state.selection.device.target + '/' +
|
||||||
})
|
image.name}
|
||||||
}
|
color="primary"
|
||||||
|
variant="contained"
|
||||||
{
|
onClick={() => this.downloadingImageIndicatorShow()}
|
||||||
this.state.downloading && (
|
>
|
||||||
<CircularProgress size={20}/>
|
<CloudDownloadIcon
|
||||||
)
|
className="download-icon"/>
|
||||||
}
|
{image.name.split('-').reverse()[0].split('.')[0]}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
this.state.downloading && (
|
||||||
|
<CircularProgress size={20}/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</TabContainer>
|
</TabContainer>
|
||||||
) : (
|
) : (
|
||||||
<TabContainer>
|
<TabContainer>
|
||||||
|
|
@ -507,7 +541,7 @@ class Home extends React.Component {
|
||||||
this.state.packages.map((package_name, i) => {
|
this.state.packages.map((package_name, i) => {
|
||||||
return (
|
return (
|
||||||
<Chip className="package"
|
<Chip className="package"
|
||||||
key={package_name + i}
|
key={package_name}
|
||||||
size="small"
|
size="small"
|
||||||
onDelete={() => this.deletePackage(
|
onDelete={() => this.deletePackage(
|
||||||
i)}
|
i)}
|
||||||
|
|
@ -531,7 +565,7 @@ class Home extends React.Component {
|
||||||
{
|
{
|
||||||
this.state.configChanged && !this.state.isBuilding && (
|
this.state.configChanged && !this.state.isBuilding && (
|
||||||
<Button variant="outlined" color="primary"
|
<Button variant="outlined" color="primary"
|
||||||
onClick={this.openConfirmBuildDialog}>
|
onClick={confirmationPopupOnBuildResquest ? this.openConfirmBuildDialog : this.buildImage}>
|
||||||
<BuildIcon/>
|
<BuildIcon/>
|
||||||
|
|
||||||
{this.props.t('Build')}
|
{this.props.t('Build')}
|
||||||
|
|
@ -540,35 +574,62 @@ class Home extends React.Component {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.isBuilding && (
|
this.state.isBuilding && (
|
||||||
<CircularProgress size={20}/>
|
<>
|
||||||
|
<CircularProgress size={20} style={{verticalAlign: 'middle'}}/>
|
||||||
|
|
||||||
|
Building image
|
||||||
|
{
|
||||||
|
this.state.queuePosition !== -1 && (
|
||||||
|
<span> (Position in queue: {this.state.queuePosition}) </span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
<Button variant="outlined" size="small"
|
||||||
|
onClick={this.cancelBuild}>
|
||||||
|
|
||||||
|
{this.props.t('Cancel')}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.state.builtImages.length > 0 && !this.state.configChanged && (
|
this.state.builtImages.length > 0 && !this.state.configChanged && (
|
||||||
<>
|
<Grid container className="device-info">
|
||||||
{
|
<Grid item xs>
|
||||||
|
{this.props.t('Model')}: <b> {this.state.selection.device['title']} </b> <br />
|
||||||
|
{this.props.t('Target')}: {this.state.selection.device['target']} <br />
|
||||||
|
{this.props.t('Version')}: {this.state.data[this.state.selection.version].name} ({this.state.data[this.state.selection.version].revision})
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs>
|
||||||
|
<b>{this.props.t('Downloads')}: </b>
|
||||||
|
{
|
||||||
this.state.builtImages.map((image) => (
|
this.state.builtImages.map((image) => (
|
||||||
<Button
|
<>
|
||||||
key={image.url}
|
<br />
|
||||||
className="download-button"
|
<Button
|
||||||
href={image.url}
|
key={image.url}
|
||||||
color="primary"
|
className="download-button"
|
||||||
variant="contained"
|
href={image.url}
|
||||||
onClick={() => this.downloadingImageIndicatorShow()}
|
color="primary"
|
||||||
>
|
variant="contained"
|
||||||
<CloudDownloadIcon
|
onClick={() => this.downloadingImageIndicatorShow()}
|
||||||
className="download-icon"/>
|
>
|
||||||
{image.type}
|
<CloudDownloadIcon
|
||||||
</Button>
|
className="download-icon"/>
|
||||||
|
{image.type}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this.state.downloading && (
|
this.state.downloading && (
|
||||||
<CircularProgress size={20}/>
|
<CircularProgress size={20}/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</>
|
</Grid>
|
||||||
|
</Grid>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ $bg-color: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-button {
|
.download-button {
|
||||||
margin-right: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.download-icon {
|
.download-icon {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,10 @@
|
||||||
"Version": "Ausführung",
|
"Version": "Ausführung",
|
||||||
"Please confirm that you want to perform this action": "Bitte bestätigen Sie, dass Sie diese Aktion ausführen möchten",
|
"Please confirm that you want to perform this action": "Bitte bestätigen Sie, dass Sie diese Aktion ausführen möchten",
|
||||||
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Das Erstellen eines Image erfordert Rechenressourcen. Wir bitten Sie daher, zu prüfen, ob diese Auswahl Ihren Wünschen entspricht",
|
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Das Erstellen eines Image erfordert Rechenressourcen. Wir bitten Sie daher, zu prüfen, ob diese Auswahl Ihren Wünschen entspricht",
|
||||||
"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.": "Geräte mit ≤4MB Flash und / oder ≤32MB RAM funktionieren, sind jedoch sehr eingeschränkt (normalerweise können sie keine zusätzlichen Pakete installieren oder ausführen), da sie über wenig RAM und Flash-Speicher verfügen. Berücksichtigen Sie dies, wenn Sie ein Gerät zum Kaufen auswählen oder wenn Sie OpenWrt auf Ihrem Gerät flashen, da es als unterstützt aufgeführt ist Zusätzliche Pakete können nicht installiert oder ausgeführt werden, da sie über wenig RAM und wenig Flash-Speicher verfügen. Berücksichtigen Sie dies, wenn Sie ein Gerät zum Kaufen auswählen oder wenn Sie sich entscheiden, OpenWrt auf Ihrem Gerät zu flashen, da es als unterstützt aufgeführt ist.",
|
"warning432": "Geräte mit ≤4MB Flash und / oder ≤32MB RAM funktionieren, sind jedoch sehr eingeschränkt (normalerweise können sie keine zusätzlichen Pakete installieren oder ausführen), da sie über wenig RAM und Flash-Speicher verfügen. Berücksichtigen Sie dies, wenn Sie ein Gerät zum Kaufen auswählen oder wenn Sie OpenWrt auf Ihrem Gerät flashen, da es als unterstützt aufgeführt ist Zusätzliche Pakete können nicht installiert oder ausgeführt werden, da sie über wenig RAM und wenig Flash-Speicher verfügen. Berücksichtigen Sie dies, wenn Sie ein Gerät zum Kaufen auswählen oder wenn Sie sich entscheiden, OpenWrt auf Ihrem Gerät zu flashen, da es als unterstützt aufgeführt ist.",
|
||||||
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
||||||
"Download OpenWrt firmware for your device!": "Laden Sie die OpenWrt-Firmware für Ihr Gerät herunter!",
|
"Download OpenWrt firmware for your device!": "Laden Sie die OpenWrt-Firmware für Ihr Gerät herunter!",
|
||||||
|
"Target": "Ziel",
|
||||||
|
"Downloads": "Herunterladen",
|
||||||
"Please use the input below to download firmware for your device!": "Bitte benutzen Sie den unten stehenden Eingang, um die Firmware für Ihr Gerät herunterzuladen!"
|
"Please use the input below to download firmware for your device!": "Bitte benutzen Sie den unten stehenden Eingang, um die Firmware für Ihr Gerät herunterzuladen!"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,10 @@
|
||||||
"Version": "Version",
|
"Version": "Version",
|
||||||
"Please confirm that you want to perform this action": "Please confirm that you want to perform this action",
|
"Please confirm that you want to perform this action": "Please confirm that you want to perform this action",
|
||||||
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Building image requires computation resources, so we would request you to check if this selection is what you want",
|
"Building image requires computation resources, so we would request you to check if this selection is what you want": "Building image requires computation resources, so we would request you to check if this selection is what you want",
|
||||||
"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.": "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.",
|
"warning432": "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.",
|
||||||
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
"OpenWrt Firmware Selector Wizard": "OpenWrt Firmware Selector Wizard",
|
||||||
"Download OpenWrt firmware for your device!": "Download OpenWrt firmware for your device!",
|
"Download OpenWrt firmware for your device!": "Download OpenWrt firmware for your device!",
|
||||||
|
"Target": "Target",
|
||||||
|
"Downloads": "Downloads",
|
||||||
"Please use the input below to download firmware for your device!": "Please use the input below to download firmware for your device!"
|
"Please use the input below to download firmware for your device!": "Please use the input below to download firmware for your device!"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,21 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
const base = 'https://cors-anywhere.herokuapp.com/https://mwarning.de/misc/json/bin';
|
const base_downloads = 'https://cors-anywhere.herokuapp.com/https://aparcar.stephen304.com/download/json-demo/openwrt/';
|
||||||
|
const base_api = 'https://cors-anywhere.herokuapp.com/https://aparcar.stephen304.com/api/';
|
||||||
|
|
||||||
class DataService {
|
class DataService {
|
||||||
|
|
||||||
getDevicesData = axios.get(
|
getVersions = () => axios.get(base_downloads + 'versions.json');
|
||||||
`${base}/overview.json`)
|
|
||||||
.then(res => res.data);
|
|
||||||
|
|
||||||
getDeviceData = (device_id) => axios.get(
|
getOverview = (path) => axios.get(base_downloads + path + '/overview.json');
|
||||||
base + '/targets/' + device_id)
|
|
||||||
.then(res => res.data);
|
|
||||||
|
|
||||||
getDistributions = axios.get(
|
getDeviceData = (device_path) => axios.get(base_downloads + device_path);
|
||||||
'https://chef.libremesh.org/api/distributions')
|
|
||||||
.then(res => res.data);
|
getDevicePackages = (version, target, profile) => axios.get(base_api + 'packages_image?distro=openwrt&version=' + version.toLowerCase() + '&target=' + target + '&profile=' + profile.toLowerCase());
|
||||||
|
|
||||||
buildImage = (board, packages, target, version) => {
|
buildImage = (board, packages, target, version) => {
|
||||||
return axios.post('https://chef.libremesh.org/api/build-request', {
|
return axios.post(base_api + 'build-request', {
|
||||||
|
profile: board,
|
||||||
board,
|
board,
|
||||||
defaults: '',
|
defaults: '',
|
||||||
distro: 'openwrt',
|
distro: 'openwrt',
|
||||||
|
|
@ -27,19 +25,7 @@ class DataService {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
buildStatusCheck = async (request_hash) => {
|
buildStatusCheck = (request_hash) => axios.get(base_api + 'build-request/' + request_hash);
|
||||||
let response = {
|
|
||||||
isBuilt: false,
|
|
||||||
};
|
|
||||||
await axios.get('https://chef.libremesh.org/api/build-request/' + request_hash).then((res) => {
|
|
||||||
response.isBuilt = res.status === 202 && res.data.files !== undefined;
|
|
||||||
response.status = res.status;
|
|
||||||
if (response.isBuilt) {
|
|
||||||
response = {...response, data: res.data};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return response;
|
|
||||||
};
|
|
||||||
|
|
||||||
getFiles = (files_url) => axios.get('https://chef.libremesh.org' + files_url).then(res => res.data);
|
getFiles = (files_url) => axios.get('https://chef.libremesh.org' + files_url).then(res => res.data);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue