From 9c34b45c3d97f2112bb911cbdbca981c3e0f22a9 Mon Sep 17 00:00:00 2001 From: Alex Fedoseev Date: Thu, 6 Aug 2015 16:52:39 +0300 Subject: [PATCH] First do it --- .gitignore | 3 ++ .../actions/CommentActionCreators.js | 38 ++++++++--------- .../assets/javascripts/components/Comment.jsx | 4 +- .../javascripts/components/CommentBox.jsx | 2 +- .../javascripts/components/CommentForm.jsx | 2 +- .../javascripts/components/CommentList.jsx | 4 +- .../javascripts/components/CommentScreen.jsx | 4 +- .../javascripts/reducers/commentReducer.js | 42 +++++++++---------- client/assets/javascripts/reducers/index.js | 3 ++ .../assets/javascripts/stores/CommentStore.js | 11 +++-- client/gulpfile.js | 10 ++--- client/server.js | 16 +++++-- client/webpack.common.config.js | 6 ++- 13 files changed, 81 insertions(+), 64 deletions(-) create mode 100644 client/assets/javascripts/reducers/index.js diff --git a/.gitignore b/.gitignore index 0650ca72..84539277 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ npm-debug.log # Ignore bundle dependencies vendor/ruby + +# RVM gemset +.ruby-gemset diff --git a/client/assets/javascripts/actions/CommentActionCreators.js b/client/assets/javascripts/actions/CommentActionCreators.js index e30dca15..6b8076c8 100644 --- a/client/assets/javascripts/actions/CommentActionCreators.js +++ b/client/assets/javascripts/actions/CommentActionCreators.js @@ -1,61 +1,61 @@ import CommentsManager from '../utils/CommentsManager'; -import * from '../constants/ActionTypes'; +import * as actionTypes from '../constants/ActionTypes'; export function incrementAjaxCounter() { return { - type: INCREMENT_AJAX_COUNTER - } + type: actionTypes.INCREMENT_AJAX_COUNTER, + }; } export function decrementAjaxCounter() { return { - type: DECREMENT_AJAX_COUNTER - } + type: actionTypes.DECREMENT_AJAX_COUNTER, + }; } export function fetchCommentsSuccess(comments) { return { - type: FETCH_COMMENTS_SUCCESS, - comments + type: actionTypes.FETCH_COMMENTS_SUCCESS, + comments, }; } export function fetchCommentsFailure(error) { return { - type: FETCH_COMMENTS_FAILURE, - error + type: actionTypes.FETCH_COMMENTS_FAILURE, + error, }; } export function submitCommentSuccess(comment) { return { - type: SUBMIT_COMMENT_SUCCESS, - comment + type: actionTypes.SUBMIT_COMMENT_SUCCESS, + comment, }; } export function submitCommentFailure(error) { return { - type: SUBMIT_COMMENT_FAILURE, - error - } + type: actionTypes.SUBMIT_COMMENT_FAILURE, + error, + }; } export function fetchComments() { - return function(dispatch) { + return dispatch => { return CommentsManager.fetchComments().then( comments => dispatch(fetchCommentsSuccess(comments)), error => dispatch(fetchCommentsFailure(error)) ); - } + }; } export function submitComment(comment) { - return function(dispatch) { + return dispatch => { dispatch(incrementAjaxCounter()); return CommentsManager.submitComment(comment).then( - comment => dispatch(submitCommentSuccess(comment), + commentFromServer => dispatch(submitCommentSuccess(commentFromServer)), error => dispatch(submitCommentFailure(error)) ).then(() => dispatch(decrementAjaxCounter())); - } + }; } diff --git a/client/assets/javascripts/components/Comment.jsx b/client/assets/javascripts/components/Comment.jsx index b1783fc4..162d3966 100644 --- a/client/assets/javascripts/components/Comment.jsx +++ b/client/assets/javascripts/components/Comment.jsx @@ -12,8 +12,8 @@ const Comment = React.createClass({ render() { const rawMarkup = marked(this.props.text); return ( -
-

+
+

{this.props.author}

diff --git a/client/assets/javascripts/components/CommentBox.jsx b/client/assets/javascripts/components/CommentBox.jsx index fc4c87ce..3c3b0cf4 100644 --- a/client/assets/javascripts/components/CommentBox.jsx +++ b/client/assets/javascripts/components/CommentBox.jsx @@ -7,7 +7,7 @@ const CommentBox = React.createClass({ propTypes: { pollInterval: React.PropTypes.number.isRequired, - actions: PropTypes.object.isRequired, + actions: React.PropTypes.object.isRequired, }, componentDidMount() { diff --git a/client/assets/javascripts/components/CommentForm.jsx b/client/assets/javascripts/components/CommentForm.jsx index bdbdae4c..878152a7 100644 --- a/client/assets/javascripts/components/CommentForm.jsx +++ b/client/assets/javascripts/components/CommentForm.jsx @@ -13,7 +13,7 @@ const CommentForm = React.createClass({ propTypes: { ajaxSending: React.PropTypes.bool.isRequired, - actions: PropTypes.object.isRequired, + actions: React.PropTypes.object.isRequired, }, getInitialState() { diff --git a/client/assets/javascripts/components/CommentList.jsx b/client/assets/javascripts/components/CommentList.jsx index 05c4151c..eb7a2fc2 100644 --- a/client/assets/javascripts/components/CommentList.jsx +++ b/client/assets/javascripts/components/CommentList.jsx @@ -10,12 +10,12 @@ const CommentList = React.createClass({ render() { const reversedData = this.props.comments.slice(0).reverse(); - const commentNodes = reversedData.map((comment, index) => { + const commentNodes = this.props.comments.get('comments').map((comment, index) => { // `key` is a React-specific concept and is not mandatory for the // purpose of this tutorial. if you're curious, see more here: // http://facebook.github.io/react/docs/multiple-components.html#dynamic-children return ( - + ); }); diff --git a/client/assets/javascripts/components/CommentScreen.jsx b/client/assets/javascripts/components/CommentScreen.jsx index d44e7fb8..b23d5e16 100644 --- a/client/assets/javascripts/components/CommentScreen.jsx +++ b/client/assets/javascripts/components/CommentScreen.jsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { fetchComments, submitComment } from '../actions/CommentActionCreators'; -const CommentActionsCreators = [fetchComments, submitComment]; +const CommentActionsCreators = { fetchComments, submitComment }; function select(state) { // Which part of the Redux global state does our component want to receive as props? @@ -20,7 +20,7 @@ const CommentScreen = React.createClass({ render() { const { dispatch, ...other } = this.props; - const actions = bindActionCreators(CommentActionCreators, dispatch); + const actions = bindActionCreators(CommentActionsCreators, dispatch); return (
{ - mState.updateIn(['comments'], comments => comments.unshift(action.comment)). - merge({ submitCommentError: '' }); - }); - case SUBMIT_COMMENT_FAILURE: - return state.merge({ submitCommentError: action.error }); - case INCREMENT_AJAX_COUNTER: - return state.merge({ ajaxCounter: state.get('ajaxCounter') + 1 }); - case DECREMENT_AJAX_COUNTER: - return state.merge({ ajaxCounter: state.get('ajaxCounter') - 1 }); - default: - return state; + case actionTypes.FETCH_COMMENTS_SUCCESS: + return state.merge({ comments: action.comments, fetchCommentError: '' }); + case actionTypes.FETCH_COMMENTS_FAILURE: + return state.merge({ fetchCommentError: action.error }); + case actionTypes.SUBMIT_COMMENT_SUCCESS: + return state.withMutatations(mState => { + mState.updateIn(['comments'], comments => comments.unshift(action.comment)). // Seems to me this is a mutation, for `comments` we should use List type instead + merge({ submitCommentError: '' }); + }); + case actionTypes.SUBMIT_COMMENT_FAILURE: + return state.merge({ submitCommentError: action.error }); + case actionTypes.INCREMENT_AJAX_COUNTER: + return state.merge({ ajaxCounter: state.get('ajaxCounter') + 1 }); + case actionTypes.DECREMENT_AJAX_COUNTER: + return state.merge({ ajaxCounter: state.get('ajaxCounter') - 1 }); + default: + return state; } } diff --git a/client/assets/javascripts/reducers/index.js b/client/assets/javascripts/reducers/index.js new file mode 100644 index 00000000..61abdebd --- /dev/null +++ b/client/assets/javascripts/reducers/index.js @@ -0,0 +1,3 @@ +import comments from './commentReducer'; + +export default { comments }; diff --git a/client/assets/javascripts/stores/CommentStore.js b/client/assets/javascripts/stores/CommentStore.js index 7e1ce90e..18e514a7 100644 --- a/client/assets/javascripts/stores/CommentStore.js +++ b/client/assets/javascripts/stores/CommentStore.js @@ -1,7 +1,10 @@ -import { createStore, applyMiddleware } from 'redux'; -import commentReducer from '../reducers/commentReducer'; +import { createStore, applyMiddleware, combineReducers } from 'redux'; +import thunk from 'redux-thunk'; +import reducers from '../reducers'; + +// Smth wrong with this one, off for now import loggerMiddleware from '../middleware/loggerMiddleware'; // applyMiddleware supercharges createStore with middleware: -const createStoreWithMiddleware = applyMiddleware(thunk, loggerMiddleware)(createStore); -export default createStoreWithMiddleware(commentReducer); +const createStoreWithMiddleware = applyMiddleware(thunk)(createStore); +export default createStoreWithMiddleware(combineReducers(reducers)); diff --git a/client/gulpfile.js b/client/gulpfile.js index eed37cf6..c1e0b244 100644 --- a/client/gulpfile.js +++ b/client/gulpfile.js @@ -1,13 +1,11 @@ const gulp = require('gulp'); -const eslint = require('gulp-eslint'); +const eslint = require('eslint/lib/cli'); // Note: To have the process exit with an error code (1) on // lint error, return the stream and pipe to failOnError last. -gulp.task('lint', function gulpLint() { - return gulp.src(['assets/javascripts/**/*.jsx', 'scripts/**/*.jsx', '*.js']) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failOnError()); +gulp.task('lint', function gulpLint(done) { + eslint.execute('--ext .js,.jsx .'); + return done(); }); gulp.task('default', ['lint'], function gulpDefault() { diff --git a/client/server.js b/client/server.js index 1e1c3d52..b95d3e78 100644 --- a/client/server.js +++ b/client/server.js @@ -1,18 +1,26 @@ -/*eslint-disable no-console, func-names, no-var */ +/* eslint-disable no-console, func-names, no-var */ var bodyParser = require('body-parser'); var webpack = require('webpack'); var WebpackDevServer = require('webpack-dev-server'); var config = require('./webpack.hot.config'); var sleep = require('sleep'); -var comments = [{author: 'Pete Hunt', text: 'Hey there!'}, - {author: 'Justin Gordon', text: 'Aloha from @railsonmaui'},]; +var comments = [ + {author: 'Pete Hunt', text: 'Hey there!'}, + {author: 'Justin Gordon', text: 'Aloha from @railsonmaui'}, +]; var server = new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, noInfo: false, - stats: {colors: true}, + stats: { + colors: true, + hash: false, + version: false, + chunks: false, + children: false, + }, }); server.app.use(bodyParser.json(null)); diff --git a/client/webpack.common.config.js b/client/webpack.common.config.js index 9ed8b42b..50471f39 100644 --- a/client/webpack.common.config.js +++ b/client/webpack.common.config.js @@ -13,8 +13,10 @@ module.exports = { // jquery: 'var jQuery' // }, resolve: { - root: [path.join(__dirname, 'scripts'), - path.join(__dirname, 'assets/javascripts'),], + root: [ + path.join(__dirname, 'scripts'), + path.join(__dirname, 'assets/javascripts'), + ], extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.scss', '.css', 'config.js'], }, module: {