Add download g-code button

This commit is contained in:
casperlamboo 2017-12-24 17:18:33 +01:00
parent c1cbe4f280
commit 246522ee5f
2 changed files with 111 additions and 45 deletions

View File

@ -11,6 +11,9 @@ import FlatButton from 'material-ui/FlatButton';
import Slider from 'material-ui/Slider'; import Slider from 'material-ui/Slider';
import LinearProgress from 'material-ui/LinearProgress'; import LinearProgress from 'material-ui/LinearProgress';
import { grey50, grey300, grey800, red500 } from 'material-ui/styles/colors'; import { grey50, grey300, grey800, red500 } from 'material-ui/styles/colors';
import Popover from 'material-ui/Popover/Popover';
import Menu from 'material-ui/Menu';
import MenuItem from 'material-ui/MenuItem';
import { Tabs, Tab } from 'material-ui/Tabs'; import { Tabs, Tab } from 'material-ui/Tabs';
import Settings from './Settings.js'; import Settings from './Settings.js';
import defaultSettings from '../settings/default.yml'; import defaultSettings from '../settings/default.yml';
@ -114,6 +117,10 @@ class Interface extends React.Component {
printers: defaultPrinter, printers: defaultPrinter,
quality: defaultQuality, quality: defaultQuality,
material: defaultMaterial, material: defaultMaterial,
popover: {
element: null,
open: false
},
settings: _.merge( settings: _.merge(
{}, {},
defaultSettings, defaultSettings,
@ -177,19 +184,21 @@ class Interface extends React.Component {
} }
}; };
slice = async () => { slice = async (target) => {
const { isSlicing, settings, printers, quality, material, mesh: { matrix } } = this.state; const { isSlicing, settings, printers, quality, material, mesh: { matrix } } = this.state;
const { name, mesh } = this.props; const { name, mesh } = this.props;
if (isSlicing) return; if (isSlicing) return;
this.setState({ isSlicing: true, progress: { action: '', slicing: 0, uploading: 0 }, error: null }); this.closePopover();
this.setState({ isSlicing: true, progress: { action: '', percentage: 0, step: 0 }, error: null });
const exportMesh = new Mesh(mesh.geometry, mesh.material); const exportMesh = new Mesh(mesh.geometry, mesh.material);
exportMesh.applyMatrix(matrix); exportMesh.applyMatrix(matrix);
try { try {
await slice(name, exportMesh, settings, printers, quality, material, progress => { await slice(target, name, exportMesh, settings, printers, quality, material, progress => {
this.setState({ progress: { ...this.state.progress, ...progress } }); this.setState({ progress: { ...this.state.progress, ...progress } });
}); });
} catch (error) { } catch (error) {
@ -200,6 +209,25 @@ class Interface extends React.Component {
} }
}; };
openPopover = (event) => {
event.preventDefault();
this.setState({
popover: {
element: event.currentTarget,
open: true
}
});
};
closePopover = () => {
this.setState({
popover: {
element: null,
open: false
}
});
};
onChangeSettings = (settings) => { onChangeSettings = (settings) => {
this.setState(settings); this.setState(settings);
}; };
@ -238,7 +266,6 @@ class Interface extends React.Component {
const { classes, defaultPrinter, defaultQuality, defaultMaterial, onCancel } = this.props; const { classes, defaultPrinter, defaultQuality, defaultMaterial, onCancel } = this.props;
const { isSlicing, progress, settings, printers, quality, material, showFullScreen, error } = this.state; const { isSlicing, progress, settings, printers, quality, material, showFullScreen, error } = this.state;
const percentage = progress ? (progress.uploading + progress.slicing) / 2.0 * 100.0 : 0.0;
const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) }; const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) };
const settingsPanel = ( const settingsPanel = (
@ -257,7 +284,7 @@ class Interface extends React.Component {
<div className={classes.sliceActions}> <div className={classes.sliceActions}>
{error && <p className={classes.error}>{error}</p>} {error && <p className={classes.error}>{error}</p>}
{isSlicing && <p>{progress.action}</p>} {isSlicing && <p>{progress.action}</p>}
{isSlicing && <LinearProgress mode="determinate" value={percentage} />} {isSlicing && <LinearProgress mode="determinate" value={progress.percentage * 100.0} />}
<div className={classes.sliceButtons}> <div className={classes.sliceButtons}>
{onCancel && <RaisedButton {onCancel && <RaisedButton
label="Cancel" label="Cancel"
@ -266,11 +293,24 @@ class Interface extends React.Component {
/>} />}
<RaisedButton <RaisedButton
label="Print" label="Print"
ref="button"
primary primary
className={`${classes.button}`} className={`${classes.button}`}
onTouchTap={this.slice} onTouchTap={this.openPopover}
disabled={isSlicing} disabled={isSlicing}
/> />
<Popover
open={this.state.popover.open}
anchorEl={this.state.popover.element}
anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
targetOrigin={{horizontal: 'left', vertical: 'bottom'}}
onRequestClose={this.closePopover}
>
<Menu>
<MenuItem primaryText="Send over WiFi" onTouchTap={() => this.slice('WIFI')} />
<MenuItem primaryText="Download GCode" onTouchTap={() => this.slice('DOWNLOAD')} />
</Menu>
</Popover>
</div> </div>
</div> </div>
</div> </div>

View File

@ -118,9 +118,23 @@ export function fetchProgress(url, { method = 'get', headers = {}, body = {} } =
const GCODE_SERVER_URL = 'https://gcodeserver.doodle3d.com'; const GCODE_SERVER_URL = 'https://gcodeserver.doodle3d.com';
const CONNECT_URL = 'http://connect.doodle3d.com/'; const CONNECT_URL = 'http://connect.doodle3d.com/';
export async function slice(name, mesh, settings, printers, quality, material, updateProgress) { export async function slice(target, name, mesh, settings, printers, quality, material, updateProgress) {
if (!printers) throw new Error('Please select a printer'); if (!printers) throw new Error('Please select a printer');
let steps;
let currentStep = 0;
switch (target) {
case 'DOWNLOAD':
steps = 1;
break;
case 'WIFI':
steps = 2;
break;
default:
steps = 1;
break;
}
const { dimensions } = settings; const { dimensions } = settings;
const centerX = dimensions.x / 2; const centerX = dimensions.x / 2;
const centerY = dimensions.y / 2; const centerY = dimensions.y / 2;
@ -129,13 +143,19 @@ export async function slice(name, mesh, settings, printers, quality, material, u
const { gcode } = await sliceGeometry(settings, mesh.geometry, mesh.material, matrix, false, false, ({ progress }) => { const { gcode } = await sliceGeometry(settings, mesh.geometry, mesh.material, matrix, false, false, ({ progress }) => {
updateProgress({ updateProgress({
action: progress.action, action: progress.action,
slicing: progress.done / progress.total percentage: currentStep / steps + progress.done / progress.total / steps
}); });
}); });
currentStep ++;
// const blob = new File([gcode], `${name}.gcode`, { type: 'text/plain;charset=utf-8' }); switch (target) {
// fileSaver.saveAs(blob); case 'DOWNLOAD': {
const blob = new File([gcode], `${name}.gcode`, { type: 'text/plain;charset=utf-8' });
fileSaver.saveAs(blob);
break;
}
case 'WIFI': {
// upload G-code file to AWS S3 // upload G-code file to AWS S3
const { data: { reservation, id } } = await fetch(`${GCODE_SERVER_URL}/upload`, { method: 'POST' }) const { data: { reservation, id } } = await fetch(`${GCODE_SERVER_URL}/upload`, { method: 'POST' })
.then(response => response.json()); .then(response => response.json());
@ -167,14 +187,20 @@ export async function slice(name, mesh, settings, printers, quality, material, u
await fetchProgress(reservation.url, { method: 'POST', body }, (progess) => { await fetchProgress(reservation.url, { method: 'POST', body }, (progess) => {
updateProgress({ updateProgress({
action: 'Uploading', action: 'Uploading',
uploading: progess.loaded / progess.total percentage: currentStep / steps + progess.loaded / progess.total / steps
}); });
}); });
currentStep ++;
const popup = window.open(`${CONNECT_URL}?uuid=${id}`, '_blank'); const popup = window.open(`${CONNECT_URL}?uuid=${id}`, '_blank');
if (!popup) throw new Error('popup was blocked by browser'); if (!popup) throw new Error('popup was blocked by browser');
} }
default:
break;
}
}
export const TabTemplate = ({ children, selected, style }) => { export const TabTemplate = ({ children, selected, style }) => {
const templateStyle = { const templateStyle = {
width: '100%', width: '100%',