mirror of
https://github.com/wassname/talk.git
synced 2026-07-01 18:40:35 +08:00
Merge branch 'master' into addINSTALL
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
|
||||
|
||||
import ModerationQueue from 'containers/ModerationQueue/ModerationQueue';
|
||||
import ModerationContainer from 'containers/ModerationQueue/ModerationContainer';
|
||||
import CommentStream from 'containers/CommentStream/CommentStream';
|
||||
import Configure from 'containers/Configure/Configure';
|
||||
import Streams from 'containers/Streams/Streams';
|
||||
@@ -10,7 +10,7 @@ import LayoutContainer from 'containers/LayoutContainer';
|
||||
|
||||
const routes = (
|
||||
<Route path='/admin' component={LayoutContainer}>
|
||||
<IndexRoute component={ModerationQueue} />
|
||||
<IndexRoute component={ModerationContainer} />
|
||||
<Route path='embed' component={CommentStream} />
|
||||
<Route path='community' component={CommunityContainer} />
|
||||
<Route path='configure' component={Configure} />
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import key from 'keymaster';
|
||||
|
||||
import {
|
||||
updateStatus,
|
||||
showBanUserDialog,
|
||||
hideBanUserDialog,
|
||||
fetchModerationQueueComments
|
||||
} from 'actions/comments';
|
||||
import {userStatusUpdate} from 'actions/users';
|
||||
|
||||
import ModerationQueue from './ModerationQueue';
|
||||
|
||||
class ModerationContainer extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
activeTab: 'pending',
|
||||
singleView: false,
|
||||
modalOpen: false
|
||||
};
|
||||
|
||||
this.onClose = this.onClose.bind(this);
|
||||
this.onTabClick = this.onTabClick.bind(this);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.props.fetchModerationQueueComments();
|
||||
key('s', () => this.setState({singleView: !this.state.singleView}));
|
||||
key('shift+/', () => this.setState({modalOpen: true}));
|
||||
key('esc', () => this.setState({modalOpen: false}));
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
key.unbind('s');
|
||||
key.unbind('shift+/');
|
||||
key.unbind('esc');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
// Hack for dynamic mdl tabs
|
||||
if (typeof componentHandler !== 'undefined') {
|
||||
|
||||
// FIXME: fix this hack
|
||||
componentHandler.upgradeAllRegistered(); // eslint-disable-line no-undef
|
||||
}
|
||||
}
|
||||
|
||||
onTabClick(activeTab) {
|
||||
this.setState({activeTab});
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.setState({modalOpen: false});
|
||||
}
|
||||
|
||||
render () {
|
||||
const {comments} = this.props;
|
||||
const premodIds = comments.ids.filter(id => comments.byId[id].status === 'premod');
|
||||
const rejectedIds = comments.ids.filter(id => comments.byId[id].status === 'rejected');
|
||||
const flaggedIds = comments.ids.filter(id => comments.byId[id].flagged === true);
|
||||
|
||||
return (
|
||||
<ModerationQueue
|
||||
onTabClick={this.onTabClick}
|
||||
onClose={this.onClose}
|
||||
premodIds={premodIds}
|
||||
rejectedIds={rejectedIds}
|
||||
flaggedIds={flaggedIds}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
comments: state.comments.toJS(),
|
||||
users: state.users.toJS()
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
fetchModerationQueueComments: () => dispatch(fetchModerationQueueComments()),
|
||||
showBanUserDialog: (userId, userName, commentId) => dispatch(showBanUserDialog(userId, userName, commentId)),
|
||||
hideBanUserDialog: () => dispatch(hideBanUserDialog(false)),
|
||||
banUser: (userId, commentId) => dispatch(userStatusUpdate('banned', userId, commentId)).then(() => {
|
||||
dispatch(fetchModerationQueueComments());
|
||||
}),
|
||||
updateStatus: (action, comment) => dispatch(updateStatus(action, comment))
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ModerationContainer);
|
||||
@@ -1,168 +1,68 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import key from 'keymaster';
|
||||
import styles from './ModerationQueue.css';
|
||||
|
||||
import ModerationKeysModal from 'components/ModerationKeysModal';
|
||||
import CommentList from 'components/CommentList';
|
||||
import BanUserDialog from 'components/BanUserDialog';
|
||||
|
||||
import {
|
||||
updateStatus,
|
||||
showBanUserDialog,
|
||||
hideBanUserDialog,
|
||||
fetchModerationQueueComments
|
||||
} from 'actions/comments';
|
||||
import {userStatusUpdate} from 'actions/users';
|
||||
import {fetchSettings} from 'actions/settings';
|
||||
import styles from './ModerationQueue.css';
|
||||
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../../translations.json';
|
||||
|
||||
/*
|
||||
* Renders the moderation queue as a tabbed layout with 3 moderation
|
||||
* queues :
|
||||
* * pending: filtered by status Untouched
|
||||
* * rejected: filtered by status Rejected
|
||||
* * flagged: with a flagged action on them
|
||||
*/
|
||||
|
||||
class ModerationQueue extends React.Component {
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
|
||||
this.state = {activeTab: 'pending', singleView: false, modalOpen: false};
|
||||
}
|
||||
|
||||
// Fetch comments and bind singleView key before render
|
||||
componentWillMount () {
|
||||
this.props.dispatch(fetchSettings());
|
||||
this.props.dispatch(fetchModerationQueueComments());
|
||||
key('s', () => this.setState({singleView: !this.state.singleView}));
|
||||
key('shift+/', () => this.setState({modalOpen: true}));
|
||||
key('esc', () => this.setState({modalOpen: false}));
|
||||
}
|
||||
|
||||
// Unbind singleView key before unmount
|
||||
componentWillUnmount () {
|
||||
key.unbind('s');
|
||||
key.unbind('shift+/');
|
||||
key.unbind('esc');
|
||||
}
|
||||
|
||||
// Hack for dynamic mdl tabs
|
||||
componentDidMount () {
|
||||
if (typeof componentHandler !== 'undefined') {
|
||||
|
||||
// FIXME: fix this hack
|
||||
componentHandler.upgradeAllRegistered(); // eslint-disable-line no-undef
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch the update status action
|
||||
onCommentAction (action, comment) {
|
||||
|
||||
// If not banning then change the status to approved or flagged as action = status
|
||||
this.props.dispatch(updateStatus(action, comment));
|
||||
}
|
||||
|
||||
showBanUserDialog (userId, userName, commentId) {
|
||||
this.props.dispatch(showBanUserDialog(userId, userName, commentId));
|
||||
}
|
||||
|
||||
hideBanUserDialog () {
|
||||
this.props.dispatch(hideBanUserDialog(false));
|
||||
}
|
||||
|
||||
banUser (userId, commentId) {
|
||||
this.props.dispatch(userStatusUpdate('banned', userId, commentId))
|
||||
.then(() => {
|
||||
this.props.dispatch(fetchModerationQueueComments());
|
||||
});
|
||||
}
|
||||
|
||||
onTabClick (activeTab) {
|
||||
this.setState({activeTab});
|
||||
}
|
||||
|
||||
// Render the tabbed lists moderation queues
|
||||
render () {
|
||||
const {comments, users, settings} = this.props;
|
||||
const {activeTab, singleView, modalOpen} = this.state;
|
||||
|
||||
const premodIds = comments.ids.filter(id => comments.byId[id].status === 'premod');
|
||||
const rejectedIds = comments.ids.filter(id => comments.byId[id].status === 'rejected');
|
||||
const flaggedIds = comments.ids.filter(id => comments.byId[id].flagged === true);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='mdl-tabs mdl-js-tabs mdl-js-ripple-effect'>
|
||||
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
|
||||
<a href='#pending' onClick={() => this.onTabClick('pending')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.pending')}</a>
|
||||
<a href='#rejected' onClick={() => this.onTabClick('rejected')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.rejected')}</a>
|
||||
<a href='#flagged' onClick={() => this.onTabClick('flagged')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.flagged')}</a>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel is-active ${styles.listContainer}`} id='pending'>
|
||||
<CommentList
|
||||
suspectWords={settings.settings.wordlist.suspect}
|
||||
isActive={activeTab === 'pending'}
|
||||
singleView={singleView}
|
||||
commentIds={premodIds}
|
||||
comments={comments.byId}
|
||||
users={users.byId}
|
||||
onClickAction={(action, comment) => this.onCommentAction(action, comment)}
|
||||
onClickShowBanDialog={(userId, userName, commentId) => this.showBanUserDialog(userId, userName, commentId)}
|
||||
modActions={['reject', 'approve', 'ban']}
|
||||
loading={comments.loading} />
|
||||
<BanUserDialog
|
||||
open={comments.showBanUserDialog}
|
||||
handleClose={() => this.hideBanUserDialog()}
|
||||
onClickBanUser={(userId, commentId) => this.banUser(userId, commentId)}
|
||||
user={comments.banUser}/>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='rejected'>
|
||||
<CommentList
|
||||
suspectWords={settings.settings.wordlist.suspect}
|
||||
isActive={activeTab === 'rejected'}
|
||||
singleView={singleView}
|
||||
commentIds={rejectedIds}
|
||||
comments={comments.byId}
|
||||
users={users.byId}
|
||||
onClickAction={(action, comment) => this.onCommentAction(action, comment)}
|
||||
modActions={['approve']}
|
||||
loading={comments.loading} />
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='flagged'>
|
||||
<CommentList
|
||||
isActive={activeTab === 'rejected'}
|
||||
suspectWords={settings.settings.wordlist.suspect}
|
||||
singleView={singleView}
|
||||
commentIds={flaggedIds}
|
||||
comments={comments.byId}
|
||||
users={users.byId}
|
||||
onClickAction={(action, comment) => this.onCommentAction(action, comment)}
|
||||
modActions={['reject', 'approve']}
|
||||
loading={comments.loading} />
|
||||
</div>
|
||||
<ModerationKeysModal open={modalOpen}
|
||||
onClose={() => this.setState({modalOpen: false})} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
actions: state.actions.toJS(),
|
||||
settings: state.settings.toJS(),
|
||||
comments: state.comments.toJS(),
|
||||
users: state.users.toJS()
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ModerationQueue);
|
||||
|
||||
const lang = new I18n(translations);
|
||||
|
||||
export default ({onTabClick, ...props}) => (
|
||||
<div>
|
||||
<div className='mdl-tabs mdl-js-tabs mdl-js-ripple-effect'>
|
||||
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
|
||||
<a href='#pending' onClick={() => onTabClick('pending')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.pending')}</a>
|
||||
<a href='#rejected' onClick={() => onTabClick('rejected')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.rejected')}</a>
|
||||
<a href='#flagged' onClick={() => onTabClick('flagged')}
|
||||
className={`mdl-tabs__tab ${styles.tab}`}>{lang.t('modqueue.flagged')}</a>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel is-active ${styles.listContainer}`} id='pending'>
|
||||
<CommentList
|
||||
isActive={props.activeTab === 'pending'}
|
||||
singleView={props.singleView}
|
||||
commentIds={props.premodIds}
|
||||
comments={props.comments.byId}
|
||||
users={props.users.byId}
|
||||
onClickAction={props.updateStatus}
|
||||
onClickShowBanDialog={props.showBanUserDialog}
|
||||
actions={['reject', 'approve', 'ban']}
|
||||
loading={props.comments.loading}/>
|
||||
<BanUserDialog
|
||||
open={props.comments.showBanUserDialog}
|
||||
handleClose={props.hideBanUserDialog}
|
||||
onClickBanUser={props.banUser}
|
||||
user={props.comments.banUser}
|
||||
/>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='rejected'>
|
||||
<CommentList
|
||||
isActive={props.activeTab === 'rejected'}
|
||||
singleView={props.singleView}
|
||||
commentIds={props.rejectedIds}
|
||||
comments={props.comments.byId}
|
||||
users={props.users.byId}
|
||||
onClickAction={props.updateStatus}
|
||||
actions={['approve']}
|
||||
loading={props.comments.loading}
|
||||
/>
|
||||
</div>
|
||||
<div className={`mdl-tabs__panel ${styles.listContainer}`} id='flagged'>
|
||||
<CommentList
|
||||
isActive={props.activeTab === 'rejected'}
|
||||
singleView={props.singleView}
|
||||
commentIds={props.flaggedIds}
|
||||
comments={props.comments.byId}
|
||||
users={props.users.byId}
|
||||
onClickAction={props.updateStatus}
|
||||
actions={['reject', 'approve']}
|
||||
loading={props.comments.loading}/>
|
||||
</div>
|
||||
<ModerationKeysModal open={props.modalOpen} onClose={props.closeModal} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user