mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
Add comment voting using graphql union type
This commit is contained in:
parent
ae92ac3d45
commit
38de180530
8 changed files with 73 additions and 34 deletions
|
@ -100,6 +100,9 @@ class CommentsItem extends Component{
|
|||
<div className="comments-item" id={comment._id}>
|
||||
<div className="comments-item-body">
|
||||
<div className="comments-item-meta">
|
||||
<div className="comments-item-vote">
|
||||
<Components.Vote collection={Comments} document={this.props.comment} currentUser={this.props.currentUser}/>
|
||||
</div>
|
||||
<Components.UsersAvatar size="small" user={comment.user}/>
|
||||
<Components.UsersName user={comment.user}/>
|
||||
<div className="comments-item-date"><FormattedRelative value={comment.postedAt}/></div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Components, registerComponent } from 'meteor/nova:lib';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { withCurrentUser, withMessages } from 'meteor/nova:core';
|
||||
import { withMessages } from 'meteor/nova:core';
|
||||
import { withVote, hasUpvoted, hasDownvoted } from 'meteor/nova:voting';
|
||||
|
||||
class Vote extends Component {
|
||||
|
|
|
@ -72,6 +72,16 @@ PostsCommentsThread.fragment = gql`
|
|||
}
|
||||
}
|
||||
userId
|
||||
upvoters {
|
||||
_id
|
||||
}
|
||||
downvoters {
|
||||
_id
|
||||
}
|
||||
upvotes # should be asked only for admins?
|
||||
downvotes # should be asked only for admins?
|
||||
baseScore # should be asked only for admins?
|
||||
score # should be asked only for admins?
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -67,7 +67,6 @@ PostsList.fragment = gql`
|
|||
url
|
||||
slug
|
||||
thumbnailUrl
|
||||
baseScore
|
||||
postedAt
|
||||
sticky
|
||||
status
|
||||
|
@ -92,6 +91,8 @@ PostsList.fragment = gql`
|
|||
_id
|
||||
}
|
||||
upvotes # should be asked only for admins?
|
||||
downvotes # should be asked only for admins?
|
||||
baseScore # should be asked only for admins?
|
||||
score # should be asked only for admins?
|
||||
viewCount # should be asked only for admins?
|
||||
clickCount # should be asked only for admins?
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
.comments-item-meta{
|
||||
@include flex-center;
|
||||
margin-bottom: $vmargin;
|
||||
|
||||
.comments-item-vote{
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.users-avatar{
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
|
|
@ -8,16 +8,30 @@ const withVote = component => {
|
|||
return graphql(gql`
|
||||
mutation vote($documentId: String, $voteType: String, $collectionName: String) {
|
||||
vote(documentId: $documentId, voteType: $voteType, collectionName: $collectionName) {
|
||||
_id
|
||||
upvotes
|
||||
upvoters {
|
||||
... on Post {
|
||||
_id
|
||||
upvotes
|
||||
upvoters {
|
||||
_id
|
||||
}
|
||||
downvotes
|
||||
downvoters {
|
||||
_id
|
||||
}
|
||||
baseScore
|
||||
}
|
||||
downvotes
|
||||
downvoters {
|
||||
... on Comment {
|
||||
_id
|
||||
upvotes
|
||||
upvoters {
|
||||
_id
|
||||
}
|
||||
downvotes
|
||||
downvoters {
|
||||
_id
|
||||
}
|
||||
baseScore
|
||||
}
|
||||
baseScore
|
||||
}
|
||||
}
|
||||
`, {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { GraphQLSchema, Utils } from 'meteor/nova:core';
|
||||
import { mutateItem, operateOnItem } from './vote.js';
|
||||
import { mutateItem } from './vote.js';
|
||||
|
||||
const voteSchema = `
|
||||
type Vote {
|
||||
|
@ -7,28 +7,31 @@ const voteSchema = `
|
|||
power: Float
|
||||
votedAt: String
|
||||
}
|
||||
type VoteResult {
|
||||
_id: String
|
||||
upvoters: [User]
|
||||
upvotes: Float
|
||||
downvoters: [User]
|
||||
downvotes: Float
|
||||
baseScore: Float
|
||||
}
|
||||
|
||||
union Votable = Post | Comment
|
||||
`;
|
||||
|
||||
GraphQLSchema.addSchema(voteSchema);
|
||||
|
||||
/*
|
||||
const resolverMap = {
|
||||
Votable: {
|
||||
__resolveType(obj, context, info){
|
||||
if(obj.title){
|
||||
return 'Post';
|
||||
}
|
||||
|
||||
Note: although returning a VoteResult object should in theory work,
|
||||
this currently messes the automatic store update on the client.
|
||||
So return a Post for now.
|
||||
if(obj.postId){
|
||||
return 'Comment';
|
||||
}
|
||||
|
||||
*/
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// GraphQLSchema.addMutation('vote(documentId: String, voteType: String, collectionName: String) : VoteResult');
|
||||
GraphQLSchema.addMutation('vote(documentId: String, voteType: String, collectionName: String) : Post');
|
||||
GraphQLSchema.addResolvers(resolverMap);
|
||||
|
||||
GraphQLSchema.addMutation('vote(documentId: String, voteType: String, collectionName: String) : Votable');
|
||||
|
||||
const voteResolver = {
|
||||
Mutation: {
|
||||
|
|
|
@ -31,28 +31,30 @@ export const operateOnItem = function (collection, originalItem, user, operation
|
|||
const votePower = getVotePower(user);
|
||||
const hasUpvotedItem = hasUpvoted(user, item);
|
||||
const hasDownvotedItem = hasDownvoted(user, item);
|
||||
const modifier = {};
|
||||
const collectionName = collection._name;
|
||||
const canDo = Users.canDo(user, `${collectionName}.${operation}`);
|
||||
|
||||
// console.log('// operateOnItem')
|
||||
// console.log('isClient: ',isClient)
|
||||
// console.log('collection: ',collection._name)
|
||||
// console.log('operation: ',operation)
|
||||
// console.log('item: ',item)
|
||||
// console.log('user: ',user)
|
||||
|
||||
const collectionName = collection._name;
|
||||
// console.log('isClient: ', isClient)
|
||||
// console.log('collection: ', collectionName)
|
||||
// console.log('operation: ', operation)
|
||||
// console.log('item: ', item)
|
||||
// console.log('user: ', user)
|
||||
// console.log('hasUpvotedItem: ', hasUpvotedItem)
|
||||
// console.log('hasDownvotedItem: ', hasDownvotedItem)
|
||||
// console.log('canDo: ', canDo)
|
||||
|
||||
// make sure item and user are defined, and user can perform the operation
|
||||
if (
|
||||
!item ||
|
||||
!user ||
|
||||
!Users.canDo(user, `${collectionName}.${operation}`) ||
|
||||
!canDo ||
|
||||
operation === "upvote" && hasUpvotedItem ||
|
||||
operation === "downvote" && hasDownvotedItem ||
|
||||
operation === "cancelUpvote" && !hasUpvotedItem ||
|
||||
operation === "cancelDownvote" && !hasDownvotedItem
|
||||
) {
|
||||
return false;
|
||||
throw new Meteor.Error(`Cannot perform operation "${collectionName}.${operation}"`);
|
||||
}
|
||||
|
||||
// ------------------------------ Sync Callbacks ------------------------------ //
|
||||
|
@ -131,6 +133,7 @@ Call operateOnItem, update the db with the result, run callbacks.
|
|||
export const mutateItem = function (collection, originalItem, user, operation) {
|
||||
const newItem = operateOnItem(collection, originalItem, user, operation, false);
|
||||
newItem.inactive = false;
|
||||
|
||||
collection.update({_id: newItem._id}, newItem, {bypassCollection2:true});
|
||||
|
||||
// --------------------- Server-Side Async Callbacks --------------------- //
|
||||
|
|
Loading…
Add table
Reference in a new issue