add custom actions

This commit is contained in:
Casper Lamboo 2018-03-07 18:21:41 +01:00
parent df6e084503
commit 38ab39f7de
3 changed files with 76 additions and 32 deletions

View File

@ -32,10 +32,11 @@ jss.createStyleSheet({
} }
}).attach(); }).attach();
const { file, selectedPrinter } = queryString.parse(location.search); let { file, selectedPrinter, actions } = queryString.parse(location.search);
if (actions) actions = JSON.parse(actions);
render(( render((
<MuiThemeProvider muiTheme={muiTheme}> <MuiThemeProvider muiTheme={muiTheme}>
<Interface fileUrl={file} selectedPrinter={selectedPrinter} name="doodle"/> <Interface actions={actions} fileUrl={file} selectedPrinter={selectedPrinter} name="doodle"/>
</MuiThemeProvider> </MuiThemeProvider>
), document.getElementById('app')); ), document.getElementById('app'));

View File

@ -113,10 +113,18 @@ class Interface extends React.Component {
onCancel: PropTypes.func, onCancel: PropTypes.func,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
muiTheme: PropTypes.object.isRequired, muiTheme: PropTypes.object.isRequired,
allowDragDrop: PropTypes.bool.isRequired allowDragDrop: PropTypes.bool.isRequired,
actions: PropTypes.arrayOf(PropTypes.shape({ type: PropTypes.string }))
}; };
static defaultProps = { static defaultProps = {
actions: [{
type: 'WIFI_PRINT',
title: 'Print over WiFi'
}, {
type: 'DOWNLOAD',
title: 'Download GCode'
}],
pixelRatio: 1, pixelRatio: 1,
name: 'Doodle3D', name: 'Doodle3D',
allowDragDrop: true allowDragDrop: true
@ -223,7 +231,7 @@ class Interface extends React.Component {
} }
}; };
slice = async (target) => { slice = async (action) => {
const { isSlicing, settings, mesh, scene: { material, mesh: { matrix } } } = this.state; const { isSlicing, settings, mesh, scene: { material, mesh: { matrix } } } = this.state;
const { name } = this.props; const { name } = this.props;
@ -232,7 +240,7 @@ class Interface extends React.Component {
this.setState({ error: 'please select a printer first' }); this.setState({ error: 'please select a printer first' });
return; return;
} }
if (target === 'WIFI' && !settings.ip) { if (action.target === 'WIFI_PRINT' && !settings.ip) {
this.setState({ error: 'please connect to a WiFi enabled printer' }); this.setState({ error: 'please connect to a WiFi enabled printer' });
return; return;
} }
@ -249,7 +257,7 @@ class Interface extends React.Component {
try { try {
const updateProgres = progress => this.setState({ progress: { ...this.state.progress, ...progress } }); const updateProgres = progress => this.setState({ progress: { ...this.state.progress, ...progress } });
await slice(target, name, exportMesh, settings, updateProgres); await slice(action, name, exportMesh, settings, updateProgres);
} catch (error) { } catch (error) {
this.setState({ error: error.message }); this.setState({ error: error.message });
throw error; throw error;
@ -333,7 +341,7 @@ class Interface extends React.Component {
} }
render() { render() {
const { classes, onCancel, selectedPrinter } = this.props; const { classes, onCancel, selectedPrinter, actions } = this.props;
const { isSlicing, progress, showFullScreen, error, objectDimensions, settings } = this.state; const { isSlicing, progress, showFullScreen, error, objectDimensions, settings } = this.state;
const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) }; const style = { ...(showFullScreen ? {} : { maxWidth: 'inherit', width: '100%', height: '100%' }) };
@ -361,26 +369,39 @@ class Interface extends React.Component {
<MalyanControl ip={settings.ip} /> : <MalyanControl ip={settings.ip} /> :
<WifiBoxControl ip={settings.ip} /> <WifiBoxControl ip={settings.ip} />
) */} ) */}
<RaisedButton {actions.length === 1 ? (
label="Print" <RaisedButton
ref="button" primary
primary label={actions[0].title}
className={`${classes.button}`} onTouchTap={() => this.slice(actions[0])}
onTouchTap={this.openPopover} className={`${classes.button}`}
disabled={isSlicing} disabled={isSlicing}
/> />
<Popover ) : (
open={this.state.popover.open} <span>
anchorEl={this.state.popover.element} <RaisedButton
anchorOrigin={{horizontal: 'left', vertical: 'bottom'}} label="Print"
targetOrigin={{horizontal: 'left', vertical: 'bottom'}} ref="button"
onRequestClose={this.closePopover} primary
> className={`${classes.button}`}
<Menu> onTouchTap={this.openPopover}
<MenuItem disabled={!Boolean(settings && settings.ip)} primaryText="Send over WiFi" onTouchTap={() => this.slice('WIFI')} /> disabled={isSlicing}
<MenuItem primaryText="Download GCode" onTouchTap={() => this.slice('DOWNLOAD')} /> />
</Menu> <Popover
</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>
{actions.map((action) => (
<MenuItem key={action.type} primaryText={action.title} onTouchTap={() => this.slice(action)} />
))}
</Menu>
</Popover>
</span>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -143,15 +143,15 @@ export function sleep(time) {
const GCODE_SERVER_URL = 'https://gcodeserver.doodle3d.com'; const GCODE_SERVER_URL = 'https://gcodeserver.doodle3d.com';
export async function slice(target, name, mesh, settings, updateProgress) { export async function slice(action, name, mesh, settings, updateProgress) {
let steps; let steps;
let currentStep = 0; let currentStep = 0;
let wifiBox; let wifiBox;
switch (target) { switch (action.target) {
case 'DOWNLOAD': case 'DOWNLOAD':
steps = 1; steps = 1;
break; break;
case 'WIFI': case 'WIFI_PRINT':
if (settings.printer === 'doodle3d_printer') { if (settings.printer === 'doodle3d_printer') {
const { state } = await getMalyanStatus(settings.ip); const { state } = await getMalyanStatus(settings.ip);
if (state !== 'idle') throw { message: 'printer is busy', code: 0 }; if (state !== 'idle') throw { message: 'printer is busy', code: 0 };
@ -165,6 +165,9 @@ export async function slice(target, name, mesh, settings, updateProgress) {
} }
steps = 2; steps = 2;
break; break;
case 'CUSTOM_UPLOAD':
steps = 2;
break;
default: default:
throw { message: 'unknown target', code: 1 }; throw { message: 'unknown target', code: 1 };
break; break;
@ -185,14 +188,14 @@ export async function slice(target, name, mesh, settings, updateProgress) {
}); });
currentStep ++; currentStep ++;
switch (target) { switch (action.target) {
case 'DOWNLOAD': { case 'DOWNLOAD': {
const file = new Blob([gcode], { type: 'text/plain' }); const file = new Blob([gcode], { type: 'text/plain' });
fileSaver.saveAs(file, `${name}.gcode`); fileSaver.saveAs(file, `${name}.gcode`);
break; break;
} }
case 'WIFI': { case 'WIFI_PRINT': {
if (settings.printer === 'doodle3d_printer') { if (settings.printer === 'doodle3d_printer') {
const body = new FormData(); const body = new FormData();
const file = new Blob([gcode], { type: 'plain/text' }); const file = new Blob([gcode], { type: 'plain/text' });
@ -251,6 +254,25 @@ export async function slice(target, name, mesh, settings, updateProgress) {
} }
break; break;
} }
case 'CUSTOM_UPLOAD': {
const body = new FormData();
const file = new Blob([`;${JSON.stringify({
...settings,
name: `${name}.gcode`,
printer: { type: settings.printers, title: printerSettings[settings.printer].title },
material: { type: settings.material, title: materialSettings[settings.material].title },
quality: { type: settings.quality, title: qualitySettings[settings.quality].title }
}).trim()}\n${gcode}`]);
body.append('file', file, 'doodle.gcode');
await fetchProgress(action.url, { method: 'POST', body }, progress => {
updateProgress({
action: 'Uploading',
percentage: (currentStep + progress.loaded / progress.total) / steps
});
});
currentStep ++;
}
default: default:
throw { message: 'unknown target', code: 1 }; throw { message: 'unknown target', code: 1 };