diff --git a/src/AC/index.js b/src/AC/index.js
index 401b5b1..b035b7d 100644
--- a/src/AC/index.js
+++ b/src/AC/index.js
@@ -1,5 +1,5 @@
import {
- INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE,
+ LOAD_COMMENTS, INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE,
START, SUCCESS, FAIL
} from '../constants'
@@ -74,4 +74,28 @@ export function loadArticleById(id) {
}))
}, 1000)
}
+}
+
+export function loadCommentsForArticle(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}
+ }))
+ .catch(error => dispatch({
+ type: LOAD_COMMENTS + FAIL,
+ payload: {id, error}
+ }))
+ },1000)
+ }
+
}
\ No newline at end of file
diff --git a/src/components/comment-list/index.js b/src/components/comment-list/index.js
index 173cb68..47e964c 100644
--- a/src/components/comment-list/index.js
+++ b/src/components/comment-list/index.js
@@ -5,6 +5,10 @@ import Comment from '../comment'
import CommentForm from '../comment-form'
import toggleOpen from '../../decorators/toggleOpen'
import './style.css'
+import {loadCommentsForArticle} from "../../AC/index";
+import {connect} from "react-redux";
+import {loadingCommentsSelector} from "../../selectors/index";
+import Loader from "../loader";
class CommentList extends Component {
static defaultProps = {
@@ -18,6 +22,10 @@ class CommentList extends Component {
toggleOpen: PropTypes.func
}
+ componentWillReceiveProps({ isOpen, loadCommentsForArticle, article }) {
+ if (!this.props.isOpen && isOpen && !article.commentsLoaded) loadCommentsForArticle(article.id)
+ }
+
render() {
const {isOpen, toggleOpen} = this.props
const text = isOpen ? 'hide comments' : 'show comments'
@@ -36,8 +44,9 @@ class CommentList extends Component {
}
getBody() {
- const {article: { comments, id }, isOpen} = this.props
+ const {article: { comments, id,commentsLoaded }, loading,isOpen} = this.props
if (!isOpen) return null
+ if(loading&&!commentsLoaded) return
return (
@@ -66,4 +75,7 @@ class CommentList extends Component {
}
-export default toggleOpen(CommentList)
\ No newline at end of file
+
+export default connect(state=>({
+ loading:loadingCommentsSelector(state)
+}),{loadCommentsForArticle})(toggleOpen(CommentList))
\ No newline at end of file
diff --git a/src/components/comment.js b/src/components/comment.js
index dba04b4..48afbfb 100644
--- a/src/components/comment.js
+++ b/src/components/comment.js
@@ -4,6 +4,7 @@ import { connect } from 'react-redux'
import { createCommentSelector } from '../selectors'
function Comment({comment}) {
+ if(!comment) return null;
return (
{comment.text} by {comment.user}
@@ -15,7 +16,7 @@ Comment.propTypes = {
comment: PropTypes.shape({
text: PropTypes.string.isRequired,
user: PropTypes.string
- }).isRequired
+ })
}
const createMapStateToProps = () => {
diff --git a/src/constants/index.js b/src/constants/index.js
index f34f842..8a18b45 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -8,6 +8,7 @@ export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const ADD_COMMENT = 'ADD_COMMENT'
+export const LOAD_COMMENTS = 'LOAD_COMMENTS'
export const START = '_START'
export const SUCCESS = '_SUCCESS'
diff --git a/src/reducer/articles.js b/src/reducer/articles.js
index 26166cc..a51a0cf 100644
--- a/src/reducer/articles.js
+++ b/src/reducer/articles.js
@@ -1,4 +1,4 @@
-import { DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, START, SUCCESS, FAIL } from '../constants'
+import { LOAD_COMMENTS, DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, START, SUCCESS, FAIL } from '../constants'
import { arrToMap } from './utils'
import { Record } from 'immutable'
@@ -8,7 +8,8 @@ const ArticleRecord = Record({
text: null,
date: null,
loading: false,
- comments: []
+ comments: [],
+ commentsLoaded:false
})
const ReducerState = Record({
@@ -45,7 +46,8 @@ export default (articles = new ReducerState(), action) => {
case LOAD_ARTICLE + SUCCESS:
return articles.setIn(['entities', payload.id], new ArticleRecord(payload.response))
-
+ case LOAD_COMMENTS + SUCCESS:
+ return articles.setIn(['entities',payload.id,'commentsLoaded'],true)
default:
return articles
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index 9f32503..fa8fc1b 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,8 +1,22 @@
import { ADD_COMMENT } from '../constants'
-import {normalizedComments} from '../fixtures'
import {arrToMap} from './utils'
+import { Record } from 'immutable'
+import {LOAD_COMMENTS, START, SUCCESS} from "../constants/index";
-export default (state = arrToMap(normalizedComments), action) => {
+const CommentRecord = Record({
+ id: null,
+ user: null,
+ text: null,
+})
+
+const ReducerState = Record({
+ entities: arrToMap([], CommentRecord),
+ loading: false,
+ loaded: false,
+ error: null
+})
+
+export default (state = new ReducerState(), action) => {
const { type, payload, randomId } = action
switch (type) {
@@ -11,7 +25,13 @@ export default (state = arrToMap(normalizedComments), action) => {
...payload.comment,
id: randomId
})
+ case LOAD_COMMENTS + START:
+ return state.set("loading",true)
+ case LOAD_COMMENTS + SUCCESS:
+ return state.update("entities",comments=>comments.merge(arrToMap(payload.response,CommentRecord)))
+ .set("loading",false)
+ .set("loaded",true)
default:
return state
}
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 0f58db6..aafc319 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -3,8 +3,9 @@ import { createSelector } from 'reselect'
export const articlesMapSelector = state => state.articles.entities
export const articleListSelector = createSelector(articlesMapSelector, articlesMap => articlesMap.valueSeq().toArray())
export const loadingArticlesSelector = state => state.articles.loading
+export const loadingCommentsSelector = state => state.comments.loading
-const commentsSelector = state => state.comments
+const commentsSelector = state => state.comments.entities
const filtersSelector = state => state.filters
const idSelector = (_, props) => props.id