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
29 changes: 27 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,
LOAD_ARTICLE_COMMENTS, START, SUCCESS, FAIL
LOAD_ARTICLE_COMMENTS, START, SUCCESS, FAIL, LOAD_ALL_COMMENTS
} from '../constants'

export function increment() {
Expand Down Expand Up @@ -82,4 +82,29 @@ export function loadArticleComments(articleId) {
payload: { articleId },
callAPI: `/api/comment?article=${articleId}`
}
}
}

export function loadAllcomments(offset, page) {
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.

Почему AllComments и почему бы не обойтись только page?

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.

Этого объяснить не могу((, не отрефакторил,

return (dispatch, getState) => {
const pageLoaded = getState().comments.loadedPages.has(page)
if (!pageLoaded) {
dispatch({
type: LOAD_ALL_COMMENTS + START,
})

setTimeout(() => {
fetch(`/api/comment?limit=5&offset=${offset}`)
.then(res => res.json())
.then(response => dispatch({
type: LOAD_ALL_COMMENTS + SUCCESS,
payload: { page },
response
}))
.catch(error => dispatch({
type: LOAD_ALL_COMMENTS + FAIL,
payload: { page, error }
}))
}, 1000)
}
}
}
5 changes: 4 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ArticlesPage from './components/routes/articles'
import UserForm from './components/user-form'
import Filters from './components/filters'
import Counter from './components/counter'
import AllComments from './components/AllComments'
import 'react-select/dist/react-select.css'

class App extends Component {
Expand All @@ -19,8 +20,10 @@ class App extends Component {
<li><NavLink to = "/counter" activeStyle = {{ color: 'red' }}>counter</NavLink></li>
<li><NavLink to = "/filters" activeStyle = {{ color: 'red' }}>filters</NavLink></li>
<li><NavLink to = "/articles" activeStyle = {{ color: 'red' }}>articles</NavLink></li>
<li><NavLink to = "/comments" activeStyle = {{ color: 'red' }}>comments</NavLink></li>
</ul>
<Switch>
<Route path = "/comments" component = {AllComments} />
<Route path = "/counter" component = {Counter} exact />
<Route path = "/filters" component = {Filters} />
<Route path = "/articles/new" render = {() => <h1>New Article Form</h1>} />
Expand All @@ -32,4 +35,4 @@ class App extends Component {
}
}

export default App
export default App
58 changes: 58 additions & 0 deletions src/components/AllComments/CommentsPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import Comment from '../comment'
import { commentsByPage, commentsLoading } from '../../selectors'
import { loadAllcomments } from '../../AC'
import Loader from '../loader'

class CommentsPage extends React.Component {

componentWillReceiveProps(nextProps) {
if (nextProps.page !== this.props.page) {
const { comments } = this.props
this.props.loadAllcomments((nextProps.page - 1)*5, nextProps.page)
}
}

render() {
const { comments, loading } = this.props
return(
<div>
{loading ? <Loader/> :
<ul>
{
comments.map(id =>
<li key = {id} className = "test__comment-list--item">
<Comment id = {id}/>
</li>)
}
</ul>
}
</div>
)
}
}

CommentsPage.propTypes = {
comments: PropTypes.array,
loading: PropTypes.bool,
loadAllcomments: PropTypes.fun
}

CommentsPage.defaultProps = {
comments: [],
}

const mapStateToProps = (state, ownProps) => {
return {
comments: commentsByPage(state, ownProps),
loading: commentsLoading(state)
}
}

const mapDispatchToProps = {
loadAllcomments
}

export default connect(mapStateToProps, mapDispatchToProps)(CommentsPage)
58 changes: 58 additions & 0 deletions src/components/AllComments/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react'
import { NavLink, Route } from 'react-router-dom'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import Comment from '../comment'
import CommentsPage from './CommentsPage'
import { loadAllcomments } from '../../AC'
import { allCommentsSelector, totalComments } from '../../selectors'

class AllComments extends React.Component {

componentDidMount() {
this.props.loadAllcomments(0, "1")
}

renderButtons = total => {
const count = new Array(Math.ceil(total / 5)).fill(null)
return count.map((_, index) => (
<NavLink to={`/comments/${index + 1}`} key={`button-page-${index + 1}`} >
<button>{index + 1}</button>
</NavLink>
))
}

render() {
const { total, match } = this.props
return(
<div>
<Route path = {`${match.path}/:page`} children = {this.getCommentsPage}/>
{this.renderButtons(total)}
</div>
)
}

getCommentsPage = ({ match }) => {
if (!match) {
return <CommentsPage page={"1"} />
}
return <CommentsPage page={match.params.page} />
}
}

AllComments.propTypes = {
match: PropTypes.object,
total: PropTypes.number
}

const mapStateToProps = (state, ownProps) => {
return {
total: totalComments(state),
}
}

const mapDispatchToProps = {
loadAllcomments
}

export default connect(mapStateToProps, mapDispatchToProps)(AllComments)
3 changes: 2 additions & 1 deletion src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'

export const ADD_COMMENT = 'ADD_COMMENT'
export const LOAD_ALL_COMMENTS = 'LOAD_ALL_COMMENTS'

export const START = '_START'
export const SUCCESS = '_SUCCESS'
export const FAIL = '_FAIL'
export const FAIL = '_FAIL'
4 changes: 2 additions & 2 deletions src/middlewares/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ export default store => next => action => {
type: type + START,
...rest
})

//REMOVE THIS!
setTimeout(() => {
fetch(callAPI)
.then(res => res.json())
.then(response => next({ ...rest, type: type + SUCCESS, response }))
.catch(error => next({ ...rest, type: type + FAIL, error }))
}, 1000)
}
}
19 changes: 16 additions & 3 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ADD_COMMENT, LOAD_ARTICLE_COMMENTS, SUCCESS } from '../constants'
import { ADD_COMMENT, LOAD_ARTICLE_COMMENTS, SUCCESS, LOAD_ALL_COMMENTS, START } from '../constants'
import {Record, OrderedMap} from 'immutable'
import {arrToMap} from './utils'

Expand All @@ -9,7 +9,10 @@ const CommentRecord = Record({
})

const ReducerState = Record({
entities: new OrderedMap({})
entities: new OrderedMap({}),
loadedPages: new OrderedMap({}),
total: null,
loading: false,
})

export default (state = new ReducerState(), action) => {
Expand All @@ -25,7 +28,17 @@ export default (state = new ReducerState(), action) => {
case LOAD_ARTICLE_COMMENTS + SUCCESS:
return state.mergeIn(['entities'], arrToMap(response, CommentRecord))

case LOAD_ALL_COMMENTS + START:
return state.updateIn(['loading'], value => true)

case LOAD_ALL_COMMENTS + SUCCESS:
const ids = response.records.map(comment => comment.id)
return state.mergeIn(['entities'], arrToMap(response.records, CommentRecord))
.mergeIn(['loadedPages'], new OrderedMap({[payload.page]: ids}))
.updateIn(['total'], value => response.total === value ? value : response.total )
.updateIn(['loading'], value => false)

default:
return state
}
}
}
2 changes: 1 addition & 1 deletion src/reducer/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export function arrToMap(arr, DataRecord) {
acc.set(item.id, DataRecord ? new DataRecord(item) : item)
, new OrderedMap({})
)
}
}
11 changes: 10 additions & 1 deletion src/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ export const filtratedArticles = createSelector(articleListSelector, filtersSele

export const articleSelector = createSelector(articlesMapSelector, idSelector, (articles, id) => articles.get(id))

export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))
export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))

const allCommentsSelector = state => state.comments.loadedPages.toJS()
const getPage = (_, props) => props.page
export const commentsByPage = createSelector(allCommentsSelector, getPage, (comments, page) => comments[page])

const totalCommentsSelector = state => state.comments.total
export const totalComments = createSelector(totalCommentsSelector, total => total)

export const commentsLoading = state => state.comments.loading