diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index 61352b921..3487f9fde 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -116,7 +116,7 @@ class ModerationContainer extends Component { let asset; - if (data.loading) { + if (!('premodCount' in data)) { return
; } diff --git a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js index a2bbbf092..a31fbd313 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js +++ b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js @@ -17,25 +17,27 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from 'coral-admin/src/translations.json'; const lang = new I18n(translations); -const Comment = ({actions = [], ...props}) => { - const links = linkify.getMatches(props.comment.body); +const Comment = ({actions = [], comment, ...props}) => { + const links = linkify.getMatches(comment.body); const linkText = links ? links.map(link => link.raw) : []; - const actionSummaries = props.comment.action_summaries; + const actionSummaries = comment.action_summaries.filter(a => a.__typename === 'FlagActionSummary'); + const flagActions = comment.actions.filter(a => a.__typename === 'FlagAction'); + return (
  • - {props.comment.user.name} + {comment.user.name} - {timeago().format(props.comment.created_at || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))} + {timeago().format(comment.created_at || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))} - props.showBanUserDialog(props.comment.user, props.comment.id, props.comment.status !== 'REJECTED')} /> + props.showBanUserDialog(comment.user, comment.id, comment.status !== 'REJECTED')} />
    - {props.comment.user.status === 'banned' ? + {comment.user.status === 'banned' ? {lang.t('comment.banned_user')} @@ -43,16 +45,16 @@ const Comment = ({actions = [], ...props}) => { : null}
    - Story: {props.comment.asset.title} + Story: {comment.asset.title} {!props.currentAsset && ( - Moderate → + Moderate → )}

    + textToHighlight={comment.body} />

    {links ? Contains Link : null} @@ -60,16 +62,16 @@ const Comment = ({actions = [], ...props}) => { {actions.map((action, i) => props.acceptComment({commentId: props.comment.id})} - rejectComment={() => props.rejectComment({commentId: props.comment.id})} + user={comment.user} + acceptComment={() => props.acceptComment({commentId: comment.id})} + rejectComment={() => props.rejectComment({commentId: comment.id})} /> )}
    - {actionSummaries && } + {flagActions && }
  • ); }; @@ -83,6 +85,7 @@ Comment.propTypes = { comment: PropTypes.shape({ body: PropTypes.string.isRequired, action_summaries: PropTypes.array, + actions: PropTypes.array, created_at: PropTypes.string.isRequired, user: PropTypes.shape({ status: PropTypes.string diff --git a/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.css b/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.css index fa7bb0cca..5b8ea4f91 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.css +++ b/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.css @@ -53,3 +53,17 @@ font-size: 12px; } } + +.lessDetail { + display: inline-block; + margin-right: 10px; +} + +.subDetail { + font-weight: normal; + color: #888; + + span { + color: black; + } +} diff --git a/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.js b/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.js index 00b7d4273..62b4e554d 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.js +++ b/client/coral-admin/src/containers/ModerationQueue/components/FlagBox.js @@ -1,6 +1,17 @@ import React, {Component, PropTypes} from 'react'; import {Icon} from 'coral-ui'; import styles from './FlagBox.css'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from 'coral-admin/src/translations.json'; +const lang = new I18n(translations); + +const shortReasons = { + 'This comment is offensive': lang.t('modqueue.offensive'), + 'This looks like an ad/marketing': lang.t('modqueue.spam/ads'), + 'This user is impersonating': lang.t('modqueue.impersonating'), + 'I don\'t like this username': lang.t('modqueue.dont-like-username'), + 'Other': lang.t('modqueue.other') +}; class FlagBox extends Component { constructor () { @@ -16,27 +27,50 @@ class FlagBox extends Component { })); } + reasonMap = (reason) => { + const shortReason = shortReasons[reason]; + + // if the short reason isn't found, just return the long one. + return shortReason ? shortReason : reason; + } + render() { - const {props} = this; + const {actionSummaries, actions} = this.props; + const {showDetail} = this.state; + return (
    -

    Flags ({props.actionSummaries.length}):

    +

    Flags ({actionSummaries.length}):

      - {props.actionSummaries.map((action, i) => -
    • {!action.reason ? No reason provided : action.reason} ({action.count})
    • + {actionSummaries.map((action, i) => +
    • {this.reasonMap(action.reason)} ({action.count})
    • )}
    - {/* More detail*/} + {showDetail ? lang.t('modqueue.less-detail') : lang.t('modqueue.more-detail')}
    - {this.state.showDetail && (
    -
      - {props.actionSummaries.map((action, i) => -
    • {!action.reason ? No reason provided : action.reason} ({action.count})
    • - )} -
    -
    )} + {showDetail && ( +
    +
      + {actionSummaries.map((summary, i) => { + + const actionList = actions.filter(a => a.reason === summary.reason); + + return ( +
    • + {this.reasonMap(summary.reason)} ({summary.count}) +
        + { + actionList.map((action, j) =>
      • {action.user.username} {action.message}
      • ) + } +
      +
    • + ); + })} +
    +
    + )}
    ); @@ -44,7 +78,14 @@ class FlagBox extends Component { } FlagBox.propTypes = { - actionSummaries: PropTypes.array.isRequired + actionSummaries: PropTypes.arrayOf(PropTypes.shape({ + reason: PropTypes.string, + count: PropTypes.number + })).isRequired, + actions: PropTypes.arrayOf(PropTypes.shape({ + message: PropTypes.string, + user: PropTypes.shape({username: PropTypes.string}) + })).isRequired }; export default FlagBox; diff --git a/client/coral-admin/src/graphql/fragments/commentView.graphql b/client/coral-admin/src/graphql/fragments/commentView.graphql index e78c28a28..8c7310bdf 100644 --- a/client/coral-admin/src/graphql/fragments/commentView.graphql +++ b/client/coral-admin/src/graphql/fragments/commentView.graphql @@ -12,4 +12,13 @@ fragment commentView on Comment { id title } + actions { + ... on FlagAction { + reason + message + user { + username + } + } + } } diff --git a/client/coral-admin/src/graphql/queries/index.js b/client/coral-admin/src/graphql/queries/index.js index f0e8e5b70..7d03b5092 100644 --- a/client/coral-admin/src/graphql/queries/index.js +++ b/client/coral-admin/src/graphql/queries/index.js @@ -55,7 +55,7 @@ export const loadMore = (fetchMore) => ({limit, cursor, sort, tab, asset_id}) => statuses, asset_id }, - updateQuery: (oldData, {fetchMoreResult:{data:{comments}}}) => { + updateQuery: (oldData, {fetchMoreResult:{comments}}) => { return { ...oldData, [tab]: [ diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json index 911411523..f317b71a7 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -51,7 +51,14 @@ "singleview": "Toggle single comment edit view", "thismenu": "Open this menu", "emptyqueue": "No more comments to moderate! You're all caught up. Go have some ☕️", - "showshortcuts": "Show Shortcuts" + "showshortcuts": "Show Shortcuts", + "more-detail": "More detail", + "less-detail": "Less detail", + "dont-like-username": "Don't like username", + "impersonating": "Impersonating", + "offensive": "Offensive", + "spam/ads": "Spam/Ads", + "other": "Other" }, "comment": { "flagged": "flagged", @@ -221,7 +228,14 @@ "shortcuts": "Atajos de teclado", "close": "Cerrar", "emptyqueue": "No se encontro ningún usuario. Están escondidos.", - "showshortcuts": "Mostrar atajos" + "showshortcuts": "Mostrar atajos", + "more-detail": "Mas detalle", + "less-detail": "Menos detalle", + "dont-like-username": "No me gusta ese nombre de usuario", + "impersonating": "Suplantación", + "offensive": "Ofensivo", + "spam/ads": "Spam/Propaganda", + "other": "Otros" }, "comment": { "flagged": "marcado", diff --git a/client/coral-framework/actions/notification.js b/client/coral-framework/actions/notification.js index 37679972d..d77a3a16c 100644 --- a/client/coral-framework/actions/notification.js +++ b/client/coral-framework/actions/notification.js @@ -1,9 +1,12 @@ import pym from '../services/PymConnection'; +import * as actions from '../constants/notification'; export const addNotification = (notifType, text) => { pym.sendMessage('coral-alert', `${notifType}|${text}`); + return {type: actions.ADD_NOTIFICATION, notifType, text}; }; export const clearNotification = () => { pym.sendMessage('coral-clear-notification'); + return {type: actions.CLEAR_NOTIFICATION}; }; diff --git a/client/coral-framework/constants/notification.js b/client/coral-framework/constants/notification.js new file mode 100644 index 000000000..a7334119a --- /dev/null +++ b/client/coral-framework/constants/notification.js @@ -0,0 +1,2 @@ +export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; +export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION';