improve follow/unfollow mutation usage

This commit is contained in:
Vasily Belolapotkov 2019-09-19 12:10:59 +03:00
parent 7d048b029d
commit 39db954ec6
4 changed files with 87 additions and 78 deletions

View File

@ -15,7 +15,7 @@
</template>
<script>
import gql from 'graphql-tag'
import { followUserMutation, unfollowUserMutation } from '~/graphql/User'
export default {
name: 'HcFollowButton',
@ -61,26 +61,23 @@ export default {
},
async toggle() {
const follow = !this.isFollowed
const mutation = follow ? 'follow' : 'unfollow'
const mutation = follow ? followUserMutation(this.$i18n) : unfollowUserMutation(this.$i18n)
this.hovered = false
this.$emit('optimistic', follow)
const optimisticResult = { followedByCurrentUser: follow }
this.$emit('optimistic', optimisticResult)
try {
await this.$apollo.mutate({
mutation: gql`
mutation($id: ID!) {
${mutation}(id: $id, type: User)
}
`,
variables: {
id: this.followId,
},
const { data } = await this.$apollo.mutate({
mutation,
variables: { id: this.followId },
})
this.$emit('update', follow)
const followedUser = follow ? data.follow : data.unfollow
this.$emit('update', followedUser)
} catch {
this.$emit('optimistic', !follow)
optimisticResult.followedByCurrentUser = !follow
this.$emit('optimistic', optimisticResult)
}
},
},

View File

@ -132,13 +132,14 @@ export default {
},
},
methods: {
optimisticFollow(follow) {
const inc = follow ? 1 : -1
this.user.followedByCurrentUser = follow
optimisticFollow({ followedByCurrentUser }) {
const inc = followedByCurrentUser ? 1 : -1
this.user.followedByCurrentUser = followedByCurrentUser
this.user.followedByCount += inc
},
updateFollow(follow) {
this.user.followedByCurrentUser = follow
updateFollow({ followedByCurrentUser, followedByCount }) {
this.user.followedByCount = followedByCount
this.user.followedByCurrentUser = followedByCurrentUser
},
},
}

View File

@ -1,72 +1,27 @@
import gql from 'graphql-tag'
import { postFragment, commentFragment } from './Fragments'
import { userFragment, postFragment, commentFragment } from './Fragments'
export default i18n => {
const lang = i18n.locale().toUpperCase()
return gql`
${userFragment(lang)}
query User($id: ID!) {
User(id: $id) {
id
slug
name
avatar
...user
about
disabled
deleted
locationName
location {
name: name${lang}
}
createdAt
badges {
id
icon
}
badgesCount
shoutedCount
commentedCount
contributionsCount
followingCount
following(first: 7) {
id
slug
name
avatar
disabled
deleted
followedByCount
followedByCurrentUser
contributionsCount
commentedCount
badges {
id
icon
}
location {
name: name${lang}
}
...user
}
followedByCount
followedByCurrentUser
isBlocked
followedBy(first: 7) {
id
slug
name
disabled
deleted
avatar
followedByCount
followedByCurrentUser
contributionsCount
commentedCount
badges {
id
icon
}
location {
name: name${lang}
}
followedBy(first: 7) {
...user
}
socialMedia {
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
}
}
}
`
}

View File

@ -43,7 +43,11 @@
<ds-flex-item>
<client-only>
<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>
</client-only>
</ds-flex-item>
@ -61,8 +65,8 @@
v-if="!user.isBlocked"
:follow-id="user.id"
:is-followed="user.followedByCurrentUser"
@optimistic="follow => (user.followedByCurrentUser = follow)"
@update="follow => fetchUser()"
@optimistic="optimisticFollow"
@update="updateFollow"
/>
<ds-button v-else fullwidth @click="unblock(user)">
{{ $t('settings.blocked-users.unblock') }}
@ -312,6 +316,7 @@ export default {
pageSize: 6,
tabActive: 'post',
filter,
followedByCountStartValue: 0,
}
},
computed: {
@ -358,10 +363,6 @@ export default {
uniq(items, field = 'id') {
return uniqBy(items, field)
},
fetchUser() {
// TODO: we should use subscriptions instead of fetching the whole user again
this.$apollo.queries.User.refetch()
},
showMoreContributions() {
const { Post: PostQuery } = this.$apollo.queries
if (!PostQuery) return // seems this can be undefined on subpages
@ -402,6 +403,27 @@ export default {
this.resetPostList()
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: {
Post: {