Add/remove breakpoints

This commit is contained in:
Anthony Laibe 2018-10-18 11:09:03 +01:00 committed by Pascal Precht
parent 60a5f52e16
commit fb29e5a7c8
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
5 changed files with 76 additions and 11 deletions

View File

@ -399,4 +399,12 @@ export function updateBaseEther(value) {
};
}
export const TOGGLE_BREAKPOINT = 'TOGGLE_BREAKPOINT';
export function toggleBreakpoint(filename, lineNumber) {
return {
type: TOGGLE_BREAKPOINT,
payload: {filename, lineNumber}
};
}

View File

@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
const SUPPORTED_LANGUAGES = ['css', 'sol', 'html', 'json'];
const DEFAULT_LANGUAGE = 'javascript';
const EDITOR_ID = 'react-monaco-editor-container';
const GUTTER_GLYPH_MARGIN = 3;
let editor;
@ -14,6 +15,7 @@ const initMonaco = (value) => {
model = editor.getModel()
}
editor = monaco.editor.create(document.getElementById(EDITOR_ID), {
glyphMargin: true,
value,
model
});
@ -21,6 +23,10 @@ const initMonaco = (value) => {
};
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = {decorations: []};
}
componentDidMount() {
initMonaco();
editor.onDidChangeModelContent((event) => {
@ -29,6 +35,12 @@ class TextEditor extends React.Component {
});
editor.layout();
window.addEventListener('resize', this.handleResize);
editor.onMouseDown((e) => {
if (e.target.type === GUTTER_GLYPH_MARGIN){
this.props.toggleBreakpoint(this.props.file.name, e.target.position.lineNumber);
}
});
}
handleResize = () => editor.layout();
@ -71,12 +83,28 @@ class TextEditor extends React.Component {
}
}
updateBreakpoints() {
const decorations = editor.deltaDecorations(this.state.decorations, this.props.breakpoints.map(breakpoint => (
{
range: new monaco.Range(breakpoint,1,breakpoint,1),
options: {
isWholeLine: true,
glyphMarginClassName: 'bg-primary rounded-circle'
}
}
)));
this.setState({decorations: decorations});
}
componentDidUpdate(prevProps) {
if (this.props.file.content !== prevProps.file.content) {
editor.setValue(this.props.file.content);
}
this.updateMarkers();
if (this.props.breakpoints.length !== this.state.decorations.length) {
this.updateBreakpoints();
}
this.updateLanguage();
}
@ -92,7 +120,9 @@ class TextEditor extends React.Component {
TextEditor.propTypes = {
onFileContentChange: PropTypes.func,
file: PropTypes.object,
contractCompile: PropTypes.object
contractCompile: PropTypes.object,
toggleBreakpoint: PropTypes.func,
breakpoints: PropTypes.array
};
export default TextEditor;

View File

@ -13,9 +13,10 @@ import {
saveFile as saveFileAction,
removeFile as removeFileAction,
contractCompile as contractCompileAction,
contractDeploy as postContractDeploy
contractDeploy as postContractDeploy,
toggleBreakpoint,
} from '../actions';
import {getCurrentFile, getContractCompile, getContractDeploys} from '../reducers/selectors';
import {getCurrentFile, getContractCompile, getContractDeploys, getBreakpointsByFilename} from '../reducers/selectors';
class TextEditorContainer extends Component {
constructor(props) {
@ -100,6 +101,8 @@ class TextEditorContainer extends Component {
return (
<TextEditor file={this.state.currentFile}
contractCompile={this.props.contractCompile}
breakpoints={this.props.breakpoints}
toggleBreakpoint={this.props.toggleBreakpoint}
onFileContentChange={(newContent) => this.onFileContentChange(newContent)} />
);
}
@ -110,13 +113,15 @@ function mapStateToProps(state, props) {
const contractCompile = getContractCompile(state, currentFile) || {};
const contractName = contractCompile.result && Object.keys(contractCompile.result)[0];
const contractDeploys = getContractDeploys(state, contractName);
const breakpoints = getBreakpointsByFilename(state, currentFile.name);
return {
compilingContract: state.compilingContract,
loading: state.loading,
error: state.errorMessage,
currentFile,
contractCompile,
compilingContract: state.compilingContract,
contractDeploys,
loading: state.loading,
error: state.errorMessage
breakpoints,
};
}
@ -133,7 +138,9 @@ TextEditorContainer.propTypes = {
compilingContract: PropTypes.bool,
contractDeploys: PropTypes.array,
loading: PropTypes.bool,
error: PropTypes.string
error: PropTypes.string,
toggleBreakpoints: PropTypes.func,
breakpoints: PropTypes.array,
};
export default connect(
@ -144,6 +151,7 @@ export default connect(
saveFile: saveFileAction.request,
removeFile: removeFileAction.request,
postContractDeploy: postContractDeploy.post,
compileContract: contractCompileAction.post
compileContract: contractCompileAction.post,
toggleBreakpoint,
},
)(TextEditorContainer);

View File

@ -1,7 +1,7 @@
import {combineReducers} from 'redux';
import {REQUEST, SUCCESS, FAILURE, CONTRACT_COMPILE, FILES, LOGOUT, AUTHENTICATE,
FETCH_CREDENTIALS, UPDATE_BASE_ETHER, CHANGE_THEME, FETCH_THEME, EXPLORER_SEARCH,
SIGN_MESSAGE, VERIFY_MESSAGE} from "../actions";
SIGN_MESSAGE, VERIFY_MESSAGE, TOGGLE_BREAKPOINT} from "../actions";
import {EMBARK_PROCESS_NAME, DARK_THEME} from '../constants';
const BN_FACTOR = 10000;
@ -281,7 +281,6 @@ const DEFAULT_MESSAGE_VERIFICATION_STATE = {
};
function messageVerification(state = DEFAULT_MESSAGE_VERIFICATION_STATE, action) {
if (action.type === VERIFY_MESSAGE[REQUEST]) {
return {...state, pending: true, error: null, payload: null };
}
@ -302,6 +301,21 @@ function messageVerification(state = DEFAULT_MESSAGE_VERIFICATION_STATE, action)
return state;
}
function breakpoints(state = {}, action) {
if (action.type === TOGGLE_BREAKPOINT) {
const {filename, lineNumber} = action.payload;
let lineNumbers = state[filename] || [];
if (lineNumbers.includes(lineNumber)){
lineNumbers = lineNumbers.filter(ln => ln !== lineNumber);
} else {
lineNumbers.push(lineNumber);
}
return {...state, [filename]: lineNumbers};
}
return state;
}
const rootReducer = combineReducers({
entities,
loading,
@ -313,7 +327,8 @@ const rootReducer = combineReducers({
theme,
searchResult,
messageSignature,
messageVerification
messageVerification,
breakpoints
});
export default rootReducer;

View File

@ -204,3 +204,7 @@ export function getVerifiedAddressPayload(state) {
export function getVerificationError(state) {
return state.messageVerification.error;
}
export function getBreakpointsByFilename(state, filename) {
return state.breakpoints[filename] || [];
}