import Telescope from 'meteor/nova:lib'; import React, { PropTypes, Component } from 'react'; import classNames from 'classnames'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { graphql } from 'react-apollo'; import gql from 'graphql-tag'; import Users from 'meteor/nova:users'; class Vote extends Component { constructor() { super(); this.upvote = this.upvote.bind(this); this.startLoading = this.startLoading.bind(this); this.stopLoading = this.stopLoading.bind(this); this.state = { loading: false } } startLoading() { this.setState({ loading: true }); } stopLoading() { this.setState({ loading: false }); } upvote(e) { e.preventDefault(); this.startLoading(); const post = this.props.post; const user = this.context.currentUser; if(!user){ this.props.flash("Please log in first"); } else { const voteType = Users.hasUpvoted(user, post) ? "cancelUpvote" : "upvote"; this.props.vote({post, voteType, currentUser: this.context.currentUser}).then(result => { this.stopLoading(); }); } } render() { const post = this.props.post; const user = this.context.currentUser; const hasUpvoted = Users.hasUpvoted(user, post); const hasDownvoted = Users.hasDownvoted(user, post); const actionsClass = classNames( "vote", {voted: hasUpvoted || hasDownvoted}, {upvoted: hasUpvoted}, {downvoted: hasDownvoted} ); return (
{this.state.loading ? : }
Upvote
{post.baseScore || 0}
) } } Vote.propTypes = { post: React.PropTypes.object.isRequired, // the current post vote: React.PropTypes.func, // mutate function with callback inside }; Vote.contextTypes = { currentUser: React.PropTypes.object, actions: React.PropTypes.object, events: React.PropTypes.object, }; // graphql const VoteWithMutation = graphql(gql` mutation postVote($postId: String, $voteType: String) { postVote(postId: $postId, voteType: $voteType) { _id baseScore } } `, { props: ({ownProps, mutate}) => ({ vote: ({post, voteType, currentUser}) => { const { baseScore, _id } = Telescope.operateOnItem(Posts, post, currentUser, voteType, true); // console.log("// votedItem") // console.log(votedItem) return mutate({ variables: {postId: post._id, voteType}, optimisticResponse: { __typename: 'Mutation', postVote: { __typename: 'Post', _id, baseScore, }, }, }) } }), })(Vote); // redux state + actions for messages const mapStateToProps = state => ({ messages: state.messages }); const mapDispatchToProps = dispatch => bindActionCreators(Telescope.actions.messages, dispatch); module.exports = connect(mapStateToProps, mapDispatchToProps)(VoteWithMutation); export default connect(mapStateToProps, mapDispatchToProps)(VoteWithMutation);