mirror of
https://github.com/wassname/talk.git
synced 2026-09-12 13:01:11 +08:00
Merge branch 'master' into ban-user
This commit is contained in:
@@ -49,7 +49,7 @@ export const setRole = (id, role) => dispatch => {
|
||||
};
|
||||
|
||||
export const setCommenterStatus = (id, status) => dispatch => {
|
||||
return fetch(`${base}/user/${id}/status`, getInit('POST', {status}))
|
||||
return coralApi(`/user/${id}/status`, {method: 'POST', body: {status}})
|
||||
.then(() => {
|
||||
return dispatch({type: SET_COMMENTER_STATUS, id, status});
|
||||
});
|
||||
|
||||
@@ -12,17 +12,18 @@ const linkify = new Linkify();
|
||||
|
||||
// Render a single comment for the list
|
||||
export default props => {
|
||||
const links = linkify.getMatches(props.comment.get('body'));
|
||||
const banned = props.comment.get('banned');
|
||||
const author_status = props.author.get('status');
|
||||
const {comment, author} = props;
|
||||
const links = linkify.getMatches(comment.get('body'));
|
||||
|
||||
return (
|
||||
<li tabIndex={props.index} className={`${styles.listItem} ${props.isActive && !props.hideActive ? styles.activeItem : ''}`}>
|
||||
<div className={styles.itemHeader}>
|
||||
<div className={styles.author}>
|
||||
<i className={`material-icons ${styles.avatar}`}>person</i>
|
||||
<span>{props.comment.get('name') || lang.t('comment.anon')}</span>
|
||||
<span className={styles.created}>{timeago().format(props.comment.get('createdAt') || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))}</span>
|
||||
{props.comment.get('flagged') ? <p className={styles.flagged}>{lang.t('comment.flagged')}</p> : null}
|
||||
<span>{author.get('displayName') || lang.t('comment.anon')}</span>
|
||||
<span className={styles.created}>{timeago().format(comment.get('createdAt') || (Date.now() - props.index * 60 * 1000), lang.getLocale().replace('-', '_'))}</span>
|
||||
{comment.get('flagged') ? <p className={styles.flagged}>{lang.t('comment.flagged')}</p> : null}
|
||||
</div>
|
||||
<div>
|
||||
{links ?
|
||||
@@ -32,14 +33,14 @@ export default props => {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{banned ?
|
||||
{author_status === 'banned' ?
|
||||
<span className={styles.banned}><Icon name='error_outline'/> Banned User</span> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.itemBody}>
|
||||
<span className={styles.body}>
|
||||
<Linkify component='span' properties={{style: linkStyles}}>
|
||||
{props.comment.get('body')}
|
||||
{comment.get('body')}
|
||||
</Linkify>
|
||||
</span>
|
||||
</div>
|
||||
@@ -59,6 +60,7 @@ const getActionButton = (action, i, props) => {
|
||||
return (
|
||||
<Button
|
||||
cStyle='darkGrey'
|
||||
key={i}
|
||||
onClick={() => props.onClickAction(props.actionsMap[action].status, props.comment.get('id'))}>{lang.t('comment.ban_user')}</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -113,13 +113,15 @@ export default class CommentList extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const {singleView, commentIds, comments, hideActive, key} = this.props;
|
||||
const {singleView, commentIds, comments, users, hideActive, key} = this.props;
|
||||
const {active} = this.state;
|
||||
|
||||
return (
|
||||
<ul className={`${styles.list} ${singleView ? styles.singleView : ''}`} {...key}>
|
||||
{commentIds.map((commentId, index) => (
|
||||
<Comment comment={comments.get(commentId)}
|
||||
{commentIds.map((commentId, index) => {
|
||||
const comment = comments.get(commentId);
|
||||
return <Comment comment={comment}
|
||||
author={users.get(comment.get('author_id'))}
|
||||
ref={el => { if (el && commentId === active) { this._active = el; } }}
|
||||
key={index}
|
||||
index={index}
|
||||
@@ -127,8 +129,8 @@ export default class CommentList extends React.Component {
|
||||
actions={this.props.actions}
|
||||
actionsMap={actions}
|
||||
isActive={commentId === active}
|
||||
hideActive={hideActive} />
|
||||
)).toArray()}
|
||||
hideActive={hideActive} />;
|
||||
}).toArray()}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class CommentStream extends React.Component {
|
||||
}
|
||||
|
||||
// Render the comment box along with the CommentList
|
||||
render ({comments}, {snackbar, snackbarMsg}) {
|
||||
render ({comments, users}, {snackbar, snackbarMsg}) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<CommentBox onSubmit={this.onSubmit} />
|
||||
@@ -48,6 +48,7 @@ class CommentStream extends React.Component {
|
||||
singleView={false}
|
||||
commentIds={comments.get('ids')}
|
||||
comments={comments.get('byId')}
|
||||
users={users.get('byId')}
|
||||
onClickAction={this.onClickAction}
|
||||
actions={['flag']}
|
||||
loading={comments.loading} />
|
||||
@@ -57,4 +58,4 @@ class CommentStream extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(({comments}) => ({comments}))(CommentStream);
|
||||
export default connect(({comments, users}) => ({comments, users}))(CommentStream);
|
||||
|
||||
@@ -90,11 +90,11 @@ class ModerationQueue extends React.Component {
|
||||
commentIds={
|
||||
comments.get('ids')
|
||||
.filter(id => !comments.get('byId')
|
||||
.get(id)
|
||||
.get('status'))
|
||||
.get(id)
|
||||
.get('status'))
|
||||
}
|
||||
comments={comments.get('byId')}
|
||||
commenters={commenters}
|
||||
commenters={commenters.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
actions={['reject', 'approve', 'ban']}
|
||||
loading={comments.loading} />
|
||||
@@ -113,7 +113,7 @@ class ModerationQueue extends React.Component {
|
||||
.get('status') === 'rejected')
|
||||
}
|
||||
comments={comments.get('byId')}
|
||||
commenters={commenters}
|
||||
commenters={commenters.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
actions={['approve']}
|
||||
loading={comments.loading} />
|
||||
@@ -127,7 +127,7 @@ class ModerationQueue extends React.Component {
|
||||
return !data.get('status') && data.get('flagged') === true;
|
||||
})}
|
||||
comments={comments.get('byId')}
|
||||
commenters={commenters}
|
||||
commenters={commenters.get('byId')}
|
||||
onClickAction={(action, id) => this.onCommentAction(action, id)}
|
||||
actions={['reject', 'approve']}
|
||||
loading={comments.loading} />
|
||||
@@ -140,6 +140,6 @@ class ModerationQueue extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(({comments}) => ({comments}))(ModerationQueue);
|
||||
export default connect(({comments, commenters}) => ({comments, commenters}))(ModerationQueue);
|
||||
|
||||
const lang = new I18n(translations);
|
||||
|
||||
@@ -2,6 +2,7 @@ import {combineReducers} from 'redux';
|
||||
import comments from 'reducers/comments';
|
||||
import settings from 'reducers/settings';
|
||||
import community from 'reducers/community';
|
||||
import users from 'reducers/users';
|
||||
import auth from 'reducers/auth';
|
||||
|
||||
// Combine all reducers into a main one
|
||||
@@ -9,6 +10,6 @@ export default combineReducers({
|
||||
settings,
|
||||
comments,
|
||||
community,
|
||||
auth
|
||||
auth,
|
||||
users
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import {Map, List, fromJS} from 'immutable';
|
||||
|
||||
const initialState = Map({
|
||||
byId: Map(),
|
||||
ids: List()
|
||||
});
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case 'USERS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceUsers(action, state);
|
||||
default: return state;
|
||||
}
|
||||
};
|
||||
|
||||
// Replace the comment list with a new one
|
||||
const replaceUsers = (action, state) => {
|
||||
const users = fromJS(action.users.reduce((prev, curr) => { prev[curr.id] = curr; return prev; }, {}));
|
||||
return state.set('byId', users)
|
||||
.set('ids', List(users.keys()));
|
||||
};
|
||||
@@ -15,9 +15,6 @@ export default store => next => action => {
|
||||
case 'COMMENTS_MODERATION_QUEUE_FETCH':
|
||||
fetchModerationQueueComments(store);
|
||||
break;
|
||||
// case 'COMMENT_STREAM_FETCH':
|
||||
// fetchCommentStream(store);
|
||||
// break;
|
||||
case 'COMMENT_UPDATE':
|
||||
updateComment(store, action.comment);
|
||||
break;
|
||||
@@ -41,12 +38,31 @@ Promise.all([
|
||||
coralApi('/comments?action_type=flag')
|
||||
])
|
||||
.then(([pending, rejected, flagged]) => {
|
||||
flagged.forEach(comment => comment.flagged = true);
|
||||
return [...pending, ...rejected, ...flagged];
|
||||
/* Combine seperate calls into a single object */
|
||||
let all = {};
|
||||
all.comments = pending.comments
|
||||
.concat(rejected.comments)
|
||||
.concat(flagged.comments.map(comment => {
|
||||
comment.flagged = true;
|
||||
return comment;
|
||||
}));
|
||||
all.users = pending.users
|
||||
.concat(rejected.users)
|
||||
.concat(flagged.users);
|
||||
all.actions = pending.actions
|
||||
.concat(rejected.actions)
|
||||
.concat(flagged.actions);
|
||||
return all;
|
||||
})
|
||||
.then(res => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
|
||||
comments: res}))
|
||||
.catch(error => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error}));
|
||||
.then(all => {
|
||||
/* Post comments and users to redux store. Actions will be posted when they are needed. */
|
||||
store.dispatch({type: 'USERS_MODERATION_QUEUE_FETCH_SUCCESS',
|
||||
users: all.users});
|
||||
store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
|
||||
comments: all.comments});
|
||||
|
||||
});
|
||||
// .catch(error => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error}));
|
||||
|
||||
// Update a comment. Now to update a comment we need to send back the whole object
|
||||
|
||||
@@ -71,8 +87,7 @@ const createComment = (store, name, comment) => {
|
||||
|
||||
// Ban a user
|
||||
const banUser = (store, comment) => {
|
||||
fetch(`${base}/user/${comment.get('author_id')}/status`, getInit('POST', {status: comment.get('status')}))
|
||||
.then(handleResp)
|
||||
coralApi(`/user/${comment.get('author_id')}/status`, {method: 'POST', body: {status: comment.get('status')}})
|
||||
.then(res => store.dispatch({type: 'USER_BAN_SUCESSS', res}))
|
||||
.catch(error => store.dispatch({type: 'USER_BAN_FAILED', error}));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user