Merge branch 'master' of github.com:Human-Connection/Nitro-Web into 37-full-text-search-top-bar

This commit is contained in:
Matt Rider 2019-03-08 17:39:20 -03:00
commit 796b2d8488
12 changed files with 770 additions and 622 deletions

View File

@ -107,7 +107,9 @@
<ds-flex-item :width="{base: 3}"> <ds-flex-item :width="{base: 3}">
<hc-follow-button <hc-follow-button
:follow-id="author.id" :follow-id="author.id"
@update="voted = true" :is-followed="author.followedByCurrentUser"
@optimistic="follow => author.followedByCurrentUser = follow"
@update="follow => author.followedByCurrentUser = follow"
/> />
</ds-flex-item> </ds-flex-item>
<ds-flex-item :width="{base: 1}"> <ds-flex-item :width="{base: 1}">
@ -139,21 +141,12 @@ export default {
trunc: { type: Number, default: null }, trunc: { type: Number, default: null },
showAuthorPopover: { type: Boolean, default: true } showAuthorPopover: { type: Boolean, default: true }
}, },
data() {
return {
voted: false
}
},
computed: { computed: {
itsMe() { itsMe() {
return this.author.slug === this.$store.getters['auth/user'].slug return this.author.slug === this.$store.getters['auth/user'].slug
}, },
fanCount() { fanCount() {
let count = Number(this.author.followedByCount) || 0 let count = Number(this.author.followedByCount) || 0
if (this.voted) {
// NOTE: this is used for presentation
count += 1
}
return count return count
}, },
author() { author() {

View File

@ -2,12 +2,15 @@
<ds-button <ds-button
:disabled="disabled || !followId" :disabled="disabled || !followId"
:loading="loading" :loading="loading"
icon="plus" :icon="icon"
primary :primary="isFollowed && !hovered"
:danger="isFollowed && hovered"
fullwidth fullwidth
@click.prevent="follow" @mouseenter.native="onHover"
@mouseleave.native="hovered = false"
@click.prevent="toggle"
> >
Folgen {{ label }}
</ds-button> </ds-button>
</template> </template>
@ -18,37 +21,69 @@ export default {
name: 'HcFollowButton', name: 'HcFollowButton',
props: { props: {
followId: { type: String, default: null } followId: { type: String, default: null },
isFollowed: { type: Boolean, default: false }
}, },
data() { data() {
return { return {
disabled: false, 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: { methods: {
follow() { onHover() {
this.loading = true 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 this.$apollo
.mutate({ .mutate({
mutation: gql` mutation: gql`
mutation($myId: ID!, $followId: ID!) { mutation($id: ID!) {
AddUserFollowing(from: { id: $myId }, to: { id: $followId }) { ${mutation}(id: $id, type: User)
from {
id
}
}
} }
`, `,
variables: { variables: {
myId: this.$store.getters['auth/user'].id, id: this.followId
followId: this.followId
} }
}) })
.then(() => { .then(res => {
this.loading = false // this.$emit('optimistic', follow ? res.data.follow : follow)
this.disabled = true this.$emit('update', follow)
this.$emit('update') })
.catch(() => {
this.$emit('optimistic', !follow)
}) })
} }
} }

View File

@ -4,20 +4,25 @@
style="text-align: center" style="text-align: center"
> >
<ds-button <ds-button
:disabled="disabled || loading" :loading="loading"
danger :disabled="disabled"
:ghost="!shouted"
:primary="shouted"
size="x-large" size="x-large"
icon="bullhorn" icon="bullhorn"
@click="shout" @click="toggle"
/> />
<ds-space margin-bottom="xx-small" /> <ds-space margin-bottom="xx-small" />
<ds-text color="soft"> <ds-text
color="soft"
class="shout-button-text"
>
<ds-heading <ds-heading
style="display: inline" style="display: inline"
tag="h3" tag="h3"
> >
{{ shoutedCount }}x {{ shoutedCount }}x
</ds-heading> Empfohlen </ds-heading> {{ $t('shoutButton.shouted') }}
</ds-text> </ds-text>
</ds-space> </ds-space>
</template> </template>
@ -28,41 +33,69 @@ import gql from 'graphql-tag'
export default { export default {
props: { props: {
count: { type: Number, default: 0 }, 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() { data() {
return { return {
loading: false, loading: false,
disabled: false, shoutedCount: this.count,
shoutedCount: this.count shouted: false
}
},
watch: {
isShouted: {
immediate: true,
handler: function(shouted) {
this.shouted = shouted
}
} }
}, },
methods: { methods: {
shout() { toggle() {
this.loading = true 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 this.$apollo
.mutate({ .mutate({
mutation: gql` mutation: gql`
mutation($myId: ID!, $postId: ID!) { mutation($id: ID!) {
AddUserShouted(from: { id: $myId }, to: { id: $postId }) { ${mutation}(id: $id, type: Post)
from {
id
}
}
} }
`, `,
variables: { variables: {
myId: this.$store.getters['auth/user'].id, id: this.postId
postId: 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.loading = false
this.disabled = true
this.shoutedCount++
this.$emit('update')
}) })
} }
} }
} }
</script> </script>
<style lang="scss">
.shout-button-text {
user-select: none;
}
</style>

View File

@ -29,6 +29,7 @@ export default app => {
slug slug
avatar avatar
followedByCount followedByCount
followedByCurrentUser
contributionsCount contributionsCount
commentsCount commentsCount
badges { badges {
@ -41,12 +42,14 @@ export default app => {
} }
} }
followedByCount followedByCount
followedByCurrentUser
followedBy(first: 7) { followedBy(first: 7) {
id id
name name
slug slug
avatar avatar
followedByCount followedByCount
followedByCurrentUser
contributionsCount contributionsCount
commentsCount commentsCount
badges { badges {

View File

@ -17,6 +17,13 @@
"moreInfo": "Was ist Human Connection?", "moreInfo": "Was ist Human Connection?",
"hello": "Hallo" "hello": "Hallo"
}, },
"followButton": {
"follow": "Folgen",
"following": "Folge Ich"
},
"shoutButton": {
"shouted": "empfohlen"
},
"profile": { "profile": {
"name": "Mein Profil", "name": "Mein Profil",
"memberSince": "Mitglied seit", "memberSince": "Mitglied seit",

View File

@ -17,6 +17,13 @@
"moreInfo": "What is Human Connection?", "moreInfo": "What is Human Connection?",
"hello": "Hello" "hello": "Hello"
}, },
"followButton": {
"follow": "Follow",
"following": "Following"
},
"shoutButton": {
"shouted": "shouted"
},
"profile": { "profile": {
"name": "My Profile", "name": "My Profile",
"memberSince": "Member since", "memberSince": "Member since",

View File

@ -56,7 +56,7 @@
"nuxt-env": "~0.1.0", "nuxt-env": "~0.1.0",
"portal-vue": "~1.5.1", "portal-vue": "~1.5.1",
"string-hash": "^1.1.3", "string-hash": "^1.1.3",
"tiptap": "^1.13.0", "tiptap": "^1.14.0",
"tiptap-extensions": "^1.13.0", "tiptap-extensions": "^1.13.0",
"v-tooltip": "~2.0.0-rc.33", "v-tooltip": "~2.0.0-rc.33",
"vue-count-to": "~1.0.13", "vue-count-to": "~1.0.13",
@ -85,7 +85,7 @@
"nodemon": "~1.18.10", "nodemon": "~1.18.10",
"prettier": "~1.14.3", "prettier": "~1.14.3",
"sass-loader": "~7.1.0", "sass-loader": "~7.1.0",
"vue-jest": "~3.0.3", "vue-jest": "~3.0.4",
"vue-svg-loader": "~0.11.0" "vue-svg-loader": "~0.11.0"
} }
} }

View File

@ -108,6 +108,7 @@ export default {
shoutedCount shoutedCount
commentsCount commentsCount
followedByCount followedByCount
followedByCurrentUser
location { location {
name: name${this.$i18n.locale().toUpperCase()} name: name${this.$i18n.locale().toUpperCase()}
} }

View File

@ -28,7 +28,9 @@
<ds-space margin="xx-large" /> <ds-space margin="xx-large" />
<hc-shout-button <hc-shout-button
v-if="post.author" v-if="post.author"
:disabled="isAuthor(post.author.id)"
:count="post.shoutedCount" :count="post.shoutedCount"
:is-shouted="post.shoutedByCurrentUser"
:post-id="post.id" :post-id="post.id"
/> />
<!-- Categories --> <!-- Categories -->
@ -188,9 +190,10 @@ export default {
contributionsCount contributionsCount
commentsCount commentsCount
followedByCount followedByCount
followedByCurrentUser
location { location {
name: name${this.$i18n.locale().toUpperCase()} name: name${this.$i18n.locale().toUpperCase()}
} }
badges { badges {
id id
key key
@ -215,6 +218,7 @@ export default {
contributionsCount contributionsCount
commentsCount commentsCount
followedByCount followedByCount
followedByCurrentUser
location { location {
name: name${this.$i18n.locale().toUpperCase()} name: name${this.$i18n.locale().toUpperCase()}
} }
@ -231,6 +235,7 @@ export default {
icon icon
} }
shoutedCount shoutedCount
shoutedByCurrentUser
} }
} }
`) `)

View File

@ -109,6 +109,7 @@ export default {
avatar avatar
contributionsCount contributionsCount
followedByCount followedByCount
followedByCurrentUser
commentsCount commentsCount
location { location {
name: name${this.$i18n.locale().toUpperCase()} name: name${this.$i18n.locale().toUpperCase()}

View File

@ -61,7 +61,7 @@
<ds-flex> <ds-flex>
<ds-flex-item> <ds-flex-item>
<no-ssr> <no-ssr>
<ds-number :label="$t('profile.following')"> <ds-number :label="$t('profile.followers')">
<hc-count-to <hc-count-to
slot="count" slot="count"
:end-val="followedByCount" :end-val="followedByCount"
@ -71,7 +71,7 @@
</ds-flex-item> </ds-flex-item>
<ds-flex-item> <ds-flex-item>
<no-ssr> <no-ssr>
<ds-number :label="$t('profile.followers')"> <ds-number :label="$t('profile.following')">
<hc-count-to <hc-count-to
slot="count" slot="count"
:end-val="Number(user.followingCount) || 0" :end-val="Number(user.followingCount) || 0"
@ -86,7 +86,9 @@
<hc-follow-button <hc-follow-button
v-if="!myProfile" v-if="!myProfile"
:follow-id="user.id" :follow-id="user.id"
@update="voted = true && fetchUser()" :is-followed="user.followedByCurrentUser"
@optimistic="follow => user.followedByCurrentUser = follow"
@update="follow => fetchUser()"
/> />
</ds-space> </ds-space>
<template v-if="user.about"> <template v-if="user.about">
@ -335,10 +337,6 @@ export default {
}, },
followedByCount() { followedByCount() {
let count = Number(this.user.followedByCount) || 0 let count = Number(this.user.followedByCount) || 0
if (this.voted) {
// NOTE: this is used for presentation
count += 1
}
return count return count
}, },
user() { user() {

1183
yarn.lock

File diff suppressed because it is too large Load Diff