mirror of
https://github.com/wassname/talk.git
synced 2026-09-11 12:51:33 +08:00
Merge branch 'master' into user-pending
This commit is contained in:
@@ -6,10 +6,21 @@ import FlagLabel from 'coral-ui/components/FlagLabel';
|
|||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
import styles from './CommentLabels.css';
|
import styles from './CommentLabels.css';
|
||||||
|
|
||||||
|
const staffRoles = ['ADMIN', 'STAFF', 'MODERATOR'];
|
||||||
|
|
||||||
function isUserFlagged(actions) {
|
function isUserFlagged(actions) {
|
||||||
return actions.some((action) => action.__typename === 'FlagAction' && action.user);
|
return actions.some((action) => action.__typename === 'FlagAction' && action.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUserFlaggedType(actions) {
|
||||||
|
return actions
|
||||||
|
.some((action) =>
|
||||||
|
action.__typename === 'FlagAction' &&
|
||||||
|
action.user &&
|
||||||
|
action.user.roles.some((role) => staffRoles.includes(role))
|
||||||
|
) ? 'Staff' : 'User';
|
||||||
|
}
|
||||||
|
|
||||||
function hasSuspectedWords(actions) {
|
function hasSuspectedWords(actions) {
|
||||||
return actions.some((action) => action.__typename === 'FlagAction' && action.reason === 'Matched suspect word filter');
|
return actions.some((action) => action.__typename === 'FlagAction' && action.reason === 'Matched suspect word filter');
|
||||||
}
|
}
|
||||||
@@ -24,7 +35,7 @@ const CommentLabels = ({comment, comment: {className, status, actions, hasParent
|
|||||||
<div className={styles.coreLabels}>
|
<div className={styles.coreLabels}>
|
||||||
{hasParent && <Label iconName="reply" className={styles.replyLabel}>reply</Label>}
|
{hasParent && <Label iconName="reply" className={styles.replyLabel}>reply</Label>}
|
||||||
{status === 'PREMOD' && <Label iconName="query_builder" className={styles.premodLabel}>Pre-Mod</Label>}
|
{status === 'PREMOD' && <Label iconName="query_builder" className={styles.premodLabel}>Pre-Mod</Label>}
|
||||||
{isUserFlagged(actions) && <FlagLabel iconName="person">User</FlagLabel>}
|
{isUserFlagged(actions) && <FlagLabel iconName="person">{getUserFlaggedType(actions)}</FlagLabel>}
|
||||||
{hasSuspectedWords(actions) && <FlagLabel iconName="sms_failed">Suspect</FlagLabel>}
|
{hasSuspectedWords(actions) && <FlagLabel iconName="sms_failed">Suspect</FlagLabel>}
|
||||||
{hasHistoryFlag(actions) && <FlagLabel iconName="sentiment_very_dissatisfied">History</FlagLabel>}
|
{hasHistoryFlag(actions) && <FlagLabel iconName="sentiment_very_dissatisfied">History</FlagLabel>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,34 +4,38 @@ import Modal from 'components/Modal';
|
|||||||
import styles from './ModerationKeysModal.css';
|
import styles from './ModerationKeysModal.css';
|
||||||
import t from 'coral-framework/services/i18n';
|
import t from 'coral-framework/services/i18n';
|
||||||
|
|
||||||
const shortcuts = [
|
|
||||||
{
|
|
||||||
title: 'modqueue.navigation',
|
|
||||||
shortcuts: {
|
|
||||||
'j': 'modqueue.next_comment',
|
|
||||||
'k': 'modqueue.prev_comment',
|
|
||||||
'ctrl+f': 'modqueue.toggle_search',
|
|
||||||
't': 'modqueue.next_queue',
|
|
||||||
's': 'modqueue.singleview',
|
|
||||||
'?': 'modqueue.thismenu'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'modqueue.actions',
|
|
||||||
shortcuts: {
|
|
||||||
'd': 'modqueue.approve',
|
|
||||||
'f': 'modqueue.reject'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export default class ModerationKeysModal extends React.Component {
|
export default class ModerationKeysModal extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
open: PropTypes.bool.isRequired,
|
open: PropTypes.bool.isRequired,
|
||||||
onClose: PropTypes.func.isRequired,
|
onClose: PropTypes.func.isRequired,
|
||||||
hideShortcutsNote: PropTypes.func.isRequired,
|
hideShortcutsNote: PropTypes.func.isRequired,
|
||||||
shortcutsNoteVisible: PropTypes.string.isRequired
|
shortcutsNoteVisible: PropTypes.string.isRequired,
|
||||||
|
queueCount: PropTypes.number.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
buildShortcuts = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
title: 'modqueue.navigation',
|
||||||
|
shortcuts: {
|
||||||
|
'j': 'modqueue.next_comment',
|
||||||
|
'k': 'modqueue.prev_comment',
|
||||||
|
'ctrl+f': 'modqueue.toggle_search',
|
||||||
|
't': 'modqueue.next_queue',
|
||||||
|
[`1...${this.props.queueCount}`]: 'modqueue.jump_to_queue',
|
||||||
|
's': 'modqueue.singleview',
|
||||||
|
'?': 'modqueue.thismenu'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'modqueue.actions',
|
||||||
|
shortcuts: {
|
||||||
|
'd': 'modqueue.approve',
|
||||||
|
'f': 'modqueue.reject'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@@ -51,7 +55,7 @@ export default class ModerationKeysModal extends React.Component {
|
|||||||
<Modal open={open} onClose={onClose}>
|
<Modal open={open} onClose={onClose}>
|
||||||
<h3>{t('modqueue.shortcuts')}</h3>
|
<h3>{t('modqueue.shortcuts')}</h3>
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
{shortcuts.map((shortcut, i) => (
|
{this.buildShortcuts().map((shortcut, i) => (
|
||||||
<table className={styles.table} key={i}>
|
<table className={styles.table} key={i}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export default withFragments({
|
|||||||
}
|
}
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
|
roles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
${getSlotFragmentSpreads(slots, 'comment')}
|
${getSlotFragmentSpreads(slots, 'comment')}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ class Moderation extends Component {
|
|||||||
key('k', () => this.select(false));
|
key('k', () => this.select(false));
|
||||||
key('f', () => this.moderate(false));
|
key('f', () => this.moderate(false));
|
||||||
key('d', () => this.moderate(true));
|
key('d', () => this.moderate(true));
|
||||||
|
this.getMenuItems()
|
||||||
|
.forEach((menuItem, idx) => key(`${idx + 1}`, () => this.selectQueue(menuItem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose = () => {
|
onClose = () => {
|
||||||
@@ -41,20 +43,23 @@ class Moderation extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nextQueue = () => {
|
nextQueue = () => {
|
||||||
const queueConfig = this.props.queueConfig;
|
|
||||||
const activeTab = this.props.activeTab;
|
const activeTab = this.props.activeTab;
|
||||||
const assetId = this.props.data.variables.asset_id;
|
|
||||||
|
|
||||||
const menuItems = Object.keys(queueConfig).map((queue) => ({
|
const menuItems = this.getMenuItems();
|
||||||
key: queue
|
|
||||||
}));
|
|
||||||
|
|
||||||
const activeTabIndex = menuItems.findIndex((item) => item.key === activeTab);
|
const activeTabIndex = menuItems.findIndex((item) => item === activeTab);
|
||||||
const nextQueueIndex = (activeTabIndex === menuItems.length - 1) ? 0 : activeTabIndex + 1;
|
const nextQueueIndex = (activeTabIndex === menuItems.length - 1) ? 0 : activeTabIndex + 1;
|
||||||
|
|
||||||
this.props.router.push(this.props.getModPath(menuItems[nextQueueIndex].key, assetId));
|
this.selectQueue(menuItems[nextQueueIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectQueue = (key) => {
|
||||||
|
const assetId = this.props.data.variables.asset_id;
|
||||||
|
this.props.router.push(this.props.getModPath(key, assetId));
|
||||||
|
}
|
||||||
|
|
||||||
|
getMenuItems = () => Object.keys(this.props.queueConfig);
|
||||||
|
|
||||||
closeSearch = () => {
|
closeSearch = () => {
|
||||||
const {toggleStorySearch} = this.props;
|
const {toggleStorySearch} = this.props;
|
||||||
toggleStorySearch(false);
|
toggleStorySearch(false);
|
||||||
@@ -175,6 +180,8 @@ class Moderation extends Component {
|
|||||||
key.unbind('k');
|
key.unbind('k');
|
||||||
key.unbind('f');
|
key.unbind('f');
|
||||||
key.unbind('d');
|
key.unbind('d');
|
||||||
|
this.getMenuItems()
|
||||||
|
.forEach((menuItem, idx) => key.unbind(`${idx + 1}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
@@ -276,6 +283,7 @@ class Moderation extends Component {
|
|||||||
shortcutsNoteVisible={moderation.shortcutsNoteVisible}
|
shortcutsNoteVisible={moderation.shortcutsNoteVisible}
|
||||||
open={moderation.modalOpen}
|
open={moderation.modalOpen}
|
||||||
onClose={this.onClose}
|
onClose={this.onClose}
|
||||||
|
queueCount={this.getMenuItems().length}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<StorySearch
|
<StorySearch
|
||||||
|
|||||||
@@ -33,8 +33,11 @@ const createAction = async ({user = {}, pubsub, loaders: {Comments}}, {item_id,
|
|||||||
|
|
||||||
if (item_type === 'USERS' && action_type === 'FLAG') {
|
if (item_type === 'USERS' && action_type === 'FLAG') {
|
||||||
|
|
||||||
// Set the user as pending if it was a user flag.
|
// Set the user as pending if it was a user flag and user has no Admin, Staff or Moderation roles
|
||||||
await UsersService.setStatus(item_id, 'PENDING');
|
let user = await UsersService.findById(item_id);
|
||||||
|
if(!user.roles){
|
||||||
|
await UsersService.setStatus(item_id, 'PENDING');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment) {
|
if (comment) {
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ en:
|
|||||||
show_shortcuts: "Show Shortcuts"
|
show_shortcuts: "Show Shortcuts"
|
||||||
singleview: "Toggle single comment edit view"
|
singleview: "Toggle single comment edit view"
|
||||||
thismenu: "Open this menu"
|
thismenu: "Open this menu"
|
||||||
|
jump_to_queue: "Jump to specific queue"
|
||||||
thousand: k
|
thousand: k
|
||||||
try_these: "Try these"
|
try_these: "Try these"
|
||||||
view_more_shortcuts: "View more shortcuts"
|
view_more_shortcuts: "View more shortcuts"
|
||||||
|
|||||||
Reference in New Issue
Block a user