Implement block/unbock UI

This commit is contained in:
Robert Schäfer 2019-08-08 01:11:42 +02:00 committed by roschaefer
parent 824b2a5561
commit 7f509b3201
9 changed files with 109 additions and 29 deletions

View File

@ -15,10 +15,12 @@ export default function Resolver(type, options = {}) {
const {
idAttribute = 'id',
undefinedToNull = [],
boolean = {},
count = {},
hasOne = {},
hasMany = {},
} = options
const _hasResolver = (resolvers, { key, connection }, { returnType }) => {
return async (parent, params, context, resolveInfo) => {
if (typeof parent[key] !== 'undefined') return parent[key]
@ -31,6 +33,26 @@ export default function Resolver(type, options = {}) {
}
}
const booleanResolver = obj => {
const resolvers = {}
for (const [key, condition] of Object.entries(obj)) {
resolvers[key] = async (parent, params, { cypherParams }, resolveInfo) => {
if (typeof parent[key] !== 'undefined') return parent[key]
const result = await instance.cypher(
`
${condition.replace('this', 'this {id: $parent.id}')} as ${key}`,
{
parent,
cypherParams,
},
)
const [record] = result.records
return record.get(key)
}
}
return resolvers
}
const countResolver = obj => {
const resolvers = {}
for (const [key, connection] of Object.entries(obj)) {
@ -67,6 +89,7 @@ export default function Resolver(type, options = {}) {
}
const result = {
...undefinedToNullResolver(undefinedToNull),
...booleanResolver(boolean),
...countResolver(count),
...hasOneResolver(hasOne),
...hasManyResolver(hasMany),

View File

@ -110,18 +110,6 @@ export default {
const [{ email }] = result.records.map(r => r.get('e').properties)
return email
},
isBlocked: async (parent, params, context, resolveInfo) => {
if (typeof parent.isBlocked !== 'undefined') return parent.isBlocked
const result = await instance.cypher(
`
MATCH (u:User { id: $currentUser.id })-[:BLOCKED]->(b:User {id: $parent.id})
RETURN COUNT(u) >= 1 as isBlocked
`,
{ parent, currentUser: context.user },
)
const [record] = result.records
return record.get('isBlocked')
},
...Resolver('User', {
undefinedToNull: [
'actorId',
@ -132,6 +120,12 @@ export default {
'locationName',
'about',
],
boolean: {
followedByCurrentUser:
'MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
isBlocked:
'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
},
count: {
contributionsCount: '-[:WROTE]->(related:Post)',
friendsCount: '<-[:FRIENDS]->(related:User)',

View File

@ -122,13 +122,34 @@ export default {
}
}
if (this.isOwner && this.resourceType === 'user') {
routes.push({
name: this.$t(`settings.name`),
path: '/settings',
icon: 'edit',
})
if (this.resourceType === 'user') {
if (this.isOwner) {
routes.push({
name: this.$t(`settings.name`),
path: '/settings',
icon: 'edit',
})
} else {
if (this.resource.isBlocked) {
routes.push({
name: this.$t(`settings.blocked-users.unblock`),
callback: () => {
this.$emit('unblock', this.resource)
},
icon: 'user-plus',
})
} else {
routes.push({
name: this.$t(`settings.blocked-users.block`),
callback: () => {
this.$emit('block', this.resource)
},
icon: 'user-times',
})
}
}
}
return routes
},
isModerator() {

View File

@ -46,6 +46,7 @@ export default i18n => {
}
followedByCount
followedByCurrentUser
isBlocked
followedBy(first: 7) {
id
slug

View File

@ -1,6 +1,6 @@
import gql from 'graphql-tag'
export default () => {
export const BlockedUsers = () => {
return gql(`
{
blockedUsers {
@ -15,3 +15,25 @@ export default () => {
}
`)
}
export const Block = () => {
return gql(`mutation($id:ID!) {
block(id: $id) {
id
name
isBlocked
followedByCurrentUser
}
}`)
}
export const Unblock = () => {
return gql(`mutation($id:ID!) {
unblock(id: $id) {
id
name
isBlocked
followedByCurrentUser
}
}`)
}

View File

@ -202,7 +202,9 @@
"name": "Name",
"slug": "Alias"
},
"empty": "Bislang hast du niemanden blockiert."
"empty": "Bislang hast du niemanden blockiert.",
"block": "Nutzer blockieren",
"unblock": "Nutzer entblocken"
}
},
"admin": {

View File

@ -203,7 +203,9 @@
"name": "Name",
"slug": "Slug"
},
"empty": "So far, you did not block anybody."
"empty": "So far, you did not block anybody.",
"block": "Block user",
"unblock": "Unblock user"
}
},
"admin": {

View File

@ -22,6 +22,8 @@
:resource="user"
:is-owner="myProfile"
class="user-content-menu"
@block="block"
@unblock="unblock"
/>
</no-ssr>
<ds-space margin="small">
@ -54,13 +56,18 @@
</ds-flex-item>
</ds-flex>
<ds-space margin="small">
<hc-follow-button
v-if="!myProfile"
:follow-id="user.id"
:is-followed="user.followedByCurrentUser"
@optimistic="follow => (user.followedByCurrentUser = follow)"
@update="follow => fetchUser()"
/>
<template v-if="!myProfile">
<hc-follow-button
v-if="!user.isBlocked"
:follow-id="user.id"
:is-followed="user.followedByCurrentUser"
@optimistic="follow => (user.followedByCurrentUser = follow)"
@update="follow => fetchUser()"
/>
<ds-button v-else fullwidth @click="unblock(user)">
{{ $t('settings.blocked-users.unblock') }}
</ds-button>
</template>
</ds-space>
<template v-if="user.about">
<hr />
@ -242,6 +249,7 @@ import HcUpload from '~/components/Upload'
import HcAvatar from '~/components/Avatar/Avatar.vue'
import PostQuery from '~/graphql/UserProfile/Post.js'
import UserQuery from '~/graphql/UserProfile/User.js'
import { Block, Unblock } from '~/graphql/settings/BlockedUsers.js'
const tabToFilterMapping = ({ tab, id }) => {
return {
@ -372,6 +380,13 @@ export default {
}
return this.uniq(this.Post.filter(post => !post.deleted))
},
async block(user) {
await this.$apollo.mutate({ mutation: Block(), variables: { id: user.id } })
await this.fetchUser()
},
async unblock(user) {
await this.$apollo.mutate({ mutation: Unblock(), variables: { id: user.id } })
},
},
apollo: {
Post: {

View File

@ -61,7 +61,7 @@
</template>
<script>
import BlockedUsers from '~/graphql/settings/BlockedUsers'
import { BlockedUsers } from '~/graphql/settings/BlockedUsers'
import HcAvatar from '~/components/Avatar/Avatar.vue'
export default {