mirror of
https://github.com/wassname/talk.git
synced 2026-07-06 05:17:19 +08:00
BestButton sends mutations to backend, but they aren't implemented yet
This commit is contained in:
@@ -17,7 +17,7 @@ import PubDate from 'coral-plugin-pubdate/PubDate';
|
||||
import {ReplyBox, ReplyButton} from 'coral-plugin-replies';
|
||||
import FlagComment from 'coral-plugin-flags/FlagComment';
|
||||
import LikeButton from 'coral-plugin-likes/LikeButton';
|
||||
import BestButton, {IfUserCanModifyBest} from 'coral-plugin-best/BestButton';
|
||||
import {BestButton, IfUserCanModifyBest, BEST_TAG, commentIsBest} from 'coral-plugin-best/BestButton';
|
||||
import LoadMore from 'coral-embed-stream/src/LoadMore';
|
||||
|
||||
import styles from './Comment.css';
|
||||
@@ -74,7 +74,13 @@ class Comment extends React.Component {
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
|
||||
// dispatch action to add a tag to a comment
|
||||
addCommentTag: React.PropTypes.func,
|
||||
|
||||
// dispatch action to remove a tag from a comment
|
||||
removeCommentTag: React.PropTypes.func,
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -93,13 +99,27 @@ class Comment extends React.Component {
|
||||
loadMore,
|
||||
setActiveReplyBox,
|
||||
activeReplyBox,
|
||||
deleteAction
|
||||
deleteAction,
|
||||
addCommentTag,
|
||||
removeCommentTag,
|
||||
} = this.props;
|
||||
|
||||
const like = getActionSummary('LikeActionSummary', comment);
|
||||
const flag = getActionSummary('FlagActionSummary', comment);
|
||||
const dontagree = getActionSummary('DontAgreeActionSummary', comment);
|
||||
|
||||
// @TODO(bengo) Should I do this for addCommentTag and/or best button
|
||||
|
||||
// @TODO(bengo) Would be best to only create these funcs on prop change
|
||||
const addBestTag = () => addCommentTag({
|
||||
comment_id: comment.id,
|
||||
tag: BEST_TAG,
|
||||
});
|
||||
const removeBestTag = () => removeCommentTag({
|
||||
comment_id: comment.id,
|
||||
tag: BEST_TAG,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className={parentId ? `reply ${styles.Reply}` : `comment ${styles.Comment}`}
|
||||
@@ -128,9 +148,9 @@ class Comment extends React.Component {
|
||||
banned={false} />
|
||||
<IfUserCanModifyBest user={currentUser}>
|
||||
<BestButton
|
||||
isBest={false}
|
||||
setBestTag={() => {}}
|
||||
removeBestTag={() => {}} />
|
||||
isBest={commentIsBest(comment)}
|
||||
addBest={addBestTag}
|
||||
removeBest={removeBestTag} />
|
||||
</IfUserCanModifyBest>
|
||||
</div>
|
||||
<div className="commentActionsRight">
|
||||
|
||||
@@ -13,7 +13,7 @@ const {addNotification, clearNotification} = notificationActions;
|
||||
const {fetchAssetSuccess} = assetActions;
|
||||
|
||||
import {queryStream} from 'coral-framework/graphql/queries';
|
||||
import {postComment, postFlag, postLike, postDontAgree, deleteAction} from 'coral-framework/graphql/mutations';
|
||||
import {postComment, postFlag, postLike, postDontAgree, deleteAction, addCommentTag, removeCommentTag} from 'coral-framework/graphql/mutations';
|
||||
import {editName} from 'coral-framework/actions/user';
|
||||
import {updateCountCache} from 'coral-framework/actions/asset';
|
||||
import {Notification, notificationActions, authActions, assetActions, pym} from 'coral-framework';
|
||||
@@ -54,7 +54,13 @@ class Embed extends Component {
|
||||
data: React.PropTypes.shape({
|
||||
loading: React.PropTypes.bool,
|
||||
error: React.PropTypes.object
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
|
||||
// dispatch action to add a tag to a comment
|
||||
addCommentTag: React.PropTypes.func,
|
||||
|
||||
// dispatch action to remove a tag from a comment
|
||||
removeCommentTag: React.PropTypes.func,
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
@@ -176,6 +182,8 @@ class Embed extends Component {
|
||||
postLike={this.props.postLike}
|
||||
postFlag={this.props.postFlag}
|
||||
postDontAgree={this.props.postDontAgree}
|
||||
addCommentTag={this.props.addCommentTag}
|
||||
removeCommentTag={this.props.removeCommentTag}
|
||||
getCounts={this.props.getCounts}
|
||||
updateCountCache={this.props.updateCountCache}
|
||||
loadMore={this.props.loadMore}
|
||||
@@ -250,6 +258,8 @@ export default compose(
|
||||
postFlag,
|
||||
postLike,
|
||||
postDontAgree,
|
||||
addCommentTag,
|
||||
removeCommentTag,
|
||||
deleteAction,
|
||||
queryStream
|
||||
)(Embed);
|
||||
|
||||
@@ -13,7 +13,13 @@ class Stream extends React.Component {
|
||||
currentUser: PropTypes.shape({
|
||||
username: PropTypes.string,
|
||||
id: PropTypes.string
|
||||
})
|
||||
}),
|
||||
|
||||
// dispatch action to add a tag to a comment
|
||||
addCommentTag: React.PropTypes.func,
|
||||
|
||||
// dispatch action to remove a tag from a comment
|
||||
removeCommentTag: React.PropTypes.func,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@@ -64,7 +70,9 @@ class Stream extends React.Component {
|
||||
loadMore,
|
||||
deleteAction,
|
||||
showSignInDialog,
|
||||
refetch
|
||||
refetch,
|
||||
addCommentTag,
|
||||
removeCommentTag,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@@ -83,6 +91,8 @@ class Stream extends React.Component {
|
||||
postLike={postLike}
|
||||
postFlag={postFlag}
|
||||
postDontAgree={postDontAgree}
|
||||
addCommentTag={addCommentTag}
|
||||
removeCommentTag={removeCommentTag}
|
||||
loadMore={loadMore}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
|
||||
@@ -217,6 +217,10 @@ hr {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.comment__action-button[disabled] {
|
||||
cursor: inherit;
|
||||
}
|
||||
|
||||
.comment__action-button--nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
mutation AddCommentTag ($comment_id: ID!, $tag: String!) {
|
||||
addCommentTag(comment_id:$comment_id, tag:$tag) {
|
||||
comment {
|
||||
tags {
|
||||
name
|
||||
}
|
||||
}
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import POST_FLAG from './postFlag.graphql';
|
||||
import POST_LIKE from './postLike.graphql';
|
||||
import POST_DONT_AGREE from './postDontAgree.graphql';
|
||||
import DELETE_ACTION from './deleteAction.graphql';
|
||||
import ADD_COMMENT_TAG from './addCommentTag.graphql';
|
||||
import REMOVE_COMMENT_TAG from './removeCommentTag.graphql';
|
||||
|
||||
import commentView from '../fragments/commentView.graphql';
|
||||
|
||||
@@ -122,3 +124,25 @@ export const deleteAction = graphql(DELETE_ACTION, {
|
||||
});
|
||||
}}),
|
||||
});
|
||||
|
||||
export const addCommentTag = graphql(ADD_COMMENT_TAG, {
|
||||
props: ({mutate}) => ({
|
||||
addCommentTag: (tag) => {
|
||||
return mutate({
|
||||
variables: {
|
||||
tag
|
||||
}
|
||||
});
|
||||
}}),
|
||||
});
|
||||
|
||||
export const removeCommentTag = graphql(REMOVE_COMMENT_TAG, {
|
||||
props: ({mutate}) => ({
|
||||
removeCommentTag: (tag) => {
|
||||
return mutate({
|
||||
variables: {
|
||||
tag
|
||||
}
|
||||
});
|
||||
}}),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
mutation RemoveCommentTag ($comment_id: ID!, $tag: String!) {
|
||||
removeCommentTag(comment_id:$comment_id, tag:$tag) {
|
||||
comment {
|
||||
tags {
|
||||
name
|
||||
}
|
||||
}
|
||||
errors {
|
||||
translation_key
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,10 @@ import {I18n} from '../coral-framework';
|
||||
import translations from './translations.json';
|
||||
import classnames from 'classnames';
|
||||
|
||||
// tag string for best comments
|
||||
export const BEST_TAG = 'BEST';
|
||||
export const commentIsBest = ({tags} = {}) => Array.isArray(tags) && tags.some(t => t === BEST_TAG);
|
||||
|
||||
const name = 'coral-plugin-best';
|
||||
const lang = new I18n(translations);
|
||||
|
||||
@@ -21,17 +25,17 @@ export const IfUserCanModifyBest = ({user, children}) => {
|
||||
* Button that lets a moderator tag a comment as "Best".
|
||||
* Used to recognize really good comments.
|
||||
*/
|
||||
class BestButton extends Component {
|
||||
export class BestButton extends Component {
|
||||
static propTypes = {
|
||||
|
||||
// whether the comment is already tagged as best
|
||||
isBest: PropTypes.bool.isRequired,
|
||||
|
||||
// set that this comment is best
|
||||
setBestTag: PropTypes.func.isRequired,
|
||||
addBest: PropTypes.func.isRequired,
|
||||
|
||||
// remove the best status
|
||||
removeBestTag: PropTypes.func.isRequired,
|
||||
removeBest: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
state = {
|
||||
@@ -40,18 +44,30 @@ class BestButton extends Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onClickSetBest = this.onClickSetBest.bind(this);
|
||||
this.onClickUnsetBest = this.onClickUnsetBest.bind(this);
|
||||
this.onClickAddBest = this.onClickAddBest.bind(this);
|
||||
this.onClickRemoveBest = this.onClickRemoveBest.bind(this);
|
||||
}
|
||||
|
||||
onClickSetBest(e) {
|
||||
async onClickAddBest(e) {
|
||||
e.preventDefault();
|
||||
this.setState({isBest: true});
|
||||
const {addBest} = this.props;
|
||||
if ( ! addBest) {
|
||||
console.warn('BestButton#onClickAddBest called even though there is no addBest prop. doing nothing');
|
||||
return;
|
||||
}
|
||||
const addBestRet = await addBest();
|
||||
console.log('addBestRet', addBestRet);
|
||||
}
|
||||
|
||||
onClickUnsetBest(e) {
|
||||
async onClickRemoveBest(e) {
|
||||
e.preventDefault();
|
||||
this.setState({isBest: false});
|
||||
const {removeBest} = this.props;
|
||||
if ( ! removeBest) {
|
||||
console.warn('BestButton#onClickAddBest called even though there is no removeBest prop. doing nothing');
|
||||
return;
|
||||
}
|
||||
const removeBestRet = await removeBest();
|
||||
console.log('removeBestRet', removeBestRet);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -59,10 +75,12 @@ class BestButton extends Component {
|
||||
// @TODO(bengo) Consider adding the comment__action classes to other buttons to add cursor:pointer and never wrap the icons
|
||||
// @TODO(bengo) Should I reuse another element like coral-ui button? Just doing what LikeButton does for now
|
||||
// Oh. I think that's styled for the admin. Don't use coral-ui button until the whole comment bottom bar does.
|
||||
const {isBest} = this.state;
|
||||
let {isBest} = this.state;
|
||||
const {addBest, removeBest} = this.props;
|
||||
return <div className={classnames(`${name}-container`, `${name}-button`, 'comment__action-button--nowrap',
|
||||
`e2e__${isBest ? 'unset' : 'set'}-best-comment`)}>
|
||||
<button onClick={isBest ? this.onClickUnsetBest : this.onClickSetBest}
|
||||
<button onClick={isBest ? this.onClickRemoveBest : this.onClickAddBest}
|
||||
disabled={ ! (isBest ? removeBest : addBest)}
|
||||
className='comment__action-button'>
|
||||
<span className={`${name}-button-text`}>{lang.t(isBest ? 'unsetBest' : 'setBest')}</span>
|
||||
<i className={`${name}-icon material-icons`} aria-hidden={true}>
|
||||
@@ -72,5 +90,3 @@ class BestButton extends Component {
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export default BestButton;
|
||||
|
||||
Reference in New Issue
Block a user