Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/AC/index.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -72,4 +72,23 @@ export function loadArticle(id) {

}, 1000)
}
}
}

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)
}
}
15 changes: 12 additions & 3 deletions src/components/CommentList.js
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -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'
Expand All @@ -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 <Loader />

const body = comments.length ? (
const body = comments.length && loadedComments ? (
<ul>
{comments.map(id => <li key = {id}><Comment id = {id} /></li>)}
</ul>
Expand All @@ -43,4 +52,4 @@ class CommentList extends Component {
}


export default toggleOpen(CommentList)
export default connect(null, { loadComments })(toggleOpen(CommentList))
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
14 changes: 13 additions & 1 deletion src/reducer/articles.js
Original file line number Diff line number Diff line change
@@ -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({
Expand All @@ -8,6 +8,8 @@ const ArticleRecord = Record({
text: null,
date: null,
loading: false,
loadedComments: false,
loadingComments: false,
comments: []
})

Expand Down Expand Up @@ -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
Expand Down
19 changes: 14 additions & 5 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -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) => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ок, но я просил для консистентности сделать структуру как у articles

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
}
11 changes: 7 additions & 4 deletions src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand All @@ -18,6 +19,8 @@ export const filtratedArticlesSelector = createSelector(articlesSelector, filter
})
})

export const createCommentSelector = () => createSelector(commentListSelector, idSelector, (comments, id) => {
return comments.get(id)
})
export const createCommentSelector = () => {
return createSelector(commentsSelector, idSelector, (comments, id) => {
return comments.get(id)
})
}