Merge branch 'reject-instream' of github.com:coralproject/talk into reject-instream

This commit is contained in:
Belen Curcio
2017-09-12 12:56:07 -03:00
15 changed files with 156 additions and 81 deletions
@@ -5,7 +5,7 @@ import {t, timeago} from 'plugin-api/beta/client/services';
import {Slot, CommentAuthorName} from 'plugin-api/beta/client/components';
import {Icon} from 'plugin-api/beta/client/components/ui';
import {pluginName} from '../../package.json';
import Button from './Button';
import FeaturedButton from '../containers/FeaturedButton';
class Comment extends React.Component {
@@ -50,7 +50,7 @@ class Comment extends React.Component {
inline
/>
<Button
<FeaturedButton
root={root}
data={data}
comment={comment}
@@ -1,12 +1,11 @@
import React from 'react';
import cn from 'classnames';
import styles from './Button.css';
import styles from './FeaturedButton.css';
import {pluginName} from '../../package.json';
import {can} from 'plugin-api/beta/client/services';
import {withTags} from 'plugin-api/beta/client/hocs';
import {Icon} from 'plugin-api/beta/client/components/ui';
const Button = (props) => {
const FeaturedButton = (props) => {
const {alreadyTagged, deleteTag, postTag, user} = props;
return can(user, 'MODERATE_COMMENTS') ? (
@@ -23,4 +22,4 @@ const Button = (props) => {
) : null ;
};
export default withTags('featured')(Button);
export default FeaturedButton;
@@ -3,10 +3,9 @@ import cn from 'classnames';
import styles from './ModActionButton.css';
import {pluginName} from '../../package.json';
import {t} from 'plugin-api/beta/client/services';
import {withTags} from 'plugin-api/beta/client/hocs';
import {Icon} from 'plugin-api/beta/client/components/ui';
export class Button extends React.Component {
export class ModActionButton extends React.Component {
constructor() {
super();
@@ -56,5 +55,5 @@ export class Button extends React.Component {
}
}
export default withTags('featured')(Button);
export default ModActionButton;
@@ -0,0 +1,4 @@
import FeaturedButton from '../components/FeaturedButton';
import {withTags} from 'plugin-api/beta/client/hocs';
export default withTags('featured')(FeaturedButton);
@@ -1,10 +1,9 @@
import {compose} from 'react-apollo';
import {excludeIf} from 'plugin-api/beta/client/hocs';
import {can} from 'plugin-api/beta/client/services';
import Button from '../components/Button';
import ModActionButton from '../components/ModActionButton';
import {withTags} from 'plugin-api/beta/client/hocs';
const enhance = compose(
excludeIf((props) => !can(props.user, 'MODERATE_COMMENTS')),
withTags('featured'),
);
export default enhance(Button);
export default enhance(ModActionButton);
@@ -1,12 +1,13 @@
import Tab from './containers/Tab';
import Tag from './containers/Tag';
import ModActionButton from './components/ModActionButton';
import TabPane from './containers/TabPane';
import translations from './translations.yml';
import update from 'immutability-helper';
import reducer from './reducer';
import ModTag from './containers/ModTag';
import ModActionButton from './containers/ModActionButton';
import ModSubscription from './containers/ModSubscription';
import {gql} from 'react-apollo';
import {findCommentInEmbedQuery} from 'coral-embed-stream/src/graphql/utils';
import {prependNewNodes} from 'plugin-api/beta/client/utils';
@@ -84,8 +85,28 @@ export default {
}
return updated;
},
}
}
},
update: (proxy) => {
if (name !== 'FEATURED') {
return;
}
const fragmentId = `Comment_${variables.id}`;
const fragment = gql`
fragment Talk_ModerationActions_addTag on Comment {
status
}
`;
const data = proxy.readFragment({fragment, id: fragmentId});
data.status = 'ACCEPTED';
proxy.writeFragment({fragment, id: fragmentId, data});
},
}),
RemoveTag: ({variables}) => ({
updateQueries: {
@@ -0,0 +1,10 @@
import {OPEN_TOOLTIP, CLOSE_TOOLTIP} from './constants';
export const openTooltip = (id) => ({
type: OPEN_TOOLTIP,
id,
});
export const closeTooltip = () => ({
type: CLOSE_TOOLTIP,
});
@@ -9,39 +9,19 @@ import ApproveCommentAction from '../containers/ApproveCommentAction';
import {Slot} from 'plugin-api/beta/client/components';
export default class ModerationActions extends React.Component {
constructor() {
super();
this.state = {
tooltip: false
};
}
toogleTooltip = () => {
const {tooltip} = this.state;
this.setState({
tooltip: !tooltip
});
}
hideTooltip = () => {
this.setState({
tooltip: false
});
}
render() {
const {tooltip} = this.state;
const {comment, asset, data} = this.props;
const {comment, asset, data, tooltipVisible, toogleTooltip, hideTooltip} = this.props;
return(
<ClickOutside onClickOutside={this.hideTooltip}>
<ClickOutside onClickOutside={hideTooltip}>
<div className={cn(styles.moderationActions, 'talk-plugin-moderation-actions')}>
<span onClick={this.toogleTooltip} className={cn(styles.arrow, 'talk-plugin-moderation-actions-arrow')}>
{tooltip ? <Icon name="keyboard_arrow_up" className={styles.icon} /> :
<span onClick={toogleTooltip} className={cn(styles.arrow, 'talk-plugin-moderation-actions-arrow')}>
{tooltipVisible ? <Icon name="keyboard_arrow_up" className={styles.icon} /> :
<Icon name="keyboard_arrow_down" className={styles.icon} />}
</span>
{tooltip && (
{tooltipVisible && (
<Tooltip>
<Slot
@@ -0,0 +1,4 @@
const prefix = 'TALK_MODERATION_ACTIONS';
export const OPEN_TOOLTIP = `${prefix}_OPEN_TOOLTIP`;
export const CLOSE_TOOLTIP = `${prefix}_CLOSE_TOOLTIP`;
@@ -1,28 +1,16 @@
import React from 'react';
import {getErrorMessages} from 'plugin-api/beta/client/utils';
import {withSetCommentStatus} from 'plugin-api/beta/client/hocs';
import {notify} from 'plugin-api/beta/client/actions/notification';
import ApproveCommentAction from '../components/ApproveCommentAction';
import isNil from 'lodash/isNil';
class ApproveCommentActionContainer extends React.Component {
approveComment = async () => {
approveComment = () => {
const {setCommentStatus, comment} = this.props;
try {
const result = await setCommentStatus({
commentId: comment.id,
status: 'ACCEPTED'
});
if (!isNil(result.data.setCommentStatus)) {
throw result.data.setCommentStatus.errors;
}
} catch (err) {
notify('error', getErrorMessages(err));
}
setCommentStatus({
commentId: comment.id,
status: 'ACCEPTED'
});
}
render() {
@@ -1,14 +1,72 @@
import React from 'react';
import {bindActionCreators} from 'redux';
import {gql, compose} from 'react-apollo';
import {openTooltip, closeTooltip} from '../actions';
import {can} from 'plugin-api/beta/client/services';
import {getShallowChanges} from 'plugin-api/beta/client/utils';
import ModerationActions from '../components/ModerationActions';
import {connect, excludeIf, withFragments} from 'plugin-api/beta/client/hocs';
const mapStateToProps = ({auth}) => ({
user: auth.user
class ModerationActionsContainer extends React.Component {
shouldComponentUpdate(nextProps) {
// Specifically handle `showTooltipForComment` if it is the only change.
const changes = getShallowChanges(this.props, nextProps);
if (changes.length === 1 && changes[0] === 'showTooltipForComment') {
const commentId = this.props.comment.id;
if (
commentId !== this.props.showTooltipForComment &&
commentId !== nextProps.showTooltipForComment
) {
return false;
}
}
// Prevent Slot from rerendering when no props has shallowly changed.
return changes.length !== 0;
}
toogleTooltip = () => {
if (this.props.showTooltipForComment === this.props.comment.id) {
this.props.closeTooltip();
} else {
this.props.openTooltip(this.props.comment.id);
}
}
hideTooltip = () => {
if (this.props.showTooltipForComment === this.props.comment.id) {
this.props.closeTooltip();
}
}
render() {
return <ModerationActions
data={this.props.data}
root={this.props.root}
asset={this.props.asset}
comment={this.props.comment}
tooltipVisible={this.props.showTooltipForComment === this.props.comment.id}
toogleTooltip={this.toogleTooltip}
hideTooltip={this.hideTooltip}
/>;
}
}
const mapStateToProps = ({auth, talkPluginModerationActions: state}) => ({
user: auth.user,
showTooltipForComment: state.showTooltipForComment,
});
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
openTooltip,
closeTooltip,
}, dispatch);
const enhance = compose(
connect(mapStateToProps),
connect(mapStateToProps, mapDispatchToProps),
withFragments({
asset: gql`
fragment TalkModerationActions_asset on Asset {
@@ -29,4 +87,4 @@ const enhance = compose(
excludeIf((props) => !can(props.user, 'MODERATE_COMMENTS')),
);
export default enhance(ModerationActions);
export default enhance(ModerationActionsContainer);
@@ -1,28 +1,16 @@
import React from 'react';
import {getErrorMessages} from 'plugin-api/beta/client/utils';
import {withSetCommentStatus} from 'plugin-api/beta/client/hocs';
import {notify} from 'plugin-api/beta/client/actions/notification';
import RejectCommentAction from '../components/RejectCommentAction';
import isNil from 'lodash/isNil';
class RejectCommentActionContainer extends React.Component {
rejectComment = async () => {
rejectComment = () => {
const {setCommentStatus, comment} = this.props;
try {
const result = await setCommentStatus({
commentId: comment.id,
status: 'REJECTED'
});
if (!isNil(result.data.setCommentStatus)) {
throw result.data.setCommentStatus.errors;
}
} catch (err) {
notify('error', getErrorMessages(err));
}
setCommentStatus({
commentId: comment.id,
status: 'REJECTED'
});
}
render() {
@@ -1,9 +1,11 @@
import ModerationActions from './containers/ModerationActions';
import translations from './translations.yml';
import reducer from './reducer';
export default {
slots: {
commentInfoBar: [ModerationActions],
},
reducer,
translations
};
@@ -0,0 +1,23 @@
import {OPEN_TOOLTIP, CLOSE_TOOLTIP} from './constants';
const initialState = {
showTooltipForComment: null,
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case OPEN_TOOLTIP:
return {
...state,
showTooltipForComment: action.id,
};
case CLOSE_TOOLTIP:
return {
...state,
showTooltipForComment: null,
contentSlot: null,
};
default :
return state;
}
}