diff --git a/src/AC/index.js b/src/AC/index.js
index e3a996a..a6176de 100644
--- a/src/AC/index.js
+++ b/src/AC/index.js
@@ -1,6 +1,6 @@
import {
INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE,
- START, SUCCESS, FAIL
+ LOAD_COMMENTS, START, SUCCESS, FAIL
} from '../constants'
export function increment() {
@@ -70,6 +70,25 @@ export function loadArticle(id) {
payload: { id, response }
}))
- }, 1000)
+ }, 300)
+ }
+}
+
+export function loadComments(id) {
+ return (dispatch) => {
+ dispatch({
+ type: LOAD_COMMENTS + START,
+ payload: { id }
+ })
+
+ setTimeout(() => {
+ fetch(`/api/comment?article=${id}`)
+ .then(res => res.json())
+ .then(response => dispatch({
+ type: LOAD_COMMENTS + SUCCESS,
+ payload: { id, response }
+ }))
+
+ }, 300)
}
}
\ No newline at end of file
diff --git a/src/components/Comment.js b/src/components/Comment.js
index 4b123ce..27480f3 100644
--- a/src/components/Comment.js
+++ b/src/components/Comment.js
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
-import {createCommentSelector} from '../selectors'
+import {commentSelector} from '../selectors'
function Comment({comment}) {
return (
@@ -20,13 +20,8 @@ Comment.propTypes = {
}).isRequired
}
-const createMapStateToProps = () => {
- const commentSelector = createCommentSelector()
- return (state, ownProps) => {
- return {
- comment: commentSelector(state, ownProps)
- }
+export default connect((state, ownProps) => {
+ return {
+ comment: commentSelector(state, ownProps)
}
-}
-
-export default connect(createMapStateToProps)(Comment)
\ No newline at end of file
+})(Comment)
\ No newline at end of file
diff --git a/src/components/CommentList.js b/src/components/CommentList.js
index 3082942..516e0e5 100644
--- a/src/components/CommentList.js
+++ b/src/components/CommentList.js
@@ -1,8 +1,12 @@
import React, {Component} from 'react'
+import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import CommentForm from './CommentForm'
import Comment from './Comment'
import toggleOpen from '../decorators/toggleOpen'
+import Loader from './common/Loader'
+import {loadComments} from '../AC'
+import { commentsLoadingSelector, commentListSelector, commentsCacheSelector, commentsLoadedIdSelector } from '../selectors'
class CommentList extends Component {
static propTypes = {
@@ -12,6 +16,11 @@ class CommentList extends Component {
toggleOpen: PropTypes.func
}
+ componentWillReceiveProps({ isOpen, article, loadComments }) {
+ //console.log('-', this.props);
+ if (!this.props.isOpen && isOpen && (this.props.loadedId != article.id)) loadComments(article.id)
+ }
+
render() {
const {isOpen, toggleOpen} = this.props
const text = isOpen ? 'hide comments' : 'show comments'
@@ -24,12 +33,13 @@ class CommentList extends Component {
}
getBody() {
- const {article: { comments, id }, isOpen} = this.props
+ const { comments, article: { id }, isOpen, loading} = this.props
if (!isOpen) return null
+ if (loading) return
const body = comments.length ? (
- {comments.map(id => )}
+ {comments.map(item => )}
) : No comments yet
@@ -43,4 +53,11 @@ class CommentList extends Component {
}
-export default toggleOpen(CommentList)
\ No newline at end of file
+export default connect(state => {
+ return {
+ loading: commentsLoadingSelector(state),
+ comments: commentListSelector(state),
+ //cache: commentsCacheSelector(state),
+ loadedId: commentsLoadedIdSelector(state)
+ }
+}, {loadComments})(toggleOpen(CommentList))
\ No newline at end of file
diff --git a/src/constants/index.js b/src/constants/index.js
index f34f842..817345f 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -3,6 +3,7 @@ export const INCREMENT = 'INCREMENT'
export const DELETE_ARTICLE = 'DELETE_ARTICLE'
export const LOAD_ALL_ARTICLES = 'LOAD_ALL_ARTICLES'
export const LOAD_ARTICLE = 'LOAD_ARTICLE'
+export const LOAD_COMMENTS = 'LOAD_COMMENTS'
export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
diff --git a/src/middlewares/api.js b/src/middlewares/api.js
index 52ed209..25ab7d1 100644
--- a/src/middlewares/api.js
+++ b/src/middlewares/api.js
@@ -16,5 +16,5 @@ export default store => next => action => {
.then(res => res.json())
.then(response => next({...rest, response, type: type + SUCCESS}))
.catch(error => next({...rest, error, type: type + FAIL}))
- }, 1000)
+ }, 300)
}
\ No newline at end of file
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index 764e28c..e5c3901 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,16 +1,46 @@
-import { ADD_COMMENT } from '../constants'
-import {normalizedComments} from '../fixtures'
+import { Map, Record } from 'immutable'
+import { ADD_COMMENT, LOAD_COMMENTS, START, SUCCESS, FAIL } from '../constants'
import {arrToMap} from './utils'
-export default (state = arrToMap(normalizedComments), action) => {
- const { type, payload, randomId } = action
+const CommentsRecord = Record({
+ id: null,
+ user: null,
+ text: null
+})
+
+const ReducerRecord = Record({
+ entities: arrToMap([], CommentsRecord),
+ loading: false,
+ loaded: false,
+ error: null,
+ //cache: false,
+ loadedId: null
+})
+
+export default (state = new ReducerRecord(), action) => {
+ const { type, payload, randomId, error } = action
switch (type) {
case ADD_COMMENT:
- return state.set(randomId, {
- ...payload.comment,
- id: randomId
- })
+ return state.setIn(['entities', randomId],
+ new CommentsRecord({ ...payload.comment, id: randomId}))
+
+ case LOAD_COMMENTS + START:
+ return state
+ .set('loading', true)
+ .set('loadedId', payload.id)
+
+ case LOAD_COMMENTS + FAIL:
+ return state
+ .set('loading', false)
+ .set('error', error)
+
+ case LOAD_COMMENTS + SUCCESS:
+ return state
+ .set('loading', false)
+ .set('loaded', true)
+ //.set('cache', true)
+ .set('entities', arrToMap(payload.response, CommentsRecord))
}
return state
diff --git a/src/selectors/index.js b/src/selectors/index.js
index c358756..e5cd983 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -3,7 +3,10 @@ import {createSelector} from 'reselect'
export const articlesMapSelector = state => state.articles.entities
export const articlesLoadingSelector = state => state.articles.loading
export const filtersSelector = state => state.filters
-export const commentListSelector = state => state.comments
+export const commentListMapSelector = state => state.comments.entities
+export const commentsLoadingSelector = state => state.comments.loading
+export const commentsLoadedIdSelector = state => state.comments.loadedId
+//export const commentsCacheSelector = state => state.comments.cache
export const idSelector = (_, props) => props.id
export const articlesSelector = createSelector(articlesMapSelector, articles => articles.valueSeq().toArray())
@@ -18,6 +21,8 @@ export const filtratedArticlesSelector = createSelector(articlesSelector, filter
})
})
-export const createCommentSelector = () => createSelector(commentListSelector, idSelector, (comments, id) => {
- return comments.get(id)
+export const commentListSelector = createSelector(commentListMapSelector, comments => comments.valueSeq().toArray())
+
+export const commentSelector = createSelector(commentListSelector, idSelector, (comments, id) => {
+ return comments.find(item => item.id == id)
})
\ No newline at end of file