diff --git a/Comment.js b/Comment.js
index 999736a..172206f 100755
--- a/Comment.js
+++ b/Comment.js
@@ -125,7 +125,7 @@ Comment.propTypes = {
image: PropTypes.string,
likeAction: PropTypes.func,
liked: PropTypes.bool,
- likesNr: PropTypes.int,
+ likesNr: PropTypes.number,
likesTapAction: PropTypes.func,
replyAction: PropTypes.func,
reportAction: PropTypes.func,
diff --git a/index.js b/index.js
index 297511b..efabd79 100755
--- a/index.js
+++ b/index.js
@@ -7,22 +7,43 @@ import {
Text,
Image,
FlatList,
+ Modal,
+ Dimensions,
ActivityIndicator,
+ TextInput,
TouchableHighlight,
TouchableOpacity
} from 'react-native'
import PropTypes from 'prop-types'
-import TimeAgo from 'react-native-timeago'
import Icon from 'react-native-vector-icons/FontAwesome'
import styles from './styles'
import Collapsible from 'react-native-collapsible'
-import * as commentActions from './ExampleActions'
+import Comment from './Comment'
-export default class Comment extends PureComponent {
+const screen = Dimensions.get('screen')
+
+export default class Comments extends PureComponent {
constructor (props) {
super(props)
+ this.bookmark = null
+ this.props = props
+ this.state = {
+ loadingComments: props.data && props.data.length ? false : true,
+ likesModalVisible: false,
+ likesModalData: null,
+ editModalVisible: false,
+ commentsLastUpdated: null,
+ expanded: [],
+ pagination: []
+ }
+ this.newCommentText = null
+ this.replyCommentText = null
+ this.editCommentText = null
+ this.editingComment = null
+ this.textInputs = []
+ this.renderComment = this.renderComment.bind(this)
this.handleReport = this.handleReport.bind(this)
this.handleReply = this.handleReply.bind(this)
@@ -30,99 +51,440 @@ export default class Comment extends PureComponent {
this.handleEdit = this.handleEdit.bind(this)
this.handleUsernameTap = this.handleUsernameTap.bind(this)
this.handleLikesTap = this.handleLikesTap.bind(this)
+ this.handleEditAction = this.handleEditAction.bind(this)
+ this.renderLike = this.renderLike.bind(this)
+ }
+
+ setLikesModalVisible (visible) {
+ this.setState({likesModalVisible: visible})
+ }
+
+ setEditModalVisible (visible) {
+ this.setState({editModalVisible: visible})
+ }
+
+ componentWillReceiveProps (nextProps) {
+ if (nextProps.data) {
+ this.setState({
+ commentsLastUpdated: new Date().getTime(),
+ loadingComments: false
+ })
+ }
+
+ }
+
+ isExpanded (id) {
+ return this.state.expanded.indexOf(id) !== -1
+ }
+
+ toggleExpand (id) {
+
+ let expanded = this.state.expanded
+
+ let index = expanded.indexOf(id)
+
+ if (index === -1) {
+ expanded.push(id)
+ } else {
+
+ expanded.splice(index, 1)
+
+ }
+ this.forceUpdate()
+ this.setState({expanded: expanded})
+
+ }
+
+ handleReport (c) {
+ this.props.reportAction(c)
+ }
+
+ handleReply (c) {
+ if (!this.props.isChild(c)) {
+ this.toggleExpand(this.props.keyExtractor(c))
+ } else {
+ let input = this.textInputs['input' + this.props.parentIdExtractor(c)]
+ input.measure((x, y, width, height, pageX, pageY) => {
+ input.focus()
+ this.props.replyAction(pageY)
+ })
+ }
}
- handleReport(){
- this.props.reportAction(this.props.data)
+ handleLike (c) {
+ this.props.likeAction(c)
}
- handleReply(){
- this.props.replyAction(this.props.data)
+
+ handleEdit (c) {
+ this.editCommentText = this.props.bodyExtractor(c)
+ this.editingComment = c
+ this.setEditModalVisible(!this.state.editModalVisible)
+ }
+
+ handleUsernameTap (username) {
+ this.props.usernameTapAction(username)
+ }
+
+ handleLikesTap (c) {
+ this.setState({likesModalData: this.props.likesExtractor(c)})
+ this.setLikesModalVisible(!this.state.likesModalVisible)
+ }
+
+ handleEditAction (c) {
+ this.props.editAction(this.editCommentText, c)
+ }
+
+ /**
+ *
+ * Generates a single comment
+ * */
+ generateComment (c) {
+ return
+ }
+
+ /**
+ * Renders comments children
+ * */
+ renderChildren (items) {
+ if (!items || !items.length) return
+ let self = this
+ return items.map(function (c) {
+
+ return
+ {self.generateComment(c)}
+
+
+
+ })
+
+ }
+
+ /**
+ * Returns last child id
+ * */
+ getLastChildCommentId (item) {
+ if (!item) return
+ const items = item[this.props.childPropName]
+ return this.props.keyExtractor(items[items.length - 1])
+ }
+
+ /**
+ * Returns first child id
+ * */
+ getFirstChildCommentId (item) {
+ if (!item) return
+ const items = item[this.props.childPropName]
+
+ return this.props.keyExtractor(items[0])
}
- handleLike(){
- this.props.likeAction(this.props.data)
+
+ /**
+ * Does a pagination action
+ * */
+ paginate (fromCommentId, direction, parentCommentId) {
+ this.setState({loadingComments: true})
+ this.props.paginateAction(fromCommentId, direction, parentCommentId)
+
}
- handleEdit(){
- this.props.editComment(this.props.data)
+
+ /**
+ * Can user edit a comment
+ * */
+ canUserEdit (item) {
+ if (this.props.viewingUserName == this.props.usernameExtractor(item)) {
+ if (!this.props.editMinuteLimit) return true
+ let created = new Date(this.props.createdTimeExtractor(item)).getTime() / 1000
+ return new Date().getTime() / 1000 - created < this.props.editMinuteLimit * 60
+ }
+ return false
}
- handleUsernameTap(){
- this.props.usernameTapAction(this.props.username)
+
+ renderLike (l) {
+ let like = l.item
+ return {this.setLikesModalVisible(false), like.tap(like.name)}}
+ style={styles.likeButton} key={like.user_id}>
+
+
+ {like.name}
+
+
}
- handleLikesTap(){
- this.props.likesTapAction(this.props.data)
+
+ /**
+ * Renders a comment with pagination
+ * */
+ renderComment (c) {
+
+ const item = c.item
+ return
+ {this.generateComment(item)}
+
+ {item.childrenCount ? this.toggleExpand(this.props.keyExtractor(item))}>
+
+
+ {this.props.usernameExtractor(item.children[0])}
+ replied
+ * {this.props.childrenCountExtractor(item)}
+ {this.props.childrenCountExtractor(item) > 1 ? ' replies' : ' reply'}
+
+ : null}
+
+ {this.props.childrenCountExtractor(item) ?
+ {this.props.childrenCountExtractor(item) > item[this.props.childPropName].length
+ ?
+ this.paginate(this.getFirstChildCommentId(item), 'down',
+ this.props.keyExtractor(item))
+ }>
+ Show
+ previous...
+
+ : null}
+
+ {this.renderChildren(item[this.props.childPropName], this.props.keyExtractor(item))}
+
+ {this.props.childrenCountExtractor(item) > item[this.props.childPropName].length
+ ? this.paginate(this.getLastChildCommentId(item), 'up',
+ this.props.keyExtractor(item))}>
+ Show
+ more...
+
+ : null}
+ : null}
+
+ this.textInputs['input' + this.props.keyExtractor(item)] = input}
+ style={styles.input}
+ multiline={true}
+ onChangeText={(text => this.replyCommentText = text)}
+ placeholder={'Write comment'}
+ numberOfLines={3}
+ />
+ {
+ this.props.saveAction(
+ this.replyCommentText, this.props.keyExtractor(item))
+ this.replyCommentText = null
+ this.textInputs['input' + this.props.keyExtractor(item)].clear()
+ }
+ }>
+
+
+
+
+
+
+
+
}
render () {
return (
-
-
-
-
-
- {this.props.likesNr ?
-
-
- {this.props.likesNr}
-
- : null}
-
+
+
+ this.textInputs['inputMain'] = input}
+ multiline={true}
+ onChangeText={((text) => this.newCommentText = text)}
+ placeholder={'Write comment'}
+ numberOfLines={3}
+ />
+ {
+ this.props.saveAction(this.newCommentText, false)
+ this.newCommentText = null
+ this.textInputs['inputMain'].clear()
+
+ }}>
+
-
-
-
-
- {this.props.username}
-
-
- {this.props.canEdit ?
-
- : null}
+ {!this.state.loadingComments && !this.props.data ?
+ No comments yet : null}
+
+
+ {!this.state.loadingComments && this.props.data ? {
+ this.paginate(this.props.keyExtractor(this.props.data[0]), 'down')
+ }}>
+
+ Show previous
- {this.props.body}
-
-
-
-
-
- Like
+
+ : null}
+ {/*Comments*/}
+ {this.props.data
+ ? this.props.keyExtractor(item)}
+ renderItem={this.renderComment}/>
+ : null}
+
+ {this.state.loadingComments ?
+
+ : null}
+
+
+ {!this.state.loadingComments
+ && this.props.data
+ ? {
+ this.paginate(this.props.keyExtractor(this.props.data[this.props.data.length - 1]), 'up')
+ }}>
+
+ Show more
+
+ : null}
+
+
+ {
+ this.setLikesModalVisible(false)
+
+ }}>
+ this.setLikesModalVisible(false)}
+ style={{
+ position: "absolute",
+ width: 100,
+ zIndex: 9,
+ alignSelf: "flex-end",
+ top: 10
+ }}>
+
+
+
+
+ Users that liked the comment
+ {this.state.likesModalVisible ? item.like_id}
+ data={this.state.likesModalData}
+ renderItem={this.renderLike}
+ /> : null}
+
+
+ {this.textInputs['editCommentInput'].focus()}}
+ transparent={true}
+ visible={this.state.editModalVisible}
+ onRequestClose={() => {
+ this.setEditModalVisible(false)
+ this.setState({editModalData: null})
+ }}>
+
+
+ this.textInputs['editCommentInput'] = input}
+ style={styles.input}
+ multiline={true}
+ defaultValue={this.editCommentText}
+ onChangeText={(text => this.editCommentText = text)}
+ placeholder={'Edit comment'}
+ numberOfLines={3}
+ />
+
+ this.setEditModalVisible(false)}>
+
+ Cancel
+
+
+
+ {
+ this.props.editAction(this.editCommentText, this.editingComment)
+ this.setEditModalVisible(!this.state.editModalVisible)
+ }}>
+
+ Save
+
+
+
-
-
- Reply
-
-
- {this.props.reported ? Reported
- : Report}
-
+
+
-
+
)
}
}
-Comment.propTypes = {
- data: PropTypes.object,
- body: PropTypes.string,
- canEdit: PropTypes.bool,
- child: PropTypes.bool,
- editComment: PropTypes.func,
- image: PropTypes.string,
- likeAction: PropTypes.func,
- liked: PropTypes.bool,
- likesNr: PropTypes.numeric,
- likesTapAction: PropTypes.func,
- replyAction: PropTypes.func,
- reportAction: PropTypes.func,
- reported: PropTypes.bool,
- updatedAt: PropTypes.string,
- username: PropTypes.string,
- usernameTapAction: PropTypes.func
-}
\ No newline at end of file
+Comments.propTypes = {
+ data: PropTypes.array.isRequired,
+ viewingUserName: PropTypes.string,
+ initialDisplayCount: PropTypes.number,
+ editMinuteLimit: PropTypes.number,
+ usernameTapAction: PropTypes.func.isRequired,
+ childPropName: PropTypes.string.isRequired,
+ isChild: PropTypes.func.isRequired,
+ keyExtractor: PropTypes.func.isRequired,
+ parentIdExtractor: PropTypes.func.isRequired,
+ usernameExtractor: PropTypes.func.isRequired,
+ editTimeExtractor: PropTypes.func.isRequired,
+ createdTimeExtractor: PropTypes.func.isRequired,
+ bodyExtractor: PropTypes.func.isRequired,
+ imageExtractor: PropTypes.func.isRequired,
+ likeExtractor: PropTypes.func.isRequired,
+ reportedExtractor: PropTypes.func.isRequired,
+ likesExtractor: PropTypes.func.isRequired,
+ childrenCountExtractor: PropTypes.func.isRequired,
+ replyAction: PropTypes.func.isRequired,
+ saveAction: PropTypes.func.isRequired,
+ editAction: PropTypes.func.isRequired,
+ reportAction: PropTypes.func.isRequired,
+ likeAction: PropTypes.func.isRequired,
+ paginateAction: PropTypes.func.isRequired
+}
+
+