diff --git a/client/index.js b/client/index.js index 1874933d..148556fc 100644 --- a/client/index.js +++ b/client/index.js @@ -1,8 +1,15 @@ -import React from 'react'; -import { render } from 'react-dom'; -import Editor from '../shared/components/Editor/Editor' +import React from 'react' +import { render } from 'react-dom' +import { Provider } from 'react-redux' +import configureStore from '../shared/redux/store/configureStore' +import App from '../shared/components/App/App' + +const initialState = window.__INITIAL_STATE__ +const store = configureStore(initialState) render( - , + + + , document.getElementById('root') ) \ No newline at end of file diff --git a/package.json b/package.json index f4a24ffe..05e3c57b 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,8 @@ "babel-core": "^6.8.0", "react": "^15.0.2", "react-css-modules": "^3.7.6", - "react-dom": "^15.0.2" + "react-dom": "^15.0.2", + "react-redux": "^4.4.5", + "redux": "^3.5.2" } } diff --git a/shared/components/App/App.jsx b/shared/components/App/App.jsx new file mode 100644 index 00000000..9aaf3f41 --- /dev/null +++ b/shared/components/App/App.jsx @@ -0,0 +1,16 @@ +import Editor from '../Editor/Editor' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import * as FileActions from '../../redux/actions' + +function mapStateToProps(state) { + return { + file: state.file + } +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators(FileActions, dispatch); +} + +export default connect(mapStateToProps, mapDispatchToProps)(Editor); \ No newline at end of file diff --git a/shared/components/Editor/Editor.jsx b/shared/components/Editor/Editor.jsx index 812da37e..3fc34a06 100644 --- a/shared/components/Editor/Editor.jsx +++ b/shared/components/Editor/Editor.jsx @@ -3,24 +3,39 @@ import CSSModules from 'react-css-modules'; import CodeMirror from 'codemirror'; import 'codemirror/mode/javascript/javascript'; -import '../../..//node_modules/codemirror/lib/codemirror.css'; +import '../../../node_modules/codemirror/lib/codemirror.css'; import './p5-widget-codemirror-theme.css'; -export default React.createClass({ - _cm: CodeMirror.Editor, - componentDidMount: function() { +class Editor extends React.Component { + _cm: CodeMirror.Editor + + componentDidMount() { this._cm = CodeMirror(this.refs.container, { theme: 'p5-widget', - // value: this.props.content, - value: 'var a = "Hello World!"', + value: this.props.file.content, + // value: "var a = 'Hello World!';", lineNumbers: true, mode: 'javascript' }); - }, - componentWillUnmount: function() { + this._cm.on('change', () => { + this.props.updateFile("sketch.js", this._cm.getValue()); + }); + } + + componentDidUpdate(prevProps) { + if (this.props.file.content !== prevProps.file.content && + this.props.file.content !== this._cm.getValue()) { + this._cm.setValue(this.props.file.content); + } + } + + componentWillUnmount() { this._cm = null; - }, - render: function() { + } + + render() { return
; } -}); \ No newline at end of file +} + +export default Editor; \ No newline at end of file diff --git a/shared/components/Preview/Preview.jsx b/shared/components/Preview/Preview.jsx new file mode 100644 index 00000000..c7bf9acb --- /dev/null +++ b/shared/components/Preview/Preview.jsx @@ -0,0 +1,11 @@ +import React from 'react'; + +class Preview extends React.Component { + _iframe: HTMLIFrameElement + + render() { + return
; + } +} + +export default Preview; \ No newline at end of file diff --git a/shared/redux/actions/index.js b/shared/redux/actions/index.js new file mode 100644 index 00000000..315a46ef --- /dev/null +++ b/shared/redux/actions/index.js @@ -0,0 +1,9 @@ +import * as ActionTypes from '../constants/constants'; + +export function updateFile(name, content) { + return { + type: ActionTypes.CHANGE_SELECTED_FILE, + name: name, + content: content + } +} \ No newline at end of file diff --git a/shared/redux/constants/constants.js b/shared/redux/constants/constants.js new file mode 100644 index 00000000..4670f1ff --- /dev/null +++ b/shared/redux/constants/constants.js @@ -0,0 +1,2 @@ +export const CHANGE_SELECTED_FILE = 'CHANGE_SELECTED_FILE'; +export const TOGGLE_SKETCH = 'TOGGLE_SKETCH'; \ No newline at end of file diff --git a/shared/redux/reducers/files.js b/shared/redux/reducers/files.js new file mode 100644 index 00000000..63f2fe3f --- /dev/null +++ b/shared/redux/reducers/files.js @@ -0,0 +1,34 @@ +import * as ActionTypes from '../constants/constants'; + +const initialState = { + name: "sketch.js", + content: "setup() { } draw() { }" +} + +const file = (state = initialState, action) => { + switch (action.type) { + case ActionTypes.CHANGE_SELECTED_FILE: + return { + name: action.name, + content: action.content + } + default: + return state + } +} + +export default file; + +//i'll add this in when there are multiple files +// const files = (state = [], action) => { +// switch (action.type) { +// case ActionTypes.CHANGE_SELECTED_FILE: +// //find the file with the name +// //update it +// //put in into the new array of files +// default: +// return state +// } +// } + +// export default files \ No newline at end of file diff --git a/shared/redux/reducers/ide.js b/shared/redux/reducers/ide.js new file mode 100644 index 00000000..e14ca741 --- /dev/null +++ b/shared/redux/reducers/ide.js @@ -0,0 +1 @@ +import * as ActionTypes from '../constants/constants'; \ No newline at end of file diff --git a/shared/redux/reducers/index.js b/shared/redux/reducers/index.js new file mode 100644 index 00000000..2b1b8d38 --- /dev/null +++ b/shared/redux/reducers/index.js @@ -0,0 +1,8 @@ +import { combineReducers } from 'redux' +import file from './files' + +const rootReducer = combineReducers({ + file +}) + +export default rootReducer \ No newline at end of file diff --git a/shared/redux/store/configureStore.js b/shared/redux/store/configureStore.js new file mode 100644 index 00000000..b6aad8d9 --- /dev/null +++ b/shared/redux/store/configureStore.js @@ -0,0 +1,20 @@ +import { createStore, applyMiddleware } from 'redux' +import rootReducer from '../reducers' + +export default function configureStore(initialState) { + const store = createStore( + rootReducer, + initialState + // applyMiddleware(thunk) + ) + + if (module.hot) { + // Enable Webpack hot module replacement for reducers + module.hot.accept('../reducers', () => { + const nextRootReducer = require('../reducers').default + store.replaceReducer(nextRootReducer) + }) + } + + return store +} \ No newline at end of file