Home Reference Source

app/components/CommentGroup.jsx

import React, { Component } from 'react';
import { connect } from 'react-redux';
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';
import Divider from 'material-ui/Divider';
import { ListItem } from 'material-ui/List';

// - Import actions
import * as commentActions from 'commentActions';

// - Import app components
import CommentList from 'CommentList';
import CommentWrite from 'CommentWrite';
import UserAvatar from 'UserAvatar';

export class CommentGroup extends Component {
    /**
     * Component constructor
     * @param  {object} props is an object properties of component
     */
    constructor(props) {
        super(props);

        this.state = {
            commentText: "",
            postDisable: true
        };
    }

    // Clear comment text field
    clearCommentWrite = () => {
        this.setState({
            commentText: '',
            postDisable: false
        });
    }

    // Post comment
    handlePostComment = () => {
        this.props.send(this.state.commentText, this.props.postId, this.clearCommentWrite);
    }

    /**
     * When comment text changed
     * @param  {event} evt is an event passed by change comment text callback funciton
     * @param  {string} data is the comment text which user writes
     */
    handleOnChange = (evt, data) => {
        this.setState({ commentText: data });

        if (data.length === 0 || data.trim() === '') {
            this.setState({
                commentText: '',
                postDisable: true
            });
        }

        else {
            this.setState({
                commentText: data,
                postDisable: false
            });
        }
    }

    /**
     * Get comments' DOM
     * @return {DOM} list of comments' DOM
     */
    commentList = () => {
        let comments = this.props.comments;

        if (comments) {
            let parsedComments = [];

            Object.keys(comments).slice(0, 3).forEach((commentId) => {
                parsedComments.push({
                    id: commentId,
                    ...comments[commentId]
                });
            });

            if (parsedComments.length === 2) {
                parsedComments.push(parsedComments[0]);
            }

            else if (parsedComments.length === 1) {
                parsedComments.push(parsedComments[0]);
                parsedComments.push(parsedComments[0]);
            }

            return parsedComments.map((comment, index) => {
                const { userInfo } = this.props;

                const commentAvatar = userInfo && userInfo[comment.userId] ? userInfo[comment.userId].avatar || '' : '';
                const commentFullName = userInfo && userInfo[comment.userId] ? userInfo[comment.userId].fullName || '' : '';

                return (<div style={{borderRadius: "0 0 7px 7px"}}><ListItem key={index} style={{ position: "", zIndex: "" }} innerDivStyle={{ padding: "6px 16px 16px 72px" }}
                    leftAvatar={<UserAvatar fullName={commentFullName} fileName={commentAvatar} style={{ top: "8px" }} size={36} />}
                    secondaryText={<div>
                        <span style={{ fontSize: "13px", color: "rgba(0,0,0,0.87)", textOverflow: "ellipsis", overflow: "hidden", display: 'block' }}>
                            {comment.userDisplayName}
                        </span>

                        <span style={{ fontSize: "13px", color: "rgba(0,0,0,0.87)", fontWeight: 300, whiteSpace: "pre-wrap", display: 'block' }}>
                            {comment.text}
                        </span>
                    </div>}
                    secondaryTextLines={2} /></div>
                );
            });
        }
    }

    /**
     * Reneder component DOM
     * @return {react element} return the DOM which rendered by component
     */
    render() {
        return (
            <div>
                <div style={this.props.comments && Object.keys(this.props.comments).length > 0 ? { display: "block" } : { display: "none" }}>
                    <Divider />
                    <div style={!this.props.open ? { display: "block" } : { display: "none" }}>
                    {/* <Paper zDepth={0} className="animate-top" style={!this.props.open ? { display: "block" } : { display: "none" }}> */}
                        <div style={{ position: "relative", height: "60px", borderRadius: '0 0 7px 7px' }} >
                            {/* <FlatButton label=" " style={{ height: "60px", zIndex: 5, borderRadius: '0 0 7px 7px' }} fullWidth={true} onClick={this.props.onToggleRequest} /> */}

                            <div className="comment__list-show">
                                {this.commentList()}
                            </div>
                        </div>
                    </div>
                    {/* </Paper> */}
                    {(this.props.comments && Object.keys(this.props.comments).length > 0)
                        ? (<Paper zDepth={0} style={this.props.open ? { display: "block", padding: "0px 0px" } : { display: "none", padding: "12px 16px" }}>
                            <CommentList comments={this.props.comments} isPostOwner={this.props.isPostOwner} disableComments={this.props.disableComments} />
                        </Paper>) : ''}
                </div>

                {!this.props.disableComments ? (<div>
                    <Divider />
                    <Paper zDepth={0} className="animate2-top10" style={{ position: "relative", overflowY: "auto", padding: "12px 16px", display: (this.props.open ? "block" : "none"), borderRadius: "0 0 7px 7px" }}>
                        <div style={{ display: "flex" }}>
                            <UserAvatar fullName={this.props.fullName} fileName={this.props.avatar} style={{ flex: "none", margin: "4px 0px" }} size={36} />
                            <div style={{ outline: "none", marginLeft: "16px", flex: "auto", flexGrow: 1 }}>
                                <TextField
                                    value={this.state.commentText}
                                    onChange={this.handleOnChange}
                                    hintText="Add a comment..."
                                    underlineShow={false}
                                    multiLine={true}
                                    rows={1}
                                    hintStyle={{ fontWeight: 100, fontSize: "14px" }}
                                    rowsMax={4}
                                    textareaStyle={{ fontWeight: 100, fontSize: "14px" }}
                                    style={{ width: '100%' }}
                                />
                            </div>
                        </div>
                        <FlatButton primary={true} disabled={this.state.postDisable} label="Post" style={{ float: "right", clear: "both", zIndex: 5, margin: "0px 5px 5px 0px", fontWeight: 400 }} onClick={this.handlePostComment} />
                    </Paper>
                </div>) : ''}
            </div>
        );
    }
}

/**
 * Map dispatch to props
 * @param  {func} dispatch is the function to dispatch action to reducers
 * @param  {object} ownProps is the props belong to component
 * @return {object}          props of component
 */
const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        send: (text, postId, callBack) => {
            dispatch(commentActions.dbAddComment({
                postId: postId,
                text: text,
                ownerPostUserId: ownProps.ownerPostUserId
            }, callBack))
        }
    }
}

/**
 * Map state to props
 * @param  {object} state is the obeject from redux store
 * @param  {object} ownProps is the props belong to component
 * @return {object}          props of component
 */
const mapStateToProps = (state, ownProps) => {
    return {
        comments: state.comment.postComments[ownProps.postId],
        avatar: state.user.info && state.user.info[state.authorize.uid] ? state.user.info[state.authorize.uid].avatar || '' : '',
        fullName: state.user.info && state.user.info[state.authorize.uid] ? state.user.info[state.authorize.uid].fullName || '' : '',
        userInfo: state.user.info

    }
}

// - Connect component to redux store
export default connect(mapStateToProps, mapDispatchToProps)(CommentGroup)