Fiddle use cases fixed

Handle use cases:

1) handle case when temp.sol doesn’t exist - due to the new saga updates, the response from retreiving a temp fiddle from the filesystem (even if it doesn’t exist) is forward to the compilation endpoint, which returns an ENOENT, and this is handled in the selector.
2) delete all code - shouldn’t return last fiddle and should compile an empty string.
3) Switch to different tab (ie contracts) then back to fiddle - previous fiddle should remain.

Also fixed an issue (most likely due to latest rebase) when deploying fiddle contracts. The gasLimit was not being specified.

Handled issue where entities stored in the state were not being put in the correct order, so a timestamp was sent with the requests and then sorted when the response was returned.
This commit is contained in:
emizzle 2018-08-29 16:12:28 +10:00 committed by Pascal Precht
parent 4ecb092ed3
commit 05b324dffe
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
7 changed files with 29 additions and 20 deletions

View File

@ -170,7 +170,7 @@ export const ensRecords = {
export const FIDDLE = createRequestTypes('FIDDLE'); export const FIDDLE = createRequestTypes('FIDDLE');
export const fiddle = { export const fiddle = {
post: (codeToCompile) => action(FIDDLE[REQUEST], {codeToCompile}), post: (codeToCompile, timestamp) => action(FIDDLE[REQUEST], {codeToCompile, timestamp}),
success: (fiddle, payload) => { success: (fiddle, payload) => {
return action(FIDDLE[SUCCESS], {fiddles: [{...fiddle, ...payload}]}); return action(FIDDLE[SUCCESS], {fiddles: [{...fiddle, ...payload}]});
}, },

View File

@ -4,7 +4,7 @@ import constants from '../constants';
function get(path, params) { function get(path, params) {
return axios.get(constants.httpEndpoint + path, params) return axios.get(constants.httpEndpoint + path, params)
.then((response) => { .then((response) => {
return {response}; return {response, error: null};
}).catch((error) => { }).catch((error) => {
return {response: null, error: error.message || 'Something bad happened'}; return {response: null, error: error.message || 'Something bad happened'};
}); });
@ -13,7 +13,7 @@ function get(path, params) {
function post(path, params) { function post(path, params) {
return axios.post(constants.httpEndpoint + path, params) return axios.post(constants.httpEndpoint + path, params)
.then((response) => { .then((response) => {
return {response}; return {response, error: null};
}) })
.catch((error) => { .catch((error) => {
return {response: null, error: error.message || 'Something bad happened'}; return {response: null, error: error.message || 'Something bad happened'};

View File

@ -22,6 +22,7 @@ class FiddleContainer extends Component {
this.state = { this.state = {
value: undefined, value: undefined,
loadingMessage: 'Loading...', loadingMessage: 'Loading...',
readOnly: true readOnly: true
}; };
this.compileTimeout = null; this.compileTimeout = null;
@ -31,24 +32,24 @@ class FiddleContainer extends Component {
componentDidMount() { componentDidMount() {
this.setState({loadingMessage: 'Loading saved state...'}); this.setState({loadingMessage: 'Loading saved state...'});
if (!this.props.fiddle) { this.props.fetchLastFiddle();
this.props.fetchLastFiddle(); }
componentDidUpdate(prevProps) {
const {lastFiddle} = this.props;
if(this.state.value === '' && prevProps.lastFiddle === lastFiddle) return;
if((!this.state.value && lastFiddle && !lastFiddle.error) && this.state.value !== lastFiddle) {
this._onCodeChange(lastFiddle, true);
} }
} }
componentDidUpdate() { _onCodeChange(newValue, immediate = false) {
if(!this.state.value && this.props.fiddle) {
this.setState({value: this.props.fiddle.codeToCompile});
}
}
_onCodeChange(newValue) {
this.setState({readOnly: false, value: newValue}); this.setState({readOnly: false, value: newValue});
if (this.compileTimeout) clearTimeout(this.compileTimeout); if (this.compileTimeout) clearTimeout(this.compileTimeout);
this.compileTimeout = setTimeout(() => { this.compileTimeout = setTimeout(() => {
this.setState({loadingMessage: 'Compiling...'}); this.setState({loadingMessage: 'Compiling...'});
this.props.postFiddle(newValue); this.props.postFiddle(newValue, Date.now());
}, 1000); }, immediate ? 0 : 1000);
} }
@ -166,7 +167,8 @@ function mapStateToProps(state) {
deployedContracts: deployedFiddle.data, deployedContracts: deployedFiddle.data,
fiddleError: fiddle.error, fiddleError: fiddle.error,
fiddleDeployError: deployedFiddle.error, fiddleDeployError: deployedFiddle.error,
loading: state.loading loading: state.loading,
lastFiddle: fiddle.data ? fiddle.data.codeToCompile : undefined
}; };
} }
@ -178,7 +180,8 @@ FiddleContainer.propTypes = {
postFiddle: PropTypes.func, postFiddle: PropTypes.func,
postFiddleDeploy: PropTypes.func, postFiddleDeploy: PropTypes.func,
deployedContracts: PropTypes.string, deployedContracts: PropTypes.string,
fetchLastFiddle: PropTypes.func fetchLastFiddle: PropTypes.func,
lastFiddle: PropTypes.any
}; };
export default connect( export default connect(

View File

@ -22,7 +22,8 @@
} }
.text__new-line, .card.warnings-card .list-group-item, .card.errors-card .list-group-item { .text__new-line, .card.warnings-card .list-group-item, .card.errors-card .list-group-item {
white-space: pre-line; white-space: pre-wrap;
font-family: monospace;
} }
.card.card-fullscreen{ .card.card-fullscreen{
z-index: 6; z-index: 6;

View File

@ -109,9 +109,11 @@ export function getMessages(state) {
} }
export function getFiddle(state) { export function getFiddle(state) {
const fiddleCompilation = _.last(state.entities.fiddles.sort((a, b) => { return (a.timestamp || 0) - (b.timestamp || 0); }));
const isNoTempFileError = Boolean(fiddleCompilation && fiddleCompilation.codeToCompile && fiddleCompilation.codeToCompile.error && fiddleCompilation.codeToCompile.error.indexOf('ENOENT') > -1);
return { return {
data: _.last(state.entities.fiddles), data: fiddleCompilation,
error: state.errorEntities.fiddles error: isNoTempFileError ? undefined : state.errorEntities.fiddles
}; };
} }

View File

@ -199,7 +199,7 @@ class ContractDeployer {
// TODO: can be moved into a afterDeploy event // TODO: can be moved into a afterDeploy event
// just need to figure out the gasLimit coupling issue // just need to figure out the gasLimit coupling issue
self.events.request('code-generator:contract:vanilla', contract, contract._gasLimit, (contractCode) => { self.events.request('code-generator:contract:vanilla', contract, contract._gasLimit || false, (contractCode) => {
self.events.request('runcode:eval', contractCode, () => {}, true); self.events.request('runcode:eval', contractCode, () => {}, true);
return callback(); return callback();
}); });

View File

@ -20,6 +20,9 @@ class Solidity {
'post', 'post',
'/embark-api/contract/compile', '/embark-api/contract/compile',
(req, res) => { (req, res) => {
if(typeof req.body.codeToCompile !== 'string'){
return res.send({error: 'Body parameter \'codeToCompile\' must be a string'});
}
const input = {'fiddle': {content: req.body.codeToCompile.replace(/\r\n/g, '\n')}}; const input = {'fiddle': {content: req.body.codeToCompile.replace(/\r\n/g, '\n')}};
this.compile_solidity_code(input, {}, true, (errors, compilationResult) => { this.compile_solidity_code(input, {}, true, (errors, compilationResult) => {
// write code to filesystem so we can view the source after page refresh // write code to filesystem so we can view the source after page refresh