diff --git a/components/Author.vue b/components/Author.vue
index f1f57113b..54770d33d 100644
--- a/components/Author.vue
+++ b/components/Author.vue
@@ -107,7 +107,9 @@
author.followedByCurrentUser = follow"
+ @update="follow => author.followedByCurrentUser = follow"
/>
@@ -139,21 +141,12 @@ export default {
trunc: { type: Number, default: null },
showAuthorPopover: { type: Boolean, default: true }
},
- data() {
- return {
- voted: false
- }
- },
computed: {
itsMe() {
return this.author.slug === this.$store.getters['auth/user'].slug
},
fanCount() {
let count = Number(this.author.followedByCount) || 0
- if (this.voted) {
- // NOTE: this is used for presentation
- count += 1
- }
return count
},
author() {
diff --git a/components/FollowButton.vue b/components/FollowButton.vue
index 3540726d2..f5c705a8d 100644
--- a/components/FollowButton.vue
+++ b/components/FollowButton.vue
@@ -2,12 +2,15 @@
- Folgen
+ {{ label }}
@@ -18,37 +21,69 @@ export default {
name: 'HcFollowButton',
props: {
- followId: { type: String, default: null }
+ followId: { type: String, default: null },
+ isFollowed: { type: Boolean, default: false }
},
data() {
return {
disabled: false,
- loading: false
+ loading: false,
+ hovered: false
+ }
+ },
+ computed: {
+ icon() {
+ if (this.isFollowed && this.hovered) {
+ return 'close'
+ } else {
+ return this.isFollowed ? 'check' : 'plus'
+ }
+ },
+ label() {
+ if (this.isFollowed) {
+ return this.$t('followButton.following')
+ } else {
+ return this.$t('followButton.follow')
+ }
+ }
+ },
+ watch: {
+ isFollowed() {
+ this.loading = false
+ this.hovered = false
}
},
methods: {
- follow() {
- this.loading = true
+ onHover() {
+ if (!this.disabled && !this.loading) {
+ this.hovered = true
+ }
+ },
+ toggle() {
+ const follow = !this.isFollowed
+ const mutation = follow ? 'follow' : 'unfollow'
+
+ this.hovered = false
+
+ this.$emit('optimistic', follow)
+
this.$apollo
.mutate({
mutation: gql`
- mutation($myId: ID!, $followId: ID!) {
- AddUserFollowing(from: { id: $myId }, to: { id: $followId }) {
- from {
- id
- }
- }
+ mutation($id: ID!) {
+ ${mutation}(id: $id, type: User)
}
`,
variables: {
- myId: this.$store.getters['auth/user'].id,
- followId: this.followId
+ id: this.followId
}
})
- .then(() => {
- this.loading = false
- this.disabled = true
- this.$emit('update')
+ .then(res => {
+ // this.$emit('optimistic', follow ? res.data.follow : follow)
+ this.$emit('update', follow)
+ })
+ .catch(() => {
+ this.$emit('optimistic', !follow)
})
}
}
diff --git a/components/ShoutButton.vue b/components/ShoutButton.vue
index 075006b2e..02d7cb639 100644
--- a/components/ShoutButton.vue
+++ b/components/ShoutButton.vue
@@ -4,20 +4,25 @@
style="text-align: center"
>
-
+
{{ shoutedCount }}x
- Empfohlen
+ {{ $t('shoutButton.shouted') }}
@@ -28,41 +33,69 @@ import gql from 'graphql-tag'
export default {
props: {
count: { type: Number, default: 0 },
- postId: { type: String, default: null }
+ postId: { type: String, default: null },
+ isShouted: { type: Boolean, default: false },
+ disabled: { type: Boolean, default: false }
},
data() {
return {
loading: false,
- disabled: false,
- shoutedCount: this.count
+ shoutedCount: this.count,
+ shouted: false
+ }
+ },
+ watch: {
+ isShouted: {
+ immediate: true,
+ handler: function(shouted) {
+ this.shouted = shouted
+ }
}
},
methods: {
- shout() {
- this.loading = true
+ toggle() {
+ const shout = !this.shouted
+ const mutation = shout ? 'shout' : 'unshout'
+ const count = shout ? this.shoutedCount + 1 : this.shoutedCount - 1
+
+ const backup = {
+ shoutedCount: this.shoutedCount,
+ shouted: this.shouted
+ }
+
+ this.shoutedCount = count
+ this.shouted = shout
+
this.$apollo
.mutate({
mutation: gql`
- mutation($myId: ID!, $postId: ID!) {
- AddUserShouted(from: { id: $myId }, to: { id: $postId }) {
- from {
- id
- }
- }
+ mutation($id: ID!) {
+ ${mutation}(id: $id, type: Post)
}
`,
variables: {
- myId: this.$store.getters['auth/user'].id,
- postId: this.postId
+ id: this.postId
}
})
- .then(() => {
+ .then(res => {
+ if (res && res.data) {
+ this.$emit('update', shout)
+ }
+ })
+ .catch(() => {
+ this.shoutedCount = backup.shoutedCount
+ this.shouted = backup.shouted
+ })
+ .finally(() => {
this.loading = false
- this.disabled = true
- this.shoutedCount++
- this.$emit('update')
})
}
}
}
+
+
diff --git a/graphql/UserProfileQuery.js b/graphql/UserProfileQuery.js
index 4e0245b52..30431602b 100644
--- a/graphql/UserProfileQuery.js
+++ b/graphql/UserProfileQuery.js
@@ -29,6 +29,7 @@ export default app => {
slug
avatar
followedByCount
+ followedByCurrentUser
contributionsCount
commentsCount
badges {
@@ -41,12 +42,14 @@ export default app => {
}
}
followedByCount
+ followedByCurrentUser
followedBy(first: 7) {
id
name
slug
avatar
followedByCount
+ followedByCurrentUser
contributionsCount
commentsCount
badges {
diff --git a/locales/de.json b/locales/de.json
index b3e6289ac..7a06b767e 100644
--- a/locales/de.json
+++ b/locales/de.json
@@ -17,6 +17,13 @@
"moreInfo": "Was ist Human Connection?",
"hello": "Hallo"
},
+ "followButton": {
+ "follow": "Folgen",
+ "following": "Folge Ich"
+ },
+ "shoutButton": {
+ "shouted": "empfohlen"
+ },
"profile": {
"name": "Mein Profil",
"memberSince": "Mitglied seit",
diff --git a/locales/en.json b/locales/en.json
index cfe634675..c49fd1318 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -17,6 +17,13 @@
"moreInfo": "What is Human Connection?",
"hello": "Hello"
},
+ "followButton": {
+ "follow": "Follow",
+ "following": "Following"
+ },
+ "shoutButton": {
+ "shouted": "shouted"
+ },
"profile": {
"name": "My Profile",
"memberSince": "Member since",
diff --git a/pages/index.vue b/pages/index.vue
index 7bc85b3a4..f4785b3ac 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -108,6 +108,7 @@ export default {
shoutedCount
commentsCount
followedByCount
+ followedByCurrentUser
location {
name: name${this.$i18n.locale().toUpperCase()}
}
diff --git a/pages/post/_slug/index.vue b/pages/post/_slug/index.vue
index 68655a31f..074db5d7b 100644
--- a/pages/post/_slug/index.vue
+++ b/pages/post/_slug/index.vue
@@ -28,7 +28,9 @@
@@ -188,9 +190,10 @@ export default {
contributionsCount
commentsCount
followedByCount
+ followedByCurrentUser
location {
- name: name${this.$i18n.locale().toUpperCase()}
- }
+ name: name${this.$i18n.locale().toUpperCase()}
+ }
badges {
id
key
@@ -215,6 +218,7 @@ export default {
contributionsCount
commentsCount
followedByCount
+ followedByCurrentUser
location {
name: name${this.$i18n.locale().toUpperCase()}
}
@@ -231,6 +235,7 @@ export default {
icon
}
shoutedCount
+ shoutedByCurrentUser
}
}
`)
diff --git a/pages/post/_slug/more-info.vue b/pages/post/_slug/more-info.vue
index 847975757..d4de5f6f3 100644
--- a/pages/post/_slug/more-info.vue
+++ b/pages/post/_slug/more-info.vue
@@ -109,6 +109,7 @@ export default {
avatar
contributionsCount
followedByCount
+ followedByCurrentUser
commentsCount
location {
name: name${this.$i18n.locale().toUpperCase()}
diff --git a/pages/profile/_slug.vue b/pages/profile/_slug.vue
index 98d3b9f48..614187004 100644
--- a/pages/profile/_slug.vue
+++ b/pages/profile/_slug.vue
@@ -61,7 +61,7 @@
-
+
-
+
user.followedByCurrentUser = follow"
+ @update="follow => fetchUser()"
/>
@@ -335,10 +337,6 @@ export default {
},
followedByCount() {
let count = Number(this.user.followedByCount) || 0
- if (this.voted) {
- // NOTE: this is used for presentation
- count += 1
- }
return count
},
user() {