diff --git a/client/coral-configure/components/ConfigureCommentStream.css b/client/coral-configure/components/ConfigureCommentStream.css index ea20e4c05..335c94377 100644 --- a/client/coral-configure/components/ConfigureCommentStream.css +++ b/client/coral-configure/components/ConfigureCommentStream.css @@ -9,12 +9,12 @@ right: 0; } -ul { +.wrapper ul { list-style: none; padding: 0; } -ul ul { +.wrapper ul ul { padding-left: 20px } @@ -23,12 +23,12 @@ ul ul { margin: 12px 12px 12px 0; } -h4 { +.wrapper h4 { font-size: 14px; margin-bottom: 5px; } -p { +.wrapper p { max-width: 380px; } diff --git a/client/coral-embed-stream/src/Comment.css b/client/coral-embed-stream/src/Comment.css index a1f7b8654..6f89208bc 100644 --- a/client/coral-embed-stream/src/Comment.css +++ b/client/coral-embed-stream/src/Comment.css @@ -38,7 +38,10 @@ .Menu { border: 1px solid #ddd; margin: 0; - +} +ul.Menu { + list-style-type: none; + padding: 0; } .MenuItem { @@ -50,6 +53,7 @@ background-color: #2E343B; color: white; padding: 1em; + max-width: 220px; } .IgnoreUserWizard header { diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index 437152eac..3afd749cb 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -15,7 +15,7 @@ import {NEW_COMMENT_COUNT_POLL_INTERVAL} from 'coral-framework/constants/comment 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 {editName, ignoreUserSuccess} from 'coral-framework/actions/user'; import {updateCountCache, viewAllComments} from 'coral-framework/actions/asset'; import {notificationActions, authActions, assetActions, pym} from 'coral-framework'; @@ -117,6 +117,15 @@ class Embed extends Component { } } + ignoreUser = async ({id}) => { + const {ignoreUser, dispatch} = this.props; + await ignoreUser({id}); + + // dispatch ignoreUserSuccess so other reducers can know about the newly + // ignored user (e.g. to hide coments by that user) + dispatch(ignoreUserSuccess({id})); + } + render () { const {activeTab} = this.state; const {closedAt, countCache = {}} = this.props.asset; @@ -253,11 +262,12 @@ class Embed extends Component { postDontAgree={this.props.postDontAgree} addCommentTag={this.props.addCommentTag} removeCommentTag={this.props.removeCommentTag} - ignoreUser={this.props.ignoreUser} + ignoreUser={this.ignoreUser} loadMore={this.props.loadMore} deleteAction={this.props.deleteAction} showSignInDialog={this.props.showSignInDialog} - comments={asset.comments} /> + comments={asset.comments} + ignoredUsers={this.props.userData.ignoredUsers} /> ({ auth: state.auth.toJS(), userData: state.user.toJS(), - asset: state.asset.toJS() + asset: state.asset.toJS(), }); const mapDispatchToProps = dispatch => ({ @@ -305,7 +315,7 @@ const mapDispatchToProps = dispatch => ({ updateCountCache: (id, count) => dispatch(updateCountCache(id, count)), viewAllComments: () => dispatch(viewAllComments()), logout: () => dispatch(logout()), - dispatch: d => dispatch(d) + dispatch: d => dispatch(d), }); export default compose( @@ -315,8 +325,8 @@ export default compose( postLike, postDontAgree, addCommentTag, - ignoreUser, removeCommentTag, + ignoreUser, deleteAction, queryStream, )(Embed); diff --git a/client/coral-embed-stream/src/Stream.js b/client/coral-embed-stream/src/Stream.js index 8ac9d2e40..4758af1c0 100644 --- a/client/coral-embed-stream/src/Stream.js +++ b/client/coral-embed-stream/src/Stream.js @@ -22,6 +22,9 @@ class Stream extends React.Component { // dispatch action to ignore another user ignoreUser: React.PropTypes.func, + + // list of user ids that should be rendered as ignored + ignoredUsers: React.PropTypes.arrayOf(React.PropTypes.string) } constructor(props) { @@ -47,35 +50,40 @@ class Stream extends React.Component { removeCommentTag, pluginProps, ignoreUser, + ignoredUsers, } = this.props; - + const commentIsIgnored = (comment) => ignoredUsers && ignoredUsers.includes(comment.user.id); return (
{ comments.map(comment => - + commentIsIgnored(comment) + ? + : ) }
@@ -83,4 +91,18 @@ class Stream extends React.Component { } } +const IgnoredCommentTombstone = () => ( +
+
+

+ This comment is hidden because you ignored this user. +

+
+); + export default Stream; diff --git a/client/coral-framework/actions/user.js b/client/coral-framework/actions/user.js index 3e80b718c..dd63cf215 100644 --- a/client/coral-framework/actions/user.js +++ b/client/coral-framework/actions/user.js @@ -1,6 +1,7 @@ import {addNotification} from '../actions/notification'; import coralApi from '../helpers/response'; import * as actions from '../constants/auth'; +import {IGNORE_USER_SUCCESS} from '../constants/user'; import I18n from 'coral-framework/modules/i18n/i18n'; import translations from './../translations'; @@ -19,3 +20,6 @@ export const editName = (username) => (dispatch) => { dispatch(editUsernameFailure(lang.t(`error.${error.translation_key}`))); }); }; + +// a user was successfully ignored +export const ignoreUserSuccess = ({id}) => ({type: IGNORE_USER_SUCCESS, id}); diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js index 5f040db5b..66e58e930 100644 --- a/client/coral-framework/constants/user.js +++ b/client/coral-framework/constants/user.js @@ -6,3 +6,4 @@ export const COMMENTS_BY_USER_SUCCESS = 'COMMENTS_BY_USER_SUCCESS'; export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE'; export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; export const UPDATE_USERNAME = 'UPDATE_USERNAME'; +export const IGNORE_USER_SUCCESS = 'IGNORE_USER_SUCCESS'; diff --git a/client/coral-framework/reducers/user.js b/client/coral-framework/reducers/user.js index b8ff54380..0c77b3f69 100644 --- a/client/coral-framework/reducers/user.js +++ b/client/coral-framework/reducers/user.js @@ -1,4 +1,4 @@ -import {Map} from 'immutable'; +import {Map, Set} from 'immutable'; import * as authActions from '../constants/auth'; import * as actions from '../constants/user'; import * as assetActions from '../constants/assets'; @@ -8,7 +8,8 @@ const initialState = Map({ profiles: [], settings: {}, myComments: [], - myAssets: [] // the assets from which myComments (above) originated + myAssets: [], // the assets from which myComments (above) originated + ignoredUsers: Set(), }); const purge = user => { @@ -38,6 +39,8 @@ export default function user (state = initialState, action) { return state.set('myAssets', action.assets); case actions.LOGOUT_SUCCESS: return initialState; + case actions.IGNORE_USER_SUCCESS: + return state.updateIn(['ignoredUsers'], i => i.add(action.id)); default : return state; }