From af5be0469f845063a916cb050652461735be0153 Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 18 Apr 2017 23:20:39 +0700 Subject: [PATCH] Refactor embed --- .../coral-embed-stream/src/actions/stream.js | 4 + .../src/components/Comment.js | 2 +- .../src/components/Embed.js | 351 ++++-------------- .../src/components/LoadMore.js | 2 +- .../src/components/NewCount.js | 10 +- .../src/components/Stream.js | 234 +++++++++--- .../src/constants/stream.js | 4 + .../src/containers/Embed.js | 103 +++++ .../src/{components => }/index.js | 7 +- .../coral-embed-stream/src/reducers/index.js | 5 + .../coral-embed-stream/src/reducers/stream.js | 23 ++ client/coral-framework/actions/asset.js | 1 - client/coral-framework/constants/asset.js | 1 - client/coral-framework/constants/comments.js | 2 - .../graphql/queries/streamQuery.graphql | 4 + client/coral-framework/reducers/asset.js | 3 - client/coral-framework/services/store.js | 19 +- client/coral-plugin-commentbox/CommentBox.js | 15 +- .../containers/ProfileContainer.js | 14 +- .../coral-sign-in/components/FakeComment.js | 2 +- 20 files changed, 431 insertions(+), 375 deletions(-) create mode 100644 client/coral-embed-stream/src/actions/stream.js create mode 100644 client/coral-embed-stream/src/constants/stream.js create mode 100644 client/coral-embed-stream/src/containers/Embed.js rename client/coral-embed-stream/src/{components => }/index.js (63%) create mode 100644 client/coral-embed-stream/src/reducers/index.js create mode 100644 client/coral-embed-stream/src/reducers/stream.js delete mode 100644 client/coral-framework/constants/comments.js diff --git a/client/coral-embed-stream/src/actions/stream.js b/client/coral-embed-stream/src/actions/stream.js new file mode 100644 index 000000000..eea2ff5c4 --- /dev/null +++ b/client/coral-embed-stream/src/actions/stream.js @@ -0,0 +1,4 @@ +import * as actions from '../constants/stream'; + +export const setActiveReplyBox = (id) => ({type: actions.SET_ACTIVE_REPLY_BOX, id}); +export const setCommentCountCache = (amount) => ({type: actions.SET_COMMENT_COUNT_CACHE, amount}); diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index 4b01e19a7..ea0b34e5b 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -18,8 +18,8 @@ import {ReplyBox, ReplyButton} from 'coral-plugin-replies'; import FlagComment from 'coral-plugin-flags/FlagComment'; import LikeButton from 'coral-plugin-likes/LikeButton'; import {BestButton, IfUserCanModifyBest, BEST_TAG, commentIsBest, BestIndicator} from 'coral-plugin-best/BestButton'; -import LoadMore from 'coral-embed-stream/src/LoadMore'; import {Slot} from 'coral-framework'; +import LoadMore from './LoadMore'; import IgnoredCommentTombstone from './IgnoredCommentTombstone'; import {TopRightMenu} from './TopRightMenu'; diff --git a/client/coral-embed-stream/src/components/Embed.js b/client/coral-embed-stream/src/components/Embed.js index b67e9e1c4..e1da63c28 100644 --- a/client/coral-embed-stream/src/components/Embed.js +++ b/client/coral-embed-stream/src/components/Embed.js @@ -1,58 +1,39 @@ import React from 'react'; -import {compose} from 'react-apollo'; -import {connect} from 'react-redux'; -import isEqual from 'lodash/isEqual'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from 'coral-framework/translations'; const lang = new I18n(translations); -import {TabBar, Tab, TabContent, Spinner, Button} from 'coral-ui'; - -const {logout, showSignInDialog, requestConfirmEmail} = authActions; -const {addNotification, clearNotification} = notificationActions; -const {fetchAssetSuccess} = assetActions; -import {NEW_COMMENT_COUNT_POLL_INTERVAL} from 'coral-framework/constants/comments'; - -import {queryStream} from 'coral-framework/graphql/queries'; -import {postComment, postFlag, postLike, postDontAgree, deleteAction, addCommentTag, removeCommentTag, ignoreUser} from 'coral-framework/graphql/mutations'; -import {editName} from 'coral-framework/actions/user'; -import {updateCountCache, viewAllComments} from 'coral-framework/actions/asset'; -import {notificationActions, authActions, assetActions, pym} from 'coral-framework'; +import {TabBar, Tab, TabContent, Button} from 'coral-ui'; import Stream from './Stream'; -import InfoBox from 'coral-plugin-infobox/InfoBox'; -import QuestionBox from 'coral-plugin-questionbox/QuestionBox'; -import {ModerationLink} from 'coral-plugin-moderation'; import Count from 'coral-plugin-comment-count/CommentCount'; -import CommentBox from 'coral-plugin-commentbox/CommentBox'; import UserBox from 'coral-sign-in/components/UserBox'; -import SignInContainer from 'coral-sign-in/containers/SignInContainer'; -import SuspendedAccount from 'coral-framework/components/SuspendedAccount'; -import ChangeUsernameContainer from '../../coral-sign-in/containers/ChangeUsernameContainer'; import ProfileContainer from 'coral-settings/containers/ProfileContainer'; import RestrictedContent from 'coral-framework/components/RestrictedContent'; import ConfigureStreamContainer from 'coral-configure/containers/ConfigureStreamContainer'; -import HighlightedComment from './Comment'; -import LoadMore from './LoadMore'; -import NewCount from './NewCount'; -class Embed extends React.Component { +export default class Embed extends React.Component { + state = { + activeTab: 0, + }; - constructor(props) { - super(props); - this.state = { - activeTab: 0, - showSignInDialog: false, - activeReplyBox: '' - }; - } + exitHighlighting = () => { + this.props.viewAllComments(); + + // TODO: don't rely on refetching. + this.props.data.refetch(); + }; changeTab = (tab) => { - - // Everytime the comes from another tab, the Stream needs to be updated. if (tab === 0) { - this.props.viewAllComments(); - this.props.data.refetch(); + if (this.props.data.comment) { + this.exitHighlighting(); + } + else { + + // TODO: don't rely on refetching. + this.props.data.refetch(); + } } this.setState({ @@ -60,105 +41,16 @@ class Embed extends React.Component { }); } - static propTypes = { - data: React.PropTypes.shape({ - loading: React.PropTypes.bool, - error: React.PropTypes.object - }).isRequired, - - // dispatch action to add a tag to a comment - addCommentTag: React.PropTypes.func, - - // dispatch action to remove a tag from a comment - removeCommentTag: React.PropTypes.func, - - // dispatch action to ignore another user - ignoreUser: React.PropTypes.func, - } - - componentDidMount () { - pym.sendMessage('childReady'); - } - - componentWillUnmount () { - clearInterval(this.state.countPoll); - } - - componentWillReceiveProps (nextProps) { - const {loadAsset} = this.props; - if(!isEqual(nextProps.data.asset, this.props.data.asset)) { - loadAsset(nextProps.data.asset); - - const {getCounts, updateCountCache, asset: {countCache}} = this.props; - const {asset} = nextProps.data; - - if (!countCache) { - updateCountCache(asset.id, asset.commentCount); - } - - this.setState({ - countPoll: setInterval(() => { - const {asset} = this.props.data; - getCounts({ - asset_id: asset.id, - limit: asset.comments.length, - sort: 'REVERSE_CHRONOLOGICAL' - }); - }, NEW_COMMENT_COUNT_POLL_INTERVAL) - }); - } - } - - componentDidUpdate(prevProps) { - if(!isEqual(prevProps.data.comment, this.props.data.comment)) { - - // Scroll to a permalinked comment if one is in the URL once the page is done rendering. - setTimeout(() => pym.scrollParentToChildEl('coralStream'), 0); - } - } - - setActiveReplyBox = (reactKey) => { - if (!this.props.auth.user) { - const offset = document.getElementById(`c_${reactKey}`).getBoundingClientRect().top - 75; - this.props.showSignInDialog(offset); - } else { - this.setState({activeReplyBox: reactKey}); - } - } - render () { const {activeTab} = this.state; - const {closedAt, countCache = {}} = this.props.asset; - const {asset, refetch, comment} = this.props.data; - const {loggedIn, isAdmin, user, showSignInDialog, signInOffset} = this.props.auth; - - // even though the permalinked comment is the highlighted one, we're displaying its parent + replies - const highlightedComment = comment && comment.parent ? comment.parent : comment; - - const openStream = closedAt === null; - - const banned = user && user.status === 'BANNED'; - - const hasOlderComments = !!( - asset && - asset.lastComment && - asset.lastComment.id !== asset.comments[asset.comments.length - 1].id - ); + const {asset, comment} = this.props.data; + const {loggedIn, isAdmin, user, showSignInDialog} = this.props.auth; const expandForLogin = showSignInDialog ? { minHeight: document.body.scrollHeight + 200 } : {}; - if (!asset) { - return ; - } - - // Find the created_at date of the first comment. If no comments exist, set the date to a week ago. - const firstCommentDate = asset.comments[0] - ? asset.comments[0].created_at - : new Date(Date.now() - 1000 * 60 * 60 * 24 * 7).toISOString(); - - const userBox = this.props.logout().then(refetch)} changeTab={this.changeTab}/>; + const userBox = ; return (
@@ -169,137 +61,50 @@ class Embed extends React.Component { Configure Stream { - highlightedComment && - + comment && + } { loggedIn ? userBox : null } - { - openStream - ?
- - - - }> - { - user - ? - : null - } - -
- :

{asset.settings.closedMessage}

- } - {!loggedIn && } - {loggedIn && user && } - {loggedIn && } - - {/* the highlightedComment is isolated after the user followed a permalink */} - { - highlightedComment - ? - :
- -
- -
- -
- } +
- + { loggedIn ? userBox : null } - +
@@ -308,34 +113,18 @@ class Embed extends React.Component { } } -const mapStateToProps = state => ({ - auth: state.auth.toJS(), - userData: state.user.toJS(), - asset: state.asset.toJS(), -}); +Embed.propTypes = { + data: React.PropTypes.shape({ + loading: React.PropTypes.bool, + error: React.PropTypes.object + }).isRequired, -const mapDispatchToProps = dispatch => ({ - requestConfirmEmail: () => dispatch(requestConfirmEmail()), - loadAsset: (asset) => dispatch(fetchAssetSuccess(asset)), - addNotification: (type, text) => addNotification(type, text), - clearNotification: () => dispatch(clearNotification()), - editName: (username) => dispatch(editName(username)), - showSignInDialog: (offset) => dispatch(showSignInDialog(offset)), - updateCountCache: (id, count) => dispatch(updateCountCache(id, count)), - viewAllComments: () => dispatch(viewAllComments()), - logout: () => dispatch(logout()), - dispatch: d => dispatch(d), -}); + // dispatch action to add a tag to a comment + addCommentTag: React.PropTypes.func, -export default compose( - connect(mapStateToProps, mapDispatchToProps), - postComment, - postFlag, - postLike, - postDontAgree, - addCommentTag, - removeCommentTag, - ignoreUser, - deleteAction, - queryStream, -)(Embed); + // dispatch action to remove a tag from a comment + removeCommentTag: React.PropTypes.func, + + // dispatch action to ignore another user + ignoreUser: React.PropTypes.func, +}; diff --git a/client/coral-embed-stream/src/components/LoadMore.js b/client/coral-embed-stream/src/components/LoadMore.js index 1a58c8d19..8c665a2db 100644 --- a/client/coral-embed-stream/src/components/LoadMore.js +++ b/client/coral-embed-stream/src/components/LoadMore.js @@ -1,7 +1,7 @@ import React, {PropTypes} from 'react'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from 'coral-framework/translations.json'; -import {ADDTL_COMMENTS_ON_LOAD_MORE} from 'coral-framework/constants/comments'; +import {ADDTL_COMMENTS_ON_LOAD_MORE} from '../constants/stream'; import {Button} from 'coral-ui'; const lang = new I18n(translations); diff --git a/client/coral-embed-stream/src/components/NewCount.js b/client/coral-embed-stream/src/components/NewCount.js index 8d7333aab..bb31e6d1d 100644 --- a/client/coral-embed-stream/src/components/NewCount.js +++ b/client/coral-embed-stream/src/components/NewCount.js @@ -3,9 +3,9 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from 'coral-framework/translations.json'; const lang = new I18n(translations); -const onLoadMoreClick = ({loadMore, commentCount, firstCommentDate, assetId, updateCountCache}) => (e) => { +const onLoadMoreClick = ({loadMore, commentCount, firstCommentDate, assetId, setCommentCountCache}) => (e) => { e.preventDefault(); - updateCountCache(assetId, commentCount); + setCommentCountCache(commentCount); loadMore({ limit: 500, cursor: firstCommentDate, @@ -15,11 +15,11 @@ const onLoadMoreClick = ({loadMore, commentCount, firstCommentDate, assetId, upd }; const NewCount = (props) => { - const newComments = props.commentCount - props.countCache; + const newComments = props.commentCount - props.commentCountCache; return
{ - props.countCache && newComments > 0 ? + props.commentCountCache && newComments > 0 ?