diff --git a/client/coral-admin/src/components/BanUserDialog.js b/client/coral-admin/src/components/BanUserDialog.js index b23d8f9d1..4f2296409 100644 --- a/client/coral-admin/src/components/BanUserDialog.js +++ b/client/coral-admin/src/components/BanUserDialog.js @@ -8,7 +8,14 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const BanUserDialog = ({open, handleClose, handleBanUser, user}) => ( +const onBanClick = (userId, commentId, handleBanUser, rejectComment, handleClose) => (e) => { + e.preventDefault(); + handleBanUser({userId}) + .then(handleClose) + .then(() => rejectComment({commentId})); +}; + +const BanUserDialog = ({open, handleClose, handleBanUser, rejectComment, user, commentId}) => ( ( - diff --git a/client/coral-admin/src/containers/Configure/Configure.css b/client/coral-admin/src/containers/Configure/Configure.css index 6cb623978..b1b1ebbaf 100644 --- a/client/coral-admin/src/containers/Configure/Configure.css +++ b/client/coral-admin/src/containers/Configure/Configure.css @@ -90,6 +90,11 @@ .configTimeoutSelect { display: inline-block; margin-left: 20px; + + i { /* fix for firefox and react-mdl-selectfield@0.2.0 */ + padding: 20px 0; + vertical-align: top; + } } .charCountTexfield { diff --git a/client/coral-admin/src/containers/Configure/StreamSettings.js b/client/coral-admin/src/containers/Configure/StreamSettings.js index 5530bc6cd..f77013bc0 100644 --- a/client/coral-admin/src/containers/Configure/StreamSettings.js +++ b/client/coral-admin/src/containers/Configure/StreamSettings.js @@ -171,6 +171,7 @@ const StreamSettings = ({updateSettings, settingsError, settings, errors}) => { + {/* the above card should be the last one if at all possible because of z-index issues with the selects */} ); }; diff --git a/client/coral-admin/src/containers/Dashboard/Dashboard.css b/client/coral-admin/src/containers/Dashboard/Dashboard.css index 72b9bd90c..cdad990ba 100644 --- a/client/coral-admin/src/containers/Dashboard/Dashboard.css +++ b/client/coral-admin/src/containers/Dashboard/Dashboard.css @@ -7,3 +7,28 @@ font-size: 1.5rem; font-weight: bold; } + +.autoUpdate { + background-color: #d5d5d5; + padding: 3px 10px 10px 10px; + margin-bottom: 0; + + i { + position: relative; + top: 7px; + } + + b { + float: right; + border-radius: 20px; + cursor: pointer; + background-color: #c0c0c0; + width: 30px; + height: 30px; + text-align: center; + top: 4px; + position: relative; + line-height: 1.7em; + font-size: 1.3em; + } +} diff --git a/client/coral-admin/src/containers/Dashboard/Dashboard.js b/client/coral-admin/src/containers/Dashboard/Dashboard.js index 96e837a9e..5b4a20282 100644 --- a/client/coral-admin/src/containers/Dashboard/Dashboard.js +++ b/client/coral-admin/src/containers/Dashboard/Dashboard.js @@ -6,11 +6,41 @@ import {getMetrics} from 'coral-admin/src/graphql/queries'; import FlagWidget from './FlagWidget'; import LikeWidget from './LikeWidget'; import {showBanUserDialog, hideBanUserDialog} from 'coral-admin/src/actions/moderation'; +import I18n from 'coral-framework/modules/i18n/i18n'; +import translations from 'coral-admin/src/translations'; +import {Spinner, Icon} from 'coral-ui'; -import {Spinner} from 'coral-ui'; +const lang = new I18n(translations); +const refreshIntervalSeconds = 60 * 5; class Dashboard extends React.Component { + state = { + noteHidden: false, + secondsUntilRefresh: refreshIntervalSeconds + } + + componentWillMount () { + setInterval(() => { // the countdown timer + let nextCount = this.state.secondsUntilRefresh - 1; + if (nextCount < 0) { + nextCount = refreshIntervalSeconds; + this.props.data.refetch(); + } + this.setState({secondsUntilRefresh: nextCount}); + }, 1000); + } + + formatTime = () => { + const minutes = Math.floor(this.state.secondsUntilRefresh / 60); + let seconds = (this.state.secondsUntilRefresh % 60).toString(); + if (seconds.length < 2) { + seconds = `0${seconds}`; + } + + return `${minutes}:${seconds}`; + } + render () { if (this.props.data && this.props.data.loading) { @@ -20,9 +50,18 @@ class Dashboard extends React.Component { const {data: {assetsByLike, assetsByFlag}} = this.props; return ( -
- - +
+

this.setState({noteHidden: true})}> + × + {lang.t('dashboard.next-update', this.formatTime())} {lang.t('dashboard.auto-update')} +

+
+ + +
); } diff --git a/client/coral-admin/src/containers/Dashboard/FlagWidget.js b/client/coral-admin/src/containers/Dashboard/FlagWidget.js index 4b86ec7d7..7d2ffe17a 100644 --- a/client/coral-admin/src/containers/Dashboard/FlagWidget.js +++ b/client/coral-admin/src/containers/Dashboard/FlagWidget.js @@ -12,43 +12,29 @@ const FlagWidget = (props) => { return (

Articles with the most flags

- - - - - - - - - { - assets.length - ? assets.map(asset => { - const flagSummary = asset.action_summaries.find(s => s.type === 'FlagAssetActionSummary'); - return ( - - - - - - ); - }) - : - } - { /* rows in a table with a fixed height will expand and ignore height. - this extra row will expand to fill the extra space. */ - assets.length < 10 ? : null - } - -
{lang.t('streams.article')}{lang.t('dashboard.flags')}
- -

{asset.title}

-

{asset.author} — Published: {new Date(asset.created_at).toLocaleDateString()}

- -
-

{flagSummary ? flagSummary.actionCount : 0}

-
- Moderate -
{lang.t('dashboard.no_flags')}
+
+

{lang.t('streams.article')}

+

{lang.t('dashboard.flags')}

+
+
+ { + assets.length + ? assets.map(asset => { + const flagSummary = asset.action_summaries.find(s => s.type === 'FlagAssetActionSummary'); + return ( +
+ Moderate +

{flagSummary ? flagSummary.actionCount : 0}

+ +

{asset.title}

+ +

{asset.author} — Published: {new Date(asset.created_at).toLocaleDateString()}

+
+ ); + }) + :
{lang.t('dashboard.no_flags')}
+ } +
); }; diff --git a/client/coral-admin/src/containers/Dashboard/LikeWidget.js b/client/coral-admin/src/containers/Dashboard/LikeWidget.js index d52676ae4..436fbcaf3 100644 --- a/client/coral-admin/src/containers/Dashboard/LikeWidget.js +++ b/client/coral-admin/src/containers/Dashboard/LikeWidget.js @@ -13,43 +13,29 @@ const LikeWidget = (props) => { return (

Articles with the most likes

- - - - - - - - - { - assets.length - ? assets.map(asset => { - const likeSummary = asset.action_summaries.find(s => s.type === 'LikeAssetActionSummary'); - return ( - - - - - - ); - }) - : - } - { /* rows in a table with a fixed height will expand and ignore height. - this extra row will expand to fill the extra space. */ - assets.length < 10 ? : null - } - -
{lang.t('streams.article')}{lang.t('modqueue.likes')}
- -

{asset.title}

-

{asset.author} — Published: {new Date(asset.created_at).toLocaleDateString()}

- -
-

{likeSummary ? likeSummary.actionCount : 0}

-
- Moderate -
{lang.t('dashboard.no_likes')}
+
+

{lang.t('streams.article')}

+

{lang.t('modqueue.likes')}

+
+
+ { + assets.length + ? assets.map(asset => { + const likeSummary = asset.action_summaries.find(s => s.type === 'LikeAssetActionSummary'); + return ( +
+ Moderate +

{likeSummary ? likeSummary.actionCount : 0}

+ +

{asset.title}

+ +

{asset.author} — Published: {new Date(asset.created_at).toLocaleDateString()}

+
+ ); + }) + :
{lang.t('dashboard.no_likes')}
+ } +
); }; diff --git a/client/coral-admin/src/containers/Dashboard/Widget.css b/client/coral-admin/src/containers/Dashboard/Widget.css index 3170cf332..401cd1fe7 100644 --- a/client/coral-admin/src/containers/Dashboard/Widget.css +++ b/client/coral-admin/src/containers/Dashboard/Widget.css @@ -1,14 +1,17 @@ :root { - --row-height: 80px; + --row-height: 60px; } .widget { - box-sizing: border-box; margin: 10px 5px 5px 5px; box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.2); - padding: 15px; flex: 1; background-color: white; + box-sizing: border-box; +} + +.widget * { + box-sizing: border-box; } .heading { @@ -16,24 +19,32 @@ padding-left: 10px; font-size: 1.5rem; font-weight: bold; + background-color: #e0e0e0; } .widgetTable { - width: 100%; - border-collapse: collapse; - user-select: none; height: calc(var(--row-height) * 10); } -.widgetTable thead th { +.widgetTable + div:after { + content: ''; + clear: both; + display: block; +} + +.widgetHead p { color: rgb(35, 102, 223); padding: 10px; text-align: left; text-transform: capitalize; + display: inline-block; + box-sizing: border-box; + margin-bottom: 0; } -.widgetTable thead th:last-child { - width: 10%; +.widgetHead p:last-child { + float: right; + margin-right: 100px; } .rowLinkify { @@ -41,6 +52,7 @@ border-bottom: 1px solid lightgrey; color: #555; height: var(--row-height); + padding: 10px; } .rowLinkify:last-child { @@ -51,16 +63,8 @@ background-color: #f8f8f8; } -.widgetTable tbody td { - padding: 10px; -} - -.widgetTable tbody td:last-child { - padding-top: 0; -} - .linkToAsset { - display: block; + display: inline-block; text-decoration: none; } @@ -69,6 +73,8 @@ padding: 10px 14px; text-decoration: none; color: black; + float: right; + margin-left: 15px; } .linkToModerate:hover { @@ -96,4 +102,6 @@ color: #555; font-size: 1.3em; font-weight: 400; + float: right; + margin-top: 7px; } diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index 2f43911b1..e53162992 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -21,12 +21,13 @@ import ModerationKeysModal from '../../components/ModerationKeysModal'; class ModerationContainer extends Component { state = { - selectedIndex: 0 + selectedIndex: 0, + sort: 'REVERSE_CHRONOLOGICAL' } componentWillMount() { const {toggleModal, singleView} = this.props; - + this.props.fetchSettings(); key('s', () => singleView()); key('shift+/', () => toggleModal(true)); @@ -74,6 +75,11 @@ class ModerationContainer extends Component { } } + selectSort = (sort) => { + this.setState({sort}); + this.props.modQueueResort(sort); + } + componentWillUnmount() { key.unbind('s'); key.unbind('shift+/'); @@ -92,7 +98,7 @@ class ModerationContainer extends Component { } render () { - const {data, moderation, settings, assets, modQueueResort, onClose, ...props} = this.props; + const {data, moderation, settings, assets, onClose, ...props} = this.props; const providedAssetId = this.props.params.id; const activeTab = this.props.route.path === ':id' ? 'premod' : this.props.route.path; @@ -115,6 +121,18 @@ class ModerationContainer extends Component { } const comments = data[activeTab]; + let activeTabCount; + switch(activeTab) { + case 'premod': + activeTabCount = data.premodCount; + break; + case 'flagged': + activeTabCount = data.flaggedCount; + break; + case 'rejected': + activeTabCount = data.rejectedCount; + break; + } return (
@@ -124,7 +142,8 @@ class ModerationContainer extends Component { premodCount={data.premodCount} rejectedCount={data.rejectedCount} flaggedCount={data.flaggedCount} - modQueueResort={modQueueResort} + selectSort={this.selectSort} + sort={this.state.sort} /> { +const ModerationQueue = ({comments, selectedIndex, commentCount, singleView, loadMore, activeTab, sort, ...props}) => { return (
    @@ -20,7 +21,7 @@ const ModerationQueue = ({comments, selectedIndex, singleView, ...props}) => { key={i} index={i} comment={comment} - commentType={props.activeTab} + commentType={activeTab} selected={i === selectedIndex} suspectWords={props.suspectWords} actions={actionsMap[status]} @@ -33,6 +34,14 @@ const ModerationQueue = ({comments, selectedIndex, singleView, ...props}) => { : {lang.t('modqueue.emptyqueue')} }
+
); }; diff --git a/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js b/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js new file mode 100644 index 000000000..f8d3f0ed4 --- /dev/null +++ b/client/coral-admin/src/containers/ModerationQueue/components/LoadMore.js @@ -0,0 +1,31 @@ +import React, {PropTypes} from 'react'; +import {Button} from 'coral-ui'; +import styles from './styles.css'; + +const LoadMore = ({comments, loadMore, sort, tab, assetId, showLoadMore}) => +
+ { + showLoadMore && + } +
; + +LoadMore.propTypes = { + comments: PropTypes.array.isRequired, + loadMore: PropTypes.func.isRequired, + sort: PropTypes.oneOf(['CHRONOLOGICAL', 'REVERSE_CHRONOLOGICAL']).isRequired, + tab: PropTypes.oneOf(['rejected', 'premod', 'flagged']).isRequired, + assetId: PropTypes.string, + showLoadMore: PropTypes.bool.isRequired +}; + +export default LoadMore; diff --git a/client/coral-admin/src/containers/ModerationQueue/components/ModerationHeader.js b/client/coral-admin/src/containers/ModerationQueue/components/ModerationHeader.js index c5a11b642..8d9f6b7e0 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/ModerationHeader.js +++ b/client/coral-admin/src/containers/ModerationQueue/components/ModerationHeader.js @@ -10,9 +10,9 @@ const ModerationHeader = props => ( props.asset ? diff --git a/client/coral-admin/src/containers/ModerationQueue/components/ModerationMenu.js b/client/coral-admin/src/containers/ModerationQueue/components/ModerationMenu.js index f9b0c266f..b8160e21b 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/ModerationMenu.js +++ b/client/coral-admin/src/containers/ModerationQueue/components/ModerationMenu.js @@ -1,4 +1,4 @@ -import React, {PropTypes, Component} from 'react'; +import React, {PropTypes} from 'react'; import CommentCount from './CommentCount'; import styles from './styles.css'; import {SelectField, Option} from 'react-mdl-selectfield'; @@ -8,57 +8,45 @@ import {Link} from 'react-router'; const lang = new I18n(translations); -class ModerationMenu extends Component { - state = { - sort: 'REVERSE_CHRONOLOGICAL', - } - - static propTypes = { - premodCount: PropTypes.number.isRequired, - rejectedCount: PropTypes.number.isRequired, - flaggedCount: PropTypes.number.isRequired, - asset: PropTypes.shape({ - id: PropTypes.string - }) - } - - selectSort = (sort) => { - this.setState({sort}); - this.props.modQueueResort(sort); - } - - render() { - const {asset, premodCount, rejectedCount, flaggedCount} = this.props; - const premodPath = asset ? `/admin/moderate/premod/${asset.id}` : '/admin/moderate/premod'; - const rejectPath = asset ? `/admin/moderate/rejected/${asset.id}` : '/admin/moderate/rejected'; - const flagPath = asset ? `/admin/moderate/flagged/${asset.id}` : '/admin/moderate/flagged'; - return ( -
-
-
-
- - {lang.t('modqueue.premod')} - - - {lang.t('modqueue.rejected')} - - - {lang.t('modqueue.flagged')} - -
- this.selectSort(sort)}> - - - +const ModerationMenu = ({asset, premodCount, rejectedCount, flaggedCount, selectSort, sort}) => { + const premodPath = asset ? `/admin/moderate/premod/${asset.id}` : '/admin/moderate/premod'; + const rejectPath = asset ? `/admin/moderate/rejected/${asset.id}` : '/admin/moderate/rejected'; + const flagPath = asset ? `/admin/moderate/flagged/${asset.id}` : '/admin/moderate/flagged'; + return ( +
+
+
+
+ + {lang.t('modqueue.premod')} + + + {lang.t('modqueue.rejected')} + + + {lang.t('modqueue.flagged')} +
+ selectSort(sort)}> + + +
- ); - } -} +
+ ); +}; + +ModerationMenu.propTypes = { + premodCount: PropTypes.number.isRequired, + rejectedCount: PropTypes.number.isRequired, + flaggedCount: PropTypes.number.isRequired, + asset: PropTypes.shape({ + id: PropTypes.string + }) +}; export default ModerationMenu; diff --git a/client/coral-admin/src/containers/ModerationQueue/components/styles.css b/client/coral-admin/src/containers/ModerationQueue/components/styles.css index 59f47faad..9576045de 100644 --- a/client/coral-admin/src/containers/ModerationQueue/components/styles.css +++ b/client/coral-admin/src/containers/ModerationQueue/components/styles.css @@ -84,11 +84,10 @@ span { margin-bottom: -1px; .settingsButton { - i { - vertical-align: middle; - margin-left: 10px; - margin-top: -4px; - } + vertical-align: middle; + margin-left: 10px; + margin-top: -4px; + font-size: 16px; } .moderateAsset { @@ -114,7 +113,15 @@ span { } &:nth-child(2) { - text-align: center; + span { + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + max-width: 344px; + display: inline-block; + vertical-align: top; + } } &:last-child { @@ -387,3 +394,23 @@ span { cursor: pointer; } } + +.loadMoreContainer { + display: flex; + justify-content: center; + width: 100%; +}; + +.loadMore { + width: 100%; + text-align: center; + color: #FFF; + max-width: 660px; + margin-bottom: 30px; + background-color: #2376D8; + cursor: pointer; +} + +.loadMore:hover { + background-color: #4399FF; +} diff --git a/client/coral-admin/src/containers/Streams/Streams.js b/client/coral-admin/src/containers/Streams/Streams.js index 96130fcba..bd5ce6e85 100644 --- a/client/coral-admin/src/containers/Streams/Streams.js +++ b/client/coral-admin/src/containers/Streams/Streams.js @@ -80,8 +80,8 @@ class Streams extends Component {
- {closed ? lang.t('streams.closed') : lang.t('streams.open')} {!statusMenuOpen && } + {closed ? lang.t('streams.closed') : lang.t('streams.open')}
{ statusMenuOpen && diff --git a/client/coral-admin/src/graphql/mutations/index.js b/client/coral-admin/src/graphql/mutations/index.js index fe3a1faf9..884e30e0c 100644 --- a/client/coral-admin/src/graphql/mutations/index.js +++ b/client/coral-admin/src/graphql/mutations/index.js @@ -22,7 +22,26 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, { commentId, status: 'ACCEPTED' }, - refetchQueries: ['ModQueue'] + updateQueries: { + ModQueue: (oldData) => { + const premod = oldData.premod.filter(c => c.id !== commentId); + const flagged = oldData.flagged.filter(c => c.id !== commentId); + const rejected = oldData.rejected.filter(c => c.id !== commentId); + const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount; + const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount; + const rejectedCount = rejected.length < oldData.rejected.length ? oldData.rejectedCount - 1 : oldData.rejectedCount; + + return { + ...oldData, + premodCount, + flaggedCount, + rejectedCount, + premod, + flagged, + rejected, + }; + } + } }); }, rejectComment: ({commentId}) => { @@ -31,7 +50,27 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, { commentId, status: 'REJECTED' }, - refetchQueries: ['ModQueue'] + updateQueries: { + ModQueue: (oldData) => { + const comment = oldData.premod.concat(oldData.flagged).filter(c => c.id === commentId)[0]; + const rejected = [comment].concat(oldData.rejected); + const premod = oldData.premod.filter(c => c.id !== commentId); + const flagged = oldData.flagged.filter(c => c.id !== commentId); + const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount; + const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount; + const rejectedCount = oldData.rejectedCount + 1; + + return { + ...oldData, + premodCount, + flaggedCount, + rejectedCount, + premod, + flagged, + rejected + }; + } + } }); } }) diff --git a/client/coral-admin/src/graphql/queries/index.js b/client/coral-admin/src/graphql/queries/index.js index c4a30ad44..13164bca2 100644 --- a/client/coral-admin/src/graphql/queries/index.js +++ b/client/coral-admin/src/graphql/queries/index.js @@ -1,6 +1,7 @@ import {graphql} from 'react-apollo'; import MOD_QUEUE_QUERY from './modQueueQuery.graphql'; +import MOD_QUEUE_LOAD_MORE from './loadMore.graphql'; import METRICS from './metricsQuery.graphql'; export const modQueueQuery = graphql(MOD_QUEUE_QUERY, { @@ -14,7 +15,8 @@ export const modQueueQuery = graphql(MOD_QUEUE_QUERY, { }, props: ({ownProps: {params: {id = null}}, data}) => ({ data, - modQueueResort: modQueueResort(id, data.fetchMore) + modQueueResort: modQueueResort(id, data.fetchMore), + loadMore: loadMore(data.fetchMore) }) }); @@ -30,6 +32,40 @@ export const getMetrics = graphql(METRICS, { } }); +export const loadMore = (fetchMore) => ({limit, cursor, sort, tab, asset_id}) => { + let statuses; + switch(tab) { + case 'premod': + statuses = ['PREMOD']; + break; + case 'flagged': + statuses = ['NONE', 'PREMOD']; + break; + case 'rejected': + statuses = ['REJECTED']; + break; + } + return fetchMore({ + query: MOD_QUEUE_LOAD_MORE, + variables: { + limit, + cursor, + sort, + statuses, + asset_id + }, + updateQuery: (oldData, {fetchMoreResult:{data:{comments}}}) => { + return { + ...oldData, + [tab]: [ + ...oldData[tab], + ...comments + ] + }; + } + }); +}; + export const modQueueResort = (id, fetchMore) => (sort) => { return fetchMore({ query: MOD_QUEUE_QUERY, diff --git a/client/coral-admin/src/graphql/queries/loadMore.graphql b/client/coral-admin/src/graphql/queries/loadMore.graphql new file mode 100644 index 000000000..56966a804 --- /dev/null +++ b/client/coral-admin/src/graphql/queries/loadMore.graphql @@ -0,0 +1,13 @@ +#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}) { + ...commentView + action_summaries { + count + ... on FlagActionSummary { + reason + } + } + } +} diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json index ac9131685..257148837 100644 --- a/client/coral-admin/src/translations.json +++ b/client/coral-admin/src/translations.json @@ -117,6 +117,8 @@ "write_message": "Write a message" }, "dashboard": { + "next-update": "{0} minutes until next update.", + "auto-update": "Data automatically updates every five minutes or when you Reload.", "no_flags": "There have been no flags in the last 5 minutes! Hooray!", "no_likes": "There have been no likes in the last 5 minutes. All quiet.", "flags": "Flags", @@ -235,6 +237,8 @@ "yes_ban_user": "Si, Suspendan el usuario" }, "dashbord": { + "next-update": "{0} minutos hasta la siguiente actualización.", + "auto-update": "Los datos se actualizan automaticamente cada 5 minutos o cuando Recargas.", "no_flags": "¡Nadie ha marcado nada en los últimos 5 minutos! ¡Bravo!", "no_likes": "A nadie le ha gustado algún comentario en los últimos 5 minutos. Todo tranquilo.", "flags": "Marcados", diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index 1c52fb68c..0b9bc4fc5 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -256,7 +256,7 @@ const mapStateToProps = state => ({ const mapDispatchToProps = dispatch => ({ requestConfirmEmail: () => dispatch(requestConfirmEmail()), loadAsset: (asset) => dispatch(fetchAssetSuccess(asset)), - addNotification: (type, text) => dispatch(addNotification(type, text)), + addNotification: (type, text) => addNotification(type, text), clearNotification: () => dispatch(clearNotification()), editName: (username) => dispatch(editName(username)), showSignInDialog: (offset) => dispatch(showSignInDialog(offset)), diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js index 537d899cd..45110f407 100644 --- a/client/coral-plugin-flags/FlagButton.js +++ b/client/coral-plugin-flags/FlagButton.js @@ -32,18 +32,30 @@ class FlagButton extends Component { if (flagged) { this.setState((prev) => prev.localPost ? {...prev, localPost: null, step: 0} : {...prev, localDelete: true}); deleteAction(localPost || flag.current_user.id); + } else if (this.state.showMenu){ + this.closeMenu(); } else { - this.setState({showMenu: !this.state.showMenu}); + this.setState({showMenu: true}); } } + closeMenu = () => { + this.setState({ + showMenu: false, + itemType: '', + reason: '', + message: '', + step: 0 + }); + } + onPopupContinue = () => { const {postFlag, postDontAgree, id, author_id} = this.props; const {itemType, reason, step, posted, message} = this.state; // Proceed to the next step or close the menu if we've reached the end if (step + 1 >= this.props.getPopupMenu.length) { - this.setState({showMenu: false}); + this.closeMenu(); } else { this.setState({step: step + 1}); } @@ -114,7 +126,7 @@ class FlagButton extends Component { } handleClickOutside () { - this.setState({showMenu: false}); + this.closeMenu(); } render () { diff --git a/client/coral-ui/components/Icon.js b/client/coral-ui/components/Icon.js index 65bf52f72..11432c753 100644 --- a/client/coral-ui/components/Icon.js +++ b/client/coral-ui/components/Icon.js @@ -1,7 +1,7 @@ import React from 'react'; import {Icon as IconMDL} from 'react-mdl'; -const Icon = ({className, name}) => ( +const Icon = ({className = '', name}) => ( );