Skip to content

Commit db612f2

Browse files
author
Parth Shah
committed
fixes #474
1 parent bc9ff21 commit db612f2

File tree

7 files changed

+181
-199
lines changed

7 files changed

+181
-199
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"formsy-react": "^0.18.1",
4343
"history": "^1.17.0",
4444
"isomorphic-fetch": "^2.2.1",
45+
"lodash": "^4.16.4",
4546
"moment": "^2.14.1",
4647
"react": "^15.3.1",
4748
"react-addons-css-transition-group": "^15.3.1",

src/components/MessageDetails/MessageDetails.jsx

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,43 @@ import ActionCard from '../ActionCard/ActionCard'
55
import BtnSeparator from '../ActionCard/BtnSeparator'
66
import Comment from '../ActionCard/Comment'
77
import AddComment from '../ActionCard/AddComment'
8-
import { THREAD_MESSAGES_PAGE_SIZE } from '../../config/constants'
98

109
class MessageDetails extends React.Component {
1110

1211
constructor(props) {
1312
super(props)
1413
this.handleLoadMoreClick = this.handleLoadMoreClick.bind(this)
15-
this.state = { showAll: false }
1614
}
1715

1816
handleLoadMoreClick() {
19-
this.setState({showAll: true})
20-
// TODO - handle the case when a topic has more than 20 comments
21-
// since those will have to retrieved from the server
22-
// if (!isLoadingComments) {
23-
// onLoadMoreComments()
24-
// }
17+
this.props.onLoadMoreMessages()
2518
}
2619

2720
render() {
2821
const {
29-
title,
30-
messages,
31-
// onLoadMoreMessages,
32-
hasMoreMessages,
33-
newMessage,
34-
onNewMessageChange,
35-
onAddNewMessage,
36-
isLoadingComments,
37-
currentUser,
38-
isAddingComment,
39-
error,
40-
allowAddingComment} = this.props
22+
title,
23+
messages,
24+
hasMoreMessages,
25+
newMessage,
26+
onNewMessageChange,
27+
onAddNewMessage,
28+
isLoadingComments,
29+
currentUser,
30+
isAddingComment,
31+
error,
32+
allowAddingComment} = this.props
4133
let authorName = currentUser.firstName
4234
if (authorName && currentUser.lastName) {
4335
authorName += ' ' + currentUser.lastName
4436
}
45-
let _messages = messages
46-
let _hasMoreMessages = hasMoreMessages
47-
if (!this.state.showAll && _messages.length > THREAD_MESSAGES_PAGE_SIZE) {
48-
_messages = _messages.slice(-THREAD_MESSAGES_PAGE_SIZE)
49-
_hasMoreMessages = true
50-
}
5137
return (
5238
<ActionCard className="main-messaging">
5339
<ActionCard.Header title={title}>
54-
{_hasMoreMessages && <BtnSeparator onClick={this.handleLoadMoreClick} isLoadingComments={ isLoadingComments }>
40+
{hasMoreMessages && <BtnSeparator onClick={this.handleLoadMoreClick} isLoadingComments={ isLoadingComments }>
5541
{isLoadingComments ? 'Loading...' : 'Load earlier messages'}
5642
</BtnSeparator>}
5743
</ActionCard.Header>
58-
{_messages && _messages.map((item, idx) =>
44+
{messages && messages.map((item, idx) =>
5945
<Comment
6046
key={idx}
6147
avatarUrl={item.author.photoURL}

src/projects/actions/projectTopics.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ const getTopicsWithComments = (projectId, tag) => {
6060
return { topics, totalCount }
6161
}
6262
return Promise.all(additionalPosts)
63-
.then(posts => {
64-
_.forEach(posts, (p) => {
65-
const topic = _.find(topics, p.topicId)
63+
.then(postArr => {
64+
_.forEach(postArr, (p) => {
65+
const topic = _.find(topics, t => p.topicId)
6666
topic.posts = _.sortBy(topic.posts.concat(p.posts), ['id'])
6767
})
6868
return { topics, totalCount }
@@ -113,11 +113,11 @@ export function createProjectTopic(projectId, topic) {
113113
}
114114
}
115115

116-
export function loadFeedComments(feedId, tag, fromIndex) {
116+
export function loadFeedComments(feedId, tag, postIds) {
117117
return (dispatch) => {
118118
return dispatch({
119119
type: LOAD_PROJECT_FEED_COMMENTS,
120-
payload: getTopicPosts(feedId, fromIndex),
120+
payload: getTopicPosts(feedId, postIds),
121121
meta: {
122122
topicId: feedId,
123123
tag

src/projects/detail/components/ProjectSpecSidebar.jsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import _ from 'lodash'
22
import React, { PropTypes, Component } from 'react'
33
import { connect } from 'react-redux'
4-
import update from 'react-addons-update'
54
import SidebarNav from './SidebarNav'
65
import { PROJECT_ROLE_OWNER, PROJECT_ROLE_CUSTOMER } from '../../../config/constants'
76
import { updateProject } from '../../actions/project'
@@ -87,7 +86,6 @@ class ProjectSpecSidebar extends Component {
8786
_.indexOf([PROJECT_ROLE_OWNER, PROJECT_ROLE_CUSTOMER], currentMemberRole) > -1
8887
return (
8988
<div className="projectSpecSidebar">
90-
<button onClick={() => this.props.updateProject(project.id, update(project, { details: { appDefinition: { goal: { value: { $apply: (x) => { return parseInt(x) + 1}}}}}}))} className="btn btn-primary">Test Save</button>
9189
<h4 className="titles gray-font">Specifications</h4>
9290
<div className="list-group">
9391
<SidebarNav items={navItems} />

src/projects/detail/containers/FeedContainer.js

Lines changed: 71 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { PropTypes } from 'react'
22
import _ from 'lodash'
33
import {
4+
THREAD_MESSAGES_PAGE_SIZE,
45
PROJECT_STATUS_DRAFT,
56
PROJECT_ROLE_CUSTOMER,
67
PROJECT_ROLE_COPILOT,
@@ -12,15 +13,13 @@ import {
1213
CODER_BOT_USER_LNAME
1314
} from '../../../config/constants'
1415
import { connect } from 'react-redux'
15-
import { update } from 'react-addons-update'
16+
import update from 'react-addons-update'
1617
import NewPost from '../../../components/Feed/NewPost'
1718
import Feed from '../../../components/Feed/Feed'
1819
import ProjectSpecification from '../../../components/ProjectSpecification/ProjectSpecification'
1920
import { loadDashboardFeeds, createProjectTopic, loadFeedComments, addFeedComment } from '../../actions/projectTopics'
2021
import spinnerWhileLoading from '../../../components/LoadingSpinner'
2122

22-
const FEED_COMMENTS_PAGE_SIZE = 3
23-
2423
const SYSTEM_USER = {
2524
firstName: CODER_BOT_USER_FNAME,
2625
lastName: CODER_BOT_USER_LNAME,
@@ -35,7 +34,7 @@ class FeedView extends React.Component {
3534
super(props)
3635
this.onNewPost = this.onNewPost.bind(this)
3736
this.onNewCommentChange = this.onNewCommentChange.bind(this)
38-
this.onLoadMoreComments = this.onLoadMoreComments.bind(this)
37+
this.onShowAllComments = this.onShowAllComments.bind(this)
3938
this.onAddNewComment = this.onAddNewComment.bind(this)
4039
this.state = { feeds : [], showAll: [] }
4140
}
@@ -48,62 +47,54 @@ class FeedView extends React.Component {
4847
this.init(nextProps)
4948
}
5049

50+
mapFeed(feed, showAll = false) {
51+
const { allMembers } = this.props
52+
const item = _.pick(feed, ['id', 'date', 'read', 'tag', 'title', 'totalPosts', 'userId', 'reference', 'referenceId', 'postIds', 'isAddingComment', 'isLoadingComments', 'error'])
53+
if (isSystemUser(item.userId)) {
54+
item.user = SYSTEM_USER
55+
item.allowComments = false
56+
} else {
57+
item.user = allMembers[item.userId]
58+
item.allowComments = true
59+
}
60+
item.unread = !feed.read
61+
// item.html = posts[feed.postIds[0]].body
62+
item.html = feed.posts[0].body
63+
// skip over the first post since that is the topic post
64+
item.totalComments = feed.totalPosts-1
65+
item.comments = []
66+
const _toComment = (p) => {
67+
return {
68+
id: p.id,
69+
content: p.body,
70+
unread: !p.read,
71+
date: p.date,
72+
author: isSystemUser(p.userId) ? SYSTEM_USER : allMembers[p.userId]
73+
}
74+
}
75+
if (showAll) {
76+
// if we are showing all comments, just iterate through the entire array
77+
_.forEach(_.slice(feed.posts, 1), p => {
78+
p.type === 'post' ? item.comments.push(_toComment(p)) : item.totalComments--
79+
})
80+
} else {
81+
// otherwise iterate from right and add to the beginning of the array
82+
_.forEachRight(_.slice(feed.posts, 1), (p) => {
83+
p.type === 'post' ? item.comments.unshift(_toComment(p)) : item.totalComments--
84+
if (!feed.showAll && item.comments.length === THREAD_MESSAGES_PAGE_SIZE)
85+
return false
86+
})
87+
}
88+
item.newComment = ''
89+
item.hasMoreComments = item.comments.length !== item.totalComments
90+
return item
91+
}
92+
5193
init(props) {
52-
const { allMembers, feeds } = props
94+
const { feeds } = props
5395
this.setState({
5496
feeds: feeds.map((feed) => {
55-
const item = _.pick(feed, ['id', 'date', 'read', 'tag', 'title', 'totalPosts', 'userId', 'reference', 'referenceId', 'postIds', 'isAddingComment', 'error'])
56-
// const showAll = this.state.showAll.indexOf(feed.id) > -1
57-
if (isSystemUser(item.userId)) {
58-
item.user = SYSTEM_USER
59-
item.allowComments = false
60-
} else {
61-
item.user = allMembers[item.userId]
62-
item.allowComments = true
63-
}
64-
item.unread = !feed.read
65-
// item.html = posts[feed.postIds[0]].body
66-
item.html = feed.posts[0].body
67-
// skip over the first post since that is the topic post
68-
item.totalComments = feed.totalPosts-1
69-
item.comments = []
70-
const _toComment = (p) => {
71-
return {
72-
id: p.id,
73-
content: p.body,
74-
unread: !p.read,
75-
date: p.date,
76-
author: isSystemUser(p.userId) ? SYSTEM_USER : allMembers[p.userId]
77-
}
78-
}
79-
if (feed.showAll) {
80-
// if we are showing all comments, just iterate through the entire array
81-
_.forEach(_.slice(feed.posts, 1), p => {
82-
p.type === 'post' ? item.comments.push(_toComment(p)) : item.totalComments--
83-
})
84-
} else {
85-
// otherwise iterate from right and add to the beginning of the array
86-
_.forEachRight(_.slice(feed.posts, 1), (p) => {
87-
p.type === 'post' ? item.comments.unshift(_toComment(p)) : item.totalComments--
88-
if (!feed.showAll && item.comments.length === 3)
89-
return false
90-
})
91-
}
92-
// item.comments = _.map(_.slice(feed.posts, 1), (p) => {
93-
// if (p.type === 'post') {
94-
// return {
95-
// content: p.body,
96-
// unread: !p.read,
97-
// date: p.date,
98-
// author: isSystemUser(p.userId) ? SYSTEM_USER : allMembers[p.userId]
99-
// }
100-
// } else {
101-
// item.totalComments--
102-
// }
103-
// }).filter(i => i)
104-
item.newComment = ''
105-
item.hasMoreComments = item.comments.length !== item.totalComments // FIXME
106-
return item
97+
return this.mapFeed(feed, this.state.showAll.indexOf(feed.id) > -1)
10798
}).filter(item => item)
10899
})
109100
}
@@ -118,7 +109,6 @@ class FeedView extends React.Component {
118109
this.props.createProjectTopic(project.id, newFeed)
119110
}
120111

121-
122112
onNewCommentChange(feedId, content) {
123113
this.setState({
124114
feeds: this.state.feeds.map((item) => {
@@ -130,36 +120,30 @@ class FeedView extends React.Component {
130120
})
131121
}
132122

133-
onLoadMoreComments(feedId) {
123+
onShowAllComments(feedId) {
134124
const { feeds } = this.props
135-
const feedIndex = _.findIndex(feeds, feed => feed.id === feedId)
136-
const item = this.state.feeds[feedIndex]
137-
const feed = feeds[feedIndex]
138-
const renderedCommentIds = _.map(item.comments, 'id')
139-
const commentsToRetrieve = _.without(feed.postIds.slice(1), ...renderedCommentIds)
140-
if (commentsToRetrieve.length) {
141-
this.props.loadFeedComments(feedId, PROJECT_FEED_TYPE_PRIMARY, commentsToRetrieve)
142-
}
143-
this.setState({showAll: update(this.state, { $push: feedId })})
144-
}
145-
146-
XonLoadMoreComments(feedId) {
147-
const { feeds } = this.state
148-
const feedIndex = _.findIndex(feeds, feed => feed.id === feedId)
149-
const feed = feeds[feedIndex]
150-
const renderedComments = feed.comments.length
151-
const availableComments = feed.posts.length - 1
152-
if (renderedComments < availableComments) {
153-
const nextPage = feed.posts.slice(-renderedComments-FEED_COMMENTS_PAGE_SIZE, -renderedComments)
154-
feed.comments = nextPage.concat(feed.comments)
155-
feed.hasMoreComments = feed.comments.length < feed.totalComments
156-
this.forceUpdate()
125+
const feed = _.find(feeds, feed => feed.id === feedId)
126+
const stateFeedIdx = _.findIndex(this.state.feeds, (f) => f.id === feedId)
127+
// in case we have already have all comments for that feed from the server,
128+
// just change the state to show all comments for that FeedId.
129+
// Otherwise load more comments from the server
130+
if (feed.posts.length < feed.postIds.length) {
131+
// load more from server
132+
const updatedFeed = update(this.state.feeds[stateFeedIdx], {
133+
isLoadingComments: { $set : true }
134+
})
135+
const retrievedPostIds = _.map(feed.posts, 'id')
136+
const commentIdsToRetrieve = _.filter(feed.postIds, _id => retrievedPostIds.indexOf(_id) === -1 )
137+
this.setState(update(this.state, {
138+
showAll: { $push: [feedId] },
139+
feeds: { $splice: [[stateFeedIdx, 1, updatedFeed ]] }
140+
}))
141+
this.props.loadFeedComments(feedId, PROJECT_FEED_TYPE_PRIMARY, commentIdsToRetrieve)
157142
} else {
158-
if (feed.comments && feed.comments.length < feed.totalComments) {
159-
const commentIds = feed.postIds.slice(-renderedComments-FEED_COMMENTS_PAGE_SIZE, -renderedComments)
160-
161-
this.props.loadFeedComments(feedId, PROJECT_FEED_TYPE_PRIMARY, commentIds)
162-
}
143+
this.setState(update(this.state, {
144+
showAll: { $push: [feedId] },
145+
feeds: { $splice: [[stateFeedIdx, 1, this.mapFeed(feed, true) ]] }
146+
}))
163147
}
164148
}
165149

@@ -191,7 +175,7 @@ class FeedView extends React.Component {
191175
currentUser={currentUser}
192176
onNewCommentChange={this.onNewCommentChange.bind(this, item.id)}
193177
onAddNewComment={this.onAddNewComment.bind(this, item.id)}
194-
onLoadMoreComments={this.onLoadMoreComments.bind(this, item.id)}
178+
onLoadMoreComments={this.onShowAllComments.bind(this, item.id)}
195179
>
196180
{item.sendForReview && <div className="panel-buttons">
197181
<button className="tc-btn tc-btn-primary tc-btn-md">Send for review</button>

0 commit comments

Comments
 (0)