diff --git a/src/AC/index.js b/src/AC/index.js index e3a996a..5295670 100644 --- a/src/AC/index.js +++ b/src/AC/index.js @@ -1,6 +1,16 @@ import { - INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, - START, SUCCESS, FAIL + INCREMENT, + DELETE_ARTICLE, + CHANGE_DATE_RANGE, + CHANGE_SELECTION, + ADD_COMMENT, + LOAD_ALL_ARTICLES, + LOAD_ARTICLE, + START, + SUCCESS, + FAIL, + LOAD_COMMENT, + LOAD_COMMENT_TO_CASHE } from '../constants' export function increment() { @@ -72,4 +82,36 @@ export function loadArticle(id) { }, 1000) } +} + + + +export function loadCommentForArticle(idArticle) { + + return (dispatch) => { + dispatch({ + type: LOAD_COMMENT + START, + payload: { idArticle } + }) + setTimeout(() => { + fetch(`/api/comment?article=${idArticle}`) + .then(res => res.json()) + .then(response => dispatch({ + type: LOAD_COMMENT + SUCCESS, + payload: { idArticle, response } + })) + }, 1000) + + + } + +} + +export function loadCommentToCashe(CasheComment, id) { + + return { + type: LOAD_COMMENT_TO_CASHE, + payload: { CasheComment, id } + } + } \ No newline at end of file diff --git a/src/components/Article/index.js b/src/components/Article/index.js index 2e4a647..48f15f8 100644 --- a/src/components/Article/index.js +++ b/src/components/Article/index.js @@ -5,7 +5,7 @@ import CSSTransition from 'react-addons-css-transition-group' import {connect} from 'react-redux' import CommentList from '../CommentList' import Loader from '../common/Loader' -import {deleteArticle, loadArticle} from '../../AC' +import { deleteArticle, loadArticle} from '../../AC' import './style.css' class Article extends PureComponent { @@ -68,7 +68,7 @@ class Article extends PureComponent { return (
{article.text}
- +
) diff --git a/src/components/Comment.js b/src/components/Comment.js index 4b123ce..d768e00 100644 --- a/src/components/Comment.js +++ b/src/components/Comment.js @@ -1,9 +1,12 @@ import React from 'react' import PropTypes from 'prop-types' import {connect} from 'react-redux' -import {createCommentSelector} from '../selectors' +import {commentSelectorId} from '../selectors' function Comment({comment}) { + + + return (
{comment.text} by {comment.user} @@ -13,20 +16,24 @@ function Comment({comment}) { Comment.propTypes = { id: PropTypes.string, - //from connect + comment: PropTypes.shape({ text: PropTypes.string.isRequired, user: PropTypes.string }).isRequired } -const createMapStateToProps = () => { - const commentSelector = createCommentSelector() - return (state, ownProps) => { - return { - comment: commentSelector(state, ownProps) - } - } -} +// const createMapStateToProps = () => { +// const commentSelector = createCommentSelector() +// return (state, ownProps) => { +// return { +// comment: commentSelector(state, ownProps) +// } +// } +// } -export default connect(createMapStateToProps)(Comment) \ No newline at end of file +export default connect ( ( state, ownProps ) => { + return { + comment: commentSelectorId( state, ownProps ) + } +} ) (Comment) \ No newline at end of file diff --git a/src/components/CommentList.js b/src/components/CommentList.js index 3082942..a75beca 100644 --- a/src/components/CommentList.js +++ b/src/components/CommentList.js @@ -4,6 +4,11 @@ import CommentForm from './CommentForm' import Comment from './Comment' import toggleOpen from '../decorators/toggleOpen' +import { connect } from 'react-redux' +import { loadCommentForArticle , loadCommentToCashe } from '../AC' +import {commentsSelector, commentsLoadingSelector, commentsSelectorCashe} from '../selectors' + +import Loader from './common/Loader' class CommentList extends Component { static propTypes = { article: PropTypes.object.isRequired, @@ -11,9 +16,18 @@ class CommentList extends Component { isOpen: PropTypes.bool, toggleOpen: PropTypes.func } + + + + componentWillReceiveProps({ isOpen, article, loadCommentForArticle }){ + + if( !this.props.isOpen && isOpen && !article.get('commentInCashe') ) loadCommentForArticle( article.id ) + + + } render() { - const {isOpen, toggleOpen} = this.props + const {isOpen, toggleOpen , comments } = this.props const text = isOpen ? 'hide comments' : 'show comments' return (
@@ -24,23 +38,52 @@ class CommentList extends Component { } getBody() { - const {article: { comments, id }, isOpen} = this.props - if (!isOpen) return null + const { comments , article, isOpen, loading , loadCommentToCashe } = this.props + console.log(comments) + + if( !article.get('commentInCashe') ) { + console.log( "before" + article.get('commentInCashe')) + loadCommentToCashe(comments, article.get('id')) + console.log( "after" + article.get('commentInCashe')) + // сейчас коменты в кеше + console.log(article.comments) + } + + + + + if (!isOpen) return null + if (loading) return const body = comments.length ? (
    - {comments.map(id =>
  • )} + {comments.map(comment =>
  • )}
) :

No comments yet

return (
{body} - +
) } } -export default toggleOpen(CommentList) \ No newline at end of file +export default connect( (state, ownProps ) => { + const { article } = ownProps + console.log(article.get('commentInCashe')) + if (! article.get('commentInCashe') ) { + return { + comments : commentsSelector(state), + loading: commentsLoadingSelector(state) + } + } + + return { + comments : commentsSelectorCashe(state, ownProps ), + loading: commentsLoadingSelector(state) + } + +}, { loadCommentForArticle, loadCommentToCashe } ) (toggleOpen(CommentList)) \ No newline at end of file diff --git a/src/constants/index.js b/src/constants/index.js index f34f842..8ca132b 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -8,7 +8,11 @@ export const CHANGE_SELECTION = 'CHANGE_SELECTION' export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE' export const ADD_COMMENT = 'ADD_COMMENT' +export const LOAD_COMMENT = 'LOAD_COMMENT' + export const START = '_START' export const SUCCESS = '_SUCCESS' -export const FAIL = '_FAIL' \ No newline at end of file +export const FAIL = '_FAIL' + +export const LOAD_COMMENT_TO_CASHE = 'LOAD_COMMENT_TO_CASHE' \ No newline at end of file diff --git a/src/reducer/articles.js b/src/reducer/articles.js index fd5939a..0a25045 100644 --- a/src/reducer/articles.js +++ b/src/reducer/articles.js @@ -1,6 +1,6 @@ import { Map, Record } from 'immutable' -import { DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, START, SUCCESS, FAIL } from '../constants' -import {arrToMap} from './utils' +import { DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE, START, SUCCESS, FAIL, LOAD_COMMENT_TO_CASHE } from '../constants' +import { arrToMap } from './utils' const ArticleRecord = Record({ id: null, @@ -8,7 +8,8 @@ const ArticleRecord = Record({ text: null, date: null, loading: false, - comments: [] + comments: [], + commentInCashe: false }) const ReducerRecord = Record({ @@ -50,7 +51,25 @@ export default (articles = new ReducerRecord(), action) => { case LOAD_ARTICLE + SUCCESS: return articles.setIn(['entities', payload.id], new ArticleRecord(payload.response)) - } + + + case LOAD_COMMENT_TO_CASHE: + { + + // console.log(payload.CasheComment) + // console.log(payload.id) + // articles: articles.updateIn( + // ['entities', payload.id, 'commentInCashe'], + // true + // ) + + return articles.updateIn( + ['entities', payload.id, 'comments'], + (comments) => payload.CasheComment + ).setIn(['entities', payload.id, 'commentInCashe'], true) + } + + } return articles } \ No newline at end of file diff --git a/src/reducer/comments.js b/src/reducer/comments.js index 764e28c..f4f7053 100644 --- a/src/reducer/comments.js +++ b/src/reducer/comments.js @@ -1,17 +1,47 @@ -import { ADD_COMMENT } from '../constants' -import {normalizedComments} from '../fixtures' -import {arrToMap} from './utils' +import { ADD_COMMENT, LOAD_COMMENT, START, SUCCESS } from '../constants' -export default (state = arrToMap(normalizedComments), action) => { - const { type, payload, randomId } = action +import { arrToMap } from './utils' +import { Map, Record } from 'immutable' + + + +const CommentsRecord = Record({ + id: null, + text: null, + user: null, + loading: false +}) + +const ReducerRecord = Record({ + entities: arrToMap([], CommentsRecord), + loading: false, + loaded: false, + error: null +}) + + +export default (comments = new ReducerRecord(), action) => { + const { type, payload, randomId, response, error } = action switch (type) { case ADD_COMMENT: - return state.set(randomId, { + return comments.setIn(['entities', randomId], new CommentsRecord({ ...payload.comment, id: randomId - }) + })) + + case LOAD_COMMENT + START: + return comments.set('loading', true) + + case LOAD_COMMENT + SUCCESS: + { + console.log(payload.response) + return comments + .set('loading', false) + .set('loaded', true) + .set('entities', arrToMap(payload.response, CommentsRecord)) + } } - return state + return comments } \ No newline at end of file diff --git a/src/selectors/index.js b/src/selectors/index.js index c358756..d350147 100644 --- a/src/selectors/index.js +++ b/src/selectors/index.js @@ -1,6 +1,10 @@ -import {createSelector} from 'reselect' +import { createSelector } from 'reselect' +import comments from '../reducer/comments'; +import articles from '../reducer/articles'; 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 @@ -9,7 +13,7 @@ export const idSelector = (_, props) => props.id export const articlesSelector = createSelector(articlesMapSelector, articles => articles.valueSeq().toArray()) export const filtratedArticlesSelector = createSelector(articlesSelector, filtersSelector, (articles, filters) => { - const {selected, dateRange: {from, to}} = filters + const { selected, dateRange: { from, to } } = filters return articles.filter(article => { const published = Date.parse(article.date) @@ -18,6 +22,21 @@ export const filtratedArticlesSelector = createSelector(articlesSelector, filter }) }) -export const createCommentSelector = () => createSelector(commentListSelector, idSelector, (comments, id) => { - return comments.get(id) +// export const createCommentSelector = () => createSelector(commentListSelector, idSelector, (comments, id) => { +// return comments.get(id) +// }) + +export const commentsMapSelector = state => state.comments.entities +export const commentsSelector = createSelector(commentsMapSelector, comments => comments.valueSeq().toArray()) + + +export const commentsLoadingSelector = state => state.comments.loading + +export const commentSelectorId = createSelector(commentsSelector, idSelector, (comments, id) => { + return comments.find(comment => comment.id == id) +}) + +/// непонятно как получить комеенты кеша которые там есть в +export const commentsSelectorCasheArt = createSelector(articlesSelector, idSelector, (articles, id) => { + return (articles.find(article => article.id == id)).comments }) \ No newline at end of file