diff --git a/client/coral-embed-stream/src/actions/asset.js b/client/coral-embed-stream/src/actions/asset.js index 6acebeafb..1fc9f09f7 100644 --- a/client/coral-embed-stream/src/actions/asset.js +++ b/client/coral-embed-stream/src/actions/asset.js @@ -1,5 +1,5 @@ import * as actions from '../constants/asset'; -import {addNotification} from 'coral-framework/actions/notification'; +import {notify} from 'coral-framework/actions/notification'; import t from 'coral-framework/services/i18n'; @@ -16,7 +16,7 @@ export const updateConfiguration = (newConfig) => (dispatch, getState, {rest}) = dispatch(updateAssetSettingsRequest()); rest(`/assets/${assetId}/settings`, {method: 'PUT', body: newConfig}) .then(() => { - dispatch(addNotification('success', t('framework.success_update_settings'))); + dispatch(notify('success', t('framework.success_update_settings'))); dispatch(updateAssetSettingsSuccess(newConfig)); }) .catch((error) => { @@ -30,7 +30,7 @@ export const updateOpenStream = (closedBody) => (dispatch, getState, {rest}) => dispatch(fetchAssetRequest()); rest(`/assets/${assetId}/status`, {method: 'PUT', body: closedBody}) .then(() => { - dispatch(addNotification('success', t('framework.success_update_settings'))); + dispatch(notify('success', t('framework.success_update_settings'))); dispatch(fetchAssetSuccess(closedBody)); }) .catch((error) => { diff --git a/client/coral-embed-stream/src/actions/auth.js b/client/coral-embed-stream/src/actions/auth.js index 55f7eb546..bf1679b1c 100644 --- a/client/coral-embed-stream/src/actions/auth.js +++ b/client/coral-embed-stream/src/actions/auth.js @@ -2,7 +2,7 @@ import jwtDecode from 'jwt-decode'; import bowser from 'bowser'; import * as actions from '../constants/auth'; import * as Storage from 'coral-framework/helpers/storage'; -import {addNotification} from 'coral-framework/actions/notification'; +import {notify} from 'coral-framework/actions/notification'; import t from 'coral-framework/services/i18n'; @@ -387,7 +387,7 @@ export const editName = (username) => (dispatch, _, {rest}) => { return rest('/account/username', {method: 'PUT', body: {username}}) .then(() => { dispatch(editUsernameSuccess()); - dispatch(addNotification('success', t('framework.success_name_update'))); + dispatch(notify('success', t('framework.success_name_update'))); }) .catch((error) => { console.error(error); diff --git a/client/coral-embed-stream/src/components/AllCommentsPane.js b/client/coral-embed-stream/src/components/AllCommentsPane.js index c141f0618..cb7c3cbb5 100644 --- a/client/coral-embed-stream/src/components/AllCommentsPane.js +++ b/client/coral-embed-stream/src/components/AllCommentsPane.js @@ -87,7 +87,7 @@ class AllCommentsPane extends React.Component { }) .catch((error) => { this.setState({loadingState: 'error'}); - forEachError(error, ({msg}) => {this.props.addNotification('error', msg);}); + forEachError(error, ({msg}) => {this.props.notify('error', msg);}); }); } @@ -129,7 +129,7 @@ class AllCommentsPane extends React.Component { ignoreUser, setActiveReplyBox, activeReplyBox, - addNotification, + notify, disableReply, postComment, asset, @@ -166,7 +166,7 @@ class AllCommentsPane extends React.Component { disableReply={disableReply} setActiveReplyBox={setActiveReplyBox} activeReplyBox={activeReplyBox} - addNotification={addNotification} + notify={notify} depth={0} postComment={postComment} asset={asset} diff --git a/client/coral-embed-stream/src/components/Comment.js b/client/coral-embed-stream/src/components/Comment.js index bb6fee981..522e8f00b 100644 --- a/client/coral-embed-stream/src/components/Comment.js +++ b/client/coral-embed-stream/src/components/Comment.js @@ -152,7 +152,7 @@ export default class Comment extends React.Component { deleteAction: PropTypes.func.isRequired, parentId: PropTypes.string, highlighted: PropTypes.string, - addNotification: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, postComment: PropTypes.func.isRequired, depth: PropTypes.number.isRequired, liveUpdates: PropTypes.bool, @@ -205,7 +205,7 @@ export default class Comment extends React.Component { onClickEdit (e) { e.preventDefault(); if (!can(this.props.currentUser, 'INTERACT_WITH_COMMUNITY')) { - this.props.addNotification('error', t('error.NOT_AUTHORIZED')); + this.props.notify('error', t('error.NOT_AUTHORIZED')); return; } this.setState({isEditing: true}); @@ -235,7 +235,7 @@ export default class Comment extends React.Component { }) .catch((error) => { this.setState({loadingState: 'error'}); - forEachError(error, ({msg}) => {this.props.addNotification('error', msg);}); + forEachError(error, ({msg}) => {this.props.notify('error', msg);}); }); emit('ui.Comment.showMoreReplies', {id}); return; @@ -252,7 +252,7 @@ export default class Comment extends React.Component { if (can(this.props.currentUser, 'INTERACT_WITH_COMMUNITY')) { this.props.setActiveReplyBox(this.props.comment.id); } else { - this.props.addNotification('error', t('error.NOT_AUTHORIZED')); + this.props.notify('error', t('error.NOT_AUTHORIZED')); } return; } @@ -331,7 +331,7 @@ export default class Comment extends React.Component { deleteAction, disableReply, maxCharCount, - addNotification, + notify, charCountEnable, showSignInDialog, liveUpdates, @@ -475,7 +475,7 @@ export default class Comment extends React.Component { + notify={notify} /> } { !isActive && @@ -487,7 +487,7 @@ export default class Comment extends React.Component { this.state.isEditing ? { if (!can(this.props.currentUser, 'INTERACT_WITH_COMMUNITY')) { - this.props.addNotification('error', t('error.NOT_AUTHORIZED')); + this.props.notify('error', t('error.NOT_AUTHORIZED')); return; } this.setState({loadingState: 'loading'}); - const {editComment, addNotification, stopEditing} = this.props; + const {editComment, notify, stopEditing} = this.props; if (typeof editComment !== 'function') {return;} let response; try { response = await editComment({body: this.state.body}); this.setState({loadingState: 'success'}); const status = response.data.editComment.comment.status; - notifyForNewCommentStatus(this.props.addNotification, status); + notifyForNewCommentStatus(this.props.notify, status); if (typeof stopEditing === 'function') { stopEditing(); } } catch (error) { this.setState({loadingState: 'error'}); - forEachError(error, ({msg}) => addNotification('error', msg)); + forEachError(error, ({msg}) => notify('error', msg)); } } diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index b37d232f7..a51b999d6 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -59,7 +59,7 @@ class Stream extends React.Component { commentClassNames, root: {asset, asset: {comment, comments, totalCommentCount}}, postComment, - addNotification, + notify, editComment, postFlag, postDontAgree, @@ -147,7 +147,7 @@ class Stream extends React.Component { />} {showCommentBox && this.setState({timesReset: this.state.timesReset + 1}); @@ -40,7 +40,7 @@ export class TopRightMenu extends React.Component { try { await ignoreUser({id}); } catch (error) { - addNotification('error', 'Failed to ignore user'); + notify('error', 'Failed to ignore user'); throw error; } }; diff --git a/client/coral-embed-stream/src/containers/Embed.js b/client/coral-embed-stream/src/containers/Embed.js index a8f6c1b18..71783e64d 100644 --- a/client/coral-embed-stream/src/containers/Embed.js +++ b/client/coral-embed-stream/src/containers/Embed.js @@ -14,7 +14,7 @@ import {getDefinitionName, getSlotFragmentSpreads} from 'coral-framework/utils'; import {withQuery} from 'coral-framework/hocs'; import Embed from '../components/Embed'; import Stream from './Stream'; -import {addNotification} from 'coral-framework/actions/notification'; +import {notify} from 'coral-framework/actions/notification'; import t from 'coral-framework/services/i18n'; import PropTypes from 'prop-types'; import {setActiveTab} from '../actions/embed'; @@ -34,19 +34,19 @@ class EmbedContainer extends React.Component { const newSubscriptions = [{ document: USER_BANNED_SUBSCRIPTION, updateQuery: () => { - addNotification('info', t('your_account_has_been_banned')); + notify('info', t('your_account_has_been_banned')); }, }, { document: USER_SUSPENDED_SUBSCRIPTION, updateQuery: () => { - addNotification('info', t('your_account_has_been_suspended')); + notify('info', t('your_account_has_been_suspended')); }, }, { document: USERNAME_REJECTED_SUBSCRIPTION, updateQuery: () => { - addNotification('info', t('your_username_has_been_rejected')); + notify('info', t('your_username_has_been_rejected')); }, }]; @@ -193,7 +193,7 @@ const mapDispatchToProps = (dispatch) => checkLogin, setActiveTab, fetchAssetSuccess, - addNotification, + notify, focusSignInDialog, blurSignInDialog, hideSignInDialog, diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index c4a3ae736..7be3d09d5 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -26,7 +26,7 @@ import { } from '../graphql/utils'; const {showSignInDialog, editName} = authActions; -const {addNotification} = notificationActions; +const {notify} = notificationActions; class StreamContainer extends React.Component { subscriptions = []; @@ -303,7 +303,7 @@ const mapStateToProps = (state) => ({ const mapDispatchToProps = (dispatch) => bindActionCreators({ showSignInDialog, - addNotification, + notify, setActiveReplyBox, editName, viewAllComments, diff --git a/client/coral-framework/actions/notification.js b/client/coral-framework/actions/notification.js index f940ab3b4..872936d15 100644 --- a/client/coral-framework/actions/notification.js +++ b/client/coral-framework/actions/notification.js @@ -1,18 +1,22 @@ import * as actions from '../constants/notification'; export const notify = (kind, msg) => (dispatch, _, {notification}) => { - switch (kind) { - case 'error': - notification.error(msg); - break; - case 'info': - notification.info(msg); - break; - case 'success': - notification.success(msg); - break; - default: - throw new Error(`Unknown notification kind ${kind}`); - } - dispatch({type: actions.NOTIFY, kind, msg}); + const messages = Array.isArray(msg) ? msg : [msg]; + + messages.forEach((message) => { + switch (kind) { + case 'error': + notification.error(message); + break; + case 'info': + notification.info(message); + break; + case 'success': + notification.success(message); + break; + default: + throw new Error(`Unknown notification kind ${kind}`); + } + dispatch({type: actions.NOTIFY, kind, message}); + }); }; diff --git a/client/coral-framework/utils/index.js b/client/coral-framework/utils/index.js index 2b4b6378f..00e95243e 100644 --- a/client/coral-framework/utils/index.js +++ b/client/coral-framework/utils/index.js @@ -147,6 +147,12 @@ export function forEachError(error, callback) { }); } +export function getErrorMessages(error) { + const result = []; + forEachError(error, ({msg}) => result.push(msg)); + return result; +} + const ascending = (a, b) => { const dateA = new Date(a.created_at); const dateB = new Date(b.created_at); diff --git a/client/talk-plugin-commentbox/CommentBox.js b/client/talk-plugin-commentbox/CommentBox.js index 084e67fc4..d4cc44f22 100644 --- a/client/talk-plugin-commentbox/CommentBox.js +++ b/client/talk-plugin-commentbox/CommentBox.js @@ -12,11 +12,11 @@ export const name = 'talk-plugin-commentbox'; // Given a newly posted comment's status, show a notification to the user // if needed -export const notifyForNewCommentStatus = (addNotification, status) => { +export const notifyForNewCommentStatus = (notify, status) => { if (status === 'REJECTED') { - addNotification('error', t('comment_box.comment_post_banned_word')); + notify('error', t('comment_box.comment_post_banned_word')); } else if (status === 'PREMOD') { - addNotification('success', t('comment_box.comment_post_notif_premod')); + notify('success', t('comment_box.comment_post_notif_premod')); } }; @@ -45,12 +45,12 @@ class CommentBox extends React.Component { postComment, assetId, parentId, - addNotification, + notify, currentUser, } = this.props; if (!can(currentUser, 'INTERACT_WITH_COMMUNITY')) { - addNotification('error', t('error.NOT_AUTHORIZED')); + notify('error', t('error.NOT_AUTHORIZED')); return; } @@ -73,7 +73,7 @@ class CommentBox extends React.Component { // Execute postSubmit Hooks this.state.hooks.postSubmit.forEach((hook) => hook(data)); - notifyForNewCommentStatus(addNotification, postedComment.status); + notifyForNewCommentStatus(notify, postedComment.status); if (commentPostedHandler) { commentPostedHandler(); @@ -81,7 +81,7 @@ class CommentBox extends React.Component { }) .catch((err) => { this.setState({loadingState: 'error'}); - forEachError(err, ({msg}) => addNotification('error', msg)); + forEachError(err, ({msg}) => notify('error', msg)); }); } @@ -186,7 +186,7 @@ CommentBox.propTypes = { currentUser: PropTypes.object.isRequired, isReply: PropTypes.bool.isRequired, canPost: PropTypes.bool, - addNotification: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, }; const mapStateToProps = ({commentBox}) => ({commentBox}); diff --git a/client/talk-plugin-flags/components/FlagButton.js b/client/talk-plugin-flags/components/FlagButton.js index 1d8438ba0..bf3da6f01 100644 --- a/client/talk-plugin-flags/components/FlagButton.js +++ b/client/talk-plugin-flags/components/FlagButton.js @@ -42,7 +42,7 @@ export default class FlagButton extends Component { this.setState({showMenu: true}); } } else { - this.props.addNotification('error', t('error.NOT_AUTHORIZED')); + this.props.notify('error', t('error.NOT_AUTHORIZED')); } } diff --git a/client/talk-plugin-history/CommentHistory.js b/client/talk-plugin-history/CommentHistory.js index 43ae93f1d..91883cdc8 100644 --- a/client/talk-plugin-history/CommentHistory.js +++ b/client/talk-plugin-history/CommentHistory.js @@ -17,7 +17,7 @@ class CommentHistory extends React.Component { }) .catch((error) => { this.setState({loadingState: 'error'}); - forEachError(error, ({msg}) => {this.props.addNotification('error', msg);}); + forEachError(error, ({msg}) => {this.props.notify('error', msg);}); }); } diff --git a/client/talk-plugin-replies/ReplyBox.js b/client/talk-plugin-replies/ReplyBox.js index 58cb0110d..50bd9a538 100644 --- a/client/talk-plugin-replies/ReplyBox.js +++ b/client/talk-plugin-replies/ReplyBox.js @@ -19,7 +19,7 @@ class ReplyBox extends Component { postComment, assetId, currentUser, - addNotification, + notify, parentId, commentPostedHandler, maxCharCount, @@ -32,7 +32,7 @@ class ReplyBox extends Component { commentPostedHandler={commentPostedHandler} parentId={parentId} onCancel={this.cancelReply} - addNotification={addNotification} + notify={notify} currentUser={currentUser} assetId={assetId} postComment={postComment} @@ -47,7 +47,7 @@ ReplyBox.propTypes = { setActiveReplyBox: PropTypes.func.isRequired, commentPostedHandler: PropTypes.func, parentId: PropTypes.string, - addNotification: PropTypes.func.isRequired, + notify: PropTypes.func.isRequired, postComment: PropTypes.func.isRequired, assetId: PropTypes.string.isRequired };