mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2026-04-06 01:25:31 +00:00
Merge pull request #1596 from Human-Connection/1583-follow-mutation
Improve follow/ufollow mutation
This commit is contained in:
commit
d830fa4ae4
@ -1,51 +1,44 @@
|
|||||||
|
import { neode as getNeode } from '../../bootstrap/neo4j'
|
||||||
|
|
||||||
|
const neode = getNeode()
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
Mutation: {
|
Mutation: {
|
||||||
follow: async (_object, params, context, _resolveInfo) => {
|
follow: async (_object, params, context, _resolveInfo) => {
|
||||||
const { id, type } = params
|
const { id: followedId, type } = params
|
||||||
|
const { user: currentUser } = context
|
||||||
|
|
||||||
const session = context.driver.session()
|
if (type === 'User' && currentUser.id === followedId) {
|
||||||
const transactionRes = await session.run(
|
return null
|
||||||
`MATCH (node {id: $id}), (user:User {id: $userId})
|
}
|
||||||
WHERE $type IN labels(node) AND NOT $id = $userId
|
|
||||||
MERGE (user)-[relation:FOLLOWS]->(node)
|
|
||||||
RETURN COUNT(relation) > 0 as isFollowed`,
|
|
||||||
{
|
|
||||||
id,
|
|
||||||
type,
|
|
||||||
userId: context.user.id,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const [isFollowed] = transactionRes.records.map(record => {
|
const [user, followedNode] = await Promise.all([
|
||||||
return record.get('isFollowed')
|
neode.find('User', currentUser.id),
|
||||||
})
|
neode.find(type, followedId),
|
||||||
|
])
|
||||||
session.close()
|
await user.relateTo(followedNode, 'following')
|
||||||
|
return followedNode.toJson()
|
||||||
return isFollowed
|
|
||||||
},
|
},
|
||||||
|
|
||||||
unfollow: async (_object, params, context, _resolveInfo) => {
|
unfollow: async (_object, params, context, _resolveInfo) => {
|
||||||
const { id, type } = params
|
const { id: followedId, type } = params
|
||||||
const session = context.driver.session()
|
const { user: currentUser } = context
|
||||||
|
|
||||||
const transactionRes = await session.run(
|
/*
|
||||||
`MATCH (user:User {id: $userId})-[relation:FOLLOWS]->(node {id: $id})
|
* Note: Neode doesn't provide an easy method for retrieving or removing relationships.
|
||||||
|
* It's suggested to use query builder feature (https://github.com/adam-cowley/neode/issues/67)
|
||||||
|
* However, pure cypher query looks cleaner IMO
|
||||||
|
*/
|
||||||
|
await neode.cypher(
|
||||||
|
`MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(node {id: $followedId})
|
||||||
WHERE $type IN labels(node)
|
WHERE $type IN labels(node)
|
||||||
DELETE relation
|
DELETE relation
|
||||||
RETURN COUNT(relation) > 0 as isFollowed`,
|
RETURN COUNT(relation) > 0 as isFollowed`,
|
||||||
{
|
{ followedId, type, currentUser },
|
||||||
id,
|
|
||||||
type,
|
|
||||||
userId: context.user.id,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
const [isFollowed] = transactionRes.records.map(record => {
|
|
||||||
return record.get('isFollowed')
|
|
||||||
})
|
|
||||||
session.close()
|
|
||||||
|
|
||||||
return isFollowed
|
const followedNode = await neode.find(type, followedId)
|
||||||
|
return followedNode.toJson()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,93 @@
|
|||||||
import { GraphQLClient } from 'graphql-request'
|
import { createTestClient } from 'apollo-server-testing'
|
||||||
import Factory from '../../seed/factories'
|
import Factory from '../../seed/factories'
|
||||||
import { host, login } from '../../jest/helpers'
|
import { getDriver } from '../../bootstrap/neo4j'
|
||||||
|
import createServer from '../../server'
|
||||||
|
import { gql } from '../../jest/helpers'
|
||||||
|
|
||||||
const factory = Factory()
|
const factory = Factory()
|
||||||
let clientUser1
|
const driver = getDriver()
|
||||||
let headersUser1
|
|
||||||
|
|
||||||
const mutationFollowUser = id => `
|
let query
|
||||||
mutation {
|
let mutate
|
||||||
follow(id: "${id}", type: User)
|
let authenticatedUser
|
||||||
|
|
||||||
|
let user1
|
||||||
|
let user2
|
||||||
|
let variables
|
||||||
|
|
||||||
|
const mutationFollowUser = gql`
|
||||||
|
mutation($id: ID!, $type: FollowTypeEnum) {
|
||||||
|
follow(id: $id, type: $type) {
|
||||||
|
name
|
||||||
|
followedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
followedByCurrentUser
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const mutationUnfollowUser = id => `
|
|
||||||
mutation {
|
const mutationUnfollowUser = gql`
|
||||||
unfollow(id: "${id}", type: User)
|
mutation($id: ID!, $type: FollowTypeEnum) {
|
||||||
|
unfollow(id: $id, type: $type) {
|
||||||
|
name
|
||||||
|
followedBy {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
followedByCurrentUser
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const userQuery = gql`
|
||||||
|
query($id: ID) {
|
||||||
|
User(id: $id) {
|
||||||
|
followedBy {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
followedByCurrentUser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
const { server } = createServer({
|
||||||
|
context: () => ({
|
||||||
|
driver,
|
||||||
|
user: authenticatedUser,
|
||||||
|
cypherParams: {
|
||||||
|
currentUserId: authenticatedUser ? authenticatedUser.id : null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
const testClient = createTestClient(server)
|
||||||
|
query = testClient.query
|
||||||
|
mutate = testClient.mutate
|
||||||
|
})
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await factory.create('User', {
|
user1 = await factory
|
||||||
id: 'u1',
|
.create('User', {
|
||||||
email: 'test@example.org',
|
id: 'u1',
|
||||||
password: '1234',
|
name: 'user1',
|
||||||
})
|
email: 'test@example.org',
|
||||||
await factory.create('User', {
|
password: '1234',
|
||||||
id: 'u2',
|
})
|
||||||
email: 'test2@example.org',
|
.then(user => user.toJson())
|
||||||
password: '1234',
|
user2 = await factory
|
||||||
})
|
.create('User', {
|
||||||
|
id: 'u2',
|
||||||
|
name: 'user2',
|
||||||
|
email: 'test2@example.org',
|
||||||
|
password: '1234',
|
||||||
|
})
|
||||||
|
.then(user => user.toJson())
|
||||||
|
|
||||||
headersUser1 = await login({ email: 'test@example.org', password: '1234' })
|
authenticatedUser = user1
|
||||||
clientUser1 = new GraphQLClient(host, { headers: headersUser1 })
|
variables = { id: user2.id, type: 'User' }
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@ -40,84 +97,73 @@ afterEach(async () => {
|
|||||||
describe('follow', () => {
|
describe('follow', () => {
|
||||||
describe('follow user', () => {
|
describe('follow user', () => {
|
||||||
describe('unauthenticated follow', () => {
|
describe('unauthenticated follow', () => {
|
||||||
it('throws authorization error', async () => {
|
test('throws authorization error', async () => {
|
||||||
const client = new GraphQLClient(host)
|
authenticatedUser = null
|
||||||
await expect(client.request(mutationFollowUser('u2'))).rejects.toThrow('Not Authorised')
|
const { errors, data } = await mutate({
|
||||||
|
mutation: mutationFollowUser,
|
||||||
|
variables,
|
||||||
|
})
|
||||||
|
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
|
||||||
|
expect(data).toMatchObject({ follow: null })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('I can follow another user', async () => {
|
test('I can follow another user', async () => {
|
||||||
const res = await clientUser1.request(mutationFollowUser('u2'))
|
const { data: result } = await mutate({
|
||||||
const expected = {
|
mutation: mutationFollowUser,
|
||||||
follow: true,
|
variables,
|
||||||
}
|
})
|
||||||
expect(res).toMatchObject(expected)
|
const expectedUser = {
|
||||||
|
name: user2.name,
|
||||||
const { User } = await clientUser1.request(`{
|
followedBy: [{ id: user1.id, name: user1.name }],
|
||||||
User(id: "u2") {
|
|
||||||
followedBy { id }
|
|
||||||
followedByCurrentUser
|
|
||||||
}
|
|
||||||
}`)
|
|
||||||
const expected2 = {
|
|
||||||
followedBy: [{ id: 'u1' }],
|
|
||||||
followedByCurrentUser: true,
|
followedByCurrentUser: true,
|
||||||
}
|
}
|
||||||
expect(User[0]).toMatchObject(expected2)
|
expect(result).toMatchObject({ follow: expectedUser })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('I can`t follow myself', async () => {
|
test('I can`t follow myself', async () => {
|
||||||
const res = await clientUser1.request(mutationFollowUser('u1'))
|
variables.id = user1.id
|
||||||
const expected = {
|
const { data: result } = await mutate({ mutation: mutationFollowUser, variables })
|
||||||
follow: false,
|
const expectedResult = { follow: null }
|
||||||
}
|
expect(result).toMatchObject(expectedResult)
|
||||||
expect(res).toMatchObject(expected)
|
|
||||||
|
|
||||||
const { User } = await clientUser1.request(`{
|
const { data } = await query({
|
||||||
User(id: "u1") {
|
query: userQuery,
|
||||||
followedBy { id }
|
variables: { id: user1.id },
|
||||||
followedByCurrentUser
|
})
|
||||||
}
|
const expectedUser = {
|
||||||
}`)
|
|
||||||
const expected2 = {
|
|
||||||
followedBy: [],
|
followedBy: [],
|
||||||
followedByCurrentUser: false,
|
followedByCurrentUser: false,
|
||||||
}
|
}
|
||||||
expect(User[0]).toMatchObject(expected2)
|
expect(data).toMatchObject({ User: [expectedUser] })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('unfollow user', () => {
|
describe('unfollow user', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
variables = {
|
||||||
|
id: user2.id,
|
||||||
|
type: 'User',
|
||||||
|
}
|
||||||
|
await mutate({ mutation: mutationFollowUser, variables })
|
||||||
|
})
|
||||||
|
|
||||||
describe('unauthenticated follow', () => {
|
describe('unauthenticated follow', () => {
|
||||||
it('throws authorization error', async () => {
|
test('throws authorization error', async () => {
|
||||||
// follow
|
authenticatedUser = null
|
||||||
await clientUser1.request(mutationFollowUser('u2'))
|
const { errors, data } = await mutate({ mutation: mutationUnfollowUser, variables })
|
||||||
// unfollow
|
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
|
||||||
const client = new GraphQLClient(host)
|
expect(data).toMatchObject({ unfollow: null })
|
||||||
await expect(client.request(mutationUnfollowUser('u2'))).rejects.toThrow('Not Authorised')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('I can unfollow a user', async () => {
|
it('I can unfollow a user', async () => {
|
||||||
// follow
|
const { data: result } = await mutate({ mutation: mutationUnfollowUser, variables })
|
||||||
await clientUser1.request(mutationFollowUser('u2'))
|
const expectedUser = {
|
||||||
// unfollow
|
name: user2.name,
|
||||||
const expected = {
|
|
||||||
unfollow: true,
|
|
||||||
}
|
|
||||||
const res = await clientUser1.request(mutationUnfollowUser('u2'))
|
|
||||||
expect(res).toMatchObject(expected)
|
|
||||||
|
|
||||||
const { User } = await clientUser1.request(`{
|
|
||||||
User(id: "u2") {
|
|
||||||
followedBy { id }
|
|
||||||
followedByCurrentUser
|
|
||||||
}
|
|
||||||
}`)
|
|
||||||
const expected2 = {
|
|
||||||
followedBy: [],
|
followedBy: [],
|
||||||
followedByCurrentUser: false,
|
followedByCurrentUser: false,
|
||||||
}
|
}
|
||||||
expect(User[0]).toMatchObject(expected2)
|
expect(result).toMatchObject({ unfollow: expectedUser })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -32,9 +32,9 @@ type Mutation {
|
|||||||
# Unshout the given Type and ID
|
# Unshout the given Type and ID
|
||||||
unshout(id: ID!, type: ShoutTypeEnum): Boolean!
|
unshout(id: ID!, type: ShoutTypeEnum): Boolean!
|
||||||
# Follow the given Type and ID
|
# Follow the given Type and ID
|
||||||
follow(id: ID!, type: FollowTypeEnum): Boolean!
|
follow(id: ID!, type: FollowTypeEnum): User
|
||||||
# Unfollow the given Type and ID
|
# Unfollow the given Type and ID
|
||||||
unfollow(id: ID!, type: FollowTypeEnum): Boolean!
|
unfollow(id: ID!, type: FollowTypeEnum): User
|
||||||
}
|
}
|
||||||
|
|
||||||
type Report {
|
type Report {
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import gql from 'graphql-tag'
|
import { followUserMutation, unfollowUserMutation } from '~/graphql/User'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'HcFollowButton',
|
name: 'HcFollowButton',
|
||||||
@ -61,26 +61,23 @@ export default {
|
|||||||
},
|
},
|
||||||
async toggle() {
|
async toggle() {
|
||||||
const follow = !this.isFollowed
|
const follow = !this.isFollowed
|
||||||
const mutation = follow ? 'follow' : 'unfollow'
|
const mutation = follow ? followUserMutation(this.$i18n) : unfollowUserMutation(this.$i18n)
|
||||||
|
|
||||||
this.hovered = false
|
this.hovered = false
|
||||||
this.$emit('optimistic', follow)
|
const optimisticResult = { followedByCurrentUser: follow }
|
||||||
|
this.$emit('optimistic', optimisticResult)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.$apollo.mutate({
|
const { data } = await this.$apollo.mutate({
|
||||||
mutation: gql`
|
mutation,
|
||||||
mutation($id: ID!) {
|
variables: { id: this.followId },
|
||||||
${mutation}(id: $id, type: User)
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
id: this.followId,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.$emit('update', follow)
|
const followedUser = follow ? data.follow : data.unfollow
|
||||||
|
this.$emit('update', followedUser)
|
||||||
} catch {
|
} catch {
|
||||||
this.$emit('optimistic', !follow)
|
optimisticResult.followedByCurrentUser = !follow
|
||||||
|
this.$emit('optimistic', optimisticResult)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -139,13 +139,14 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
optimisticFollow(follow) {
|
optimisticFollow({ followedByCurrentUser }) {
|
||||||
const inc = follow ? 1 : -1
|
const inc = followedByCurrentUser ? 1 : -1
|
||||||
this.user.followedByCurrentUser = follow
|
this.user.followedByCurrentUser = followedByCurrentUser
|
||||||
this.user.followedByCount += inc
|
this.user.followedByCount += inc
|
||||||
},
|
},
|
||||||
updateFollow(follow) {
|
updateFollow({ followedByCurrentUser, followedByCount }) {
|
||||||
this.user.followedByCurrentUser = follow
|
this.user.followedByCount = followedByCount
|
||||||
|
this.user.followedByCurrentUser = followedByCurrentUser
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,72 +1,27 @@
|
|||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
import { postFragment, commentFragment } from './Fragments'
|
import { userFragment, postFragment, commentFragment } from './Fragments'
|
||||||
|
|
||||||
export default i18n => {
|
export default i18n => {
|
||||||
const lang = i18n.locale().toUpperCase()
|
const lang = i18n.locale().toUpperCase()
|
||||||
return gql`
|
return gql`
|
||||||
|
${userFragment(lang)}
|
||||||
|
|
||||||
query User($id: ID!) {
|
query User($id: ID!) {
|
||||||
User(id: $id) {
|
User(id: $id) {
|
||||||
id
|
...user
|
||||||
slug
|
|
||||||
name
|
|
||||||
avatar
|
|
||||||
about
|
about
|
||||||
disabled
|
|
||||||
deleted
|
|
||||||
locationName
|
locationName
|
||||||
location {
|
|
||||||
name: name${lang}
|
|
||||||
}
|
|
||||||
createdAt
|
createdAt
|
||||||
badges {
|
|
||||||
id
|
|
||||||
icon
|
|
||||||
}
|
|
||||||
badgesCount
|
badgesCount
|
||||||
shoutedCount
|
|
||||||
commentedCount
|
|
||||||
contributionsCount
|
|
||||||
followingCount
|
followingCount
|
||||||
following(first: 7) {
|
following(first: 7) {
|
||||||
id
|
...user
|
||||||
slug
|
|
||||||
name
|
|
||||||
avatar
|
|
||||||
disabled
|
|
||||||
deleted
|
|
||||||
followedByCount
|
|
||||||
followedByCurrentUser
|
|
||||||
contributionsCount
|
|
||||||
commentedCount
|
|
||||||
badges {
|
|
||||||
id
|
|
||||||
icon
|
|
||||||
}
|
|
||||||
location {
|
|
||||||
name: name${lang}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
followedByCount
|
followedByCount
|
||||||
followedByCurrentUser
|
followedByCurrentUser
|
||||||
isBlocked
|
isBlocked
|
||||||
followedBy(first: 7) {
|
followedBy(first: 7) {
|
||||||
id
|
...user
|
||||||
slug
|
|
||||||
name
|
|
||||||
disabled
|
|
||||||
deleted
|
|
||||||
avatar
|
|
||||||
followedByCount
|
|
||||||
followedByCurrentUser
|
|
||||||
contributionsCount
|
|
||||||
commentedCount
|
|
||||||
badges {
|
|
||||||
id
|
|
||||||
icon
|
|
||||||
}
|
|
||||||
location {
|
|
||||||
name: name${lang}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
socialMedia {
|
socialMedia {
|
||||||
id
|
id
|
||||||
@ -145,3 +100,37 @@ export const markAsReadMutation = i18n => {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const followUserMutation = i18n => {
|
||||||
|
const lang = i18n.locale().toUpperCase()
|
||||||
|
return gql`
|
||||||
|
${userFragment(lang)}
|
||||||
|
mutation($id: ID!) {
|
||||||
|
follow(id: $id, type: User) {
|
||||||
|
name
|
||||||
|
followedByCount
|
||||||
|
followedByCurrentUser
|
||||||
|
followedBy(first: 7) {
|
||||||
|
...user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const unfollowUserMutation = i18n => {
|
||||||
|
const lang = i18n.locale().toUpperCase()
|
||||||
|
return gql`
|
||||||
|
${userFragment(lang)}
|
||||||
|
mutation($id: ID!) {
|
||||||
|
unfollow(id: $id, type: User) {
|
||||||
|
name
|
||||||
|
followedByCount
|
||||||
|
followedByCurrentUser
|
||||||
|
followedBy(first: 7) {
|
||||||
|
...user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|||||||
@ -48,7 +48,11 @@
|
|||||||
<ds-flex-item>
|
<ds-flex-item>
|
||||||
<client-only>
|
<client-only>
|
||||||
<ds-number :label="$t('profile.followers')">
|
<ds-number :label="$t('profile.followers')">
|
||||||
<hc-count-to slot="count" :end-val="user.followedByCount" />
|
<hc-count-to
|
||||||
|
slot="count"
|
||||||
|
:start-val="followedByCountStartValue"
|
||||||
|
:end-val="user.followedByCount"
|
||||||
|
/>
|
||||||
</ds-number>
|
</ds-number>
|
||||||
</client-only>
|
</client-only>
|
||||||
</ds-flex-item>
|
</ds-flex-item>
|
||||||
@ -66,8 +70,8 @@
|
|||||||
v-if="!user.isBlocked"
|
v-if="!user.isBlocked"
|
||||||
:follow-id="user.id"
|
:follow-id="user.id"
|
||||||
:is-followed="user.followedByCurrentUser"
|
:is-followed="user.followedByCurrentUser"
|
||||||
@optimistic="follow => (user.followedByCurrentUser = follow)"
|
@optimistic="optimisticFollow"
|
||||||
@update="follow => fetchUser()"
|
@update="updateFollow"
|
||||||
/>
|
/>
|
||||||
<ds-button v-else fullwidth @click="unblock(user)">
|
<ds-button v-else fullwidth @click="unblock(user)">
|
||||||
{{ $t('settings.blocked-users.unblock') }}
|
{{ $t('settings.blocked-users.unblock') }}
|
||||||
@ -317,6 +321,7 @@ export default {
|
|||||||
pageSize: 6,
|
pageSize: 6,
|
||||||
tabActive: 'post',
|
tabActive: 'post',
|
||||||
filter,
|
filter,
|
||||||
|
followedByCountStartValue: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -367,10 +372,6 @@ export default {
|
|||||||
uniq(items, field = 'id') {
|
uniq(items, field = 'id') {
|
||||||
return uniqBy(items, field)
|
return uniqBy(items, field)
|
||||||
},
|
},
|
||||||
fetchUser() {
|
|
||||||
// TODO: we should use subscriptions instead of fetching the whole user again
|
|
||||||
this.$apollo.queries.User.refetch()
|
|
||||||
},
|
|
||||||
showMoreContributions() {
|
showMoreContributions() {
|
||||||
const { Post: PostQuery } = this.$apollo.queries
|
const { Post: PostQuery } = this.$apollo.queries
|
||||||
if (!PostQuery) return // seems this can be undefined on subpages
|
if (!PostQuery) return // seems this can be undefined on subpages
|
||||||
@ -411,6 +412,27 @@ export default {
|
|||||||
this.resetPostList()
|
this.resetPostList()
|
||||||
this.$apollo.queries.Post.refetch()
|
this.$apollo.queries.Post.refetch()
|
||||||
},
|
},
|
||||||
|
optimisticFollow({ followedByCurrentUser }) {
|
||||||
|
/*
|
||||||
|
* Note: followedByCountStartValue is updated to avoid counting from 0 when follow/unfollow
|
||||||
|
*/
|
||||||
|
this.followedByCountStartValue = this.user.followedByCount
|
||||||
|
const currentUser = this.$store.getters['auth/user']
|
||||||
|
if (followedByCurrentUser) {
|
||||||
|
this.user.followedByCount++
|
||||||
|
this.user.followedBy = [currentUser, ...this.user.followedBy]
|
||||||
|
} else {
|
||||||
|
this.user.followedByCount--
|
||||||
|
this.user.followedBy = this.user.followedBy.filter(user => user.id !== currentUser.id)
|
||||||
|
}
|
||||||
|
this.user.followedByCurrentUser = followedByCurrentUser
|
||||||
|
},
|
||||||
|
updateFollow({ followedByCurrentUser, followedBy, followedByCount }) {
|
||||||
|
this.followedByCountStartValue = this.user.followedByCount
|
||||||
|
this.user.followedByCount = followedByCount
|
||||||
|
this.user.followedByCurrentUser = followedByCurrentUser
|
||||||
|
this.user.followedBy = followedBy
|
||||||
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
Post: {
|
Post: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user