diff --git a/.gitignore b/.gitignore
index e8dfd14e7..a619f0988 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,5 +19,6 @@ plugins/*
!plugins/coral-plugin-facebook-auth
!plugins/coral-plugin-respect
!plugins/coral-plugin-offtopic
+!plugins/coral-plugin-like
**/node_modules/*
diff --git a/client/coral-admin/src/components/ActionButton.js b/client/coral-admin/src/components/ActionButton.js
index ae75b829e..3651ee939 100644
--- a/client/coral-admin/src/components/ActionButton.js
+++ b/client/coral-admin/src/components/ActionButton.js
@@ -3,9 +3,8 @@ import styles from './ModerationList.css';
import {Button} from 'coral-ui';
import {menuActionsMap} from '../containers/ModerationQueue/helpers/moderationQueueActionsMap';
-const ActionButton = ({type = '', status, ...props}) => {
+const ActionButton = ({type = '', active, ...props}) => {
const typeName = type.toLowerCase();
- const active = ((type === 'REJECT' && status === 'REJECTED') || (type === 'APPROVE' && status === 'ACCEPTED'));
let text = menuActionsMap[type].text;
if (text === 'Approve' && active) {
@@ -25,7 +24,7 @@ const ActionButton = ({type = '', status, ...props}) => {
};
ActionButton.propTypes = {
- status: PropTypes.string
+ active: PropTypes.bool
};
export default ActionButton;
diff --git a/client/coral-admin/src/containers/Dashboard/FlagWidget.js b/client/coral-admin/src/containers/Dashboard/FlagWidget.js
index afd732cc7..abf348897 100644
--- a/client/coral-admin/src/containers/Dashboard/FlagWidget.js
+++ b/client/coral-admin/src/containers/Dashboard/FlagWidget.js
@@ -21,7 +21,7 @@ const FlagWidget = ({assets}) => {
? assets.map(asset => {
let flagSummary = null;
if (asset.action_summaries) {
- flagSummary = asset.action_summaries.find(s => s.type === 'FlagAssetActionSummary');
+ flagSummary = asset.action_summaries.find(s => s.__typename === 'FlagAssetActionSummary');
}
return (
diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
index eb59f369e..7a3aab909 100644
--- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
+++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
@@ -5,7 +5,7 @@ import key from 'keymaster';
import isEqual from 'lodash/isEqual';
import styles from './components/styles.css';
-import {modQueueQuery} from '../../graphql/queries';
+import {modQueueQuery, getQueueCounts} from '../../graphql/queries';
import {banUser, setCommentStatus} from '../../graphql/mutations';
import {fetchSettings} from 'actions/settings';
@@ -220,6 +220,7 @@ const mapDispatchToProps = dispatch => ({
export default compose(
connect(mapStateToProps, mapDispatchToProps),
setCommentStatus,
+ getQueueCounts,
modQueueQuery,
banUser
)(ModerationContainer);
diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
index 433859e9a..a25e7b5e3 100644
--- a/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
+++ b/client/coral-admin/src/containers/ModerationQueue/ModerationQueue.js
@@ -9,51 +9,67 @@ import translations from 'coral-admin/src/translations';
import LoadMore from './components/LoadMore';
const lang = new I18n(translations);
-const ModerationQueue = ({comments, selectedIndex, commentCount, singleView, loadMore, activeTab, sort, ...props}) => {
- return (
-
-
- {
- comments.length
- ? comments.map((comment, i) => {
- const status = comment.action_summaries ? 'FLAGGED' : comment.status;
- return ;
- })
- : {lang.t('modqueue.emptyqueue')}
- }
-
-
-
- );
-};
+class ModerationQueue extends React.Component {
-ModerationQueue.propTypes = {
- bannedWords: PropTypes.arrayOf(PropTypes.string).isRequired,
- suspectWords: PropTypes.arrayOf(PropTypes.string).isRequired,
- currentAsset: PropTypes.object,
- showBanUserDialog: PropTypes.func.isRequired,
- rejectComment: PropTypes.func.isRequired,
- acceptComment: PropTypes.func.isRequired,
- comments: PropTypes.array.isRequired
-};
+ static propTypes = {
+ bannedWords: PropTypes.arrayOf(PropTypes.string).isRequired,
+ suspectWords: PropTypes.arrayOf(PropTypes.string).isRequired,
+ currentAsset: PropTypes.object,
+ showBanUserDialog: PropTypes.func.isRequired,
+ rejectComment: PropTypes.func.isRequired,
+ acceptComment: PropTypes.func.isRequired,
+ comments: PropTypes.array.isRequired
+ }
+
+ componentDidUpdate (prev) {
+ const {loadMore, comments, commentCount, sort, activeTab: tab, assetId: asset_id} = this.props;
+
+ // if the user just moderated the last (visible) comment
+ // AND there are more comments available on the server,
+ // go ahead and load more comments
+ if (prev.comments.length > 0 && comments.length === 0 && commentCount > 0) {
+ loadMore({sort, tab, asset_id});
+ }
+ }
+
+ render () {
+ const {comments, selectedIndex, commentCount, singleView, loadMore, activeTab, sort, ...props} = this.props;
+
+ return (
+
+
+ {
+ comments.length
+ ? comments.map((comment, i) => {
+ const status = comment.action_summaries ? 'FLAGGED' : comment.status;
+ return ;
+ })
+ : {lang.t('modqueue.emptyqueue')}
+ }
+
+
+
+ );
+ }
+}
export default ModerationQueue;
diff --git a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js
index e575beb0a..619a3cd7a 100644
--- a/client/coral-admin/src/containers/ModerationQueue/components/Comment.js
+++ b/client/coral-admin/src/containers/ModerationQueue/components/Comment.js
@@ -66,15 +66,17 @@ const Comment = ({actions = [], comment, ...props}) => {
{links ?
Contains Link : null}
- {actions.map((action, i) =>
-
props.acceptComment({commentId: comment.id})}
- rejectComment={() => props.rejectComment({commentId: comment.id})}
- />
- )}
+ {actions.map((action, i) => {
+ const active = (action === 'REJECT' && comment.status === 'REJECTED') ||
+ (action === 'APPROVE' && comment.status === 'ACCEPTED');
+ return props.acceptComment({commentId: comment.id})}
+ rejectComment={() => props.rejectComment({commentId: comment.id})} />;
+ })}
diff --git a/client/coral-admin/src/containers/ModerationQueue/components/CommentCount.js b/client/coral-admin/src/containers/ModerationQueue/components/CommentCount.js
index 14cf8ecfc..0517caf0f 100644
--- a/client/coral-admin/src/containers/ModerationQueue/components/CommentCount.js
+++ b/client/coral-admin/src/containers/ModerationQueue/components/CommentCount.js
@@ -1,9 +1,25 @@
import React, {PropTypes} from 'react';
import styles from './CommentCount.css';
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from 'coral-admin/src/translations.json';
+const lang = new I18n(translations);
-const CommentCount = props => (
- {props.count}
-);
+const CommentCount = ({count}) => {
+ let number = count;
+
+ // shorten large counts to abbreviations
+ if (number / 1e9 > 1) {
+ number = `${(number / 1e9).toFixed(1)}${lang.t('modqueue.billion')}`;
+ } else if (number / 1e6 > 1) {
+ number = `${(number / 1e6).toFixed(1)}${lang.t('modqueue.million')}`;
+ } else if (number / 1e3 > 1) {
+ number = `${(number / 1e3).toFixed(1)}${lang.t('modqueue.thousand')}`;
+ }
+
+ return (
+ {number}
+ );
+};
CommentCount.propTypes = {
count: PropTypes.number.isRequired
diff --git a/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js b/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js
index f16635486..c90d3cd14 100644
--- a/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js
+++ b/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js
@@ -7,13 +7,16 @@ const LoadMore = ({comments, loadMore, sort, tab, assetId, showLoadMore}) =>
{
showLoadMore &&
}
diff --git a/client/coral-admin/src/graphql/fragments/assetMetricsView.graphql b/client/coral-admin/src/graphql/fragments/assetMetricsView.graphql
index c77fbc32b..726194143 100644
--- a/client/coral-admin/src/graphql/fragments/assetMetricsView.graphql
+++ b/client/coral-admin/src/graphql/fragments/assetMetricsView.graphql
@@ -6,7 +6,6 @@ fragment metrics on Asset {
created_at
commentCount
action_summaries {
- type: __typename
actionCount
actionableItemCount
}
diff --git a/client/coral-admin/src/graphql/mutations/index.js b/client/coral-admin/src/graphql/mutations/index.js
index 4d62201d1..6b21c8421 100644
--- a/client/coral-admin/src/graphql/mutations/index.js
+++ b/client/coral-admin/src/graphql/mutations/index.js
@@ -44,6 +44,7 @@ export const suspendUser = graphql(SUSPEND_USER, {
})
});
+const views = ['all', 'premod', 'flagged', 'accepted', 'rejected'];
export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
props: ({mutate}) => ({
acceptComment: ({commentId}) => {
@@ -54,7 +55,9 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
},
updateQueries: {
ModQueue: (oldData) => {
- const comment = oldData.all.find(c => c.id === commentId);
+ const comment = views.reduce((comment, view) => {
+ return comment ? comment : oldData[view].find(c => c.id === commentId);
+ }, null);
let accepted;
let acceptedCount = oldData.acceptedCount;
@@ -76,10 +79,10 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
return {
...oldData,
- premodCount,
- flaggedCount,
- acceptedCount,
- rejectedCount,
+ premodCount: Math.max(0, premodCount),
+ flaggedCount: Math.max(0, flaggedCount),
+ acceptedCount: Math.max(0, acceptedCount),
+ rejectedCount: Math.max(0, rejectedCount),
premod,
flagged,
accepted,
@@ -97,7 +100,9 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
},
updateQueries: {
ModQueue: (oldData) => {
- const comment = oldData.all.find(c => c.id === commentId);
+ const comment = views.reduce((comment, view) => {
+ return comment ? comment : oldData[view].find(c => c.id === commentId);
+ }, null);
let rejected;
let rejectedCount = oldData.rejectedCount;
@@ -119,10 +124,10 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
return {
...oldData,
- premodCount,
- flaggedCount,
- acceptedCount,
- rejectedCount,
+ premodCount: Math.max(0, premodCount),
+ flaggedCount: Math.max(0, flaggedCount),
+ acceptedCount: Math.max(0, acceptedCount),
+ rejectedCount: Math.max(0, rejectedCount),
premod,
flagged,
accepted,
diff --git a/client/coral-admin/src/graphql/queries/getQueueCounts.graphql b/client/coral-admin/src/graphql/queries/getQueueCounts.graphql
new file mode 100644
index 000000000..4a7c00d87
--- /dev/null
+++ b/client/coral-admin/src/graphql/queries/getQueueCounts.graphql
@@ -0,0 +1,22 @@
+query Counts ($asset_id: ID) {
+ allCount: commentCount(query: {
+ asset_id: $asset_id
+ })
+ acceptedCount: commentCount(query: {
+ statuses: [ACCEPTED],
+ asset_id: $asset_id
+ })
+ premodCount: commentCount(query: {
+ statuses: [PREMOD],
+ asset_id: $asset_id
+ })
+ rejectedCount: commentCount(query: {
+ statuses: [REJECTED],
+ asset_id: $asset_id
+ })
+ flaggedCount: commentCount(query: {
+ action_type: FLAG,
+ asset_id: $asset_id,
+ statuses: [NONE, PREMOD]
+ })
+}
diff --git a/client/coral-admin/src/graphql/queries/index.js b/client/coral-admin/src/graphql/queries/index.js
index 9d2357ce7..f26c8464e 100644
--- a/client/coral-admin/src/graphql/queries/index.js
+++ b/client/coral-admin/src/graphql/queries/index.js
@@ -4,6 +4,7 @@ import MOD_QUEUE_QUERY from './modQueueQuery.graphql';
import MOD_QUEUE_LOAD_MORE from './loadMore.graphql';
import MOD_USER_FLAGGED_QUERY from './modUserFlaggedQuery.graphql';
import METRICS from './metricsQuery.graphql';
+import GET_QUEUE_COUNTS from './getQueueCounts.graphql';
export const modQueueQuery = graphql(MOD_QUEUE_QUERY, {
options: ({params: {id = null}}) => {
@@ -33,34 +34,34 @@ export const getMetrics = graphql(METRICS, {
}
});
-export const loadMore = (fetchMore) => ({limit, cursor, sort, tab, asset_id}) => {
- let statuses;
+export const loadMore = (fetchMore) => ({limit = 10, cursor, sort, tab, asset_id}) => {
+ let variables = {
+ limit,
+ cursor,
+ sort,
+ asset_id
+ };
switch(tab) {
case 'all':
- statuses = null;
+ variables.statuses = null;
break;
case 'accepted':
- statuses = ['ACCEPTED'];
+ variables.statuses = ['ACCEPTED'];
break;
case 'premod':
- statuses = ['PREMOD'];
+ variables.statuses = ['PREMOD'];
break;
case 'flagged':
- statuses = ['NONE', 'PREMOD'];
+ variables.statuses = ['NONE', 'PREMOD'];
+ variables.action_type = 'FLAG';
break;
case 'rejected':
- statuses = ['REJECTED'];
+ variables.statuses = ['REJECTED'];
break;
}
return fetchMore({
query: MOD_QUEUE_LOAD_MORE,
- variables: {
- limit,
- cursor,
- sort,
- statuses,
- asset_id
- },
+ variables,
updateQuery: (oldData, {fetchMoreResult:{comments}}) => {
return {
...oldData,
@@ -93,3 +94,14 @@ export const modQueueResort = (id, fetchMore) => (sort) => {
updateQuery: (oldData, {fetchMoreResult:{data}}) => data
});
};
+
+export const getQueueCounts = graphql(GET_QUEUE_COUNTS, {
+ options: ({params: {id = null}}) => {
+ return {
+ pollInterval: 5000,
+ variables: {
+ asset_id: id
+ }
+ };
+ }
+});
diff --git a/client/coral-admin/src/graphql/queries/loadMore.graphql b/client/coral-admin/src/graphql/queries/loadMore.graphql
index 56966a804..a42c7b2bf 100644
--- a/client/coral-admin/src/graphql/queries/loadMore.graphql
+++ b/client/coral-admin/src/graphql/queries/loadMore.graphql
@@ -1,7 +1,7 @@
#import "../fragments/commentView.graphql"
-query LoadMoreModQueue($limit: Int = 10, $cursor: Date, $sort: SORT_ORDER, $asset_id: ID, $statuses:[COMMENT_STATUS!]) {
- comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sort: $sort}) {
+query LoadMoreModQueue($limit: Int = 10, $cursor: Date, $sort: SORT_ORDER, $asset_id: ID, $statuses:[COMMENT_STATUS!], $action_type: ACTION_TYPE) {
+ comments(query: {limit: $limit, cursor: $cursor, asset_id: $asset_id, statuses: $statuses, sort: $sort, action_type: $action_type}) {
...commentView
action_summaries {
count
diff --git a/client/coral-admin/src/services/fragmentMatcher.js b/client/coral-admin/src/services/fragmentMatcher.js
index afb87d445..531708f31 100644
--- a/client/coral-admin/src/services/fragmentMatcher.js
+++ b/client/coral-admin/src/services/fragmentMatcher.js
@@ -20,7 +20,6 @@ const fm = new IntrospectionFragmentMatcher({
name: 'Response',
possibleTypes: [
{name: 'CreateCommentResponse'},
- {name: 'CreateLikeResponse'},
{name: 'CreateFlagResponse'},
{name: 'CreateDontAgreeResponse'},
{name: 'DeleteActionResponse'},
@@ -37,8 +36,8 @@ const fm = new IntrospectionFragmentMatcher({
kind: 'INTERFACE',
name: 'Action',
possibleTypes: [
+ {name: 'DefaultAction'},
{name: 'FlagAction'},
- {name: 'LikeAction'},
{name: 'DontAgreeAction'}
],
},
@@ -46,8 +45,8 @@ const fm = new IntrospectionFragmentMatcher({
kind: 'INTERFACE',
name: 'ActionSummary',
possibleTypes: [
+ {name: 'DefaultActionSummary'},
{name: 'FlagActionSummary'},
- {name: 'LikeActionSummary'},
{name: 'DontAgreeActionSummary'}
],
},
@@ -57,7 +56,6 @@ const fm = new IntrospectionFragmentMatcher({
possibleTypes: [
{name: 'DefaultAssetActionSummary'},
{name: 'FlagAssetActionSummary'},
- {name: 'LikeAssetActionSummary'}
]
}
],
diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json
index 6401f4990..3f9392656 100644
--- a/client/coral-admin/src/translations.json
+++ b/client/coral-admin/src/translations.json
@@ -63,7 +63,10 @@
"impersonating": "Impersonating",
"offensive": "Offensive",
"spam/ads": "Spam/Ads",
- "other": "Other"
+ "other": "Other",
+ "thousand": "k",
+ "million": "M",
+ "billion": "B"
},
"comment": {
"flagged": "flagged",
@@ -248,7 +251,10 @@
"impersonating": "Suplantación",
"offensive": "Ofensivo",
"spam/ads": "Spam/Propaganda",
- "other": "Otros"
+ "other": "Otros",
+ "thousand": "m",
+ "million": "M",
+ "billion": "B"
},
"comment": {
"flagged": "marcado",
diff --git a/client/coral-configure/components/ConfigureCommentStream.css b/client/coral-configure/components/ConfigureCommentStream.css
index 335c94377..a8cbc36cb 100644
--- a/client/coral-configure/components/ConfigureCommentStream.css
+++ b/client/coral-configure/components/ConfigureCommentStream.css
@@ -3,10 +3,8 @@
}
.apply {
- position: absolute;
- top: 38%;
- transform: translateX(-50%);
- right: 0;
+ float: right;
+ margin: 0 10px;
}
.wrapper ul {
diff --git a/client/coral-configure/components/ConfigureCommentStream.js b/client/coral-configure/components/ConfigureCommentStream.js
index a7153823b..fe93f3272 100644
--- a/client/coral-configure/components/ConfigureCommentStream.js
+++ b/client/coral-configure/components/ConfigureCommentStream.js
@@ -10,8 +10,7 @@ export default ({handleChange, handleApply, changed, ...props}) => (