Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HT6 #36

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

HT6 #36

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
31 changes: 18 additions & 13 deletions src/AC/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {DELETE_ARTICLE, INCREMENT, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT,
LOAD_ALL_ARTICLES, LOAD_ARTICLE, START, SUCCESS, FAIL
LOAD_ALL_ARTICLES, LOAD_ALL_COMMENTS, LOAD_ARTICLE, START, SUCCESS, FAIL
} from '../constants'

export function increment() {
Expand Down Expand Up @@ -44,25 +44,30 @@ export function loadAllArticles() {
}
}

export function loadAllComments() {
return {
type: LOAD_ALL_COMMENTS,
callAPI: '/api/comment'
Copy link
Owner

Choose a reason for hiding this comment

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

не все комменты, только для одной статьи

}
}

export function loadArticle(id) {
return (dispatch) => {
dispatch({
type: LOAD_ARTICLE + START,
payload: { id }
})

setTimeout(() => {
fetch(`/api/article/${id}`)
.then(res => res.json())
.then(response => dispatch({
type: LOAD_ARTICLE + SUCCESS,
payload: { id, response }
}))
.catch(error => dispatch({
type: LOAD_ARTICLE + FAIL,
payload: { id, error }
}))
}, 1000)
fetch(`/api/article/${id}`)
.then(res => res.json())
.then(response => dispatch({
type: LOAD_ARTICLE + SUCCESS,
payload: { id, response }
}))
.catch(error => dispatch({
type: LOAD_ARTICLE + FAIL,
payload: { id, error }
}))
}
}

Expand Down
20 changes: 10 additions & 10 deletions src/components/Comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import {commentSelectorFactory} from '../selectors'

function Comment({comment}) {
function Comment({comment = {}}) {
return (
<div>
<p>{comment.text} <b>by {comment.user}</b></p>
Expand All @@ -20,14 +20,14 @@ Comment.propTypes = {
}).isRequired
}

const mapStateToProps = () => {
const commentSelector = commentSelectorFactory()
// const mapStateToProps = () => {
// const commentSelector = commentSelectorFactory()

return (state, ownProps) => {
return {
comment: commentSelector(state, ownProps)
}
}
}
// return (state, ownProps) => {
// return {
// comment: commentSelector(state, ownProps)
// }
// }
// }

export default connect(mapStateToProps)(Comment)
export default Comment
79 changes: 53 additions & 26 deletions src/components/CommentList.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ import PropTypes from 'prop-types'
import Comment from './Comment'
import CommentForm from './CommentForm'
import toggleOpen from '../decorators/toggleOpen'
import {connect} from 'react-redux'
import {loadAllComments} from '../AC'
import Loader from './Loader'

function CommentList({article, isOpen, toggleOpen}) {
const text = isOpen ? 'hide comments' : 'show comments'
return (
<div>
<button onClick={toggleOpen}>{text}</button>
{getBody({article, isOpen})}
</div>
)
class CommentList extends Component {
render() {
let { article, isOpen, toggleOpen, loadAllComments, loaded, loading, comments } = this.props

const text = isOpen ? 'hide comments' : 'show comments'
return (
<div>
<button onClick={toggleOpen}>{text}</button>
{isOpen && <Comments {...{article, isOpen, loadAllComments, loaded, loading, commentsState: comments}} />}
</div>
)
}
}

CommentList.propTypes = {
Expand All @@ -21,23 +28,43 @@ CommentList.propTypes = {
toggleOpen: PropTypes.func
}

function getBody({article: {comments = [], id}, isOpen}) {
if (!isOpen) return null
if (!comments.length) return (
<div>
<p>No comments yet</p>
<CommentForm articleId = {id} />
</div>
)

return (
<div>
<ul>
{comments.map(id => <li key={id}><Comment id = {id}/></li>)}
</ul>
<CommentForm articleId = {id} />
</div>
)
class Comments extends Component {
componentDidMount() {
Copy link
Owner

Choose a reason for hiding this comment

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

а изменения, только mount?

const {loaded, loading, loadAllComments} = this.props
if (!loaded || !loading) loadAllComments()
}

render() {
let {article: {comments = [], id}, loading, commentsState} = this.props

if (loading) return <Loader />

if (!comments.length) return (
<div>
<p>No comments yet</p>
<CommentForm articleId = {id} />
</div>
)

return (
<div>
<ul>
{comments.map(id =>
<li key={id}>
<Comment comment = {commentsState.get(id)}/>
</li>
)}
</ul>
<CommentForm articleId = {id} />
</div>
)
}
}

export default toggleOpen(CommentList)
export default toggleOpen(connect((state) => {
return {
comments: state.comments.comments,
loading: state.comments.loading,
loaded: state.comments.loaded
}
}, {loadAllComments})(CommentList))
4 changes: 3 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ export const ADD_COMMENT = 'ADD_COMMENT'

export const START = '_START'
export const SUCCESS = '_SUCCESS'
export const FAIL = '_FAIL'
export const FAIL = '_FAIL'

export const LOAD_ALL_COMMENTS = 'LOAD_ALL_COMMENTS'
2 changes: 1 addition & 1 deletion src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export function arrToMap(arr, DataRecord = Map) {

export function mapToArr(obj) {
return obj.valueSeq().toArray()
}
}
17 changes: 6 additions & 11 deletions src/middlewares/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@ export default store => next => action => {
const {callAPI, type, ...rest} = action
if (!callAPI) return next(action)

next({
...rest, type: type + START
})
next({ ...rest, type: type + START })

setTimeout(() => {
fetch(callAPI)
.then(res => res.json())
.then(response => next({...rest, type: type + SUCCESS, response}))
.catch(error => next({...rest, type: type + FAIL, error}))
}, 1000)

}
fetch(callAPI)
.then(res => res.json())
.then(response => next({ ...rest, type: type + SUCCESS, response }))
.catch(error => next({ ...rest, type: type + FAIL, error }))
}
2 changes: 1 addition & 1 deletion src/reducer/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ export default (articleState = defaultState, action) => {
}

return articleState
}
}
37 changes: 31 additions & 6 deletions src/reducer/comments.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
import {normalizedComments as defaulComments} from '../fixtures'
import {ADD_COMMENT} from '../constants'
import {ADD_COMMENT, LOAD_ALL_COMMENTS, START, SUCCESS} from '../constants'
import {arrToMap} from '../helpers'
import {OrderedMap, Record} from 'immutable'

const commentsMap = arrToMap(defaulComments)
const CommentRecord = Record({
id: null,
user: '',
text: ''
})

export default (commentsState = commentsMap, action) => {
const {type, payload, randomId} = action
const ReducerState = Record({
comments: new OrderedMap({}),
Copy link
Owner

Choose a reason for hiding this comment

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

лучше нейтральное название, вроде entities

loading: false,
loaded: false
Copy link
Owner

Choose a reason for hiding this comment

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

Такая система не пойдет, нужно было загружать не все комменты, а для отдельных статей

})

const defaultState = new ReducerState()

export default (commentsState = defaultState, action) => {
const {type, payload, randomId, response} = action

switch (type) {
case ADD_COMMENT:
return {...commentsState, [randomId]: payload.comment}
return commentsState.updateIn([randomId]: payload.comment)

case LOAD_ALL_COMMENTS + START:
return commentsState.set('loading', true)

case LOAD_ALL_COMMENTS + SUCCESS:{
let comments = arrToMap(Array.prototype.slice.call(response.records), CommentRecord)
Copy link
Owner

Choose a reason for hiding this comment

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

slice лишнее


return commentsState
.set('comments', comments)
.set('loading', false)
.set('loaded', true)
}
}

return commentsState
}
}