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
26 changes: 25 additions & 1 deletion src/AC/index.js
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -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)
}

}
16 changes: 14 additions & 2 deletions src/components/comment-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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'
Expand All @@ -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 <Loader/>

return (
<div className="test__comment-list--body">
Expand Down Expand Up @@ -66,4 +75,7 @@ class CommentList extends Component {
}


export default toggleOpen(CommentList)

export default connect(state=>({
loading:loadingCommentsSelector(state)
}),{loadCommentsForArticle})(toggleOpen(CommentList))
3 changes: 2 additions & 1 deletion src/components/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { connect } from 'react-redux'
import { createCommentSelector } from '../selectors'

function Comment({comment}) {
if(!comment) return null;
return (
<div>
{comment.text} <b>by {comment.user}</b>
Expand All @@ -15,7 +16,7 @@ Comment.propTypes = {
comment: PropTypes.shape({
text: PropTypes.string.isRequired,
user: PropTypes.string
}).isRequired
})
}

const createMapStateToProps = () => {
Expand Down
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
8 changes: 5 additions & 3 deletions src/reducer/articles.js
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -8,7 +8,8 @@ const ArticleRecord = Record({
text: null,
date: null,
loading: false,
comments: []
comments: [],
commentsLoaded:false
})

const ReducerState = Record({
Expand Down Expand Up @@ -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
Expand Down
24 changes: 22 additions & 2 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -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,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

здесь не достаточно повесить loading на весь comments, ведь ты для конкрентной статьи загружаешь

loaded: false,
error: null
})

export default (state = new ReducerState(), action) => {
const { type, payload, randomId } = action

switch (type) {
Expand All @@ -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)))
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

.mergeIn

.set("loading",false)
.set("loaded",true)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Почему loaded === true, ведь ты загрузил только для одной статьи?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Но ведь процесс загрузки комментариев был(хоть и для одной страницы) и нужно показать что он окончен. А в article я поставил признак, загружены ли комментарии для данной страницы

default:
return state
}
Expand Down
3 changes: 2 additions & 1 deletion src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down