diff --git a/client/coral-admin/src/actions/moderation.js b/client/coral-admin/src/actions/moderation.js index 1c803d87d..5136db4c3 100644 --- a/client/coral-admin/src/actions/moderation.js +++ b/client/coral-admin/src/actions/moderation.js @@ -15,33 +15,11 @@ export const hideShortcutsNote = () => { return {type: actions.HIDE_SHORTCUTS_NOTE}; }; -export const viewUserDetail = (userId) => ({type: actions.VIEW_USER_DETAIL, userId}); -export const hideUserDetail = () => ({type: actions.HIDE_USER_DETAIL}); - export const setSortOrder = (order) => ({ type: actions.SET_SORT_ORDER, order }); -export const changeUserDetailStatuses = (tab) => { - let statuses; - if (tab === 'all') { - statuses = ['NONE', 'ACCEPTED', 'REJECTED', 'PREMOD']; - } else if (tab === 'rejected') { - statuses = ['REJECTED']; - } - return {type: actions.CHANGE_USER_DETAIL_STATUSES, tab, statuses}; -}; - -export const clearUserDetailSelections = () => ({type: actions.CLEAR_USER_DETAIL_SELECTIONS}); - -export const toggleSelectCommentInUserDetail = (id, active) => { - return { - type: active ? actions.SELECT_USER_DETAIL_COMMENT : actions.UNSELECT_USER_DETAIL_COMMENT, - id - }; -}; - export const toggleStorySearch = (active) => ({ type: active ? actions.SHOW_STORY_SEARCH : actions.HIDE_STORY_SEARCH }); diff --git a/client/coral-admin/src/actions/userDetail.js b/client/coral-admin/src/actions/userDetail.js new file mode 100644 index 000000000..fe9aa2df5 --- /dev/null +++ b/client/coral-admin/src/actions/userDetail.js @@ -0,0 +1,24 @@ +import * as actions from 'constants/userDetail'; + +export const viewUserDetail = (userId) => ({type: actions.VIEW_USER_DETAIL, userId}); +export const hideUserDetail = () => ({type: actions.HIDE_USER_DETAIL}); + +export const changeUserDetailStatuses = (tab) => { + let statuses; + if (tab === 'all') { + statuses = ['NONE', 'ACCEPTED', 'REJECTED', 'PREMOD']; + } else if (tab === 'rejected') { + statuses = ['REJECTED']; + } + return {type: actions.CHANGE_USER_DETAIL_STATUSES, tab, statuses}; +}; + +export const clearUserDetailSelections = () => ({type: actions.CLEAR_USER_DETAIL_SELECTIONS}); + +export const toggleSelectCommentInUserDetail = (id, active) => { + return { + type: active ? actions.SELECT_USER_DETAIL_COMMENT : actions.UNSELECT_USER_DETAIL_COMMENT, + id + }; +}; + diff --git a/client/coral-admin/src/components/ActionButton.js b/client/coral-admin/src/components/ActionButton.js index e084d8e7a..3dbac206b 100644 --- a/client/coral-admin/src/components/ActionButton.js +++ b/client/coral-admin/src/components/ActionButton.js @@ -1,7 +1,7 @@ import React, {PropTypes} from 'react'; import styles from './ModerationList.css'; import {Button} from 'coral-ui'; -import {menuActionsMap} from '../routes/Moderation/helpers/moderationQueueActionsMap'; +import {menuActionsMap} from '../utils/moderationQueueActionsMap'; import t from 'coral-framework/services/i18n'; diff --git a/client/coral-admin/src/routes/Moderation/components/ButtonCopyToClipboard.js b/client/coral-admin/src/components/ButtonCopyToClipboard.js similarity index 100% rename from client/coral-admin/src/routes/Moderation/components/ButtonCopyToClipboard.js rename to client/coral-admin/src/components/ButtonCopyToClipboard.js diff --git a/client/coral-admin/src/components/CommentAnimatedEdit.css b/client/coral-admin/src/components/CommentAnimatedEdit.css new file mode 100644 index 000000000..83be36c11 --- /dev/null +++ b/client/coral-admin/src/components/CommentAnimatedEdit.css @@ -0,0 +1,24 @@ +.bodyLeave { + position: absolute; + width: 100%; + top: 0; + background-color: white; + opacity: 1.0; + transition: background 400ms, opacity 800ms 1600ms; + pointer-events: none; +} + +.bodyLeaveActive { + opacity: 0; + background-color: rgba(255,255,0, 0.2); +} + +.bodyEnter { + opacity: 0; + pointer-events: none; +} + +.bodyEnterActive { + opacity: 1.0; + transition: opacity 800ms 2400ms; +} diff --git a/client/coral-admin/src/components/CommentAnimatedEdit.js b/client/coral-admin/src/components/CommentAnimatedEdit.js new file mode 100644 index 000000000..141dc12cc --- /dev/null +++ b/client/coral-admin/src/components/CommentAnimatedEdit.js @@ -0,0 +1,24 @@ +import React from 'react'; +import {murmur3} from 'murmurhash-js'; +import {CSSTransitionGroup} from 'react-transition-group'; +import styles from './CommentAnimatedEdit.css'; + +export default ({children, body}) => { + return ( + + {React.cloneElement(React.Children.only(children), {key: murmur3(body)})} + + ); +}; diff --git a/client/coral-admin/src/components/CommentBodyHighlighter.js b/client/coral-admin/src/components/CommentBodyHighlighter.js new file mode 100644 index 000000000..3b3ee3318 --- /dev/null +++ b/client/coral-admin/src/components/CommentBodyHighlighter.js @@ -0,0 +1,27 @@ +import React from 'react'; +import Highlighter from 'react-highlight-words'; +import Linkify from 'react-linkify'; +const linkify = new Linkify(); + +export default ({suspectWords, bannedWords, body, ...rest}) => { + + const links = linkify.getMatches(body); + const linkText = links ? links.map((link) => link.raw) : []; + + // since words are checked against word boundaries on the backend, + // should be the behavior on the front end as well. + // currently the highlighter plugin does not support out of the box. + const searchWords = [...suspectWords, ...bannedWords] + .filter((w) => { + return new RegExp(`(^|\\s)${w}(\\s|$)`, 'i').test(body); + }) + .concat(linkText); + + return ( + + ); +}; diff --git a/client/coral-admin/src/routes/Moderation/components/CommentType.css b/client/coral-admin/src/components/CommentType.css similarity index 70% rename from client/coral-admin/src/routes/Moderation/components/CommentType.css rename to client/coral-admin/src/components/CommentType.css index 3144a5bd7..beafc2a7c 100644 --- a/client/coral-admin/src/routes/Moderation/components/CommentType.css +++ b/client/coral-admin/src/components/CommentType.css @@ -1,22 +1,19 @@ .commentType { - position: absolute; - right: 15px; - top: 11px; + display: inline-block; color: white; background: grey; height: 32px; box-sizing: border-box; line-height: 29px; - padding: 2px 8px 2px 26px; + padding: 2px 8px; border-radius: 2px; font-size: 12px; - i { + > i { font-size: 14px; - position: absolute; - left: 6px; - top: 8px; + vertical-align: text-top; margin: 0; + margin-right: 4px; } &.premod { diff --git a/client/coral-admin/src/routes/Moderation/components/CommentType.js b/client/coral-admin/src/components/CommentType.js similarity index 84% rename from client/coral-admin/src/routes/Moderation/components/CommentType.js rename to client/coral-admin/src/components/CommentType.js index 346b5f1e6..075ec5a78 100644 --- a/client/coral-admin/src/routes/Moderation/components/CommentType.js +++ b/client/coral-admin/src/components/CommentType.js @@ -1,12 +1,13 @@ import React, {PropTypes} from 'react'; import styles from './CommentType.css'; import {Icon} from 'coral-ui'; +import cn from 'classnames'; const CommentType = (props) => { const typeData = getTypeData(props.type); return ( - + {typeData.text} ); diff --git a/client/coral-admin/src/routes/Moderation/components/FlagBox.css b/client/coral-admin/src/components/FlagBox.css similarity index 100% rename from client/coral-admin/src/routes/Moderation/components/FlagBox.css rename to client/coral-admin/src/components/FlagBox.css diff --git a/client/coral-admin/src/routes/Moderation/components/FlagBox.js b/client/coral-admin/src/components/FlagBox.js similarity index 98% rename from client/coral-admin/src/routes/Moderation/components/FlagBox.js rename to client/coral-admin/src/components/FlagBox.js index caa8b3fbc..38af61c5c 100644 --- a/client/coral-admin/src/routes/Moderation/components/FlagBox.js +++ b/client/coral-admin/src/components/FlagBox.js @@ -61,7 +61,7 @@ class FlagBox extends Component {