mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
feat(frontend): observe posts (#8293)
* After creating the post, the author of it automatically observes it to get notifications when there are interactions * a user that comments a post, automatically observes that post to get notifications when there are more interactions on that post * mutation that switches the state of the obeservation of a post on and off * remove duplicate code * fix unit tests * add metric observed users count to posts * change naming * Add follow post entry to post menu * Add FollowButton (WIP), show unfollow in menu when already followed * Follow/unfollow post => observe * Update slashed bell * Add requests to observe/unobserve posts * Add ObserveButton functionality * Rename isObservedByMe * Add observingUsersCount; simplify ObserveButton and menu entries * Fix locales * Add snapshot test for ObserveButton (WIP) * Remove empty routes push * Add test for ObserveButton * Add test for ContentMenu, improve ObserveButton test * Remove unneeded fields from PostQuery --------- Co-authored-by: Moriz Wahl <moriz.wahl@gmx.de>
This commit is contained in:
parent
81b7d4a09c
commit
1e6a74b8ce
1
webapp/assets/_new/icons/svgs/bell-slashed.svg
Normal file
1
webapp/assets/_new/icons/svgs/bell-slashed.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1080" height="1080"><rect width="100%" height="100%" fill="transparent"/><path d="M15 3a2 2 0 0 1 2 2c0 .085-.021.168-.031.25C20.49 6.174 23 9.523 23 13.281V22c0 .565.435 1 1 1h1v2h-7.188c.114.316.188.647.188 1 0 1.645-1.355 3-3 3s-3-1.355-3-3c0-.353.073-.684.188-1H5v-2h1c.565 0 1-.435 1-1v-9c0-3.726 2.574-6.866 6.031-7.75C13.021 5.168 13 5.085 13 5a2 2 0 0 1 2-2zm-.437 4A6.004 6.004 0 0 0 9 13v9c0 .353-.073.684-.188 1h12.375a2.925 2.925 0 0 1-.188-1v-8.719c0-3.319-2.546-6.183-5.813-6.281-.064-.002-.124 0-.188 0-.148 0-.292-.011-.438 0zM15 25c-.564 0-1 .436-1 1 0 .564.436 1 1 1 .564 0 1-.436 1-1 0-.564-.436-1-1-1z" style="stroke:none;stroke-width:1;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:1" transform="translate(33.75) scale(33.75)"/><rect width="74.334" height="74.334" x="-37.167" y="-37.167" rx="0" ry="0" style="stroke:#000;stroke-width:0;stroke-dasharray:none;stroke-linecap:butt;stroke-dashoffset:0;stroke-linejoin:miter;stroke-miterlimit:4;fill:#000;fill-rule:nonzero;opacity:1" transform="matrix(9.42 -12.59 .8 .6 538.54 541.95)" vector-effect="non-scaling-stroke"/></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -500,6 +500,44 @@ describe('ContentMenu.vue', () => {
|
||||
],
|
||||
])
|
||||
})
|
||||
|
||||
it('can observe posts', async () => {
|
||||
const wrapper = await openContentMenu({
|
||||
isOwner: false,
|
||||
resourceType: 'contribution',
|
||||
resource: {
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
isObservedByMe: false,
|
||||
},
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter((item) => item.text() === 'post.menu.observe')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('toggleObservePost')).toEqual([
|
||||
['d23a4265-f5f7-4e17-9f86-85f714b4b9f8', true],
|
||||
])
|
||||
})
|
||||
|
||||
it('can unobserve posts', async () => {
|
||||
const wrapper = await openContentMenu({
|
||||
isOwner: false,
|
||||
resourceType: 'contribution',
|
||||
resource: {
|
||||
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
|
||||
isObservedByMe: true,
|
||||
},
|
||||
})
|
||||
wrapper
|
||||
.findAll('.ds-menu-item')
|
||||
.filter((item) => item.text() === 'post.menu.unobserve')
|
||||
.at(0)
|
||||
.trigger('click')
|
||||
expect(wrapper.emitted('toggleObservePost')).toEqual([
|
||||
['d23a4265-f5f7-4e17-9f86-85f714b4b9f8', false],
|
||||
])
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -99,6 +99,24 @@ export default {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (this.resource.isObservedByMe) {
|
||||
routes.push({
|
||||
label: this.$t(`post.menu.unobserve`),
|
||||
callback: () => {
|
||||
this.$emit('toggleObservePost', this.resource.id, false)
|
||||
},
|
||||
icon: 'bell-slashed',
|
||||
})
|
||||
} else {
|
||||
routes.push({
|
||||
label: this.$t(`post.menu.observe`),
|
||||
callback: () => {
|
||||
this.$emit('toggleObservePost', this.resource.id, true)
|
||||
},
|
||||
icon: 'bell',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isOwner && this.resourceType === 'comment') {
|
||||
|
||||
60
webapp/components/ObserveButton.spec.js
Normal file
60
webapp/components/ObserveButton.spec.js
Normal file
@ -0,0 +1,60 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import ObserveButton from './ObserveButton.vue'
|
||||
|
||||
const localVue = global.localVue
|
||||
|
||||
describe('ObserveButton', () => {
|
||||
let mocks
|
||||
|
||||
const Wrapper = (count = 1, postId = '123', isObserved = true) => {
|
||||
return mount(ObserveButton, {
|
||||
mocks,
|
||||
localVue,
|
||||
propsData: {
|
||||
count,
|
||||
postId,
|
||||
isObserved,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
let wrapper
|
||||
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
$t: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
describe('observed', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(1, '123', true)
|
||||
})
|
||||
|
||||
it('renders', () => {
|
||||
expect(wrapper.element).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('emits toggleObservePost with false when clicked', () => {
|
||||
const button = wrapper.find('.base-button')
|
||||
button.trigger('click')
|
||||
expect(wrapper.emitted('toggleObservePost')).toEqual([['123', false]])
|
||||
})
|
||||
})
|
||||
|
||||
describe('unobserved', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper(1, '123', false)
|
||||
})
|
||||
|
||||
it('renders', () => {
|
||||
expect(wrapper.element).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('emits toggleObservePost with true when clicked', () => {
|
||||
const button = wrapper.find('.base-button')
|
||||
button.trigger('click')
|
||||
expect(wrapper.emitted('toggleObservePost')).toEqual([['123', true]])
|
||||
})
|
||||
})
|
||||
})
|
||||
39
webapp/components/ObserveButton.vue
Normal file
39
webapp/components/ObserveButton.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<ds-space margin="xx-small" class="text-align-center">
|
||||
<base-button :loading="loading" :filled="isObserved" icon="bell" circle @click="toggle" />
|
||||
<ds-space margin-bottom="xx-small" />
|
||||
<ds-text color="soft" class="observe-button-text">
|
||||
<ds-heading style="display: inline" tag="h3">{{ count }}x</ds-heading>
|
||||
{{ $t('observeButton.observed') }}
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
count: { type: Number, default: 0 },
|
||||
postId: { type: String, default: null },
|
||||
isObserved: { type: Boolean, default: false },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
this.$emit('toggleObservePost', this.postId, !this.isObserved)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.observe-button-text {
|
||||
user-select: none;
|
||||
}
|
||||
.text-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@ -59,7 +59,7 @@
|
||||
:key="category.id"
|
||||
v-tooltip="{
|
||||
content: `
|
||||
${$t(`contribution.category.name.${category.slug}`)}:
|
||||
${$t(`contribution.category.name.${category.slug}`)}:
|
||||
${$t(`contribution.category.description.${category.slug}`)}
|
||||
`,
|
||||
placement: 'bottom-start',
|
||||
@ -97,6 +97,7 @@
|
||||
:is-owner="isAuthor"
|
||||
@pinPost="pinPost"
|
||||
@unpinPost="unpinPost"
|
||||
@toggleObservePost="toggleObservePost"
|
||||
/>
|
||||
</client-only>
|
||||
</footer>
|
||||
@ -212,6 +213,9 @@ export default {
|
||||
unpinPost(post) {
|
||||
this.$emit('unpinPost', post)
|
||||
},
|
||||
toggleObservePost(postId, value) {
|
||||
this.$emit('toggleObservePost', postId, value)
|
||||
},
|
||||
visibilityChanged(isVisible, entry, id) {
|
||||
if (!this.post.viewedTeaserByCurrentUser && isVisible) {
|
||||
this.$apollo
|
||||
|
||||
81
webapp/components/__snapshots__/ObserveButton.spec.js.snap
Normal file
81
webapp/components/__snapshots__/ObserveButton.spec.js.snap
Normal file
@ -0,0 +1,81 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ObserveButton observed renders 1`] = `
|
||||
<div
|
||||
class="ds-space text-align-center"
|
||||
style="margin-top: 4px; margin-bottom: 4px;"
|
||||
>
|
||||
<button
|
||||
class="base-button --icon-only --circle --filled"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="base-icon"
|
||||
>
|
||||
<!---->
|
||||
</span>
|
||||
|
||||
<!---->
|
||||
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="ds-space"
|
||||
style="margin-bottom: 4px;"
|
||||
/>
|
||||
|
||||
<p
|
||||
class="ds-text observe-button-text ds-text-soft"
|
||||
>
|
||||
<h3
|
||||
class="ds-heading ds-heading-h3"
|
||||
style="display: inline;"
|
||||
>
|
||||
1x
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ObserveButton unobserved renders 1`] = `
|
||||
<div
|
||||
class="ds-space text-align-center"
|
||||
style="margin-top: 4px; margin-bottom: 4px;"
|
||||
>
|
||||
<button
|
||||
class="base-button --icon-only --circle"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="base-icon"
|
||||
>
|
||||
<!---->
|
||||
</span>
|
||||
|
||||
<!---->
|
||||
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="ds-space"
|
||||
style="margin-bottom: 4px;"
|
||||
/>
|
||||
|
||||
<p
|
||||
class="ds-text observe-button-text ds-text-soft"
|
||||
>
|
||||
<h3
|
||||
class="ds-heading ds-heading-h3"
|
||||
style="display: inline;"
|
||||
>
|
||||
1x
|
||||
</h3>
|
||||
|
||||
|
||||
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
@ -48,6 +48,9 @@
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</template>
|
||||
|
||||
@ -13,6 +13,8 @@ export default (i18n) => {
|
||||
updatedAt
|
||||
disabled
|
||||
deleted
|
||||
isPostObservedByMe
|
||||
postObservingUsersCount
|
||||
author {
|
||||
id
|
||||
slug
|
||||
|
||||
@ -38,4 +38,5 @@ module.exports = {
|
||||
},
|
||||
moduleFileExtensions: ['js', 'json', 'vue'],
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
snapshotSerializers: ['jest-serializer-vue'],
|
||||
}
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Benachrichtigungen",
|
||||
"user": "Nutzer"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": "beobachtet"
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": "Antworten",
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Beitrag löschen",
|
||||
"edit": "Beitrag bearbeiten",
|
||||
"observe": "Beitrag beobachten",
|
||||
"observedSuccessfully": "Du beobachtest diesen Beitrag!",
|
||||
"pin": "Beitrag anheften",
|
||||
"pinnedSuccessfully": "Beitrag erfolgreich angeheftet!",
|
||||
"unobserve": "Beitrag nicht mehr beobachten",
|
||||
"unobservedSuccessfully": "Du beobachtest diesen Beitrag nicht mehr!",
|
||||
"unpin": "Beitrag loslösen",
|
||||
"unpinnedSuccessfully": "Angehefteten Beitrag erfolgreich losgelöst!"
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Notifications",
|
||||
"user": "User"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": "observed"
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": "Reply",
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Delete post",
|
||||
"edit": "Edit post",
|
||||
"observe": "Observe post",
|
||||
"observedSuccessfully": "You are now observing this post!",
|
||||
"pin": "Pin post",
|
||||
"pinnedSuccessfully": "Post pinned successfully!",
|
||||
"unobserve": "Stop to observe post",
|
||||
"unobservedSuccessfully": "You are no longer observing this post!",
|
||||
"unpin": "Unpin post",
|
||||
"unpinnedSuccessfully": "Post unpinned successfully!"
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Notificaciones",
|
||||
"user": "Usuario"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": "Contestar",
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Borrar contribución",
|
||||
"edit": "Editar contribución",
|
||||
"observe": "Observar contribución",
|
||||
"observedSuccessfully": null,
|
||||
"pin": "Anclar contribución",
|
||||
"pinnedSuccessfully": "¡Contribución anclado con éxito!",
|
||||
"unobserve": "Dejar de observar contribución",
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": "Desanclar contribución",
|
||||
"unpinnedSuccessfully": "¡Contribución desanclado con éxito!"
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Notifications",
|
||||
"user": "Utilisateur"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": null,
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Supprimer le Post",
|
||||
"edit": "Modifier le Post",
|
||||
"observe": "Observer le Post",
|
||||
"observedSuccessfully": null,
|
||||
"pin": "Épingler le Post",
|
||||
"pinnedSuccessfully": "Poste épinglé avec succès!",
|
||||
"unobserve": "Ne plus observer le Post",
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": "Retirer l'épingle du poste",
|
||||
"unpinnedSuccessfully": "Épingle retirer du Post avec succès!"
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": null,
|
||||
"user": null
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": null,
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": null,
|
||||
"edit": null,
|
||||
"observe": null,
|
||||
"observedSuccessfully": null,
|
||||
"pin": null,
|
||||
"pinnedSuccessfully": null,
|
||||
"unobserve": null,
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": null,
|
||||
"unpinnedSuccessfully": null
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": null,
|
||||
"user": null
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": null,
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": null,
|
||||
"edit": null,
|
||||
"observe": null,
|
||||
"observedSuccessfully": null,
|
||||
"pin": null,
|
||||
"pinnedSuccessfully": null,
|
||||
"unobserve": null,
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": null,
|
||||
"unpinnedSuccessfully": null
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": null,
|
||||
"user": null
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": null,
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Usuń wpis",
|
||||
"edit": "Edytuj wpis",
|
||||
"observe": null,
|
||||
"observedSuccessfully": null,
|
||||
"pin": null,
|
||||
"pinnedSuccessfully": null,
|
||||
"unobserve": null,
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": null,
|
||||
"unpinnedSuccessfully": null
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Notificações",
|
||||
"user": "Usuário"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": null,
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Excluir publicação",
|
||||
"edit": "Editar publicação",
|
||||
"observe": "Observar publicação",
|
||||
"observedSuccessfully": null,
|
||||
"pin": "Fixar publicação",
|
||||
"pinnedSuccessfully": "Publicação fixada com sucesso!",
|
||||
"unobserve": "Deixar de observar publicação",
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": "Desafixar publicação",
|
||||
"unpinnedSuccessfully": "Publicação desafixada com sucesso!"
|
||||
},
|
||||
|
||||
@ -747,6 +747,9 @@
|
||||
"title": "Уведомления",
|
||||
"user": "Пользователь"
|
||||
},
|
||||
"observeButton": {
|
||||
"observed": null
|
||||
},
|
||||
"post": {
|
||||
"comment": {
|
||||
"reply": "Ответ",
|
||||
@ -778,8 +781,12 @@
|
||||
"menu": {
|
||||
"delete": "Удалить пост",
|
||||
"edit": "Редактировать пост",
|
||||
"observe": null,
|
||||
"observedSuccessfully": null,
|
||||
"pin": "Закрепить пост",
|
||||
"pinnedSuccessfully": "Пост больше не закреплен!",
|
||||
"unobserve": null,
|
||||
"unobservedSuccessfully": null,
|
||||
"unpin": "Открепить пост",
|
||||
"unpinnedSuccessfully": "Пост успешно не закреплено!"
|
||||
},
|
||||
|
||||
@ -35,5 +35,23 @@ export default {
|
||||
})
|
||||
.catch((error) => this.$toast.error(error.message))
|
||||
},
|
||||
toggleObservePost(postId, value, refetchPostList = () => {}) {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: PostMutations().toggleObservePost,
|
||||
variables: {
|
||||
value,
|
||||
id: postId,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
const message = this.$t(
|
||||
`post.menu.${value ? 'observedSuccessfully' : 'unobservedSuccessfully'}`,
|
||||
)
|
||||
this.$toast.success(message)
|
||||
refetchPostList()
|
||||
})
|
||||
.catch((error) => this.$toast.error(error.message))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
"express": "~4.21.2",
|
||||
"graphql": "~14.7.0",
|
||||
"intersection-observer": "^0.12.0",
|
||||
"jest-serializer-vue": "^3.1.0",
|
||||
"jsonwebtoken": "~9.0.2",
|
||||
"linkify-it": "~5.0.0",
|
||||
"mapbox-gl": "1.13.2",
|
||||
|
||||
@ -283,6 +283,9 @@
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</template>
|
||||
|
||||
@ -116,6 +116,9 @@
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</template>
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
:is-owner="isAuthor"
|
||||
@pinPost="pinPost"
|
||||
@unpinPost="unpinPost"
|
||||
@toggleObservePost="toggleObservePost"
|
||||
/>
|
||||
</client-only>
|
||||
</section>
|
||||
@ -111,6 +112,18 @@
|
||||
:post-id="post.id"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
<!-- Follow Button -->
|
||||
<ds-flex-item
|
||||
:width="{ lg: '15%', md: '22%', sm: '22%', base: '100%' }"
|
||||
class="shout-button"
|
||||
>
|
||||
<observe-button
|
||||
:is-observed="post.isObservedByMe"
|
||||
:count="post.observingUsersCount"
|
||||
:post-id="post.id"
|
||||
@toggleObservePost="toggleObservePost"
|
||||
/>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-space>
|
||||
<!-- Comments -->
|
||||
@ -156,6 +169,7 @@ import ContentMenu from '~/components/ContentMenu/ContentMenu'
|
||||
import DateTimeRange from '~/components/DateTimeRange/DateTimeRange'
|
||||
import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
import HcShoutButton from '~/components/ShoutButton.vue'
|
||||
import ObserveButton from '~/components/ObserveButton.vue'
|
||||
import LocationTeaser from '~/components/LocationTeaser/LocationTeaser'
|
||||
import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParamsLink.vue'
|
||||
import {
|
||||
@ -184,6 +198,7 @@ export default {
|
||||
HcCategory,
|
||||
HcHashtag,
|
||||
HcShoutButton,
|
||||
ObserveButton,
|
||||
LocationTeaser,
|
||||
PageParamsLink,
|
||||
UserTeaser,
|
||||
@ -302,6 +317,8 @@ export default {
|
||||
},
|
||||
async createComment(comment) {
|
||||
this.post.comments.push(comment)
|
||||
this.post.isObservedByMe = comment.isPostObservedByMe
|
||||
this.post.observingUsersCount = comment.postObservingUsersCount
|
||||
},
|
||||
pinPost(post) {
|
||||
this.$apollo
|
||||
@ -325,6 +342,24 @@ export default {
|
||||
})
|
||||
.catch((error) => this.$toast.error(error.message))
|
||||
},
|
||||
toggleObservePost(postId, value) {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: PostMutations().toggleObservePost,
|
||||
variables: {
|
||||
value,
|
||||
id: postId,
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
const message = this.$t(
|
||||
`post.menu.${value ? 'observedSuccessfully' : 'unobservedSuccessfully'}`,
|
||||
)
|
||||
this.$toast.success(message)
|
||||
this.$apollo.queries.Post.refetch()
|
||||
})
|
||||
.catch((error) => this.$toast.error(error.message))
|
||||
},
|
||||
toggleNewCommentForm(showNewCommentForm) {
|
||||
this.showNewCommentForm = showNewCommentForm
|
||||
},
|
||||
@ -379,7 +414,7 @@ export default {
|
||||
position: relative;
|
||||
/* The padding top makes sure the correct height is set (according to the
|
||||
hero image aspect ratio) before the hero image loads so
|
||||
the autoscroll works correctly when following a comment link.
|
||||
the autoscroll works correctly when following a comment link.
|
||||
*/
|
||||
|
||||
padding-top: calc(var(--hero-image-aspect-ratio) * (100% + 48px));
|
||||
|
||||
@ -156,6 +156,9 @@
|
||||
@removePostFromList="posts = removePostFromList(post, posts)"
|
||||
@pinPost="pinPost(post, refetchPostList)"
|
||||
@unpinPost="unpinPost(post, refetchPostList)"
|
||||
@toggleObservePost="
|
||||
(postId, value) => toggleObservePost(postId, value, refetchPostList)
|
||||
"
|
||||
/>
|
||||
</masonry-grid-item>
|
||||
</template>
|
||||
|
||||
@ -12609,6 +12609,13 @@ jest-runtime@^29.7.0:
|
||||
slash "^3.0.0"
|
||||
strip-bom "^4.0.0"
|
||||
|
||||
jest-serializer-vue@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-serializer-vue/-/jest-serializer-vue-3.1.0.tgz#af65817aa416d019f837b6cc53f121a3222846f4"
|
||||
integrity sha512-vXz9/3IgBbLhsaVANYLG4ROCQd+Wg3qbB6ICofzFL+fbhSFPlqb0/MMGXcueVsjaovdWlYiRaLQLpdi1PTcoRQ==
|
||||
dependencies:
|
||||
pretty "2.0.0"
|
||||
|
||||
jest-snapshot@^29.7.0:
|
||||
version "29.7.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5"
|
||||
@ -16155,7 +16162,7 @@ pretty-time@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e"
|
||||
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
|
||||
|
||||
pretty@^2.0.0:
|
||||
pretty@2.0.0, pretty@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty/-/pretty-2.0.0.tgz#adbc7960b7bbfe289a557dc5f737619a220d06a5"
|
||||
integrity sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user