diff --git a/src/AC/index.js b/src/AC/index.js
index 401b5b1..216e59e 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() {
@@ -74,4 +74,26 @@ export function loadArticleById(id) {
}))
}, 1000)
}
-}
\ No newline at end of file
+}
+
+export function loadCommentsByArticleId(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)
+ }
+}
diff --git a/src/components/comment-list/index.js b/src/components/comment-list/index.js
index 173cb68..045467c 100644
--- a/src/components/comment-list/index.js
+++ b/src/components/comment-list/index.js
@@ -4,6 +4,10 @@ import CSSTransition from 'react-addons-css-transition-group'
import Comment from '../comment'
import CommentForm from '../comment-form'
import toggleOpen from '../../decorators/toggleOpen'
+import {loadingCommentsSelect, loadedCommentsSelect} from '../../selectors'
+import {connect} from 'react-redux'
+import {loadCommentsByArticleId} from '../../AC'
+import Loader from '../loader'
import './style.css'
class CommentList extends Component {
@@ -18,6 +22,10 @@ class CommentList extends Component {
toggleOpen: PropTypes.func
}
+ componentWillReceiveProps({isOpen, loadCommentsByArticleId, article}){
+ if (!this.props.isOpen && isOpen && !article.commentsLoaded) loadCommentsByArticleId(article.id)
+ }
+
render() {
const {isOpen, toggleOpen} = this.props
const text = isOpen ? 'hide comments' : 'show comments'
@@ -36,19 +44,21 @@ class CommentList extends Component {
}
getBody() {
- const {article: { comments, id }, isOpen} = this.props
+ const {article: { comments, id, commentsLoaded }, isOpen, loading, loaded} = this.props
if (!isOpen) return null
-
- return (
-
- {
- comments.length
- ? this.getComments()
- :
No comments yet
- }
-
-
- )
+ if (loading) return
+ if (commentsLoaded){
+ return (
+
+ {
+ comments.length
+ ? this.getComments()
+ :
No comments yet
+ }
+
+
+ )
+ }
}
getComments() {
@@ -66,4 +76,7 @@ class CommentList extends Component {
}
-export default toggleOpen(CommentList)
\ No newline at end of file
+export default connect(state => ({
+ loading: loadingCommentsSelect(state),
+ loaded: loadedCommentsSelect(state)
+}), {loadCommentsByArticleId})(toggleOpen(CommentList))
diff --git a/src/constants/index.js b/src/constants/index.js
index f34f842..9ef403c 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -8,7 +8,8 @@ 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'
-export const FAIL = '_FAIL'
\ No newline at end of file
+export const FAIL = '_FAIL'
diff --git a/src/reducer/articles.js b/src/reducer/articles.js
index 26166cc..afabb7c 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 { DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, LOAD_COMMENTS, START, SUCCESS } 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({
@@ -46,8 +47,10 @@ 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
}
-}
\ No newline at end of file
+}
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index 9f32503..98643bb 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,18 +1,37 @@
-import { ADD_COMMENT } from '../constants'
-import {normalizedComments} from '../fixtures'
+import { ADD_COMMENT, LOAD_COMMENTS, SUCCESS, START } from '../constants'
import {arrToMap} from './utils'
+import {Record} from 'immutable'
-export default (state = arrToMap(normalizedComments), action) => {
+const CommentRecord = Record({
+ id: null,
+ text: null,
+ user: null,
+})
+
+const ReducerState = Record({
+ entities: arrToMap([], CommentRecord),
+ loading: false,
+ loaded: false,
+ error: null
+})
+
+export default (comments = new ReducerState(), action) => {
const { type, payload, randomId } = action
switch (type) {
case ADD_COMMENT:
- return state.set(randomId, {
- ...payload.comment,
- id: randomId
- })
+ return comments.setIn(['entities', randomId], { ...payload.comment, id: randomId })
+
+ case LOAD_COMMENTS + START:
+ return comments.set('loading', true)
+
+ case LOAD_COMMENTS + SUCCESS:
+ return comments
+ .update('entities', comments => Object.assign(comments, arrToMap(payload.response, CommentRecord)))
+ .set('loading', false)
+ .set('loaded', true)
default:
- return state
+ return comments
}
-}
\ No newline at end of file
+}
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 0f58db6..cd5fd32 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -4,7 +4,10 @@ export const articlesMapSelector = state => state.articles.entities
export const articleListSelector = createSelector(articlesMapSelector, articlesMap => articlesMap.valueSeq().toArray())
export const loadingArticlesSelector = state => state.articles.loading
-const commentsSelector = state => state.comments
+const commentsSelector = state => state.comments.entities
+export const loadingCommentsSelect = state => state.comments.loading
+export const loadedCommentsSelect = state => state.comments.loaded
+
const filtersSelector = state => state.filters
const idSelector = (_, props) => props.id
@@ -19,4 +22,4 @@ export const filtratedArticles = createSelector(articleListSelector, filtersSele
})
})
-export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))
\ No newline at end of file
+export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))