Add emotions buttons, get it filtering

This commit is contained in:
mattwr18 2019-09-06 15:45:56 +02:00
parent e81942c6f5
commit 07c58fc03e
8 changed files with 154 additions and 103 deletions

View File

@ -1,21 +1,27 @@
type EMOTED @relation(name: "EMOTED") {
from: User
to: Post
from: User
to: Post
emotion: Emotion
#createdAt: DateTime
#updatedAt: DateTime
createdAt: String
updatedAt: String
emotion: Emotion
# createdAt: DateTime
# updatedAt: DateTime
createdAt: String
updatedAt: String
}
input _EMOTEDInput {
emotion: Emotion
createdAt: String
updatedAt: String
emotion: Emotion
createdAt: String
updatedAt: String
}
input _PostEMOTEDFilter {
emotion: Emotion
createdAt: String
updatedAt: String
}
type Mutation {
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
}
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
}

View File

@ -1,92 +1,92 @@
type Post {
id: ID!
activityId: String
objectId: String
author: User @relation(name: "WROTE", direction: "IN")
title: String!
slug: String
content: String!
contentExcerpt: String
image: String
imageUpload: Upload
visibility: Visibility
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
createdAt: String
updatedAt: String
language: String
relatedContributions: [Post]!
@cypher(
statement: """
MATCH (this)-[:TAGGED|CATEGORIZED]->(categoryOrTag)<-[:TAGGED|CATEGORIZED]-(post:Post)
WHERE NOT post.deleted AND NOT post.disabled
RETURN DISTINCT post
LIMIT 10
"""
)
id: ID!
activityId: String
objectId: String
author: User @relation(name: "WROTE", direction: "IN")
title: String!
slug: String
content: String!
contentExcerpt: String
image: String
imageUpload: Upload
visibility: Visibility
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
createdAt: String
updatedAt: String
language: String
relatedContributions: [Post]!
@cypher(
statement: """
MATCH (this)-[: TAGGED|CATEGORIZED]->(categoryOrTag)<-[: TAGGED|CATEGORIZED]-(post: Post)
WHERE NOT post.deleted AND NOT post.disabled
RETURN DISTINCT post
LIMIT 10
"""
)
tags: [Tag]! @relation(name: "TAGGED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
tags: [Tag]! @relation(name: "TAGGED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
comments: [Comment]! @relation(name: "COMMENTS", direction: "IN")
commentsCount: Int!
@cypher(
statement: "MATCH (this)<-[:COMMENTS]-(r:Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
)
comments: [Comment]! @relation(name: "COMMENTS", direction: "IN")
commentsCount: Int!
@cypher(
statement: "MATCH (this)<-[: COMMENTS]-(r: Comment) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
)
shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN")
shoutedCount: Int!
@cypher(
statement: "MATCH (this)<-[:SHOUTED]-(r:User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
)
shoutedBy: [User]! @relation(name: "SHOUTED", direction: "IN")
shoutedCount: Int!
@cypher(
statement: "MATCH (this)<-[: SHOUTED]-(r: User) WHERE NOT r.deleted = true AND NOT r.disabled = true RETURN COUNT(DISTINCT r)"
)
# Has the currently logged in user shouted that post?
shoutedByCurrentUser: Boolean!
@cypher(
statement: "MATCH (this)<-[:SHOUTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1"
)
# Has the currently logged in user shouted that post?
shoutedByCurrentUser: Boolean!
@cypher(
statement: "MATCH (this)<-[: SHOUTED]-(u: User { id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1"
)
emotions: [EMOTED]
emotionsCount: Int!
@cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)")
emotions: [EMOTED]
emotionsCount: Int!
@cypher(statement: "MATCH (this)<-[emoted: EMOTED]-(: User) RETURN COUNT(DISTINCT emoted)")
}
input _PostInput {
id: ID!
id: ID!
}
type Mutation {
CreatePost(
id: ID
title: String!
slug: String
content: String!
image: String
imageUpload: Upload
visibility: Visibility
language: String
categoryIds: [ID]
contentExcerpt: String
): Post
UpdatePost(
id: ID!
title: String!
slug: String
content: String!
contentExcerpt: String
image: String
imageUpload: Upload
visibility: Visibility
language: String
categoryIds: [ID]
): Post
DeletePost(id: ID!): Post
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
CreatePost(
id: ID
title: String!
slug: String
content: String!
image: String
imageUpload: Upload
visibility: Visibility
language: String
categoryIds: [ID]
contentExcerpt: String
): Post
UpdatePost(
id: ID!
title: String!
slug: String
content: String!
contentExcerpt: String
image: String
imageUpload: Upload
visibility: Visibility
language: String
categoryIds: [ID]
): Post
DeletePost(id: ID!): Post
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
}
type Query {
PostsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int!
PostsEmotionsByCurrentUser(postId: ID!): [String]
}
PostsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int!
PostsEmotionsByCurrentUser(postId: ID!): [String]
}

View File

@ -1,5 +1,5 @@
<template>
<ds-space>
<ds-space margin-top="large">
<ds-flex id="filter-posts-header">
<ds-heading tag="h4">{{ $t('filter-posts.categories.header') }}</ds-heading>
<ds-space margin-bottom="large" />

View File

@ -61,6 +61,7 @@ describe('FilterPosts.vue', () => {
},
'postsFilter/filteredCategoryIds': jest.fn(() => []),
'postsFilter/filteredByUsersFollowed': jest.fn(),
'postsFilter/filteredByEmotions': jest.fn(() => jest.fn()),
}
const openFilterPosts = () => {
const store = new Vuex.Store({ mutations, getters })

View File

@ -13,23 +13,23 @@
<template slot="popover">
<ds-container>
<categories-filter-menu-items :chunk="chunk" />
<follows-filter-menu-items :user="currentUser" />
<general-filter-menu-items :user="currentUser" />
</ds-container>
</template>
</dropdown>
</template>
<script>
import _ from 'lodash'
import { chunk } from 'lodash'
import Dropdown from '~/components/Dropdown'
import { mapGetters } from 'vuex'
import CategoriesFilterMenuItems from './CategoriesFilterMenuItems'
import FollowsFilterMenuItems from './FollowsFilterMenuItems'
import GeneralFilterMenuItems from './GeneralFilterMenuItems'
export default {
components: {
Dropdown,
CategoriesFilterMenuItems,
FollowsFilterMenuItems,
GeneralFilterMenuItems,
},
props: {
placement: { type: String },
@ -42,7 +42,7 @@ export default {
filterActive: 'postsFilter/isActive',
}),
chunk() {
return _.chunk(this.categories, 2)
return chunk(this.categories, 2)
},
},
}

View File

@ -4,7 +4,7 @@
<ds-heading tag="h4">{{ $t('filter-posts.general.header') }}</ds-heading>
<ds-space margin-bottom="large" />
</ds-flex>
<ds-flex>
<ds-flex :gutter="{ lg: 'large' }">
<ds-flex-item
:width="{ base: '100%', sm: '100%', md: '100%', lg: '10%' }"
class="categories-menu-item"
@ -32,6 +32,21 @@
</ds-flex-item>
</ds-flex>
</ds-flex-item>
<div v-for="emotion in Object.keys(PostsEmotionsCountByEmotion)" :key="emotion">
<ds-flex-item :width="{ lg: '100%' }">
<ds-button
size="large"
ghost
@click="toogleFilteredByEmotions(emotion)"
class="emotions-buttons"
>
<img :src="iconPath(emotion)" width="40" />
</ds-button>
<div class="emotions-mobile-space text-center">
<p class="emotions-label">{{ $t(`contribution.emotions-label.${emotion}`) }}</p>
</div>
</ds-flex-item>
</div>
<ds-space margin-bottom="large" />
</ds-flex>
</ds-space>
@ -43,15 +58,28 @@ export default {
props: {
user: { type: Object, required: true },
},
data() {
return {
PostsEmotionsCountByEmotion: { funny: 0, happy: 0, surprised: 0, cry: 0, angry: 0 },
}
},
computed: {
...mapGetters({
filteredByUsersFollowed: 'postsFilter/filteredByUsersFollowed',
filteredByEmotions: 'postsFilter/filteredByEmotions',
}),
},
methods: {
...mapMutations({
toggleFilteredByFollowed: 'postsFilter/TOGGLE_FILTER_BY_FOLLOWED',
toogleFilteredByEmotions: 'postsFilter/TOGGLE_FILTER_BY_EMOTIONS',
}),
iconPath(emotion) {
if (this.filteredByEmotions(emotion)) {
return `/img/svg/emoji/${emotion}_color.svg`
}
return `/img/svg/emoji/${emotion}.svg`
},
},
}
</script>
@ -72,4 +100,8 @@ export default {
float: left;
}
}
.text-center {
text-align: center;
}
</style>

View File

@ -27,12 +27,8 @@
<template v-else>
<ds-grid-item :row-span="2" column-span="fullWidth">
<hc-empty icon="docs" />
<ds-text align="center">
{{ $t('index.no-results') }}
</ds-text>
<ds-text align="center">
{{ $t('index.change-filter-settings') }}
</ds-text>
<ds-text align="center">{{ $t('index.no-results') }}</ds-text>
<ds-text align="center">{{ $t('index.change-filter-settings') }}</ds-text>
</ds-grid-item>
</template>
</masonry-grid>

View File

@ -40,6 +40,19 @@ export const mutations = {
if (isEmpty(get(filter, 'categories_some.id_in'))) delete filter.categories_some
state.filter = filter
},
TOGGLE_FILTER_BY_EMOTIONS(state, emotion) {
const filter = clone(state.filter)
const emotionName = get(filter, 'emotions_in.emotions')
if (emotionName) {
delete filter.emotions_in
state.filter = filter
} else {
state.filter = {
...filter,
emotions_in: { emotion: emotion },
}
}
},
}
export const getters = {
@ -55,4 +68,7 @@ export const getters = {
filteredByUsersFollowed(state) {
return !!get(state.filter, 'author.followedBy_some.id')
},
filteredByEmotions: state => emotion => {
return get(state.filter, 'emotions_in.emotion') === emotion
},
}