Ocelot-Social/webapp/components/ShoutButton.vue
Ulf Gebhardt 4b3a26d517
feat(webapp): shout comments (#8600)
* shout comments

* fix notifications

* Remove whitespace for empty category sections

* Overhaul post actions

* Adjust spacing

* Allow fine-grained size control for icons and circle buttons via css variables; adjust comments layout

* Adjust spacing

* Add test for ActionButton (WIP)

* Rename import

* Remove text and add count bubble

* Use filled icons to indicate active states

* Adjust sizes and orientation

* Remove unused properties, add test

* Fix ObserveButton test

* Fix ShoutButton test

* fix tests

* Adapt styles

* Adjust style for larger numbers

* Remove unused icon

* Fix test structure

* Remove unused class names

---------

Co-authored-by: Maximilian Harz <maxharz@gmail.com>
2025-05-31 00:13:15 +02:00

86 lines
1.8 KiB
Vue

<template>
<action-button
:loading="loading"
:disabled="disabled"
:count="shoutedCount"
:text="$t('shoutButton.shouted')"
:filled="shouted"
icon="heart-o"
@click="toggle"
/>
</template>
<script>
import gql from 'graphql-tag'
import ActionButton from '~/components/ActionButton.vue'
export default {
components: {
ActionButton,
},
props: {
count: { type: Number, default: 0 },
nodeType: { type: String },
nodeId: { type: String, default: null },
isShouted: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
},
data() {
return {
loading: false,
shoutedCount: this.count,
shouted: false,
}
},
watch: {
isShouted: {
immediate: true,
handler: function (shouted) {
this.shouted = shouted
},
},
},
methods: {
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($id: ID!, $type: ShoutTypeEnum!) {
${mutation}(id: $id, type: $type)
}
`,
variables: {
id: this.nodeId,
type: this.nodeType,
},
})
.then((res) => {
if (res && res.data) {
this.$emit('update', shout)
}
})
.catch(() => {
this.shoutedCount = backup.shoutedCount
this.shouted = backup.shouted
})
.finally(() => {
this.loading = false
})
},
},
}
</script>