// - Import react components import React, { Component } from 'react' import { withRouter } from 'react-router-dom' import { connect } from 'react-redux' import PropTypes from 'prop-types' import Button from 'material-ui/Button' import { grey, teal } from 'material-ui/colors' import SvgCamera from 'material-ui-icons/PhotoCamera' import Paper from 'material-ui/Paper' import List, { ListItem, ListItemIcon, ListItemText } from 'material-ui/List' import InfiniteScroll from 'react-infinite-scroller' import { getTranslate, getActiveLanguage } from 'react-localize-redux' import { Map, List as ImuList } from 'immutable' // - Import app components import PostComponent from 'src/components/post' import PostWriteComponent from 'src/components/postWrite' import UserAvatarComponent from 'src/components/userAvatar' import LoadMoreProgressComponent from 'src/layouts/loadMoreProgress' // - Import API import * as PostAPI from 'src/api/PostAPI' // - Import actions import * as globalActions from 'src/store/actions/globalActions' import { IStreamComponentProps } from './IStreamComponentProps' import { IStreamComponentState } from './IStreamComponentState' import { Post } from 'src/core/domain/posts' // - Create StreamComponent component class export class StreamComponent extends Component { static propTypes = { /** * If it's true , writing post block will be visible */ displayWriting: PropTypes.bool.isRequired, /** * A list of post */ posts: PropTypes.object, /** * The title of home header */ homeTitle: PropTypes.string } styles = { postWritePrimaryText: { color: grey[400], cursor: 'text' }, postWtireItem: { fontWeight: '200' } } /** * Component constructor * @param {object} props is an object properties of component */ constructor(props: IStreamComponentProps) { super(props) this.state = { /** * It's true if we want to have two column of posts */ divided: false, /** * If it's true comment will be disabled on post */ disableComments: this.props.disableComments!, /** * If it's true share will be disabled on post */ disableSharing: this.props.disableSharing!, /** * If it's true, post write will be open */ openPostWrite: false, /** * The title of home header */ homeTitle: props.homeTitle!, /** * If there is more post to show {true} or not {false} */ hasMorePosts: true } // Binding functions to `this` this.postLoad = this.postLoad.bind(this) this.handleOpenPostWrite = this.handleOpenPostWrite.bind(this) this.handleClosePostWrite = this.handleClosePostWrite.bind(this) } /** * Open post write * * * @memberof StreamComponent */ handleOpenPostWrite = () => { this.setState({ openPostWrite: true }) } /** * Close post write * * * @memberof StreamComponent */ handleClosePostWrite = () => { this.setState({ openPostWrite: false }) } /** * Create a list of posts * @return {DOM} posts */ postLoad = () => { let { match } = this.props let posts: Map> = this.props.posts let { tag } = match.params if (posts === undefined || !(posts.keySeq().count() > 0)) { return (

'Nothing has shared.'

) } else { let postBack = { divided: false, oddPostList: [], evenPostList: [] } let parsedPosts: ImuList = ImuList() posts.forEach((post: Map) => { if (tag) { let regex = new RegExp('#' + tag, 'g') let postMatch = String(post.get('body', '')).match(regex) if (postMatch !== null) { parsedPosts = parsedPosts.push(post) } } else { parsedPosts = parsedPosts.push(post) } }) const sortedPosts = PostAPI.sortImuObjectsDate(parsedPosts) if (sortedPosts.count() > 6) { postBack.divided = true } else { postBack.divided = false } let index = 0 sortedPosts.forEach((post) => { let newPost: any = (
{index > 1 || (!postBack.divided && index > 0) ?
: ''}
) if ((index % 2) === 1 && postBack.divided) { postBack.oddPostList.push(newPost as never) } else { postBack.evenPostList.push(newPost as never) } ++index }) return postBack } } /** * Scroll loader */ scrollLoad = (page: number) => { const { loadStream } = this.props loadStream!(page, 10) } componentWillMount() { const { setHomeTitle } = this.props setHomeTitle!() } /** * Reneder component DOM * @return {react element} return the DOM which rendered by component */ render() { const { tag, displayWriting, hasMorePosts, translate } = this.props const postList = this.postLoad() as { evenPostList: Post[], oddPostList: Post[], divided: boolean } | any return ( } >
{displayWriting && !tag ? ( {translate!('home.postWriteButtonText')}} />
) : ''} {postList.evenPostList}
{postList.divided ? (
{postList.oddPostList}
) : ''}
) } } /** * 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: any, ownProps: IStreamComponentProps) => { return { setHomeTitle: () => dispatch(globalActions.setHeaderTitle(ownProps.homeTitle || '')), showTopLoading: () => dispatch(globalActions.showTopLoading()), hideTopLoading: () => dispatch(globalActions.hideTopLoading()) } } /** * 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: Map, ownProps: IStreamComponentProps) => { const uid = state.getIn(['authorize', 'uid']) const user = state.getIn(['user', 'info', uid]) return { translate: getTranslate(state.get('locale')), avatar: user.avatar || '', fullName: user.fullName || '' } } // - Connect component to redux store export default withRouter(connect(mapStateToProps, mapDispatchToProps)(StreamComponent as any) as any) as typeof StreamComponent