Skip to content

V2 #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Apr 5, 2019
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ daemon.downloading.subscribe(download => {

```

## Version 2

Version 2 of the arduino-create-agent aims to provide a cleaner api based on promises.
It will remain confined to a v2 property on the daemon object until it will be stable.
At the moment it only supports tool management.

```js
daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
// Your Agent doesn't support v2
}
// Your Agent supports v2
});

daemon.v2.installedTools()
.then(tools => console.debug(tools)) // [{"name":"avrdude","version":"6.3.0-arduino9","packager":"arduino"}]

let payload = {
name: 'avrdude',
version: '6.3.0-arduino9',
packager: 'arduino',
url: 'http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-i686-w64-mingw32.zip',
checksum: 'SHA-256:f3c5cfa8d0b3b0caee81c5b35fb6acff89c342ef609bf4266734c6266a256d4f',
signature: '7628b488c7ffd21ae1ca657245751a4043c419fbab5c256a020fb53f17eb88686439f54f18e78a80b40fc2de742f79b78ed4338c959216dc8ae8279e482d2d4117eeaf34a281ce2369d1dc4356f782c0940d82610f1c892e913b637391c39e95d4d4dfe82d8dbc5350b833186a70a62c7952917481bad798a9c8b4905df91bd914fbdfd6e98ef75c8f7fb06284278da449ce05b27741d6eda156bbdb906d519ff7d7d5042379fdfc55962b3777fb9240b368552182758c297e39c72943d75d177f2dbb584b2210301250796dbe8af11f0cf06d762fe4f912294f4cdc8aff26715354cfb33010a81342fbbc438912eb424a39fc0c52a9b2bf722051a6f3b024bd'
}
daemon.v2.installTool(payload) // Will install the tool in the system
```

## Development and test features
Just run `npm run dev` and open your browser on http://localhost:8000

Expand Down
43 changes: 23 additions & 20 deletions demo/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import React from 'react';
import Daemon from '../src';

import { HEX } from './serial_mirror';
import V2 from './v2/v2.jsx';

const chromeExtensionID = 'hfejhkbipnickajaidoppbadcomekkde';

Expand Down Expand Up @@ -173,11 +174,11 @@ class App extends React.Component {
{device.Name} - IsOpen: <span className={device.IsOpen ? 'open' : 'closed'}>
{device.IsOpen ? 'true' : 'false'}
</span> - <a href="#" onClick={(e) => this.handleOpen(e, device.Name)}>
open
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matteosuppo pleeease, don't modify the formatting 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry vscode decided it was better that way. I didn't even notice. Should I put it the way it was?

Copy link
Contributor

@AlbyIanna AlbyIanna Apr 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, vscode has its own will sometimes. Yes please 👍

open
</a> - <a href="#" onClick={(e) => this.handleClose(e, device.Name)}>
close
close
</a> - <a href="#" onClick={(e) => handleBootloaderMode(e, device.Name)}>
bootloader mode
bootloader mode
</a>
</li>);

Expand All @@ -186,7 +187,7 @@ class App extends React.Component {
</li>);

const supportedBoards = this.state.supportedBoards.map((board, i) => <li key={i}>
{ board }
{board}
</li>);

let uploadClass;
Expand All @@ -213,24 +214,26 @@ class App extends React.Component {

return (
<div>
<V2 daemon={daemon}></V2>

<h1>Arduino Create Plugin Client Demo</h1>

<div className="section">
<h2>Plugin info</h2>

<p>
Agent status: <span className={ this.state.agentStatus ? 'found' : 'not-found' }>
{ this.state.agentStatus ? 'Found' : 'Not found' }
Agent status: <span className={this.state.agentStatus ? 'found' : 'not-found'}>
{this.state.agentStatus ? 'Found' : 'Not found'}
</span>
</p>
<p>
Channel status: <span className={ this.state.channelStatus ? 'found' : 'not-found' }>
{ this.state.channelStatus ? 'Connected' : 'Not connected' }
Channel status: <span className={this.state.channelStatus ? 'found' : 'not-found'}>
{this.state.channelStatus ? 'Connected' : 'Not connected'}
</span>
</p>

<pre>
{ this.state.agentInfo }
{this.state.agentInfo}
</pre>
</div>

Expand All @@ -239,12 +242,12 @@ class App extends React.Component {

<strong>serial:</strong>
<ul>
{ listSerialDevices }
{listSerialDevices}
</ul>

<strong>network:</strong>
<ul>
{ listNetworkDevices }
{listNetworkDevices}
</ul>

<p id="error"></p>
Expand All @@ -266,20 +269,20 @@ class App extends React.Component {
<h2>Serial Monitor</h2>

<form onSubmit={this.handleSend}>
<input id="serial-input" value={this.state.serialInput} onChange={this.handleChangeSerial}/>
<input id="serial-input" value={this.state.serialInput} onChange={this.handleChangeSerial} />
<input type="submit" value="Send" />
</form>

<textarea id="serial-textarea" value={ this.state.serialMonitorContent } readOnly/>
<textarea id="serial-textarea" value={this.state.serialMonitorContent} readOnly />
</div>

<div className="section">
<h2>Upload a sample sketch on a MKR1000 at /dev/ttyACM0</h2>
<button onClick={ handleUpload } disabled={ this.state.uploadStatus === daemon.UPLOAD_IN_PROGRESS }>Upload Sketch</button><br/>
<div>Upload status: <span className={ uploadClass }> { this.state.uploadStatus }</span> <span>{ this.state.uploadError }</span></div>
<button onClick={handleUpload} disabled={this.state.uploadStatus === daemon.UPLOAD_IN_PROGRESS}>Upload Sketch</button><br />
<div>Upload status: <span className={uploadClass}> {this.state.uploadStatus}</span> <span>{this.state.uploadError}</span></div>
</div>

{ daemon.downloading ? <div className="section">
{daemon.downloading ? <div className="section">
<h2>Download tool (not supported on Chrome OS)</h2>

<div>
Expand All @@ -300,19 +303,19 @@ class App extends React.Component {
</div>

<form onSubmit={handleDownloadTool}>
<div><input id="toolname" placeholder="Tool Name"/></div>
<div><input id="toolname" placeholder="Tool Name" /></div>
<div><input id="toolversion" placeholder="Tool Version" /></div>
<div><input id="package" placeholder="Package" /></div>
<div><input id="replacement" placeholder="Replacement strategy"/></div>
<div><input id="replacement" placeholder="Replacement strategy" /></div>

<input type="submit" value="Download" />
<div>Download status: <span className={ downloadClass }> { this.state.downloadStatus }</span></div>
<div>Download status: <span className={downloadClass}> {this.state.downloadStatus}</span></div>
</form>
</div> : null}

<div className="section">
<h2>Errors</h2>
<div className="error">{ this.state.error }</div>
<div className="error">{this.state.error}</div>
</div>
</div>
);
Expand Down
37 changes: 33 additions & 4 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
-->

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Expand All @@ -26,15 +27,20 @@
<style>
body {
color: #2c353a;
font-family: Lucida Grande,Lucida,Verdana,sans-serif;
font-family: Lucida Grande, Lucida, Verdana, sans-serif;
padding: 15px;
}

#error, .not-found, .closed, .error {
#error,
.not-found,
.closed,
.error {
color: red
}

.found, .open, .success {
.found,
.open,
.success {
color: green;
}

Expand All @@ -53,9 +59,32 @@
.section {
margin: 20px;
}
.install-tool-container .tool-input {
display: flex;
margin: 10px 0;
}

.install-tool-container .tool-input label {
flex: 0 1 200px;
}

.install-tool-container .tool-input input {
flex: 0 1 500px;
}

table {
border-collapse: collapse;
}

table td {
border: 1px solid black;
padding: 3px;
}
</style>
</head>

<body>
<div id="root"></div>
</body>
</html>

</html>
107 changes: 107 additions & 0 deletions demo/v2/install_tool.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React from 'react';
import { flatMap } from 'rxjs/operators';

export class V2InstallTool extends React.Component {
constructor() {
super();
this.state = {
name: 'avrdude',
version: '6.3.0-arduino9',
packager: 'arduino',
url: 'http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-i686-w64-mingw32.zip',
checksum: 'SHA-256:f3c5cfa8d0b3b0caee81c5b35fb6acff89c342ef609bf4266734c6266a256d4f',
signature: '7628b488c7ffd21ae1ca657245751a4043c419fbab5c256a020fb53f17eb88686439f54f18e78a80b40fc2de742f79b78ed4338c959216dc8ae8279e482d2d4117eeaf34a281ce2369d1dc4356f782c0940d82610f1c892e913b637391c39e95d4d4dfe82d8dbc5350b833186a70a62c7952917481bad798a9c8b4905df91bd914fbdfd6e98ef75c8f7fb06284278da449ce05b27741d6eda156bbdb906d519ff7d7d5042379fdfc55962b3777fb9240b368552182758c297e39c72943d75d177f2dbb584b2210301250796dbe8af11f0cf06d762fe4f912294f4cdc8aff26715354cfb33010a81342fbbc438912eb424a39fc0c52a9b2bf722051a6f3b024bd',
res: ''
};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

componentDidMount() {
this.daemon = this.props.daemon;

this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
});
}

handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}

handleSubmit(event) {
event.preventDefault();

this.daemonV2.installTool({
name: this.state.name,
version: this.state.version,
packager: this.state.packager,
checksum: this.state.checksum,
signature: this.state.signature,
url: this.state.url,

})
.then(res => {
this.setState({
res: JSON.stringify(res, null, 2)
});
})
.catch(err => {
this.setState({
res: JSON.stringify(err, null, 2)
});
});
}

render() {
return (
<section className="install-tool-container">
<h2>Install a new tool</h2>
<form onSubmit={this.handleSubmit}>
<div className="tool-input">
<label for="name">
Name:
</label>
<input type="text" name="name" value={this.state.name} onChange={this.handleChange} />
</div>
<div className="tool-input">
<label for="version">
Version:
</label>
<input type="text" name="version" value={this.state.version} onChange={this.handleChange} />
</div>
<div className="tool-input">
<label for="packager">
Packager:
</label>
<input type="text" name="packager" value={this.state.packager} onChange={this.handleChange} />
</div>
<div className="tool-input">
<label for="url">
Url:
</label>
<input type="text" name="url" value={this.state.url} onChange={this.handleChange} />
</div>
<div className="tool-input">
<label for="checksum">
Checksum:
</label>
<input type="text" name="checksum" value={this.state.checksum} onChange={this.handleChange} />
</div>
<div className="tool-input">
<label for="signature">
Signature:
</label>
<input type="text" name="signature" value={this.state.signature} onChange={this.handleChange} />
</div>
<input type="submit" value="Submit" />
</form>
<textarea cols="100" rows="10" value={this.state.res} readOnly></textarea>
</section>
);
}
}
60 changes: 60 additions & 0 deletions demo/v2/v2.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import { V2InstallTool } from './install_tool.jsx';

class V2 extends React.Component {
constructor() {
super();
this.state = {
tools: []
};
}

componentDidMount() {
this.daemon = this.props.daemon;

this.daemon.agentV2Found.subscribe(daemonV2 => {
if (!daemonV2) {
return;
}
this.daemonV2 = daemonV2;
this.daemonV2.installedTools().then(res => {
this.setState({
tools: res
});
});
});
}

render() {
const tools = this.state.tools.map((tool, i) => <tr key={i}>
<td>{tool.packager}</td>
<td>{tool.name}</td>
<td>{tool.version}</td>
</tr>);

return (
<section>
<h2>V2</h2>
<section>
<h3>Installed tools</h3>
<form onSubmit={this.handleInstallTool}>
<table>
<thead>
<tr>
<th>Packager</th>
<th>Name</th>
<th>Version</th>
</tr>
</thead>
<tbody>{tools}</tbody>
</table>
</form>

<V2InstallTool daemon={this.props.daemon}></V2InstallTool>
</section>
</section >
);
}
}

export default V2;
Loading