- follow PR review by @roschaefer
This commit is contained in:
Matt Rider 2019-08-07 14:55:32 +02:00
parent fa033e69bd
commit 39a94a8aac
13 changed files with 230 additions and 181 deletions

View File

@ -27,12 +27,6 @@ const onlyYourself = rule({
return context.user.id === args.id return context.user.id === args.id
}) })
const isMyEmotion = rule({
cache: 'no_cache',
})(async (parent, args, context, info) => {
return context.user.id === args.from.id
})
const isMyOwn = rule({ const isMyOwn = rule({
cache: 'no_cache', cache: 'no_cache',
})(async (parent, args, context, info) => { })(async (parent, args, context, info) => {
@ -163,8 +157,8 @@ const permissions = shield(
User: or(noEmailFilter, isAdmin), User: or(noEmailFilter, isAdmin),
isLoggedIn: allow, isLoggedIn: allow,
Badge: allow, Badge: allow,
postsEmotionsCountByEmotion: allow, PostsEmotionsCountByEmotion: allow,
postsEmotionsCountByCurrentUser: allow, PostsEmotionsByCurrentUser: allow,
}, },
Mutation: { Mutation: {
'*': deny, '*': deny,
@ -200,7 +194,7 @@ const permissions = shield(
requestPasswordReset: allow, requestPasswordReset: allow,
resetPassword: allow, resetPassword: allow,
AddPostEmotions: isAuthenticated, AddPostEmotions: isAuthenticated,
RemovePostEmotions: isMyEmotion, RemovePostEmotions: isAuthenticated,
}, },
User: { User: {
email: isMyOwn, email: isMyOwn,

View File

@ -0,0 +1,34 @@
import uuid from 'uuid/v4'
module.exports = {
id: { type: 'string', primary: true, default: uuid },
activityId: { type: 'string', allow: [null] },
objectId: { type: 'string', allow: [null] },
author: {
type: 'relationship',
relationship: 'WROTE',
target: 'User',
direction: 'in',
},
title: { type: 'string', disallow: [null], min: 3 },
slug: { type: 'string', allow: [null] },
content: { type: 'string', disallow: [null], min: 3 },
contentExcerpt: { type: 'string', allow: [null] },
image: { type: 'string', allow: [null] },
deleted: { type: 'boolean', default: false },
disabled: { type: 'boolean', default: false },
disabledBy: {
type: 'relationship',
relationship: 'DISABLED',
target: 'User',
direction: 'in',
},
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
updatedAt: {
type: 'string',
isoDate: true,
required: true,
default: () => new Date().toISOString(),
},
language: { type: 'string', allow: [null] },
}

View File

@ -56,4 +56,19 @@ module.exports = {
required: true, required: true,
default: () => new Date().toISOString(), default: () => new Date().toISOString(),
}, },
emoted: {
type: 'relationships',
relationship: 'EMOTED',
target: 'Post',
direction: 'out',
properties: {
emotion: {
type: 'string',
valid: ['happy', 'cry', 'surprised', 'angry', 'funny'],
invalid: [null],
},
},
eager: true,
cascade: true,
},
} }

View File

@ -6,4 +6,5 @@ export default {
InvitationCode: require('./InvitationCode.js'), InvitationCode: require('./InvitationCode.js'),
EmailAddress: require('./EmailAddress.js'), EmailAddress: require('./EmailAddress.js'),
SocialMedia: require('./SocialMedia.js'), SocialMedia: require('./SocialMedia.js'),
Post: require('./Post.js'),
} }

View File

@ -92,23 +92,25 @@ export default {
}, },
RemovePostEmotions: async (object, params, context, resolveInfo) => { RemovePostEmotions: async (object, params, context, resolveInfo) => {
const session = context.driver.session() const session = context.driver.session()
const { from, to, data } = params const { to, data } = params
const { id: from } = context.user
const transactionRes = await session.run( const transactionRes = await session.run(
`MATCH (userFrom:User {id: $from.id})-[emotedRelation:EMOTED {emotion: $data.emotion}]->(postTo:Post {id: $to.id}) `MATCH (userFrom:User {id: $from})-[emotedRelation:EMOTED {emotion: $data.emotion}]->(postTo:Post {id: $to.id})
DELETE emotedRelation DELETE emotedRelation
RETURN userFrom
`, `,
{ from, to, data }, { from, to, data },
) )
session.close() session.close()
const [emoted] = transactionRes.records.map(record => { const [userFrom] = transactionRes.records.map(record => {
return record.get('emotedRelation').properties.emotion return record.get('userFrom')
}) })
if (!userFrom) throw new Error('Not Authorised!')
return !emoted return Boolean(userFrom)
}, },
}, },
Query: { Query: {
postsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => { PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => {
const session = context.driver.session() const session = context.driver.session()
const { postId, data } = params const { postId, data } = params
const transactionRes = await session.run( const transactionRes = await session.run(
@ -125,22 +127,21 @@ export default {
return emotionsCount return emotionsCount
}, },
postsEmotionsCountByCurrentUser: async (object, params, context, resolveInfo) => { PostsEmotionsByCurrentUser: async (object, params, context, resolveInfo) => {
const session = context.driver.session() const session = context.driver.session()
const { postId } = params const { postId } = params
const transactionRes = await session.run( const transactionRes = await session.run(
`MATCH (user:User {id: $userId})-[emoted:EMOTED]->(post:Post {id: $postId}) `MATCH (user:User {id: $userId})-[emoted:EMOTED]->(post:Post {id: $postId})
RETURN emoted.emotion as emotion`, RETURN collect(emoted.emotion) as emotion`,
{ userId: context.user.id, postId }, { userId: context.user.id, postId },
) )
session.close() session.close()
const emotionsArray = []
transactionRes.records.map(record => {
emotionsArray.push(record.get('emotion'))
})
return emotionsArray const [emotions] = transactionRes.records.map(record => {
return record.get('emotion')
})
return emotions
}, },
}, },
} }

View File

@ -406,15 +406,17 @@ describe('emotions', () => {
owner, owner,
postMutationAction, postMutationAction,
user, user,
postQueryAction postQueryAction,
const postEmotionsCountQuery = ` postToEmote,
postToEmoteNode
const PostsEmotionsCountQuery = `
query($id: ID!) { query($id: ID!) {
Post(id: $id) { Post(id: $id) {
emotionsCount emotionsCount
} }
} }
` `
const postEmotionsQuery = ` const PostsEmotionsQuery = `
query($id: ID!) { query($id: ID!) {
Post(id: $id) { Post(id: $id) {
emotions { emotions {
@ -425,14 +427,27 @@ describe('emotions', () => {
} }
} }
} }
`
const addPostEmotionsMutation = `
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) {
from { id }
to { id }
emotion
}
}
` `
beforeEach(async () => { beforeEach(async () => {
userParams.id = 'u1987' userParams.id = 'u1987'
authorParams.id = 'u257' authorParams.id = 'u257'
createPostVariables.id = 'p1376'
const someUserNode = await instance.create('User', userParams) const someUserNode = await instance.create('User', userParams)
someUser = await someUserNode.toJson() someUser = await someUserNode.toJson()
ownerNode = await instance.create('User', authorParams) ownerNode = await instance.create('User', authorParams)
owner = await ownerNode.toJson() owner = await ownerNode.toJson()
postToEmoteNode = await instance.create('Post', createPostVariables)
postToEmote = await postToEmoteNode.toJson()
await postToEmoteNode.relateTo(ownerNode, 'author')
postMutationAction = async (user, mutation, variables) => { postMutationAction = async (user, mutation, variables) => {
const { server } = createServer({ const { server } = createServer({
@ -462,42 +477,29 @@ describe('emotions', () => {
const { query } = createTestClient(server) const { query } = createTestClient(server)
return query({ query: postQuery, variables }) return query({ query: postQuery, variables })
} }
addPostEmotionsVariables = {
from: { id: authorParams.id },
to: { id: postToEmote.id },
data: { emotion: 'happy' },
}
}) })
describe('AddPostEmotions', () => { describe('AddPostEmotions', () => {
let postEmotionsQueryVariables let postsEmotionsQueryVariables
beforeEach(async () => { beforeEach(async () => {
user = owner postsEmotionsQueryVariables = { id: postToEmote.id }
const {
data: { CreatePost },
} = await postMutationAction(user, createPostMutation, createPostVariables)
addPostEmotionsVariables = {
from: { id: authorParams.id },
to: { id: CreatePost.id },
data: { emotion: 'happy' },
}
postEmotionsQueryVariables = { id: CreatePost.id }
}) })
const addPostEmotionsMutation = `
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) {
from { id }
to { id }
emotion
}
}
`
describe('unauthenticated', () => { describe('unauthenticated', () => {
it('throws authorization error', async () => { it('throws authorization error', async () => {
user = null user = null
const result = await postMutationAction( const addPostEmotions = await postMutationAction(
user, user,
addPostEmotionsMutation, addPostEmotionsMutation,
addPostEmotionsVariables, addPostEmotionsVariables,
) )
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') expect(addPostEmotions.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
}) })
@ -535,7 +537,7 @@ describe('emotions', () => {
await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables) await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables)
await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables) await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables)
await expect( await expect(
postQueryAction(postEmotionsCountQuery, postEmotionsQueryVariables), postQueryAction(PostsEmotionsCountQuery, postsEmotionsQueryVariables),
).resolves.toEqual(expect.objectContaining(expected)) ).resolves.toEqual(expect.objectContaining(expected))
}) })
@ -551,7 +553,7 @@ describe('emotions', () => {
addPostEmotionsVariables.data.emotion = 'surprised' addPostEmotionsVariables.data.emotion = 'surprised'
await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables) await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables)
await expect( await expect(
postQueryAction(postEmotionsQuery, postEmotionsQueryVariables), postQueryAction(PostsEmotionsQuery, postsEmotionsQueryVariables),
).resolves.toEqual(expect.objectContaining(expectedResponse)) ).resolves.toEqual(expect.objectContaining(expectedResponse))
}) })
}) })
@ -579,16 +581,19 @@ describe('emotions', () => {
}) })
describe('RemovePostEmotions', () => { describe('RemovePostEmotions', () => {
let removePostEmotionsVariables, postEmotionsQueryVariables let removePostEmotionsVariables, postsEmotionsQueryVariables
const removePostEmotionsMutation = ` const removePostEmotionsMutation = `
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) { mutation($to: _PostInput!, $data: _EMOTEDInput!) {
RemovePostEmotions(from: $from, to: $to, data: $data) RemovePostEmotions(to: $to, data: $data)
} }
` `
beforeEach(() => { beforeEach(async () => {
await ownerNode.relateTo(postToEmoteNode, 'emoted', { emotion: 'cry' })
await postMutationAction(user, addPostEmotionsMutation, addPostEmotionsVariables)
postsEmotionsQueryVariables = { id: postToEmote.id }
removePostEmotionsVariables = { removePostEmotionsVariables = {
from: { id: authorParams.id }, to: { id: postToEmote.id },
to: { id: 'p1376' },
data: { emotion: 'cry' }, data: { emotion: 'cry' },
} }
}) })
@ -596,45 +601,25 @@ describe('emotions', () => {
describe('unauthenticated', () => { describe('unauthenticated', () => {
it('throws authorization error', async () => { it('throws authorization error', async () => {
user = null user = null
const result = await postMutationAction( const removePostEmotions = await postMutationAction(
user, user,
removePostEmotionsMutation, removePostEmotionsMutation,
removePostEmotionsVariables, removePostEmotionsVariables,
) )
expect(removePostEmotions.errors[0]).toHaveProperty('message', 'Not Authorised!')
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
}) })
describe('authenticated', () => { describe('authenticated', () => {
beforeEach(async () => {
user = owner
const {
data: { CreatePost },
} = await postMutationAction(user, createPostMutation, createPostVariables)
await factory.emote({
from: authorParams.id,
to: CreatePost.id,
data: 'cry',
})
await factory.emote({
from: authorParams.id,
to: CreatePost.id,
data: 'happy',
})
postEmotionsQueryVariables = { id: CreatePost.id }
})
describe('but not the emoter', () => { describe('but not the emoter', () => {
it('throws an authorization error', async () => { it('throws an authorization error', async () => {
user = someUser user = someUser
const result = await postMutationAction( const removePostEmotions = await postMutationAction(
user, user,
removePostEmotionsMutation, removePostEmotionsMutation,
removePostEmotionsVariables, removePostEmotionsVariables,
) )
expect(removePostEmotions.errors[0]).toHaveProperty('message', 'Not Authorised!')
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
}) })
@ -654,7 +639,7 @@ describe('emotions', () => {
} }
await postMutationAction(user, removePostEmotionsMutation, removePostEmotionsVariables) await postMutationAction(user, removePostEmotionsMutation, removePostEmotionsVariables)
await expect( await expect(
postQueryAction(postEmotionsQuery, postEmotionsQueryVariables), postQueryAction(PostsEmotionsQuery, postsEmotionsQueryVariables),
).resolves.toEqual(expect.objectContaining(expectedResponse)) ).resolves.toEqual(expect.objectContaining(expectedResponse))
}) })
}) })
@ -662,54 +647,44 @@ describe('emotions', () => {
}) })
describe('posts emotions count', () => { describe('posts emotions count', () => {
let postsEmotionsCountByEmotionVariables let PostsEmotionsCountByEmotionVariables
let postsEmotionsCountByCurrentUserVariables let PostsEmotionsByCurrentUserVariables
const postsEmotionsCountByEmotionQuery = ` const PostsEmotionsCountByEmotionQuery = `
query($postId: ID!, $data: _EMOTEDInput!) { query($postId: ID!, $data: _EMOTEDInput!) {
postsEmotionsCountByEmotion(postId: $postId, data: $data) PostsEmotionsCountByEmotion(postId: $postId, data: $data)
} }
` `
const postsEmotionsCountByCurrentUserQuery = ` const PostsEmotionsByCurrentUserQuery = `
query($postId: ID!) { query($postId: ID!) {
postsEmotionsCountByCurrentUser(postId: $postId) PostsEmotionsByCurrentUser(postId: $postId)
} }
` `
beforeEach(async () => { beforeEach(async () => {
user = owner await ownerNode.relateTo(postToEmoteNode, 'emoted', { emotion: 'cry' })
const {
data: { CreatePost }, PostsEmotionsCountByEmotionVariables = {
} = await postMutationAction(user, createPostMutation, createPostVariables) postId: postToEmote.id,
await factory.emote({
from: authorParams.id,
to: CreatePost.id,
data: 'cry',
})
postsEmotionsCountByEmotionVariables = {
postId: CreatePost.id,
data: { emotion: 'cry' }, data: { emotion: 'cry' },
} }
postsEmotionsCountByCurrentUserVariables = { postId: CreatePost.id } PostsEmotionsByCurrentUserVariables = { postId: postToEmote.id }
}) })
describe('postsEmotionsCountByEmotion', () => { describe('PostsEmotionsCountByEmotion', () => {
it("returns a post's emotions count", async () => { it("returns a post's emotions count", async () => {
const expectedResponse = { data: { postsEmotionsCountByEmotion: 1 } } const expectedResponse = { data: { PostsEmotionsCountByEmotion: 1 } }
await expect( await expect(
postQueryAction(postsEmotionsCountByEmotionQuery, postsEmotionsCountByEmotionVariables), postQueryAction(PostsEmotionsCountByEmotionQuery, PostsEmotionsCountByEmotionVariables),
).resolves.toEqual(expect.objectContaining(expectedResponse)) ).resolves.toEqual(expect.objectContaining(expectedResponse))
}) })
}) })
describe('postsEmotionsCountByEmotion', () => { describe('PostsEmotionsCountByEmotion', () => {
it("returns a currentUser's emotions on a post", async () => { it("returns a currentUser's emotions on a post", async () => {
const expectedResponse = { data: { postsEmotionsCountByCurrentUser: ['cry'] } } const expectedResponse = { data: { PostsEmotionsByCurrentUser: ['cry'] } }
await expect( await expect(
postQueryAction( postQueryAction(PostsEmotionsByCurrentUserQuery, PostsEmotionsByCurrentUserVariables),
postsEmotionsCountByCurrentUserQuery,
postsEmotionsCountByCurrentUserVariables,
),
).resolves.toEqual(expect.objectContaining(expectedResponse)) ).resolves.toEqual(expect.objectContaining(expectedResponse))
}) })
}) })

View File

@ -91,10 +91,11 @@ type Mutation {
language: String language: String
categoryIds: [ID] categoryIds: [ID]
): Post ): Post
RemovePostEmotions(from: _UserInput!, to: _PostInput!, data: _EMOTEDInput!): Boolean! AddPostEmotions(from: _UserInput!, to: _PostInput!, data: _EMOTEDInput!): EMOTED
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): Boolean!
} }
type Query { type Query {
postsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int! PostsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int!
postsEmotionsCountByCurrentUser(postId: ID!): [String] PostsEmotionsByCurrentUser(postId: ID!): [String]
} }

View File

@ -1,5 +1,5 @@
import { mount, createLocalVue } from '@vue/test-utils' import { mount, createLocalVue } from '@vue/test-utils'
import EmotionsButtons from './EmotionsButtons.vue' import Emotions from './Emotions.vue'
import Styleguide from '@human-connection/styleguide' import Styleguide from '@human-connection/styleguide'
import Vuex from 'vuex' import Vuex from 'vuex'
import PostMutations from '~/graphql/PostMutations.js' import PostMutations from '~/graphql/PostMutations.js'
@ -9,7 +9,7 @@ const localVue = createLocalVue()
localVue.use(Styleguide) localVue.use(Styleguide)
localVue.use(Vuex) localVue.use(Vuex)
describe('EmotionsButtons.vue', () => { describe('Emotions.vue', () => {
let wrapper let wrapper
let mocks let mocks
let propsData let propsData
@ -39,7 +39,7 @@ describe('EmotionsButtons.vue', () => {
}), }),
query: jest.fn().mockResolvedValue({ query: jest.fn().mockResolvedValue({
data: { data: {
postsEmotionsCountByEmotion: 1, PostsEmotionsCountByEmotion: 1,
}, },
}), }),
}, },
@ -59,7 +59,7 @@ describe('EmotionsButtons.vue', () => {
const store = new Vuex.Store({ const store = new Vuex.Store({
getters, getters,
}) })
return mount(EmotionsButtons, { mocks, propsData, store, localVue }) return mount(Emotions, { mocks, propsData, store, localVue })
} }
beforeEach(() => { beforeEach(() => {
wrapper = Wrapper() wrapper = Wrapper()
@ -72,7 +72,7 @@ describe('EmotionsButtons.vue', () => {
describe('adding emotions', () => { describe('adding emotions', () => {
let expectedParams let expectedParams
beforeEach(() => { beforeEach(() => {
wrapper.vm.postsEmotionsCountByEmotion.funny = 0 wrapper.vm.PostsEmotionsCountByEmotion.funny = 0
funnyButton = wrapper.findAll('button').at(0) funnyButton = wrapper.findAll('button').at(0)
funnyButton.trigger('click') funnyButton.trigger('click')
}) })
@ -82,16 +82,16 @@ describe('EmotionsButtons.vue', () => {
expect(funnyImage.attributes().src).toEqual(funnyImageSrc) expect(funnyImage.attributes().src).toEqual(funnyImageSrc)
}) })
it('sends the addPostEmotionsMutation for an emotion when clicked', () => { it('sends the AddPostEmotionsMutation for an emotion when clicked', () => {
expectedParams = { expectedParams = {
mutation: PostMutations().addPostEmotionsMutation, mutation: PostMutations().AddPostEmotionsMutation,
variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } }, variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } },
} }
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams)) expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
}) })
it('increases the postEmotionsCountByEmotion for the emotion clicked', () => { it('increases the PostsEmotionsCountByEmotion for the emotion clicked', () => {
expect(wrapper.vm.postsEmotionsCountByEmotion.funny).toEqual(1) expect(wrapper.vm.PostsEmotionsCountByEmotion.funny).toEqual(1)
}) })
it('adds an emotion to selectedEmotions to show the colored image when the button is active', () => { it('adds an emotion to selectedEmotions to show the colored image when the button is active', () => {
@ -103,16 +103,16 @@ describe('EmotionsButtons.vue', () => {
funnyButton.trigger('click') funnyButton.trigger('click')
}) })
it('sends the removePostEmotionsMutation when a user clicks on an active emotion', () => { it('sends the RemovePostEmotionsMutation when a user clicks on an active emotion', () => {
expectedParams = { expectedParams = {
mutation: PostMutations().removePostEmotionsMutation, mutation: PostMutations().RemovePostEmotionsMutation,
variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } }, variables: { from: { id: 'u176' }, to: { id: 'p143' }, data: { emotion: 'funny' } },
} }
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams)) expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expect.objectContaining(expectedParams))
}) })
it('decreases the postEmotionsCountByEmotion for the emotion clicked', async () => { it('decreases the PostsEmotionsCountByEmotion for the emotion clicked', async () => {
expect(wrapper.vm.postsEmotionsCountByEmotion.funny).toEqual(0) expect(wrapper.vm.PostsEmotionsCountByEmotion.funny).toEqual(0)
}) })
it('removes an emotion from selectedEmotions to show the default image', async () => { it('removes an emotion from selectedEmotions to show the default image', async () => {

View File

@ -1,18 +1,13 @@
<template> <template>
<ds-flex :gutter="{ lg: 'large' }" class="emotions-flex"> <ds-flex :gutter="{ lg: 'large' }" class="emotions-flex">
<div v-for="emotion in Object.keys(postsEmotionsCountByEmotion)" :key="emotion"> <div v-for="emotion in Object.keys(PostsEmotionsCountByEmotion)" :key="emotion">
<ds-flex-item :width="{ lg: '100%' }"> <ds-flex-item :width="{ lg: '100%' }">
<ds-button size="large" ghost @click="toggleEmotion(emotion)" class="emotions-buttons"> <hc-emotions-button
<img :src="iconPath(emotion)" width="40" /> @toggleEmotion="toggleEmotion"
</ds-button> :PostsEmotionsCountByEmotion="PostsEmotionsCountByEmotion"
<ds-space margin-bottom="xx-small" /> :iconPath="iconPath(emotion)"
<div class="emotions-mobile-space"> :emotion="emotion"
<p class="emotions-label">{{ $t(`contribution.emotions-label.${emotion}`) }}</p> />
<ds-text style="display: inline" size="medium" :key="postsEmotionsCountByEmotion[emotion]">
{{ postsEmotionsCountByEmotion[emotion] }}x
</ds-text>
{{ $t('contribution.emotions-label.emoted') }}
</div>
</ds-flex-item> </ds-flex-item>
</div> </div>
</ds-flex> </ds-flex>
@ -20,17 +15,21 @@
<script> <script>
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { postsEmotionsCountByCurrentUser } from '~/graphql/PostQuery.js' import HcEmotionsButton from '~/components/EmotionsButton/EmotionsButton'
import { PostsEmotionsByCurrentUser } from '~/graphql/PostQuery.js'
import PostMutations from '~/graphql/PostMutations.js' import PostMutations from '~/graphql/PostMutations.js'
export default { export default {
components: {
HcEmotionsButton,
},
props: { props: {
post: { type: Object, default: () => {} }, post: { type: Object, default: () => {} },
}, },
data() { data() {
return { return {
selectedEmotions: [], selectedEmotions: [],
postsEmotionsCountByEmotion: { funny: 0, happy: 0, surprised: 0, cry: 0, angry: 0 }, PostsEmotionsCountByEmotion: { funny: 0, happy: 0, surprised: 0, cry: 0, angry: 0 },
} }
}, },
computed: { computed: {
@ -39,7 +38,7 @@ export default {
}), }),
}, },
created() { created() {
Object.keys(this.postsEmotionsCountByEmotion).map(emotion => { Object.keys(this.PostsEmotionsCountByEmotion).map(emotion => {
this.emotionsCount(emotion) this.emotionsCount(emotion)
}) })
}, },
@ -54,8 +53,8 @@ export default {
this.$apollo this.$apollo
.mutate({ .mutate({
mutation: this.isActive(emotion) mutation: this.isActive(emotion)
? PostMutations().removePostEmotionsMutation ? PostMutations().RemovePostEmotionsMutation
: PostMutations().addPostEmotionsMutation, : PostMutations().AddPostEmotionsMutation,
variables: { variables: {
from: { id: this.currentUser.id }, from: { id: this.currentUser.id },
to: { id: this.post.id }, to: { id: this.post.id },
@ -64,8 +63,8 @@ export default {
}) })
.then(() => { .then(() => {
this.isActive(emotion) this.isActive(emotion)
? this.postsEmotionsCountByEmotion[emotion]-- ? this.PostsEmotionsCountByEmotion[emotion]--
: this.postsEmotionsCountByEmotion[emotion]++ : this.PostsEmotionsCountByEmotion[emotion]++
const index = this.selectedEmotions.indexOf(emotion) const index = this.selectedEmotions.indexOf(emotion)
if (index > -1) { if (index > -1) {
@ -87,52 +86,31 @@ export default {
.query({ .query({
query: gql` query: gql`
query($postId: ID!, $data: _EMOTEDInput!) { query($postId: ID!, $data: _EMOTEDInput!) {
postsEmotionsCountByEmotion(postId: $postId, data: $data) PostsEmotionsCountByEmotion(postId: $postId, data: $data)
} }
`, `,
variables: { postId: this.post.id, data: { emotion } }, variables: { postId: this.post.id, data: { emotion } },
fetchPolicy: 'no-cache', fetchPolicy: 'no-cache',
}) })
.then(({ data: { postsEmotionsCountByEmotion } }) => { .then(({ data: { PostsEmotionsCountByEmotion } }) => {
this.postsEmotionsCountByEmotion[emotion] = postsEmotionsCountByEmotion this.PostsEmotionsCountByEmotion[emotion] = PostsEmotionsCountByEmotion
}) })
}, },
}, },
apollo: { apollo: {
postsEmotionsCountByCurrentUser: { PostsEmotionsByCurrentUser: {
query() { query() {
return postsEmotionsCountByCurrentUser() return PostsEmotionsByCurrentUser()
}, },
variables() { variables() {
return { return {
postId: this.post.id, postId: this.post.id,
} }
}, },
result({ data: { postsEmotionsCountByCurrentUser } }) { result({ data: { PostsEmotionsByCurrentUser } }) {
this.selectedEmotions = postsEmotionsCountByCurrentUser this.selectedEmotions = PostsEmotionsByCurrentUser
}, },
}, },
}, },
} }
</script> </script>
<style lang="scss">
.emotions-flex {
justify-content: space-evenly;
text-align: center;
}
.emotions-label {
font-size: $font-size-small;
}
.emotions-buttons {
&:hover {
background-color: $background-color-base;
}
}
@media only screen and (max-width: 960px) {
.emotions-mobile-space {
margin-bottom: 32px;
}
}
</style>

View File

@ -0,0 +1,50 @@
<template>
<div>
<ds-button size="large" ghost @click="toggleEmotion(emotion)" class="emotions-buttons">
<img :src="iconPath" width="40" />
</ds-button>
<ds-space margin-bottom="xx-small" />
<div class="emotions-mobile-space">
<p class="emotions-label">{{ $t(`contribution.emotions-label.${emotion}`) }}</p>
<p style="display: inline" :key="PostsEmotionsCountByEmotion[emotion]">
{{ PostsEmotionsCountByEmotion[emotion] }}x
</p>
{{ $t('contribution.emotions-label.emoted') }}
</div>
</div>
</template>
<script>
export default {
props: {
iconPath: { type: String, default: null },
PostsEmotionsCountByEmotion: { type: Object, default: () => {} },
emotion: { type: String, default: null },
},
methods: {
toggleEmotion(emotion) {
this.$emit('toggleEmotion', emotion)
},
},
}
</script>
<style lang="scss">
.emotions-flex {
justify-content: space-evenly;
text-align: center;
}
.emotions-label {
font-size: $font-size-small;
}
.emotions-buttons {
&:hover {
background-color: $background-color-base;
}
}
@media only screen and (max-width: 960px) {
.emotions-mobile-space {
margin-bottom: 32px;
}
}
</style>

View File

@ -60,7 +60,7 @@ export default () => {
} }
} }
`, `,
addPostEmotionsMutation: gql` AddPostEmotionsMutation: gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) { mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) { AddPostEmotions(from: $from, to: $to, data: $data) {
emotion emotion
@ -73,9 +73,9 @@ export default () => {
} }
} }
`, `,
removePostEmotionsMutation: gql` RemovePostEmotionsMutation: gql`
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) { mutation($to: _PostInput!, $data: _EMOTEDInput!) {
RemovePostEmotions(from: $from, to: $to, data: $data) RemovePostEmotions(to: $to, data: $data)
} }
`, `,
} }

View File

@ -122,10 +122,10 @@ export const filterPosts = i18n => {
` `
} }
export const postsEmotionsCountByCurrentUser = () => { export const PostsEmotionsByCurrentUser = () => {
return gql` return gql`
query postsEmotionsCountByCurrentUser($postId: ID!) { query PostsEmotionsByCurrentUser($postId: ID!) {
postsEmotionsCountByCurrentUser(postId: $postId) PostsEmotionsByCurrentUser(postId: $postId)
} }
` `
} }

View File

@ -46,7 +46,7 @@
:width="{ lg: '75%', md: '75%', sm: '75%' }" :width="{ lg: '75%', md: '75%', sm: '75%' }"
class="emotions-buttons-mobile" class="emotions-buttons-mobile"
> >
<hc-emotions-buttons :post="post" /> <hc-emotions :post="post" />
</ds-flex-item> </ds-flex-item>
<ds-flex-item :width="{ lg: '10%', md: '3%', sm: '3%' }" /> <ds-flex-item :width="{ lg: '10%', md: '3%', sm: '3%' }" />
<!-- Shout Button --> <!-- Shout Button -->
@ -85,7 +85,7 @@ import HcCommentForm from '~/components/comments/CommentForm'
import HcCommentList from '~/components/comments/CommentList' import HcCommentList from '~/components/comments/CommentList'
import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers' import { postMenuModalsData, deletePostMutation } from '~/components/utils/PostHelpers'
import PostQuery from '~/graphql/PostQuery.js' import PostQuery from '~/graphql/PostQuery.js'
import HcEmotionsButtons from '~/components/EmotionsButtons/EmotionsButtons' import HcEmotions from '~/components/Emotions/Emotions'
export default { export default {
name: 'PostSlug', name: 'PostSlug',
@ -101,7 +101,7 @@ export default {
ContentMenu, ContentMenu,
HcCommentForm, HcCommentForm,
HcCommentList, HcCommentList,
HcEmotionsButtons, HcEmotions,
ContentViewer, ContentViewer,
}, },
head() { head() {