2017-06-13 18:40:05 -06:00
|
|
|
import React, {Component} from 'react';
|
|
|
|
import { StyleSheet, css } from 'aphrodite/no-important';
|
|
|
|
import PropTypes from 'prop-types';
|
2017-06-21 19:11:04 -06:00
|
|
|
import FileSaver from 'file-saver';
|
2017-06-13 18:40:05 -06:00
|
|
|
|
|
|
|
import OpenDbc from '../api/opendbc';
|
|
|
|
import DBC from '../models/can/dbc';
|
|
|
|
import Modal from './Modal';
|
2017-06-21 19:11:04 -06:00
|
|
|
import TabStyles from '../styles/modal-tabs';
|
2017-06-13 18:40:05 -06:00
|
|
|
|
|
|
|
export default class SaveDbcModal extends Component {
|
|
|
|
static propTypes = {
|
|
|
|
dbc: PropTypes.instanceOf(DBC).isRequired,
|
|
|
|
sourceDbcFilename: PropTypes.string.isRequired,
|
|
|
|
onCancel: PropTypes.func.isRequired,
|
2017-06-28 21:28:39 -06:00
|
|
|
onDbcSaved: PropTypes.func.isRequired,
|
2017-06-30 22:27:04 -06:00
|
|
|
openDbcClient: PropTypes.instanceOf(OpenDbc).isRequired,
|
|
|
|
hasGithubAuth: PropTypes.bool.isRequired,
|
|
|
|
loginWithGithub: PropTypes.element.isRequired
|
2017-06-13 18:40:05 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
2017-06-21 19:11:04 -06:00
|
|
|
tab: 'GitHub',
|
2017-06-13 18:40:05 -06:00
|
|
|
openDbcFork: null,
|
|
|
|
dbcFilename: this.props.sourceDbcFilename
|
|
|
|
};
|
|
|
|
|
|
|
|
this.onContinue = this.onContinue.bind(this);
|
|
|
|
this.forkOpenDbcAndWait = this.forkOpenDbcAndWait.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
async componentWillMount() {
|
2017-06-28 21:28:39 -06:00
|
|
|
const openDbcFork = await this.props.openDbcClient.getUserOpenDbcFork();
|
2017-06-13 18:40:05 -06:00
|
|
|
this.setState({openDbcFork})
|
|
|
|
}
|
|
|
|
|
|
|
|
async onContinue() {
|
2017-06-21 19:11:04 -06:00
|
|
|
const {tab} = this.state;
|
|
|
|
if(tab === 'GitHub') {
|
|
|
|
const {openDbcFork, dbcFilename} = this.state;
|
2017-06-28 21:28:39 -06:00
|
|
|
const filename = this.state.dbcFilename.replace(/\.dbc/g, '') + '.dbc';
|
|
|
|
const success = await this.props.openDbcClient.commitFile(openDbcFork,
|
|
|
|
filename,
|
2017-06-21 19:11:04 -06:00
|
|
|
this.props.dbc.text());
|
|
|
|
if(success) {
|
2017-06-28 21:28:39 -06:00
|
|
|
this.props.onDbcSaved(filename);
|
2017-06-21 19:11:04 -06:00
|
|
|
}
|
|
|
|
} else if(tab === 'Download') {
|
|
|
|
const blob = new Blob([this.props.dbc.text()], {type: "text/plain;charset=utf-8"});
|
2017-06-28 21:28:39 -06:00
|
|
|
|
|
|
|
|
|
|
|
const filename = this.state.dbcFilename.replace(/\.dbc/g, '') + '.dbc';
|
|
|
|
FileSaver.saveAs(blob, filename, true);
|
2017-06-13 18:40:05 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async forkOpenDbcAndWait() {
|
2017-06-28 21:28:39 -06:00
|
|
|
const forkResponseSuccess = await this.props.openDbcClient.fork();
|
2017-06-13 18:40:05 -06:00
|
|
|
if(forkResponseSuccess) {
|
|
|
|
let isTimedOut = false;
|
|
|
|
const interval = window.setInterval(() => {
|
|
|
|
if(!isTimedOut) {
|
2017-06-28 21:28:39 -06:00
|
|
|
this.props.openDbcClient.getUserOpenDbcFork().then((openDbcFork) => {
|
2017-06-13 18:40:05 -06:00
|
|
|
if(openDbcFork !== null) {
|
|
|
|
this.setState({openDbcFork});
|
|
|
|
window.clearInterval(interval);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
window.clearInterval(interval);
|
|
|
|
}
|
|
|
|
}, 3000);
|
|
|
|
|
|
|
|
const timeout = window.setTimeout(() => {
|
|
|
|
isTimedOut = true;
|
|
|
|
}, 30000);
|
|
|
|
} else {
|
|
|
|
// fork failed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
forkStep() {
|
|
|
|
const {openDbcFork} = this.state;
|
|
|
|
let content;
|
|
|
|
if(openDbcFork !== null) {
|
2017-06-21 00:01:41 -06:00
|
|
|
content = <p>Done! {openDbcFork}</p>;
|
2017-06-30 22:27:04 -06:00
|
|
|
} else if(this.props.hasGithubAuth) {
|
2017-06-21 00:01:41 -06:00
|
|
|
content = <p className={css(Styles.pointer, Styles.forkOpenDbc)}
|
2017-06-13 18:40:05 -06:00
|
|
|
onClick={this.forkOpenDbcAndWait}>Fork OpenDBC</p>;
|
2017-06-30 22:27:04 -06:00
|
|
|
} else {
|
|
|
|
content = this.props.loginWithGithub;
|
2017-06-13 18:40:05 -06:00
|
|
|
}
|
2017-06-21 00:01:41 -06:00
|
|
|
return (<div className={css(Styles.step, (openDbcFork !== null ? Styles.stepDone : null))}>
|
|
|
|
{openDbcFork !== null ? <p>Fork OpenDBC</p> : null}
|
2017-06-13 18:40:05 -06:00
|
|
|
{content}
|
|
|
|
</div>);
|
|
|
|
}
|
|
|
|
|
|
|
|
nameStep() {
|
|
|
|
return (<div className={css(Styles.step)}>
|
|
|
|
<p>Choose a filename</p>
|
|
|
|
<input type="text"
|
2017-06-28 21:28:39 -06:00
|
|
|
value={this.state.dbcFilename.replace(/\.dbc/g, '')}
|
2017-06-29 18:04:40 -06:00
|
|
|
size={this.state.dbcFilename.length + 2}
|
2017-06-13 18:40:05 -06:00
|
|
|
onChange={(e) =>
|
|
|
|
this.setState({dbcFilename: e.target.value})} />
|
2017-06-28 21:28:39 -06:00
|
|
|
<span className={css(Styles.fileExtension)}>.dbc</span>
|
2017-06-13 18:40:05 -06:00
|
|
|
</div>);
|
|
|
|
}
|
|
|
|
|
2017-06-21 19:11:04 -06:00
|
|
|
tabContent() {
|
|
|
|
const {tab} = this.state;
|
|
|
|
if(tab === 'GitHub') {
|
|
|
|
return (<div><p>Save your DBC modificiations to GitHub</p>
|
|
|
|
{this.forkStep()}
|
|
|
|
{this.nameStep()}</div>);
|
|
|
|
} else if(tab === 'Download') {
|
|
|
|
return (<div>
|
|
|
|
<p>Download your DBC</p>
|
|
|
|
{this.nameStep()}
|
|
|
|
</div>);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tab(tabName) {
|
|
|
|
return <p className={css(TabStyles.tab, this.state.tab === tabName ? TabStyles.selectedTab : null)}
|
|
|
|
onClick={() => {this.setState({tab: tabName})}}>
|
|
|
|
{tabName}
|
|
|
|
</p>
|
|
|
|
}
|
|
|
|
|
|
|
|
continueText() {
|
|
|
|
const {tab} = this.state;
|
|
|
|
if(tab === 'GitHub'){
|
|
|
|
return "Commit to GitHub";
|
|
|
|
} else if(tab === 'Download') {
|
|
|
|
return "Download";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
continueEnabled() {
|
|
|
|
const {tab} = this.state;
|
|
|
|
if(tab === 'GitHub') {
|
|
|
|
return this.state.openDbcFork != null
|
|
|
|
&& this.state.dbcFilename.length > 0
|
|
|
|
} else if(tab === 'Download') {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-13 18:40:05 -06:00
|
|
|
render() {
|
|
|
|
return (<Modal title={"Save DBC"}
|
2017-06-21 19:11:04 -06:00
|
|
|
continueText={this.continueText()}
|
|
|
|
continueEnabled={this.continueEnabled()}
|
2017-06-13 18:40:05 -06:00
|
|
|
onCancel={this.props.onCancel}
|
|
|
|
onContinue={this.onContinue}>
|
2017-06-21 19:11:04 -06:00
|
|
|
<div className={css(TabStyles.tabs)}>
|
|
|
|
{this.tab('GitHub')}
|
|
|
|
{this.tab('Download')}
|
|
|
|
</div>
|
2017-06-25 19:34:42 -06:00
|
|
|
<div className={css(TabStyles.tabContent)}>
|
|
|
|
{this.tabContent()}
|
|
|
|
</div>
|
2017-06-13 18:40:05 -06:00
|
|
|
</Modal>);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const Styles = StyleSheet.create({
|
|
|
|
step: {
|
|
|
|
borderBottom: '1px solid rgba(0,0,0,0.2)',
|
2017-06-21 00:01:41 -06:00
|
|
|
flexDirection: 'row',
|
|
|
|
paddingTop: 10,
|
|
|
|
paddingBottom: 10
|
|
|
|
},
|
|
|
|
stepDone: {
|
|
|
|
color: 'rgb(200,200,200)'
|
|
|
|
},
|
|
|
|
forkOpenDbc: {
|
|
|
|
':hover': {
|
|
|
|
textDecoration: 'underline'
|
|
|
|
}
|
2017-06-13 18:40:05 -06:00
|
|
|
},
|
|
|
|
pointer: {
|
|
|
|
cursor: 'pointer'
|
|
|
|
}
|
|
|
|
});
|