diff --git a/src/AC/index.js b/src/AC/index.js index e3a996a..d2f997b 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() { @@ -72,4 +72,23 @@ export function loadArticle(id) { }, 1000) } -} \ No newline at end of file +} + +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 } + })) + + }, 1000) + } +} diff --git a/src/components/CommentList.js b/src/components/CommentList.js index 3082942..d0d3b35 100644 --- a/src/components/CommentList.js +++ b/src/components/CommentList.js @@ -1,8 +1,11 @@ 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 {loadComments} from '../AC' +import Loader from './common/Loader' class CommentList extends Component { static propTypes = { @@ -12,6 +15,11 @@ class CommentList extends Component { toggleOpen: PropTypes.func } + componentWillReceiveProps({ isOpen, article, loadComments }) { + console.log('article--', article) + if (!this.props.isOpen && isOpen && !article.loadedComments) loadComments(article.id) + } + render() { const {isOpen, toggleOpen} = this.props const text = isOpen ? 'hide comments' : 'show comments' @@ -24,10 +32,11 @@ class CommentList extends Component { } getBody() { - const {article: { comments, id }, isOpen} = this.props + const {article: { comments, id, loadedComments, loadingComments }, isOpen} = this.props if (!isOpen) return null + if (loadingComments) return - const body = comments.length ? ( + const body = comments.length && loadedComments ? ( @@ -43,4 +52,4 @@ class CommentList extends Component { } -export default toggleOpen(CommentList) \ No newline at end of file +export default connect(null, { loadComments })(toggleOpen(CommentList)) \ No newline at end of file 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 fd5939a..713b0ab 100644 --- a/src/reducer/articles.js +++ b/src/reducer/articles.js @@ -1,5 +1,5 @@ import { Map, Record } from 'immutable' -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, START, SUCCESS, FAIL, LOAD_COMMENTS } from '../constants' import {arrToMap} from './utils' const ArticleRecord = Record({ @@ -8,6 +8,8 @@ const ArticleRecord = Record({ text: null, date: null, loading: false, + loadedComments: false, + loadingComments: false, comments: [] }) @@ -50,6 +52,16 @@ export default (articles = new ReducerRecord(), action) => { case LOAD_ARTICLE + SUCCESS: return articles.setIn(['entities', payload.id], new ArticleRecord(payload.response)) + + case LOAD_COMMENTS + START: + return articles + .setIn(['entities', payload.id, 'loadingComments'], true) + .setIn(['entities', payload.id, 'loadedComments'], false) + + case LOAD_COMMENTS + SUCCESS: + return articles + .setIn(['entities', payload.id, 'loadingComments'], false) + .setIn(['entities', payload.id, 'loadedComments'], true) } return articles diff --git a/src/reducer/comments.js b/src/reducer/comments.js index 764e28c..ee92e01 100644 --- a/src/reducer/comments.js +++ b/src/reducer/comments.js @@ -1,17 +1,26 @@ -import { ADD_COMMENT } from '../constants' -import {normalizedComments} from '../fixtures' +import { Map, Record } from 'immutable' +import { ADD_COMMENT, LOAD_COMMENTS, START, SUCCESS } from '../constants' import {arrToMap} from './utils' -export default (state = arrToMap(normalizedComments), action) => { +const CommentRecord = Record({ + id: null, + user: null, + text: null +}) + +export default (comments = arrToMap([], CommentRecord), action) => { const { type, payload, randomId } = action switch (type) { case ADD_COMMENT: - return state.set(randomId, { + return comments.set(randomId, { ...payload.comment, id: randomId }) + + case LOAD_COMMENTS + SUCCESS: + return comments.merge(arrToMap(payload.response, CommentRecord)) } - return state + return comments } \ No newline at end of file diff --git a/src/selectors/index.js b/src/selectors/index.js index c358756..0da3ad8 100644 --- a/src/selectors/index.js +++ b/src/selectors/index.js @@ -3,7 +3,8 @@ 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 commentsSelector = state => state.comments +export const commentsLoadedSelector = state => state.articles[state.article.id].loadedComments export const idSelector = (_, props) => props.id export const articlesSelector = createSelector(articlesMapSelector, articles => articles.valueSeq().toArray()) @@ -18,6 +19,8 @@ export const filtratedArticlesSelector = createSelector(articlesSelector, filter }) }) -export const createCommentSelector = () => createSelector(commentListSelector, idSelector, (comments, id) => { - return comments.get(id) -}) \ No newline at end of file +export const createCommentSelector = () => { + return createSelector(commentsSelector, idSelector, (comments, id) => { + return comments.get(id) + }) +} \ No newline at end of file